summaryrefslogtreecommitdiff
path: root/specs/xextproto/multibuf.xml
diff options
context:
space:
mode:
Diffstat (limited to 'specs/xextproto/multibuf.xml')
-rw-r--r--specs/xextproto/multibuf.xml1628
1 files changed, 1628 insertions, 0 deletions
diff --git a/specs/xextproto/multibuf.xml b/specs/xextproto/multibuf.xml
new file mode 100644
index 0000000..9e2b065
--- /dev/null
+++ b/specs/xextproto/multibuf.xml
@@ -0,0 +1,1628 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+<!ENTITY % defs SYSTEM "defs.ent"> %defs;
+]>
+
+
+<!-- lifted from troff+ms+XMan by doclifter -->
+<book id="multibuf">
+
+<bookinfo>
+ <title>Extending X for Double-Buffering, Multi-Buffering, and Stereo</title>
+ <authorgroup>
+ <othercredit>
+ <firstname>Jeffrey</firstname><surname>Friedberg</surname>
+ </othercredit>
+ <othercredit>
+ <firstname>Larry</firstname><surname>Seiler</surname>
+ </othercredit>
+ <othercredit>
+ <firstname>Jeff</firstname><surname>Vroom</surname>
+ </othercredit>
+ </authorgroup>
+ <copyright><year>1989</year><holder>Digital Equipment Corporation</holder></copyright>
+ <releaseinfo>X Version 11, Release &fullrelvers;</releaseinfo>
+ <releaseinfo>Version 3.3</releaseinfo>
+
+<legalnotice>
+<para>
+Permission to use, copy, modify, and distribute this documentation for any
+purpose and without fee is hereby granted, provided that the above copyright
+notice and this permission notice appear in all copies.
+Digital Equipment Corporation makes no representations
+about the suitability for any purpose of the information in
+this document. This documentation is provided "as is"
+without express or implied warranty. This document
+is subject to change.
+</para>
+</legalnotice>
+
+<legalnotice>
+<para role="multiLicensing">Copyright © 1989, 1994 X Consortium</para>
+<para>
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the ``Software''), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+</para>
+<para>
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+</para>
+<para>
+THE SOFTWARE IS PROVIDED &ldquo;AS IS&rdquo;, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+</para>
+<para>
+Except as contained in this notice, the name of the X Consortium shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from the X Consortium.
+</para>
+<para>X Window System is a trademark of The OpenGroup.</para>
+
+</legalnotice>
+</bookinfo>
+
+<preface><title>Warning</title>
+<warning><para>
+The <emphasis remap='I'>Multi-Buffering</emphasis> extension described here
+was a draft standard of the X Consortium prior to Release 6.1. It has been
+superseded by the Double Buffer
+Extension (DBE). DBE is an X Consortium Standard as of Release 6.1.
+</para></warning>
+</preface>
+
+<chapter id='Introduction'>
+<title>Introduction</title>
+
+<para>
+Several proposals have been written that address some of the
+issues surrounding the support of double-buffered, multi-buffered,
+and stereo windows in the X Window System:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+<emphasis remap='I'>Extending X for Double-Buffering,</emphasis>
+Jeffrey Friedberg, Larry Seiler, Randi Rost.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>(Proposal for) Double-Buffering Extensions</emphasis>,
+Jeff Vroom.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>An Extension to X.11 for Displays with Multiple Buffers,</emphasis>
+David S.H. Rosenthal.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+<emphasis remap='I'>A Multiple Buffering/Stereo Proposal</emphasis>,
+Mark Patrick.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+The authors of this proposal have tried to unify the above documents
+to yield a proposal that incorporates support for double-buffering,
+multi-buffering, and stereo in a way that is acceptable to all concerned.
+</para>
+</chapter>
+
+<chapter id='Goals'>
+<title>Goals</title>
+
+<para>
+Clients should be able to:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+Associate multiple buffers with a window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Paint in any buffer associated with a window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Display any buffer associated with a window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Display a series of buffers in a window in rapid succession
+to achieve a <emphasis remap='I'>smooth</emphasis> animation.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Request simultaneous display of different buffers in different windows.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+In addition, the extension should:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+Allow existing X applications to run unchanged.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Support a range of implementation methods that can capitalize on
+existing hardware features.
+ </para>
+ </listitem>
+</itemizedlist>
+
+</chapter>
+
+<chapter id='Image_Buffers'>
+<title>Image Buffers</title>
+
+<para>
+Normal windows are created using the standard
+<function>CreateWindow</function> request:
+</para>
+
+<literallayout class="monospaced">
+CreateWindow
+ parent : WINDOW
+ w_id : WINDOW
+ depth : CARD8
+ visual : VISUALID or CopyFromParent
+ x, y : INT16
+ width, height : INT16
+ border_width : INT16
+ value_mask : BITMASK
+ value_list : LISTofVALUE
+</literallayout>
+
+<para>
+This request allocates a set of window attributes and
+a buffer into which an image can be drawn.
+The contents of this <emphasis remap='I'>image buffer</emphasis> will
+be displayed when the window is mapped to the screen.
+</para>
+
+<para>
+To support double-buffering and multi-buffering,
+we introduce the notion that additional image buffers can
+be created and bound together to form groups.
+The following rules will apply:
+</para>
+
+<itemizedlist>
+ <listitem>
+ <para>
+All image buffers in a group will have the same
+visual type, depth, and geometry (ie: width and height).
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Only one image buffer per group can be displayed
+at a time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Draw operations can occur to any image buffer at
+any time.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Window management requests (<function>MapWindow</function>, <function>DestroyWindow</function>,
+<function>ConfigureWindow</function>, etc...)
+affect all image buffers associated with a window.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+Appropriate resize and exposure events will be generated
+for every image buffer that is affected by a window
+management operation.
+ </para>
+ </listitem>
+</itemizedlist>
+
+<para>
+By allowing draw operations to occur on any image buffer at any time,
+a client could, on a multi-threaded multi-processor server,
+simultaneously build up images for display.
+To support this, each buffer must have its own resource ID.
+Since buffers are different than windows and pixmaps
+(buffers are not hierarchical and pixmaps cannot be displayed)
+a new resource, <function>Buffer</function>, is introduced.
+Furthermore, a <function>Buffer</function> is also a <function>Drawable</function>, thus
+draw operations may also be performed on buffers simply
+by passing a buffer ID to the existing pixmap/window
+interface.
+</para>
+
+<para>
+To allow existing X applications to work unchanged, we assume
+a window ID passed in a draw request, for a multi-buffered
+window, will be an <emphasis remap='I'>alias</emphasis> for the ID of the currently
+displayed image buffer. Any draw requests (eq: <function>GetImage</function>) on
+the window will be relative to the displayed image buffer.
+</para>
+
+<para>
+In window management requests, only a window ID will be
+accepted. Requests like <function>QueryTree</function>, will continue to
+return only window ID's. Most events will return
+just the window ID. Some new events, described in a subsequent
+section, will return a buffer ID.
+</para>
+
+<para>
+When a window has backing store the contents of the window
+are saved off-screen. Likewise, when the contents of an image
+buffer of a multi-buffer window is saved off-screen, it is
+said to have backing store. This applies to all image buffers,
+whether or not they are selected for display.
+</para>
+
+<para>
+In some multi-buffer implementations, undisplayed buffers might be
+implemented using pixmaps. Since the contents of pixmaps exist
+off-screen and are not affected by occlusion, these image buffers
+in effect have backing store.
+</para>
+
+<para>
+On the other hand, both the displayed and undisplayed image buffers
+might be implemented using a subset of the on-screen pixels.
+In this case, unless the contents of an image buffer are saved
+off-screen, these image buffers in effect do not have backing store.
+</para>
+
+<para>
+Output to any image buffer of an unmapped multi-buffered window
+that does not have backing store is discarded. Output to any
+image buffer of a mapped multi-buffer window will be performed;
+however, portions of an image buffer may be occluded or clipped.
+</para>
+
+<para>
+When an unmapped multi-buffered window becomes mapped, the contents
+of any image buffer buffer that did not have backing store is
+tiled with the background and zero or more exposure events are
+generated. If no background is defined for the window, then
+the screen contents are not altered and the contents of any
+undisplayed image buffers are undefined. If backing store was
+maintained for an image buffer, then no exposure events are generated.
+</para>
+</chapter>
+
+<chapter id='New_Requests'>
+<title>New Requests</title>
+
+<para>
+The new request, <function>CreateImageBuffers</function>, creates a group of
+image buffers and associates them with a normal X window:
+</para>
+
+<literallayout class="monospaced">
+CreateImageBuffers
+ w_id : WINDOW
+ buffers : LISTofBUFFER
+ update_action : {Undefined,Background,Untouched,Copied}
+ update_hint : {Frequent,Intermittent,Static}
+ =&gt;
+ number_buffers : CARD16
+
+ (Errors: Window, IDChoice, Value)
+</literallayout>
+
+<para>
+One image buffer will be associated with each ID passed in
+<emphasis remap='I'>buffers</emphasis>.
+The first buffer of the list is referred to as buffer[0], the next
+buffer[1], and so on. Each buffer will have the same visual type
+and geometry as the window.
+Buffer[0] will refer to the image buffer already associated
+with the window ID and its contents will not be modified.
+The displayed image buffer attribute is set to buffer[0].
+</para>
+
+<para>
+Image buffers for the remaining ID's (buffer[1],...) are allocated.
+If the window is mapped, or if these image buffers have backing
+store, their contents will be tiled with the window background
+(if no background is defined, the buffer contents are undefined),
+and zero or more expose events will be generated for each of these
+buffers. The contents of an image buffer is undefined when
+the window is unmapped and the buffer does not have backing store.
+</para>
+
+<para>
+If the window already has a group of image buffers
+associated with it (ie: from a previous <function>CreateImageBuffers</function> request)
+the actions described for <function>DestroyImageBuffers</function> are performed first
+(this will delete the association of the previous buffer ID's and
+their buffers as well as de-allocate all buffers except for the
+one already associated with the window ID).
+</para>
+
+<para>
+To allow a server implementation to efficiently allocate the
+buffers, the total number of buffers required and
+the update action (how they will behave during an update)
+is specified "up front" in the request.
+If the server cannot allocate all the buffers requested, the
+total number of buffers actually allocated will be returned.
+No <function>Alloc</function> errors will be generated \- buffer[0] can
+always be associated with the existing displayed image buffer.
+</para>
+
+<para>
+For example, an application that wants to animate a short movie
+loop may request 64 image buffers. The server may only be able to
+support 16 image buffers of this type, size, and depth.
+The application can then decide 16 buffers is sufficient and may
+truncate the movie loop, or it may decide it really needs
+64 and will free the buffers and complain to the user.
+</para>
+
+<para>
+One might be tempted to provide a request that inquires whether
+<emphasis remap='I'>n</emphasis>
+buffers of a particular type, size, and depth
+<emphasis remap='I'>could</emphasis> be allocated.
+But if the query is decoupled from the actual allocation,
+another client could sneak in and take the buffers before the
+original client has allocated them.
+</para>
+
+<para>
+While any buffer of a group can be selected for display,
+some applications may display buffers in a predictable order
+(ie: the movie loop application). The
+<emphasis remap='I'>list order</emphasis>
+(buffer[0], buffer[1], ...) will be used as a hint by the
+server as to which buffer will be displayed next.
+A client displaying buffers in this order may see a
+performance improvement.
+</para>
+
+<para>
+<emphasis remap='I'>update_action</emphasis> indicates what should happen to a previously
+displayed buffer when a different buffer becomes displayed.
+Possible actions are:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term>Undefined</term>
+ <listitem>
+ <para>
+The contents of the buffer that was
+last displayed will become undefined after the update. This
+is the most efficient action since it allows the implementation
+to trash the contents of the buffer if it needs to.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Background</term>
+ <listitem>
+ <para>
+The contents of the buffer that was
+last displayed will be set to the background of the window after the update.
+The background action allows devices to use a fast clear
+capability during an update.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Untouched</term>
+ <listitem>
+ <para>
+The contents of the buffer that was
+last displayed will be untouched after the update. Used
+primarily when cycling through images that have already
+been drawn.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Copied</term>
+ <listitem>
+ <para>
+The contents of the buffer that was
+last displayed will become the same as those that are being
+displayed after the update. This is useful when incrementally
+adding to an image.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+
+
+<para>
+<emphasis remap='I'>update_hint</emphasis> indicates how often the client will
+request a different buffer to be displayed.
+This hint will allow smart server implementations to choose the
+most efficient means to support a multi-buffered window based
+on the current need of the application (dumb implementations
+may choose to ignore this hint). Possible hints are:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term>Frequent</term>
+ <listitem>
+ <para>
+An animation or movie loop is
+being attempted and the fastest, most efficient means for
+multi-buffering should be employed.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Intermittent</term>
+ <listitem>
+ <para>
+The displayed image will be
+changed every so often. This is common for images that are
+displayed at a rate slower than a second. For example, a
+clock that is updated only once a minute.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Static</term>
+ <listitem>
+ <para>
+The displayed image buffer will
+not be changed any time soon. Typically set by an application
+whenever there is a pause in the animation.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+To display an image buffer the following request can be used:
+</para>
+
+<literallayout class="monospaced">
+DisplayImageBuffers
+ buffers : LISTofBUFFER
+ min_delay : CARD16
+ max_delay : CARD16
+
+ (Errors: Buffer, Match)
+</literallayout>
+
+<para>
+The image buffers listed will become displayed as simultaneously
+as possible and the update action, bound at
+<function>CreateImageBuffers</function>
+time, will be performed.
+</para>
+
+<para>
+A list of buffers is specified to
+allow the server to efficiently change the display of more than one
+window at a time (ie: when a global screen swap method is used).
+Attempting to simultaneously display
+multiple image buffers from the same window is an error
+(<function>Match</function>) since it violates the rule that only one
+image buffer per group can be displayed at a time.
+</para>
+
+<para>
+If a specified buffer is already displayed,
+any delays and update action will still be
+performed for that buffer. In this instance,
+only the update action of <emphasis remap='I'>Background</emphasis>
+(and possibly
+<emphasis remap='I'>Undefined</emphasis>) will have any affect on the
+contents of the displayed buffer. These semantics allow
+an animation application to successfully execute
+even when there is only a single buffer available
+for a window.
+</para>
+<para>
+<!-- .LP -->
+When a <function>DisplayImageBuffers</function> request is made to an unmapped
+multi-buffered window, the effect of the update action depends
+on whether the image buffers involved have backing store.
+When the target of the update action is an image buffer that
+does not have backing store, output is discarded. When the
+target image buffer does have backing store, the update is performed;
+however, when the source of the update is an image buffer does not
+have backing store (as in the case of update action
+<emphasis remap='I'>Copied</emphasis>), the
+contents of target image buffer will become undefined.
+</para>
+<para>
+<!-- .LP -->
+<emphasis remap='I'>min_delay</emphasis> and
+<emphasis remap='I'>max_delay</emphasis> put a bound on how long the
+server should wait before processing the display request.
+For each of the windows to be updated by this request, at least
+<emphasis remap='I'>min_delay</emphasis> milli-seconds should elapse since
+the last
+time any of the windows were updated; conversely, no window
+should have to wait more than <emphasis remap='I'>max_delay</emphasis>
+milli-seconds before being updated.
+</para>
+
+<para>
+<emphasis remap='I'>min_delay</emphasis> allows an application to
+<emphasis remap='I'>slow down</emphasis> an animation or movie loop so that
+it appears
+synchronized at a rate the server can support given the current load.
+For example, a <emphasis remap='I'>min_delay</emphasis> of 100 indicates the
+server should
+wait at least 1/10 of a second since the last time any of the
+windows were updated. A <emphasis remap='I'>min_delay</emphasis> of zero
+indicates no waiting is necessary.
+</para>
+
+<para>
+<emphasis remap='I'>max_delay</emphasis> can be thought of as an additional
+delay beyond <emphasis remap='I'>min_delay</emphasis> the server is allowed
+to wait
+to facilitate such things as efficient update of multiple windows.
+If <emphasis remap='I'>max_delay</emphasis> would require an update before
+<emphasis remap='I'>min_delay</emphasis>
+is satisfied, then the server should process the display request as
+soon as the <emphasis remap='I'>min_delay</emphasis> requirement is met. A
+typical value for <emphasis remap='I'>max_delay</emphasis> is zero.
+</para>
+
+<para>
+To implement the above functionality, the time since the last
+update by a <function>DisplayImageBuffers</function> request for each
+multi-buffered
+window needs to be saved as state by the server.
+The server may delay execution of the <function>DisplayImageBuffers</function>
+request until the appropriate time (e.g. by requeuing the
+request after computing the timeout);
+however, the entire request must be processed in one operation.
+Request execution indivisibility must be maintained. When
+a server is implemented with internal concurrency, the
+extension must adhere to the same concurrency semantics
+as those defined for the core protocol.
+</para>
+
+<para>
+To explicitly clear a rectangular area of an image buffer to
+the window background, the following request can be used:
+</para>
+
+<literallayout class="monospaced">
+ClearImageBufferArea
+ buffer : BUFFER
+ x, y : INT16
+ w, h : CARD16
+ exposures : BOOL
+
+ (Errors: Buffer, Value)
+</literallayout>
+
+<para>
+Like the X <function>ClearArea</function> request,
+<emphasis remap='I'>x</emphasis> and <emphasis remap='I'>y</emphasis>
+are relative to
+the window's origin and specify the upper-left corner of the rectangle.
+If <emphasis remap='I'>width</emphasis> is zero, it is replaced with the
+current window width
+minus <emphasis remap='I'>x</emphasis>. If
+<emphasis remap='I'>height</emphasis> is zero it is replaced with the current
+window height minus <emphasis remap='I'>y</emphasis>. If the window has a
+defined background tile, the rectangle is tiled with a plane mask of all ones,
+a function of <emphasis remap='I'>Copy</emphasis>, and a subwindow-mode of
+<emphasis remap='I'>ClipByChildren</emphasis>.
+If the window has background <emphasis remap='I'>None</emphasis>, the
+contents of the buffer
+are not changed. In either case, if
+<emphasis remap='I'>exposures</emphasis> is true, then one or
+more exposure events are generated for regions of the rectangle that are
+either visible or are being retained in backing store.
+</para>
+
+<para>
+<!-- .LP -->
+The group of image buffers allocated by a
+<function>CreateImageBuffers</function>
+request can be destroyed with the following request:
+</para>
+
+<literallayout class="monospaced">
+DestroyImageBuffers
+ w_id : WINDOW
+
+ (Error: Window)
+</literallayout>
+
+<para>
+The association between the buffer ID's and their corresponding
+image buffers are deleted. Any image buffers not selected for
+display are de-allocated. If the window is not multi-buffered,
+the request is ignored.
+</para>
+
+</chapter>
+
+<chapter id='Attributes'>
+<title>Attributes</title>
+
+<para>
+The following attributes will be associated with each window that
+is multi-buffered:
+</para>
+
+<literallayout class="monospaced">
+ displayed_buffer : CARD16
+ update_action : {Undefined,Background,Untouched,Copied}
+ update_hint : {Frequent,Intermittent,Static}
+ window_mode : {Mono,Stereo}
+ buffers : LISTofBUFFER
+</literallayout>
+
+<para>
+<emphasis remap='I'>displayed_buffer</emphasis> is set to the
+<emphasis remap='I'>index</emphasis> of the currently
+displayed image buffer (for stereo windows, this will be
+the index of the left buffer \- the index of the right buffer
+is simply <emphasis remap='I'>index</emphasis>+1).
+<emphasis remap='I'>window_mode</emphasis> indicates whether this window is
+<emphasis remap='I'>Mono</emphasis> or <emphasis remap='I'>Stereo</emphasis>.
+The ID for each buffer associated with the window is recorded
+in the <emphasis remap='I'>buffers</emphasis> list.
+The above attributes can be queried with the following request:
+</para>
+
+<literallayout class="monospaced">
+GetMultiBufferAttributes
+ w_id : WINDOW
+ =&gt;
+ displayed_buffer : CARD16
+ update_action : {Undefined,Background,Untouched,Copied}
+ update_hint : {Frequent,Intermittent,Static}
+ window_mode : {Mono,Stereo}
+ buffers : LISTofBUFFER
+
+ (Errors: Window, Access, Value)
+</literallayout>
+
+<para>
+If the window is not multi-buffered, a <function>Access</function> error
+will be generated.
+The only multi-buffer attribute that can be explicitly set
+is <emphasis remap='I'>update_hint</emphasis>. Rather than have a specific
+request to set this attribute, a generic set request is provided to
+allow for future expansion:
+</para>
+
+<literallayout class="monospaced">
+SetMultiBufferAttributes
+ w_id : WINDOW
+ value_mask : BITMASK
+ value_list : LISTofVALUE
+
+ (Errors: Window, Match, Value)
+</literallayout>
+
+<para>
+If the window is not multi-buffered, a <function>Match</function> error
+will be generated.
+The following attributes are maintained for each buffer of a
+multi-buffered window:
+</para>
+
+<literallayout class="monospaced">
+ window : WINDOW
+ event_mask : SETofEVENT
+ index : CARD16
+ side : {Mono,Left,Right}
+</literallayout>
+
+<para>
+<emphasis remap='I'>window</emphasis> indicates the window this buffer is
+associated with.
+<emphasis remap='I'>event_mask</emphasis> specifies which events, relevant to
+buffers, will be sent back to the client via the associated buffer ID
+(initially no events are selected).
+<emphasis remap='I'>index</emphasis> is the list position (0, 1, ...) of the
+buffer.
+<emphasis remap='I'>side</emphasis> indicates whether this buffer is
+associated with
+the left side or right side of a stereo window.
+For non-stereo windows, this attribute will be set to
+<emphasis remap='I'>Mono</emphasis>.
+These attributes can be queried with the following request:
+</para>
+
+<literallayout class="monospaced">
+GetBufferAttributes
+ buffer : BUFFER
+ =&gt;
+ window : WINDOW
+ event_mask : SETofEVENT
+ index : CARD16
+ side : {Mono,Left,Right}
+
+ (Errors: Buffer, Value)
+</literallayout>
+
+<para>
+The only buffer attribute that can be explicitly set
+is <emphasis remap='I'>event_mask</emphasis>.
+The only events that are valid are
+<function>Expose</function> and the new
+<function>ClobberNotify</function> and <function>UpdateNotify</function>
+event (see Events section below). <!-- xref -->
+A <function>Value</function> error will be generated if an event not
+selectable for a buffer is specified in an event mask.
+Rather than have a specific request
+to set this attribute, a generic set request is provided to
+allow for future expansion:
+</para>
+
+<literallayout class="monospaced">
+SetBufferAttributes
+ buffer : BUFFER
+ value_mask : BITMASK
+ value_list : LISTofVALUE
+
+ (Errors: Buffer, Value)
+</literallayout>
+
+<para>
+Clients may want to query the server about basic multi-buffer
+and stereo capability on a per screen basis. The following request
+returns a large list of information
+that would most likely be read once by Xlib for each screen, and used as a
+data base for other Xlib queries:
+</para>
+
+<literallayout class="monospaced">
+GetBufferInfo
+ root : WINDOW
+ =&gt;
+ info : LISTofSCREEN_INFO
+</literallayout>
+
+<para>
+Where <function>SCREEN_INFO</function> and
+<function>BUFFER_INFO</function> are defined as:
+</para>
+
+<literallayout class="monospaced">
+ SCREEN_INFO : [ normal_info : LISTofBUFFER_INFO,
+ stereo_info : LISTofBUFFER_INFO ]
+
+ BUFFER_INFO : [ visual : VISUALID,
+ max_buffers : CARD16,
+ depth : CARD8 ]
+</literallayout>
+
+<para>
+Information regarding multi-buffering of normal (mono) windows
+is returned in the <emphasis remap='I'>normal_info</emphasis> list.
+The <emphasis remap='I'>stereo_info</emphasis>
+list contains information about stereo windows.
+If the <emphasis remap='I'>stereo_info</emphasis> list is empty, stereo
+windows are
+not supported on the screen. If
+<emphasis remap='I'>max_buffers</emphasis> is zero,
+the maximum number of buffers for the depth and visual is
+a function of the size of the created window and current
+memory limitations.
+</para>
+
+<para>
+The following request returns the major and minor version numbers
+of this extension:
+</para>
+
+<literallayout class="monospaced">
+GetBufferVersion
+ =&gt;
+ major_number : CARD8
+ minor_number : CARD8
+</literallayout>
+
+<para>
+The version numbers are an escape hatch in case future revisions of
+the protocol are necessary. In general, the major version would
+increment for incompatible changes, and the minor version would
+increment for small upward compatible changes. Barring changes, the
+major version will be 1, and the minor version will be 1.
+</para>
+</chapter>
+
+<chapter id='Events'>
+<title>Events</title>
+
+<para>
+All events normally generated for single-buffered
+windows are also generated for multi-buffered windows.
+Most of these events (ie: <function>ConfigureNotify</function>) will
+only be generated for the window and not for each buffer.
+These events will return a window ID.
+</para>
+
+<para>
+<function>Expose</function> events will be generated for both the window
+and any buffer affected. When this event is generated for
+a buffer, the same event structure will be used
+but a buffer ID is returned instead of a window ID.
+Clients, when processing these events, will know whether an
+ID returned in an event structure is for a window or a buffer
+by comparing the returned ID to the ones returned when the
+window and buffer were created.
+</para>
+
+<para>
+<function>GraphicsExposure</function> and
+<function>NoExposure</function> are generated
+using whatever ID is specified in the graphics operation.
+If a window ID is specified, the event will contain the
+window ID. If a buffer ID is specified, the event will
+contain the buffer ID.
+</para>
+<para>
+In some implementations, moving a window
+over a multi-buffered window may cause one or more of its buffers
+to get overwritten or become unwritable. To allow a
+client drawing into one of these buffers the opportunity
+to stop drawing until some portion of the buffer is
+writable, the following event is added:
+</para>
+
+<literallayout class="monospaced">
+ClobberNotify
+ buffer : BUFFER
+ state : {Unclobbered,PartiallyClobbered,FullyClobbered}
+</literallayout>
+
+<para>
+The <function>ClobberNotify</function> event is reported to clients selecting
+<emphasis remap='I'>ClobberNotify</emphasis> on a buffer. When a buffer
+that was fully
+or partially clobbered becomes unclobbered, an event with
+<emphasis remap='I'>Unclobbered</emphasis>
+is generated. When a buffer that was unclobbered becomes
+partially clobbered, an event with
+<emphasis remap='I'>PartiallyClobbered</emphasis>
+is generated. When a buffer that was unclobbered or
+partially clobbered becomes fully clobbered, an event with
+<emphasis remap='I'>FullyClobbered</emphasis> is generated.
+</para>
+
+<para>
+<function>ClobberNotify</function> events on a given buffer are
+generated before any <function>Expose</function> events on that buffer,
+but it is not required that all <function>ClobberNotify</function>
+events on all buffers be generated before all
+<function>Expose</function> events on all buffers.
+</para>
+
+<para>
+The ordering of <function>ClobberNotify</function> events with respect
+to <function>VisibilityNotify</function> events is not constrained.
+</para>
+
+<para>
+If multiple buffers were used as an image FIFO between an image
+server and the X display server, then the FIFO manager would like
+to know when a buffer that was previously displayed, has been
+undisplayed and updated, as the side effect of a
+<function>DisplayImageBuffers</function>
+request. This allows the FIFO manager to load up a future frame as
+soon as a buffer becomes available. To support this,
+the following event is added:
+</para>
+
+<literallayout class="monospaced">
+UpdateNotify
+ buffer : BUFFER
+</literallayout>
+
+<para>
+The <function>UpdateNotify</function> event is reported to clients selecting
+<emphasis remap='I'>UpdateNotify</emphasis> on a buffer. Whenever a buffer
+becomes <emphasis remap='I'>updated</emphasis>
+(e.g. its update action is performed as part of a
+<function>DisplayImageBuffers</function>
+request), an <function>UpdateNotify</function> event is generated.
+</para>
+</chapter>
+
+<chapter id='Errors'>
+<title>Errors</title>
+
+<para>
+The following error type has been added to support
+this extension:
+</para>
+
+<sect1 id='Buffer_2'>
+<title>Buffer</title>
+<para>
+A value for a BUFFER argument does not name a defined BUFFER.
+</para>
+</sect1>
+
+<sect1 id='Double_Buffering_Normal_Windows'>
+<title>Double-Buffering Normal Windows</title>
+
+<para>
+The following pseudo-code fragment illustrates how to create and display
+a double-buffered image:
+</para>
+
+<literallayout class="monospaced">
+/*
+ * Create a normal window
+ */
+CreateWindow( W, ... )
+
+/*
+ * Create two image buffers. Assume after display, buffer
+ * contents become "undefined". Assume we will "frequently"
+ * update the display. Abort if we don't get two buffers,
+ */
+n = CreateImageBuffers( W, [B0,B1], Undefined, Frequent )
+if (n != 2) &lt;abort&gt;
+
+/*
+ * Map window to the screen
+ */
+MapWindow( W )
+
+/*
+ * Draw images using alternate buffers, display every
+ * 1/10 of a second. Note we draw B1 first so it will
+ * "pop" on the screen
+ */
+while animating
+{
+ &lt;draw picture using B1&gt;
+ DisplayImageBuffers( [B1], 100, 0 )
+
+ &lt;draw picture using B0&gt;
+ DisplayImageBuffers( [B0], 100, 0 )
+}
+
+/*
+ * Strip image buffers and leave window with
+ * contents of last displayed image buffer.
+ */
+DestroyImageBuffers( W )
+</literallayout>
+
+</sect1>
+
+<sect1 id='Multi_Buffering_Normal_Windows'>
+<title>Multi-Buffering Normal Windows</title>
+
+<para>
+Multi-buffered images are also supported by these requests.
+The following pseudo-code fragment illustrates how to create a
+a multi-buffered image and cycle through the images to
+simulate a movie loop:
+</para>
+
+<literallayout class="monospaced">
+/*
+ * Create a normal window
+ */
+CreateWindow( W, ... )
+
+/*
+ * Create 'N' image buffers. Assume after display, buffer
+ * contents are "untouched". Assume we will "frequently"
+ * update the display. Abort if we don't get all the buffers.
+ */
+n = CreateImageBuffers( W, [B0,B1,...,B(N-1)], Untouched, Frequent )
+if (n != N) &lt;abort&gt;
+
+/*
+ * Map window to screen
+ */
+MapWindow( W )
+
+/*
+ * Draw each frame of movie one per buffer
+ */
+foreach frame
+ &lt;draw frame using B(i)&gt;
+
+/*
+ * Cycle through frames, one frame every 1/10 of a second.
+ */
+while animating
+{
+ foreach frame
+ DisplayImageBuffers( [B(i)], 100, 0 )
+}
+</literallayout>
+
+</sect1>
+
+<sect1 id='Stereo_Windows'>
+<title>Stereo Windows</title>
+<para>
+<emphasis remap='I'>How</emphasis> stereo windows are supported on a server
+is implementation
+dependent. A server may contain specialized hardware that allows
+left and right images to be toggled at field or frame rates. The
+stereo affect may only be perceived with the aid of special
+viewing glasses. The <emphasis remap='I'>display</emphasis> of a
+stereo picture should
+be independent of how often the contents of the picture are
+<emphasis remap='I'>updated</emphasis> by an application. Double and
+multi-buffering
+of images should be possible regardless of whether the image
+is displayed normally or in stereo.
+</para>
+
+<para>
+To achieve this goal, a simple extension to normal windows
+is suggested. Stereo windows are just like normal windows
+except the displayed image is made up of a left image
+buffer and a right image buffer. To create a stereo window,
+a client makes the following request:
+</para>
+
+<literallayout class="monospaced">
+CreateStereoWindow
+ parent : WINDOW
+ w_id : WINDOW
+ left, right : BUFFER
+ depth : CARD8
+ visual : VISUALID or CopyFromParent
+ x, y : INT16
+ width, height : INT16
+ border_width : INT16
+ value_mask : BITMASK
+ value_list : LISTofVALUE
+
+ (Errors: Alloc, Color, Cursor, Match,
+ Pixmap, Value, Window)
+</literallayout>
+
+<para>
+This request, modeled after the <function>CreateWindow</function> request,
+adds just two new parameters: <emphasis remap='I'>left</emphasis> and
+<emphasis remap='I'>right</emphasis>.
+For stereo, it is essential that one can distinguish whether
+a draw operation is to occur on the left image or right image.
+While an internal mode could have been added to achieve this,
+using two buffer ID's allows clients to simultaneously build up
+the left and right components of a stereo image. These
+ID's always refer to (are an alias for) the left and right
+image buffers that are currently <emphasis remap='I'>displayed</emphasis>.
+</para>
+
+<para>
+Like normal windows, the window ID is used whenever a window
+management operation is to be performed. Window queries would
+also return this window ID (eg: <function>QueryTree</function>) as would most
+events. Like the window ID, the left and right buffer ID's
+each have their own event mask. They can be set and queried
+using the <function>Set/GetBufferAttributes</function> requests.
+</para>
+
+<para>
+Using the window ID of a stereo window in a draw request
+(eg: <function>GetImage</function>) results in pixels that are
+<emphasis remap='I'>undefined</emphasis>.
+Possible semantics are that both left and right images get
+drawn, or just a single side is operated on (existing applications
+will have to be re-written to explicitly use the left and right
+buffer ID's in order to successfully create, fetch, and store
+stereo images).
+</para>
+
+<para>
+Having an explicit <function>CreateStereoWindow</function> request is helpful
+in that a server implementation will know from the onset whether
+a stereo window is desired and can return appropriate status
+to the client if it cannot support this functionality.
+</para>
+
+<para>
+Some hardware may support separate stereo and non-stereo modes,
+perhaps with different vertical resolutions. For example, the
+vertical resolution in stereo mode may be half that of non-stereo
+mode. Selecting one mode or the other must be done through some
+means outside of this extension (eg: by providing a separate
+screen for each hardware display mode). The screen attributes
+(ie: x/y resolution) for a screen that supports normal windows,
+may differ from a screen that supports stereo windows;
+however, all windows, regardless of type, displayed on the
+same screen must have the same screen attributes
+(ie: pixel aspect ratio).
+</para>
+
+<para>
+If a screen that supports stereo windows also supports
+normal windows, then the images presented to the left and
+right eyes for normal windows should be the same
+(ie: have no stereo offset).
+</para>
+
+</sect1>
+
+<sect1 id='Single_Buffered_Stereo_Windows'>
+<title>Single-Buffered Stereo Windows</title>
+
+<para>
+The following shows how to create and display a single-buffered
+stereo image:
+</para>
+<literallayout class="monospaced">
+/*
+ * Create the stereo window, map it the screen,
+ * and draw the left and right images
+ */
+CreateStereoWindow( W, L, R, ... )
+
+MapWindow( W )
+
+&lt;draw picture using L,R&gt;
+</literallayout>
+</sect1>
+
+<sect1 id='Double_Buffering_Stereo_Windows'>
+<title>Double-Buffering Stereo Windows</title>
+
+<para>
+Additional image buffers may be added to a stereo window
+to allow double or multi-buffering of stereo images.
+Simply use the the <function>CreateImageBuffers</function> request.
+Even numbered buffers (0,2,...) will be left buffers.
+Odd numbered buffers (1,3,...) will be right buffers.
+Displayable stereo images are formed by consecutive
+left/right pairs of image buffers. For example,
+(buffer[0],buffer[1]) form the first displayable
+stereo image; (buffer[2],buffer[3]) the next;
+and so on.
+</para>
+
+<para>
+The <function>CreateImageBuffers</function> request will only create
+pairs of left and right image buffers for stereo windows.
+By always pairing left and right image
+buffers together, implementations might be able to
+perform some type of optimization. If an odd number
+of buffers is specified, a <function>Value</function> error is generated.
+All the rules mentioned at the start of this proposal
+still apply to the image buffers supported by a stereo window.
+</para>
+
+<para>
+To display a image buffer pair of a multi-buffered stereo image,
+either the left buffer ID or right buffer ID may be specified in a
+<function>DisplayImageBuffers</function> request, but not both.
+</para>
+
+<para>
+To double-buffer a stereo window:
+</para>
+
+<literallayout class="monospaced">
+/*
+ * Create stereo window and map it to the screen
+ */
+CreateStereoWindow( W, L, R, ... )
+
+/*
+ * Create two pairs of image buffers. Assume after display,
+ * buffer contents become "undefined". Assume we will "frequently"
+ * update the display. Abort if we did get all the buffers.
+ */
+n = CreateImageBuffers( W, [L0,R0,L1,R1], Undefined, Frequently )
+if (n != 4) &lt;abort&gt;
+
+/*
+ * Map window to the screen
+ */
+MapWindow( W )
+
+/*
+ * Draw images using alternate buffers,
+ * display every 1/10 of a second.
+ */
+while animating
+{
+ &lt;draw picture using L1,R1&gt;
+ DisplayImageBuffers( [L1], 100, 0 )
+
+ &lt;draw picture using L0,R0&gt;
+ DisplayImageBuffers( [L0], 100, 0 )
+}
+</literallayout>
+
+</sect1>
+
+<sect1 id='Multi_Buffering_Stereo_Windows'>
+<title>Multi-Buffering Stereo Windows</title>
+
+<para>
+To cycle through <emphasis remap='I'>N</emphasis> stereo images:
+</para>
+
+<literallayout class="monospaced">
+/*
+ * Create stereo window
+ */
+CreateStereoWindow( W, L, R, ... )
+
+/*
+ * Create N pairs of image buffers. Assume after display,
+ * buffer contents are "untouched". Assume we will "frequently"
+ * update the display. Abort if we don't get all the buffers.
+ */
+n = CreateImageBuffers( W, [L0,R0,...,L(N-1),R(N-1)], Untouched, Frequently )
+if (n != N*2) &lt;abort&gt;
+
+/*
+ * Map window to screen
+ */
+MapWindow( W )
+
+/*
+ * Draw the left and right halves of each image
+ */
+foreach stereo image
+ &lt;draw picture using L(i),R(i)&gt;
+
+/*
+ * Cycle through images every 1/10 of a second
+ */
+while animating
+{
+ foreach stereo image
+ DisplayImageBuffers( [L(i)], 100, 0 )
+}
+</literallayout>
+</sect1>
+
+<sect1 id='Protocol_Encoding'>
+<title>Protocol Encoding</title>
+
+<para>
+The official name of this extension is "Multi-Buffering".
+When this string passed to <function>QueryExtension</function> the
+information returned should be interpreted as follows:
+</para>
+
+<variablelist>
+ <varlistentry>
+ <term>major-opcode</term>
+ <listitem>
+ <para>
+Specifies the major opcode of this extension.
+The first byte of each extension request should
+specify this value.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>first-event</term>
+ <listitem>
+ <para>
+Specifies the code that will be returned when
+<function>ClobberNotify</function> events are generated.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>first-error</term>
+ <listitem>
+ <para>
+Specifies the code that will be returned when
+<function>Buffer</function> errors are generated.
+ </para>
+ </listitem>
+ </varlistentry>
+</variablelist>
+
+<para>
+The following sections describe the protocol
+encoding for this extension.
+</para>
+</sect1>
+</chapter>
+
+<chapter id='TYPES'>
+<title>TYPES</title>
+
+<literallayout class="monospaced">
+BUFFER_INFO
+
+4 VISUALID visual
+2 CARD16 max-buffers
+1 CARD8 depth
+1 unused
+</literallayout>
+
+<literallayout class="monospaced">
+SETofBUFFER_EVENT
+
+ #x00008000 Exposure
+ #x02000000 ClobberNotify
+ #x04000000 UpdateNotify
+</literallayout>
+
+</chapter>
+
+<chapter id='EVENTS_2'>
+<title>EVENTS</title>
+
+<literallayout class="monospaced">
+<function>ClobberNotify</function>
+1 see <emphasis remap='I'>first-event</emphasis> code
+1 unused
+2 CARD16 sequence number
+4 BUFFER buffer
+1 state
+ 0 Unclobbered
+ 1 PartiallyClobbered
+ 2 FullyClobbered
+23 unused
+</literallayout>
+
+<literallayout class="monospaced">
+<function>UpdateNotify</function>
+1 <emphasis remap='I'>first-event</emphasis>+1 code
+1 unused
+2 CARD16 sequence number
+4 BUFFER buffer
+24 unused
+</literallayout>
+
+</chapter>
+<chapter id='ERRORS_2'>
+<title>ERRORS</title>
+
+<literallayout class="monospaced">
+<function>Buffer</function>
+1 0 Error
+1 see <emphasis remap='I'>first-error</emphasis> code
+2 CARD16 sequence number
+4 CARD32 bad resource id
+2 CARD16 minor-opcode
+1 CARD8 major-opcode
+21 unused
+</literallayout>
+
+</chapter>
+
+<chapter id='Requests'>
+<title>REQUESTS</title>
+
+<literallayout class="monospaced">
+<function>GetBufferVersion</function>
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 0 minor-opcode
+2 1 request length
+-&gt;
+1 1 Reply
+1 unused
+2 CARD16 sequencenumber
+4 0 reply length
+1 CARD8 majorversion number
+1 CARD8 minorversion number
+22 unused
+
+
+<function>CreateImageBuffers</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 1 minor-opcode
+2 3+n requestlength
+4 WINDOW wid
+1 update-action
+ 0 Undefined
+ 1 Background
+ 2 Untouched
+ 3 Copied
+1 update-hint
+ 0 Frequent
+ 1 Intermittent
+ 2 Static
+2 unused
+4n LISTofBUFFER buffer-list
+-&gt;
+1 1 Reply
+1 unused
+2 CARD16 sequencenumber
+4 0 reply length
+2 CARD16 number-buffers
+22 unused
+
+
+<function>DestroyImageBuffers</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 2 minor-opcode
+2 2 request length
+4 WINDOW wid
+
+
+<function>DisplayImageBuffers</function>
+
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+2 2+n requestlength
+2 CARD16 min-delay
+2 CARD16 max-delay
+4n LISTofBUFFER buffer-list
+
+
+<function>SetMultiBufferAttributes</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 4 minor-opcode
+2 3+n requestlength
+4 WINDOW wid
+4 BITMASK value-mask (has n bits set to 1)
+ #x00000001 update-hint
+4n LISTofVALUE value-list
+VALUEs
+1 update-hint
+ 0 Frequent
+ 1 Intermittent
+ 2 Static
+
+
+<function>GetMultiBufferAttributes</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 5 minor-opcode
+2 2 request length
+4 WINDOW wid
+1 1 Reply
+1 unused
+2 CARD16 sequencenumber
+4 n reply length
+2 CARD16 displayed-buffer
+1 update-action
+ 0 Undefined
+ 1 Background
+ 2 Untouched
+ 3 Copied
+1 update-hint
+ 0 Frequent
+ 1 Intermittent
+ 2 Static
+1 window-mode
+ 0 Mono
+ 1 Stereo
+19 unused
+4n LISTofBUFFER buffer list
+
+
+<function>SetBufferAttributes</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 6 minor-opcode
+2 3+n requestlength
+4 BUFFER buffer
+4 BITMASK value-mask (has n bits set to 1)
+ #x00000001 event-mask
+4n LISTofVALUE value-list
+VALUEs
+4 SETofBUFFER_EVENT event-mask
+
+<function>GetBufferAttributes</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 7 minor-opcode
+2 2 request length
+4 BUFFER buffer
+-&gt;
+1 1 Reply
+1 unused
+2 CARD16 sequencenumber
+4 0 reply length
+4 WINDOW wid
+4 SETofBUFFER_EVENT event-mask
+2 CARD16 index
+ 1 side
+ 0 Mono
+ 1 Left
+ 2 Right
+13 unused
+
+<function>GetBufferInfo</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 8 minor-opcode
+2 2 request length
+4 WINDOW root
+1 1 Reply
+1 unused
+2 CARD16 sequencenumber
+4 2(n+m) replylength
+2 n number BUFFER_INFO in normal-info
+2 m number BUFFER_INFO in stereo-info
+20 unused
+8n LISTofBUFFER_INFO normal-info
+8m LISTofBUFFER_INFO stereo-info
+
+<function>CreateStereoWindow</function>
+
+1 see <emphasis remap='I'>major-opcode</emphasis> major-opcode
+1 9 minor-opcode
+2 11+n requestlength
+3 unused
+1 CARD8 depth
+4 WINDOW wid
+4 WINDOW parent
+4 BUFFER left
+4 BUFFER right
+2 INT16 x
+2 INT16 y
+2 CARD16 width
+2 CARD16 height
+2 CARD16 border-width
+2 class
+ 0 CopyFromParent
+ 1 InputOutput
+ 2 InputOnly
+4 VISUALID visual
+ 0 CopyFromParent
+4 BITMASK value-mask (has n bits set to 1)
+ encodings are the same
+ as for CreateWindow
+4n LISTofVALUE value-list
+ encodings are the same
+ as for CreateWindow
+
+
+<function>ClearImageBufferArea</function>
+
+1 see major-opcode major-opcode
+1 10 minor-opcode
+2 5 request length
+4 WINDOW buffer
+2 INT16 x
+2 INT16 y
+2 CARD16 width
+2 CARD16 height
+3 unused
+1 BOOL exposures
+
+</literallayout>
+
+</chapter>
+</book>