[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
27.1 Introduction to Consoles; Devices; Frames; Windows | ||
27.2 Point | ||
27.3 Window Hierarchy | ||
27.4 The Window Object | ||
27.5 Modules for the Basic Displayable Lisp Objects |
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
A window-system window that you see on the screen is called a frame in Emacs terminology. Each frame is subdivided into one or more non-overlapping panes, called (confusingly) windows. Each window displays the text of a buffer in it. (See above on Buffers.) Note that buffers and windows are independent entities: Two or more windows can be displaying the same buffer (potentially in different locations), and a buffer can be displayed in no windows.
A single display screen that contains one or more frames is called a display. Under most circumstances, there is only one display. However, more than one display can exist, for example if you have a multi-headed console, i.e. one with a single keyboard but multiple displays. (Typically in such a situation, the various displays act like one large display, in that the mouse is only in one of them at a time, and moving the mouse off of one moves it into another.) In some cases, the different displays will have different characteristics, e.g. one color and one mono.
XEmacs can display frames on multiple displays. It can even deal simultaneously with frames on multiple keyboards (called consoles in XEmacs terminology). Here is one case where this might be useful: You are using XEmacs on your workstation at work, and leave it running. Then you go home and dial in on a TTY line, and you can use the already-running XEmacs process to display another frame on your local TTY.
Thus, there is a hierarchy console -> display -> frame -> window. There is a separate Lisp object type for each of these four concepts. Furthermore, there is logically a selected console, selected display, selected frame, and selected window. Each of these objects is distinguished in various ways, such as being the default object for various functions that act on objects of that type. Note that every containing object remembers the “selected” object among the objects that it contains: e.g. not only is there a selected window, but every frame remembers the last window in it that was selected, and changing the selected frame causes the remembered window within it to become the selected window. Similar relationships apply for consoles to devices and devices to frames.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Recall that every buffer has a current insertion position, called
point. Now, two or more windows may be displaying the same buffer,
and the text cursor in the two windows (i.e. point
) can be in
two different places. You may ask, how can that be, since each
buffer has only one value of point
? The answer is that each window
also has a value of point
that is squirreled away in it. There
is only one selected window, and the value of “point” in that buffer
corresponds to that window. When the selected window is changed
from one window to another displaying the same buffer, the old
value of point
is stored into the old window’s “point” and the
value of point
from the new window is retrieved and made the
value of point
in the buffer. This means that window-point
for the selected window is potentially inaccurate, and if you
want to retrieve the correct value of point
for a window,
you must special-case on the selected window and retrieve the
buffer’s point instead. This is related to why save-window-excursion
does not save the selected window’s value of point
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
If a frame contains multiple windows (panes), they are always created by splitting an existing window along the horizontal or vertical axis. Terminology is a bit confusing here: to split a window horizontally means to create two side-by-side windows, i.e. to make a vertical cut in a window. Likewise, to split a window vertically means to create two windows, one above the other, by making a horizontal cut.
If you split a window and then split again along the same axis, you will end up with a number of panes all arranged along the same axis. The precise way in which the splits were made should not be important, and this is reflected internally. Internally, all windows are arranged in a tree, consisting of two types of windows, combination windows (which have children, and are covered completely by those children) and leaf windows, which have no children and are visible. Every combination window has two or more children, all arranged along the same axis. There are (logically) two subtypes of windows, depending on whether their children are horizontally or vertically arrayed. There is always one root window, which is either a leaf window (if the frame contains only one window) or a combination window (if the frame contains more than one window). In the latter case, the root window will have two or more children, either horizontally or vertically arrayed, and each of those children will be either a leaf window or another combination window.
Here are some rules:
nil
. Remember that horizontally-arrayed
means “side-by-side” and vertically-arrayed means
one above the other.
start
(the
first buffer position displayed in the window) and pointm
(the window’s stashed value of point
—see above) fields,
while combination windows have nil
in these fields.
next
and prev
fields of each child window.
dead
bit to 1 and clear out the
next
, prev
, hchild
, and vchild
fields, for
GC purposes.
next
field of the root
points to the minibuffer, and the prev
field of the minibuffer
points to the root. The other next
and prev
fields are
nil
, and the frame points to both of these windows.
Minibuffer-less frames have no minibuffer window, and the next
and prev
of the root window are nil
. Minibuffer-only
frames have no root window, and the next
of the minibuffer window
is nil
but the prev
points to itself. (#### This is an
artifact that should be fixed.)
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
Windows have the following accessible fields:
frame
The frame that this window is on.
mini_p
Non-nil
if this window is a minibuffer window.
buffer
The buffer that the window is displaying. This may change often during the life of the window.
dedicated
Non-nil
if this window is dedicated to its buffer.
pointm
This is the value of point in the current buffer when this window is selected; when it is not selected, it retains its previous value.
start
The position in the buffer that is the first character to be displayed in the window.
force_start
If this flag is non-nil
, it says that the window has been
scrolled explicitly by the Lisp program. This affects what the next
redisplay does if point is off the screen: instead of scrolling the
window to show the text around point, it moves point to a location that
is on the screen.
last_modified
The modified
field of the window’s buffer, as of the last time
a redisplay completed in this window.
last_point
The buffer’s value of point, as of the last time a redisplay completed in this window.
left
This is the left-hand edge of the window, measured in columns. (The leftmost column on the screen is column 0.)
top
This is the top edge of the window, measured in lines. (The top line on the screen is line 0.)
height
The height of the window, measured in lines.
width
The width of the window, measured in columns.
next
This is the window that is the next in the chain of siblings. It is
nil
in a window that is the rightmost or bottommost of a group of
siblings.
prev
This is the window that is the previous in the chain of siblings. It is
nil
in a window that is the leftmost or topmost of a group of
siblings.
parent
Internally, XEmacs arranges windows in a tree; each group of siblings has a parent window whose area includes all the siblings. This field points to a window’s parent.
Parent windows do not display buffers, and play little role in display except to shape their child windows. Emacs Lisp programs usually have no access to the parent windows; they operate on the windows at the leaves of the tree, which actually display buffers.
hscroll
This is the number of columns that the display in the window is scrolled horizontally to the left. Normally, this is 0.
use_time
This is the last time that the window was selected. The function
get-lru-window
uses this field.
display_table
The window’s display table, or nil
if none is specified for it.
update_mode_line
Non-nil
means this window’s mode line needs to be updated.
base_line_number
The line number of a certain position in the buffer, or nil
.
This is used for displaying the line number of point in the mode line.
base_line_pos
The position in the buffer for which the line number is known, or
nil
meaning none is known.
region_showing
If the region (or part of it) is highlighted in this window, this field
holds the mark position that made one end of that region. Otherwise,
this field is nil
.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
‘console-msw.c’ ‘console-msw.h’ ‘console-stream.c’ ‘console-stream.h’ ‘console-tty.c’ ‘console-tty.h’ ‘console-x.c’ ‘console-x.h’ ‘console.c’ ‘console.h’ |
These modules implement the console Lisp object type. A console contains multiple display devices, but only one keyboard and mouse. Most of the time, a console will contain exactly one device.
This model may no longer suffice. The X Window System (at least) now supports a variety of input devices, including touchscreens and tablets, as well as the traditional keyboard and mouse, and may even be able to support multiple instances of a single type of input device (especially pointing devices) on a single console.
Consoles are the top of a lisp object inclusion hierarchy. Consoles contain devices, which contain frames, which contain windows.
‘device-msw.c’ ‘device-tty.c’ ‘device-x.c’ ‘device.c’ ‘device.h’ |
These modules implement the device Lisp object type. This abstracts a particular screen or connection on which frames are displayed. As with Lisp objects, event interfaces, and other subsystems, the device code is separated into a generic component that contains a standardized interface (in the form of a set of methods) onto particular device types.
The device subsystem defines all the methods and provides method services for not only device operations but also for the frame, window, menubar, scrollbar, toolbar, and other displayable-object subsystems. The reason for this is that all of these subsystems have the same subtypes (X, TTY, Microsoft Windows, etc.) as devices do.
This abstraction is probably broken (as of late 2004), at least for X consoles, with the advent of the Xft library. Xft is a complete break from the traditional approach to text rendering in the X11 environment, since fonts are composed of glyphs rendered by client-side code. These glyphs are then transmitted to the server as sets of trapezoids, and displayed by the XRender extension (where available; the X11 core protocol can also be used, but this is slow). The XRender extension is especially attractive because it allows modern image composition techniques to be used to render antialiased fonts.
By contrast, the traditional approach renders fonts on the server side as a collection of bitmaps. It is also possible use a font server that knows how to render antialiased fonts, but for some reason this approach has never caught on.
The problem that this creates for XEmacs is that the traditional (and still popular) widget sets, the various Athena variants and the Motif widget set, are based on the server-side rendering model. Thus, even if XEmacs-specific widgets (such as the basic text window, the Lucid menubar, and the recently added tab control) can be adapted to render text via Xft, older widgets (such as buttons and labels) and “modern” widgets derived from traditional widgets (the progress gauge) still expect their font resources to be converted to server-side fonts. Then text is rendered by calls to the core protocol via Xlib, rather than by calls to the XRender protocol via Xft.
It’s even possible to imagine a situation where a widget is composed of components which draw their own text (predefined widgets) as well as new components which can draw using more modern methods. Handling this will either require reworking the Emacs face mechanism to provide a way to determine whether this widget can use that font, or ways to give each of several different widgets, even different components of a given widget, a different face property. This is already an issue, as widgets generally derive their font from the gui-element face, but this might not be appropriate for widgets embedded in a buffer.
There seem to be two overall ways to go.
‘frame-msw.c’ ‘frame-tty.c’ ‘frame-x.c’ ‘frame.c’ ‘frame.h’ |
Each device contains one or more frames in which objects (e.g. text) are displayed. A frame corresponds to a window in the window system; usually this is a top-level window but it could potentially be one of a number of overlapping child windows within a top-level window, using the MDI (Multiple Document Interface) protocol in Microsoft Windows or a similar scheme.
The ‘frame-*’ files implement the frame Lisp object type and provide the generic and device-type-specific operations on frames (e.g. raising, lowering, resizing, moving, etc.).
‘window.c’ ‘window.h’ |
Each frame consists of one or more non-overlapping windows (better known as panes in standard window-system terminology) in which a buffer’s text can be displayed. Windows can also have scrollbars displayed around their edges.
‘window.c’ and ‘window.h’ implement the window Lisp object type and provide code to manage windows. Since windows have no associated resources in the window system (the window system knows only about the frame; no child windows or anything are used for XEmacs windows), there is no device-type-specific code here; all of that code is part of the redisplay mechanism or the code for particular object types such as scrollbars.
[ << ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated by Aidan Kehoe on December 27, 2016 using texi2html 1.82.