@setfilename ../info/screens
@node Screens, Buttons, General Information, top
@chapter Screens

This chapter describes screen features supported by Epoch, except for
the elisp extensions described in @ref{Miscellaneous}.

@menu
* Screen Basics::              Screen Basics
* Screen Properties::          Screen Properties
* Controlling Screens::        Controlling Screens
* Screens and Windows::        Screens and Windows
* Manipulating Screens::       Manipulating Screens
* Screen Updating::            Screen Updating
* Icons::                      Icons
@end menu

@node Screen Basics, Screen Properties, Screens, Screens
@section Screen Basics

@cindex X windows and GNU Emacs windows
@cindex window configuration

In this document, the term  @dfn{screen} will mean an X window, and
@dfn{window} will refer to an editor window to avoid confusion.
In most cases working within a screen will be the same as in GNU Emacs.

@cindex screens
Each screen contains its own Emacs window hierarchy.  (This terminology
is a little confusing: when GNU Emacs uses the term @dfn{window} this
refers to the logical structure in which a buffer is displayed.  The
name "window" was already appropriated, so we had to call our
``X-windows'' something different; they are therefore called
@dfn{screens}.)  When a screen is first created, it contains a single
window with its mode line covering the entire screen.  The buffer for this 
window is set to @code{*scratch*} unless a different buffer is specified.

@cindex edit screens
@cindex minibuffer screens
Epoch supports two types of screens:  @dfn{edit screens} and
@dfn{minibuffer screens}. There is always exactly one minibuffer screen.
The number of edit screens can change, but there is always at least one.
Emacs assumes there is at least one edit window at all times.  A single edit 
screen and the minibuffer screen together act much like
normal GNU Emacs.

@cindex selected screen
@cindex current screen
At any time there is a single @dfn{selected screen}, analogous to the
selected window, also called the @dfn{current screen}.  Standard
window functions work, but they only apply to the current screen.  E.g.,
@code{one-window-p} returns non-@code{nil} if there is only one window
on the current screen. Buffers are shared among all screens, so any
buffer in any window can be accessed, and will show up in buffer lists.
Killing buffers removes them from all windows. The current version of
Epoch does not update non-current screens by default (see
@code{epoch::global-update} in @xref{Screen Updating}).

@cindex screen object
Epoch adds @dfn{screens} as a new Emacs Lisp primitive type.  Screens
are printed as @code{#<screen @var{n}>}, where @var{n} is the
@dfn{screen ID}.  This ID is a sequence number attached to a screen when
it is created.  It serves primarily as a human convenience.  Any
argument to a primitive listed as @var{screen} can be either a screen
object or a screen ID.  However, when the result of a function is a
screen, this means a screen object is returned unless specifically
mentioned to do otherwise.  Optional screen arguments default to the
current screen unless otherwise specified.

@cindex mapped screen
@cindex unmapped screen
A screen that is displayed is said to be @dfn{mapped}; if it is only
displayed as an icon, it is said to be @dfn{unmapped}.  By X Window
System conventions, a screen is mapped iff its X window is mapped.

There is one significant difference between screens and windows: screens
are known to external programs (e.g., the X-server). This means that the
GNU Emacs scheme for window activities is not sufficient for screen
activities.  In particular, the creation of screens is much more complex
than window creation.


@cindex create screen
@defun epoch::create-screen &optional buffer alist
Creates a new screen (unmapped), and returns it.  If the @var{buffer} argument
is present, that buffer is attached to the single window originally
present in the screen, otherwise the @code{*scratch*} buffer is used.
The @var{alist} argument is used to override screen creation defaults.
See @code{*create-screen-alist-hook*} below.
@end defun 

@defun create-screen &optional buffer alist
Calls @code{epoch::create-screen} but does some additional things.  The
alist passed to @code{epoch::create-screen} is a copy of @var{alist}
appended with a copy of @code{epoch-mode-alist} and two additional
properties.  These additional properties are @code{icon-name} and
@code{title} (which here default to @var{buffer name}@@@var{system
name}).  Also see @code{*create-screen-alist-hook} below.
@end defun

@defvar *create-screen-alist-hook*
@cindex hooks
@cindex create screen
This is a hook variable used by @code{create-screen}. Just before the
call to @code{epoch::create-screen}, each function in the hook is called
with the screen property alist @code{create-screen} has generated. Each
function should return a new version of the alist to be used instead.
Normally, the hook function will add or modify some of the entries in
the alist. See the code in @xref{Screen Pools} for an example.
@end defvar


@node Screen Properties, Controlling Screens, Screen Basics, Screens
@section Screen Properties

@cindex screen properties or attributes
@cindex screen default-sets
Screens have a large number of properties (or attributes) that can
differ between screens, and are externally visible (e.g., colors, cursor
shape and color, font, size, title, class).  Most of the complexity of
screen creation is involved in dealing with these properties.  Epoch
deals with @dfn{default-sets} which are collections of X window property
types and values.  When a screen is created, a @dfn{default-set} is used to
set the various properties of the screen.  For information on default sets
@xref{X Window Program Defaults}.

In order to allow more variety in screens, Epoch provides more ways of
overriding the global X default set. A global variable
@code{epoch::screen-properties} contains an alist of screen properties.
At screen creation time, a copy of the global default-set is made, and
entries are overwritten with values from
@code{epoch::screen-properties}.  After that, the alist given as
an argument to @code{create-screen} (if any) is used to override any previous
values.

The order of determination of the default set for each screen is as follows (in
increasing order of precedence):

@enumerate
@item  
X Window Program Defaults (@pxref{X Window Program Defaults})

@item  
@cindex @code{epoch::screen-properties} alist
Values in @code{epoch::screen-properties}.

@item  
@cindex @code{epoch::create-screen} properties alist
Alist argument to @code{epoch::create-screen}.

@item  
@vindex @code{epoch-mode-alist} properties alist
Mode-specific values using @code{epoch-mode-alist}, if
@code{create-screen} is used for creation.

@item  
@cindex @code{create-screen} properties alist
Alist argument to @code{create-screen}.

@end enumerate


@defvar epoch::screen-properties
This variable should contain an alist, the key values being screen
property keys. The primitive attempts to bypass bad entries, but if the
alist is improperly formed, Epoch may experience bizarre failures.
@end defvar


@defvar epoch-mode-alist
This variable allows you to associate a set of X defaults with an emacs
mode.  The form is a list, each element of which is a form
@code{(mode-name . @var{alist-of-defaults})}.  Whenever
@code{create-screen} is called, the mode of the @var{buffer} argument
(or the @code{scratch} buffer's mode if @var{buffer} is @code{nil}) is used to
look in the alist.

This feature allows you to set geometry, colors, font, etc by mode.  It's
useful to allow (for example) 80x60 windows for @file{.c} and @file{.h}
files, but a regular size window for other file types.  See the definition
of @file{epoch-mode-alist} in @file{epoch.el} for some examples.

Thus you can set up a default mode to epoch upon entry and then override 
portions of it at the time you call @code{create-screen}. 
@end defvar


The table below is a list of all screen property keys recognized by the
screen creation routines. The defaults listed are the hard-wired defaults, but
they may be superceded as described in @ref{X Window Program Defaults}. 
Values listed as
@code{flag} are false if the value is @code{nil}, true for any other
value.

As an example, to set screens to have the font @samp{@code{9x15}} and
the @samp{@code{Gumby}} cursor, the following Elisp code would be used:

@example
(setq epoch::screen-properties
  (cons '(font . "9x15") 
         (cons '(cursor-glyph . 56) epoch::screen-properties)))
@end example


@table @kbd

@item Name
Type, Default, Description

@item foreground
@cindex screen foreground
String, Black, Screen foreground

@item background
@cindex screen background
String, White, Screen background 

@item cursor-color
@cindex text cursor color
String, Black, Text cursor color

@item cursor-foreground
@cindex cursor foreground color
String, White, cursor foreground color

@item cursor-background
@cindex cursor background color
String, Black, cursor background color

@item border-color
@cindex border color
String, White, X border color

@item in-border-width
@cindex internal border width
Number, 2, Internal border width

@item ex-border-width
@cindex external border width
Number, 1, External border width

@item title
@cindex screen title
String, ``Edit'', Screen title

@item name
@cindex screen resource name
String, ``epoch'', Screen resource name

@item class
@cindex screen class name
String, ``Emacs'', Screen class name

@item update
@cindex screen updating
String, false, Flag to indicate non-local screen updating

@item geometry
@cindex screen geometry
String, 80x24, Geometry specifier.
Size units are characters.  Screen must be at least 2 lines high.

@item cursor-glyph
@cindex cursor glyph
Number, 86, X cursor glyph. Index into the cursor font.

@item reverse
@cindex reverse
Flag, False, Reverse foreground / background 

@item font
@cindex font
String, ``fixed'', Font name 

@item icon-name
@cindex icon name
String, ``'', Name of Icon for Screen

@item motion
@cindex motion events
Flag, nil, @code{t} will cause motion-events to be sent to
screen, @code{nil} will inhibit this.

@item parent
@cindex X parent resource id
X resource, nil,
If non-@code{nil}, must be an X ``resource id''.  The new
screen is created as a child of this resource.  Useful to provide
clipping-parents, for example when trying to put screen in a form of some
kind.   @i{This option is extremely dangerous and you should not use it if
you dont know what you are doing.}

@item initial-state
@cindex screen initial state
@cindex NormalState
@cindex IconicState
Flag, True,
Starting state of screen. True means NormalState,
false is IconicState.
@end table


@node Controlling Screens, Screens and Windows, Screen Properties, Screens
@section Controlling Screens

The primitives in this section concern internal manipulations of screens.

@defun epoch::get-screen &optional screen
@findex make-screen
Coerces a @var{screen} or screen ID argument to the corresponding screen
object.
@end defun

@defun epoch::get-screen-id &optional screen
@findex make-id
Coerces a @var{screen} or screen ID to the corresponding screen ID.
Returns @code{nil} if the screen is deleted.
@end defun

@defun make-screen &optional screen
Use get-screen instead. OBSOLETE.
@end defun

@defun make-id &optional screen
Use get-screen-id instead. OBSOLETE.
@end defun

@defun epoch::screen-p screen
@findex epoch::screenp
Returns @code{t} if the argument is of type @var{screen}, @code{nil}
otherwise.  
@end defun

@defun epoch::screen-list &optional unmapped
@cindex unmapped screens list
Returns a list of all mapped screens, except the minibuffer which is
never in the list. If the argument @var{unmapped} 
non-@code{nil} then unmapped screens are also included.
@end defun

@defun epoch::next-screen &optional screen unmapped
Returns the next screen in the internal ordering. With no arguments, it
is the next screen after the current screen. A @var{screen} argument returns
the next screen past the argument. Unmapped screens are not
returned, unless the second argument @var{unmapped} is
non-@code{nil}.  The minibuffer screen is never returned.
@end defun

@defun epoch::prev-screen &optional screen unmapped
Same as @code{epoch::next-screen} except the internal screen list is
traversed in the opposite order.
@end defun

@defun epoch::select-screen &optional screen
Makes the argument @var{screen} the current edit screen. The default is
the next screen, as defined by @code{epoch::next-screen}. The minibuffer
screen cannot be selected. Unmapped screens may be selected, but only
explicitly or if only unmapped screens are left.  Epoch attempts to remember
what window was last selected in each screen, and selects that one.  The hook
@var{*select-screen-hook*} is run at this time.


Returns the selected screen, or @code{nil} if given a bad argument or if
@var{screen} has been deleted.

@b{Note:} If a window is selected by @code{select-window}, an implicit
@code{epoch::select-screen} is done to select the screen the window is on.
This insures that the current window is on the current screen whether
@code{epoch::select-screen} or @code{select-window} was used. In fact, this
primitive actually works by selecting a window in the new screen.
@end defun

@defvar *select-screen-hook*
This hook is run by @code{epoch::select-screen}, and can be used to trap
both @code{focus} and @code{move} events.
@end defvar

@defun epoch::current-screen
Returns the current edit screen. The minibuffer screen is never returned.
@end defun

@defun epoch::minibuf-screen
Returns the minibuffer screen.
@end defun

@defun epoch::delete-screen &optional screen
Deletes a screen. Returns @code{t} if successful, @code{nil} otherwise.
It is an error to delete the sole remaining screen, and Epoch will not allow
this.

If you delete a screen and it is the current screen, it first uses
@code{epoch::select-screen} to select a new screen.

@cindex ICCCM compatability for deletion
@b{BUG:} Window managers can delete the last edit screen. If this happens,
Epoch will crash and burn in short order.  Window managers  @i{should}
obey the ICCCM standard and send a delete signal to the client; then
Epoch can grab this and terminate gracefully.  
@end defun

@node Screens and Windows, Manipulating Screens, Controlling Screens, Screens
@section Screens and Windows

Epoch supports all of the windowing ability of GNU-Emacs on each screen.
Every window is on a screen, and can never be moved from that screen.
Epoch provides some primitives to help in the interaction between
screens and windows.

@defun epoch::get-buffer-window buffer
Searchs for a window displaying @var{buffer} on all screens. Returns such a
window if successful, @code{nil} otherwise.  This is effectively an updated
version of the normal primitive  @code{get-buffer-window}, which searches
only the current screen and minibuffer.

Note: selecting a window also selects the screen it is on. Remember that
the window may be on an unmapped screen. This function has no wrapper
since that would collide with the standard function
@code{get-buffer-window}.
@end defun

@defun epoch::screens-of-buffer buffer
Returns a list of all screens on which @var{buffer} is displayed in a window.
@end defun

@defun epoch::screen-of-window window
Returns the screen that @var{window} is on.
@end defun

@defun epoch::first-window &optional screen
Returns the first window in canonical order for @var{screen}.
Use @code{next-window} to find the other windows in the @var{screen}.
@end defun

@defun epoch::selected-window &optional screen
Returns the selected window for @var{screen}. This is the window that
would be selected if the screen it is on were selected, or equivalently
the selected window the last time @var{screen} was the current screen.

Note: There is no wrapper for this function, since that would collide
with the standard function @code{selected-window}.
@end defun

@node Manipulating Screens, Screen Updating, Screens and Windows, Screens
@section Manipulating Screens

@cindex windowing system controls

These primitives allow control of the windowing system aspects of screens.
Most of them correspond directly to X-window calls.

Each of these functions return the screen, if successful, or
@code{nil} otherwise.

The @var{screen-or-xwin} arguments may be screen objects or X resource
object with type window (@pxref{X Resources}).


@defun epoch::raise-screen &optional screen-or-xwin
Raises the @var{screen-or-xwin} to the top of the display.  This is called
by @code{epoch::select-screen}.
@end defun

@defun epoch::lower-screen &optional screen-or-xwin
Lowers the @var{screen-or-xwin} to the bottom of the display.
@end defun

@defun epoch::map-screen &optional screen-or-xwin
Maps the @var{screen-or-xwin} onto the display. No effect if the screen is
already mapped.
@end defun

@defun epoch::unmap-screen &optional screen-or-xwin
Unmaps the @var{screen-or-xwin}. This is for sophisticated users only, as it
does not check to see if the screen is the edit screen or the
minibuffer. If the unmapped screen is the edit screen, it remains so -
you just won't be able to see it.
@end defun

@defun epoch::mapraised-screen &optional screen-or-xwin
This does a MapRaised call on the @var{screen-or-xwin}.  This is equivalent to
doing a map followed atomically by a raise.  If no argument is present,
it uses the current screen.
@end defun

@defun epoch::iconify-screen &optional screen
Sends ICCCM client message requesting iconification of screen (or current
screen if no argument present).  

@cindex ICCCM compatibilty for iconify
@b{Note:}
@itemize @bullet
@item  
Some window managers are not ICCCM compliant and will not handle
this correctly.  

@item  
ICCCM standard says that to uniconify, an
@code{epoch::map-screen} should be used.  This doesn't seem to work for
many window managers at present.
@end itemize

@end defun


@defun epoch::screen-mapped-p &optional screen
Returns @code{t} if the @var{screen} exists and is mapped, @code{nil}
otherwise.
@end defun

@defun epoch::screen-height &optional screen
Returns the height (in characters) of the @var{screen}. @b{NOTE:} there is no
Epoch wrapper function for this primitive, as it would conflict with the 
existing GNU Emacs @code{screen-height} primitive.

@end defun

@defun epoch::screen-width &optional screen
Returns the width (in characters) of the @var{screen}. @b{NOTE:} there is no
Epoch wrapper function for this primitive, as it would conflict with the
existing GNU Emacs @code{screen-width} primitive.
@end defun

@defun epoch::change-screen-size &optional width height screen
Attempts to resize the @var{screen}, leaving the upper left corner fixed.
The @var{width} and @var{height} are in characters, and default to the 
current width and height. This uses the @code{XResizeWindow()} call, which may
be intercepted by the window manager.  The @var{width} and @var{height}
values are adjusted be be not more than 150.  The @var{height} is
adjusted to at least 1 for the minibuffer and 2 for edit screens.
@end defun

@defun epoch::font &optional font screen
If called with @code{nil} @var{font} argument, this function returns the
current font.  If called with @code{font} argument, it changes
@var{screen}'s font to be that font.  It will resize the screen so that
it still has the same character geometry.  It operates on the current
screen if @var{screen} is @code{nil}.  The result is a list of three
elements: Font name, character-width, character-height in pixels.
@end defun

@defun epoch::title &optional name screen
If called with @code{nil} @var{name} argument, this function returns the
X screen name for @var{screen} or the current screen.  If @code{name} is
a string, @var{screen}'s title is changed accordingly.
@end defun

@defun epoch::plane-size
@cindex minor screens
Returns a cons pair.  Car is plane width, cdr is plane height in pixels.
(A plane is a ``minor screen'' on a display:  on mono screens, there is
just one plane, color screens sometimes have several).
@end defun

@defun epoch::screen-information &optional screen-or-xwin
Returns information about @var{screen-or-xwin}, or the current screen if
@var{screen-or-xwin} is @code{nil}.  The information is a list with
the following elements:

@enumerate
@item  
@cindex X and Y location of screen
X location of screen in pixels

@item  
Y location of screen in pixels

@item  
@cindex width and height of screen
Width of screen in character columns

@item  
Height of screen in character lines

@item  
@cindex external and internal borderwidth of screen
External Borderwidth in pixels

@item  
Internal Borderwidth; for an xwin, this is always 0.

@item  
@cindex screen mapped state
Map state: @code{t} if normal, @code{nil} if iconic.

@end enumerate
@end defun

@defun epoch::move-screen x y &optional screen-or-xwin
Sends request to window manager to move upper-left corner of
@var{screen-or-xwin} (or current screen if no third argument) to given
(@var{x},@var{y}) coordinates in pixels.  Note that some window managers may
choose to ignore this request.
@end defun


@defun epoch::foreground &optional color screen
Set/get the foreground color of the screen. If @var{color} is @code{nil}
then the function returns the current foreground color triplet.
Otherwise it attempts to set the foreground color, and returns @code{t}
on success and @code{nil} otherwise.
@end defun

@defun epoch::background &optional color screen
Set/get the background color of the screen. If @var{color} is @code{nil} then
the function returns the current background color triplet. Otherwise
it attempts to set the background color, and returns @code{t} on success
and @code{nil} otherwise.
@end defun

@defun epoch::cursor-color &optional color screen
Set/get the text cursor color of the screen. If @var{color} is @code{nil} then
the function returns the current text cursor color triplet. Otherwise
it attempts to set the text cursor color, and returns @code{t} on success
and @code{nil} otherwise.
@end defun

@defun epoch::cursor-glyph &optional glyph screen
Set/get the X cursor glyph. If @var{glyph} is @code{nil}, returns the
current glyph number, otherwise attempts to set the glyph.
@end defun

@defun epoch::flash-screen &optional screen-or-xwin
Flash the @var{screen-or-xwin}. If the argument is a screen object, the
flashing is done by exchanging the foreground and background colors,
pausing .25 seconds, and then exchanging them again. For an X-window
resource (even if it is an Epoch screen), the flashing is done by
inverting the pixels, pausing, and then inverting again. This is
effective on a monochrome display, but is not as effective for color,
depending on the foreground and background colors.
@end defun

@node Screen Updating,  , Manipulating Screens, Screens
@section Screen Updating

@cindex screen updating
Epoch allows you to control which screens are updated
as their contents are changed.  The default is to only update the current
screen, which is maximally efficient.  It is possible,
however, to set things up so that all screens or only some subset of the
screens are updated.  This is useful if you are editing a buffer which 
is displayed on multiple screens, or if you have a shell or other 
process running in one buffer and you are working in another.  
Then you can set things up so that the screen with the shell 
continues to update as it runs, while you work in another screen. 
There are several ways to do this, all involving the value of the 
global variable @code{epoch::global-update}.

The functions and variables are:

@defvar epoch::global-update
There are three classes of values for this variable.

@itemize @bullet
@item  
set to @code{nil}.  Disables updating all but the local screen.

@item
set to @code{t}.  Enables potential updates: particular screens
to be updated conditionally based on the value of the screen-local update 
@var{flag}.  This flag may be set using @code{epoch::set-update}, and is 
stored in the @code{epoch-mode-alist} variable.

@item  
set to any other value: causes all screens to be updated.  This is
a shorthand for setting to @code{t} and then setting the update property on
each screen individually.

@end itemize
@end defvar

@defun epoch::set-update arg &optional screen
Sets update flag to  @var{arg} for @var{screen}, or current screen if nil.
@var{arg} must be @code{t} for update, @code{nil} for no update.  Returns
previous value of flag.
@end defun

@defun epoch::update-p &optional screen
Returns  @code{t} if @var{screen}'s update flag is set, @code{nil} otherwise.
Uses current screen if @var{screen} argument is not present.  This function
should be @code{epoch::updatep}.
@end defun
 
In addition you can use the following primitives to help control when
screens get updated:

@defun epoch::redisplay-screen &optional screen
Forces a non-premptive redraw of argument @var{screen} (current screen if 
@code{nil}.
@end defun

@defun epoch::set-screen-modified &optional screen
Mark the argument @var{screen} (current if @code{nil}) as modified for
update next time Epoch gets around to an update.
@end defun

