1mExtending X for Double-Buffering, Multi-Buffering,0m
			 1mand Stereo0m


		     4mJeffrey24m 4mFriedberg0m
			4mLarry24m 4mSeiler0m
			 4mJeff24m 4mVroom0m
			Version 3.3
		      January 11, 1990

4mThe24m Multi-Buffering 4mextension24m 4mdescribed24m 4mhere24m 4mwas24m 4ma24m 4mdraft24m 4mstandard24m 4mof24m 4mthe0m
4mX24m 4mConsortium24m 4mprior24m 4mto24m 4mRelease24m 4m6.1.24m  4mIt24m 4mhas24m 4mbeen24m 4msuperseded24m 4mby24m 4mthe24m 4mDouble24m 4mBuffer0m
4mExtension24m 4m(DBE).24m  4mDBE24m 4mis24m 4man24m 4mX24m 4mConsortium24m 4mStandard24m 4mas24m 4mof24m 4mRelease24m 4m6.1.0m


1mIntroduction0m

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:

ˇ    4mExtending24m 4mX24m 4mfor24m 4mDouble-Buffering,24m Jeffrey Friedberg,
     Larry Seiler, Randi Rost.

ˇ    4m(Proposal24m 4mfor)24m 4mDouble-Buffering24m 4mExtensions24m, Jeff Vroom.

ˇ    4mAn24m 4mExtension24m 4mto24m 4mX.1124m 4mfor24m 4mDisplays24m 4mwith24m 4mMultiple0m
     4mBuffers,24m David S.H. Rosenthal.

ˇ    4mA24m 4mMultiple24m 4mBuffering/Stereo24m 4mProposal24m, Mark Patrick.
-----------
Copyright Š 1989 Digital Equipment Corporation.
Permission to use, copy, modify, and distribute
this documentation for any purpose and without fee
is hereby granted, provided that the above copy-
right 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.
Copyright Š 1989, 1994 X Consortium
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, subli-
cense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished









			     -2-


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.

1mGoals0m

Clients should be able to:

ˇ    Associate multiple buffers with a window.

ˇ    Paint in any buffer associated with a window.

ˇ    Display any buffer associated with a window.

ˇ    Display a series of buffers in a window in rapid suc-
     cession to achieve a 4msmooth24m animation.

ˇ    Request simultaneous display of different buffers in
     different windows.

In addition, the extension should:

ˇ    Allow existing X applications to run unchanged.

ˇ    Support a range of implementation methods that can cap-
     italize on existing hardware features.





-----------
to do so, subject to the following conditions:
The above copyright notice and this permission
notice shall be included in all copies or substan-
tial portions of the Software.
THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WAR-
RANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONIN-
FRINGEMENT.  IN NO EVENT SHALL THE X CONSORTIUM BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHER-
WISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
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.
4mX24m 4mWindow24m 4mSystem24m is a trademark of X Consortium,
Inc.









			     -3-


1mImage Buffers0m

Normal windows are created using the standard 1mCreateWindow0m
request:

     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


This request allocates a set of window attributes and a
buffer into which an image can be drawn.  The contents of
this 4mimage24m 4mbuffer24m will be displayed when the window is
mapped to the screen.

To support double-buffering and multi-buffering, we intro-
duce the notion that additional image buffers can be created
and bound together to form groups.  The following rules will
apply:

ˇ    All image buffers in a group will have the same visual
     type, depth, and geometry (ie: width and height).

ˇ    Only one image buffer per group can be displayed at a
     time.

ˇ    Draw operations can occur to any image buffer at any
     time.

ˇ    Window management requests (1mMapWindow22m, 1mDestroyWindow22m,
     1mConfigureWindow22m, etc...)  affect all image buffers
     associated with a window.

ˇ    Appropriate resize and exposure events will be gener-
     ated for every image buffer that is affected by a win-
     dow management operation.

By allowing draw operations to occur on any image buffer at
any time, a client could, on a multi-threaded multi-proces-
sor 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 dis-
played) a new resource, 1mBuffer22m, is introduced.  Furthermore,
a 1mBuffer 22mis also a 1mDrawable22m, thus draw operations may also
be performed on buffers simply by passing a buffer ID to the
existing pixmap/window interface.









			     -4-


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 4malias24m for the ID of the cur-
rently displayed image buffer.	Any draw requests (eq:
1mGetImage22m) on the window will be relative to the displayed
image buffer.

In window management requests, only a window ID will be
accepted.  Requests like 1mQueryTree22m, 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.

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.

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.

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.

Output to any image buffer of an unmapped multi-buffered
window that does not have backing store is discarded.  Out-
put to any image buffer of a mapped multi-buffer window will
be performed; however, portions of an image buffer may be
occluded or clipped.

When an unmapped multi-buffered window becomes mapped, the
contents of any image buffer buffer that did not have back-
ing 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.

1mNew Requests0m

The new request, 1mCreateImageBuffers22m, creates a group of
image buffers and associates them with a normal X window:














			     -5-


     CreateImageBuffers
	  w_id		 : WINDOW
	  buffers	 : LISTofBUFFER
	  update_action	 : {Undefined,Background,Untouched,Copied}
	  update_hint	 : {Frequent,Intermittent,Static}
	  =>
	  number_buffers : CARD16

	  (Errors: Window, IDChoice, Value)

One image buffer will be associated with each ID passed in
4mbuffers24m.  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].

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.

If the window already has a group of image buffers associ-
ated with it (ie: from a previous 1mCreateImageBuffers0m
request) the actions described for 1mDestroyImageBuffers 22mare
performed first (this will delete the association of the
previous buffer ID's and their buffers as well as de-allo-
cate all buffers except for the one already associated with
the window ID).

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 actu-
ally allocated will be returned.  No 1mAlloc 22merrors will be
generated - buffer[0] can always be associated with the
existing displayed image buffer.

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.

One might be tempted to provide a request that inquires
whether 4mn24m buffers of a particular type, size, and depth









			     -6-


4mcould24m 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.

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 4mlist24m 4morder0m
(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.

4mupdate_action24m indicates what should happen to a previously
displayed buffer when a different buffer becomes displayed.
Possible actions are:

4mUndefined24m	    The contents of the buffer that was last dis-
	       played 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.

4mBackground24m	    The contents of the buffer that was last dis-
	       played 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.

4mUntouched24m	    The contents of the buffer that was last dis-
	       played will be untouched after the update.
	       Used primarily when cycling through images
	       that have already been drawn.

4mCopied24m	    The contents of the buffer that was last dis-
	       played will become the same as those that are
	       being displayed after the update.  This is
	       useful when incrementally adding to an image.

4mupdate_hint24m 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 cur-
rent need of the application (dumb implementations may
choose to ignore this hint).  Possible hints are:

4mFrequent24m	    An animation or movie loop is being attempted
	       and the fastest, most efficient means for
	       multi-buffering should be employed.

4mIntermittent24m   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.









			     -7-


4mStatic24m	    The displayed image buffer will not be
	       changed any time soon.  Typically set by an
	       application whenever there is a pause in the
	       animation.

To display an image buffer the following request can be
used:

     DisplayImageBuffers
	  buffers	  : LISTofBUFFER
	  min_delay	  : CARD16
	  max_delay	  : CARD16

	  (Errors: Buffer, Match)

The image buffers listed will become displayed as simultane-
ously as possible and the update action, bound at 1mCreateIm-0m
1mageBuffers 22mtime, will be performed.

A list of buffers is specified to allow the server to effi-
ciently 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 (1mMatch22m) since it violates the rule
that only one image buffer per group can be displayed at a
time.

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 4mBackground24m (and
possibly 4mUndefined24m) 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.

When a 1mDisplayImageBuffers 22mrequest 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 dis-
carded.	 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 4mCopied24m), the contents of
target image buffer will become undefined.

4mmin_delay24m and 4mmax_delay24m 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
4mmin_delay24m milli-seconds should elapse since the last time
any of the windows were updated; conversely, no window
should have to wait more than 4mmax_delay24m milli-seconds before
being updated.










			     -8-


4mmin_delay24m allows an application to 4mslow24m 4mdown24m an animation or
movie loop so that it appears synchronized at a rate the
server can support given the current load.  For example, a
4mmin_delay24m 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 4mmin_delay24m of zero indicates no waiting is neces-
sary.

4mmax_delay24m can be thought of as an additional delay beyond
4mmin_delay24m the server is allowed to wait to facilitate such
things as efficient update of multiple windows.	 If
4mmax_delay24m would require an update before 4mmin_delay24m is satis-
fied, then the server should process the display request as
soon as the 4mmin_delay24m requirement is met.	A typical value
for 4mmax_delay24m is zero.

To implement the above functionality, the time since the
last update by a 1mDisplayImageBuffers 22mrequest for each multi-
buffered window needs to be saved as state by the server.
The server may delay execution of the 1mDisplayImageBuffers0m
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 execu-
tion 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.

To explicitly clear a rectangular area of an image buffer to
the window background, the following request can be used:

     ClearImageBufferArea
	  buffer	  : BUFFER
	  x, y		  : INT16
	  w, h		  : CARD16
	  exposures	  : BOOL

	  (Errors: Buffer, Value)


Like the X 1mClearArea 22mrequest, 4mx24m and 4my24m are relative to the
window's origin and specify the upper-left corner of the
rectangle.  If 4mwidth24m is zero, it is replaced with the cur-
rent window width minus 4mx24m.	 If 4mheight24m is zero it is replaced
with the current window height minus 4my24m.  If the window has a
defined background tile, the rectangle is tiled with a plane
mask of all ones, a function of 4mCopy24m, and a subwindow-mode
of 4mClipByChildren24m.	 If the window has background 4mNone24m, the
contents of the buffer are not changed.	 In either case, if
4mexposures24m is true, then one or more exposure events are gen-
erated for regions of the rectangle that are either visible
or are being retained in backing store.











			     -9-


The group of image buffers allocated by a 1mCreateImageBuffers0m
request can be destroyed with the following request:

     DestroyImageBuffers
	  w_id	    : WINDOW

	  (Error: Window)


The association between the buffer ID's and their corre-
sponding 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.

1mAttributes0m

The following attributes will be associated with each window
that is multi-buffered:

	  displayed_buffer : CARD16
	  update_action	   : {Undefined,Background,Untouched,Copied}
	  update_hint	   : {Frequent,Intermittent,Static}
	  window_mode	   : {Mono,Stereo}
	  buffers	   : LISTofBUFFER


4mdisplayed_buffer24m is set to the 4mindex24m of the currently dis-
played image buffer (for stereo windows, this will be the
index of the left buffer - the index of the right buffer is
simply 4mindex24m+1).  4mwindow_mode24m indicates whether this window
is 4mMono24m or 4mStereo24m.  The ID for each buffer associated with
the window is recorded in the 4mbuffers24m list.  The above
attributes can be queried with the following request:

     GetMultiBufferAttributes
	  w_id		   : WINDOW
	  =>
	  displayed_buffer : CARD16
	  update_action	   : {Undefined,Background,Untouched,Copied}
	  update_hint	   : {Frequent,Intermittent,Static}
	  window_mode	   : {Mono,Stereo}
	  buffers	   : LISTofBUFFER

	  (Errors: Window, Access, Value)


If the window is not multi-buffered, a 1mAccess 22merror will be
generated.  The only multi-buffer attribute that can be
explicitly set is 4mupdate_hint24m.  Rather than have a specific
request to set this attribute, a generic set request is pro-
vided to allow for future expansion:












			    -10-


     SetMultiBufferAttributes
	  w_id		  : WINDOW
	  value_mask	  : BITMASK
	  value_list	  : LISTofVALUE

	  (Errors: Window, Match, Value)


If the window is not multi-buffered, a 1mMatch 22merror will be
generated.  The following attributes are maintained for each
buffer of a multi-buffered window:

	  window	   : WINDOW
	  event_mask	   : SETofEVENT
	  index		   : CARD16
	  side		   : {Mono,Left,Right}


4mwindow24m indicates the window this buffer is associated with.
4mevent_mask24m specifies which events, relevant to buffers, will
be sent back to the client via the associated buffer ID
(initially no events are selected).  4mindex24m is the list posi-
tion (0, 1, ...) of the buffer.	 4mside24m 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 4mMono24m.  These attributes can be queried with the
following request:

     GetBufferAttributes
	  buffer	  : BUFFER
	  =>
	  window	   : WINDOW
	  event_mask	   : SETofEVENT
	  index		   : CARD16
	  side		   : {Mono,Left,Right}

	  (Errors: Buffer, Value)


The only buffer attribute that can be explicitly set is
4mevent_mask24m.  The only events that are valid are 1mExpose 22mand
the new 1mClobberNotify 22mand 1mUpdateNotify 22mevent (see Events
section below).	 A 1mValue 22merror 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 expan-
sion:
















			    -11-


     SetBufferAttributes
	  buffer	  : BUFFER
	  value_mask	  : BITMASK
	  value_list	  : LISTofVALUE

	  (Errors: Buffer, Value)


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:

     GetBufferInfo
	  root		  : WINDOW
	  =>
	  info		  : LISTofSCREEN_INFO


Where 1mSCREEN_INFO 22mand 1mBUFFER_INFO 22mare defined as:


	  SCREEN_INFO	  : [ normal_info : LISTofBUFFER_INFO,
			      stereo_info : LISTofBUFFER_INFO ]

	  BUFFER_INFO	  : [ visual	  : VISUALID,
			      max_buffers : CARD16,
			      depth	  : CARD8 ]


Information regarding multi-buffering of normal (mono) win-
dows is returned in the 4mnormal_info24m list.	The 4mstereo_info0m
list contains information about stereo windows.	 If the
4mstereo_info24m list is empty, stereo windows are not supported
on the screen.	If 4mmax_buffers24m 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.

The following request returns the major and minor version
numbers of this extension:

     GetBufferVersion
	  =>
	  major_number	  : CARD8
	  minor_number	  : CARD8


The version numbers are an escape hatch in case future revi-
sions 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.









			    -12-


1mEvents0m

All events normally generated for single-buffered windows
are also generated for multi-buffered windows.	Most of
these events (ie: 1mConfigureNotify22m) will only be generated
for the window and not for each buffer.	 These events will
return a window ID.

1mExpose 22mevents 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.

1mGraphicsExposure 22mand 1mNoExposure 22mare 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.

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:

     ClobberNotify
	  buffer	 :  BUFFER
	  state		 : {Unclobbered,PartiallyClobbered,FullyClobbered}


The 1mClobberNotify 22mevent is reported to clients selecting
4mClobberNotify24m on a buffer.	 When a buffer that was fully or
partially clobbered becomes unclobbered, an event with
4mUnclobbered24m is generated.	When a buffer that was unclob-
bered becomes partially clobbered, an event with 4mPartially-0m
4mClobbered24m is generated.  When a buffer that was unclobbered
or partially clobbered becomes fully clobbered, an event
with 4mFullyClobbered24m is generated.

1mClobberNotify 22mevents on a given buffer are generated before
any 1mExpose 22mevents on that buffer, but it is not required
that all 1mClobberNotify 22mevents on all buffers be generated
before all 1mExpose 22mevents on all buffers.

The ordering of 1mClobberNotify 22mevents with respect to 1mVisi-0m
1mbilityNotify 22mevents is not constrained.

If multiple buffers were used as an image FIFO between an
image server and the X display server, then the FIFO manager









			    -13-


would like to know when a buffer that was previously dis-
played, has been undisplayed and updated, as the side effect
of a 1mDisplayImageBuffers 22mrequest.	This allows the FIFO man-
ager to load up a future frame as soon as a buffer becomes
available.  To support this, the following event is added:

     UpdateNotify
	  buffer	 :  BUFFER


The 1mUpdateNotify 22mevent is reported to clients selecting
4mUpdateNotify24m on a buffer.	Whenever a buffer becomes 4mupdated0m
(e.g. its update action is performed as part of a 1mDisplayIm-0m
1mageBuffers 22mrequest), an 1mUpdateNotify 22mevent is generated.

1mErrors0m

The following error type has been added to support this
extension:

1mBuffer	 22mA value for a BUFFER argument does not name a
	       defined BUFFER.









































			    -14-


1mDouble-Buffering Normal Windows0m

The following pseudo-code fragment illustrates how to create
and display a double-buffered image:

     /*
      * 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) <abort>

     /*
      * 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
     {
	  <draw picture using B1>
	  DisplayImageBuffers( [B1], 100, 0 )

	  <draw picture using B0>
	  DisplayImageBuffers( [B0], 100, 0 )
     }

     /*
      * Strip image buffers and leave window with
      * contents of last displayed image buffer.
      */
     DestroyImageBuffers( W )





















			    -15-


1mMulti-Buffering Normal Windows0m

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:

     /*
      * 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) <abort>

     /*
      * Map window to screen
      */
     MapWindow( W )

     /*
      * Draw each frame of movie one per buffer
      */
     foreach frame
	  <draw frame using B(i)>

     /*
      * Cycle through frames, one frame every 1/10 of a second.
      */
     while animating
     {
	  foreach frame
	       DisplayImageBuffers( [B(i)], 100, 0 )
     }
























			    -16-


1mStereo Windows0m

4mHow24m stereo windows are supported on a server is implementa-
tion 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 4mdisplay24m of a stereo
picture should be independent of how often the contents of
the picture are 4mupdated24m by an application.	 Double and
multi-buffering of images should be possible regardless of
whether the image is displayed normally or in stereo.

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:

     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)


This request, modeled after the 1mCreateWindow 22mrequest, adds
just two new parameters: 4mleft24m and 4mright24m.  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 4mdisplayed24m.

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: 1mQueryTree22m) 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 1mSet/GetBufferAttributes 22mrequests.

Using the window ID of a stereo window in a draw request
(eg: 1mGetImage22m) results in pixels that are 4mundefined24m.	Possi-
ble semantics are that both left and right images get drawn,









			    -17-


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).

Having an explicit 1mCreateStereoWindow 22mrequest is helpful in
that a server implementation will know from the onset
whether a stereo window is desired and can return appropri-
ate status to the client if it cannot support this function-
ality.

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 dis-
play 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).

If a screen that supports stereo windows also supports nor-
mal windows, then the images presented to the left and right
eyes for normal windows should be the same (ie: have no
stereo offset).

1mSingle-Buffered Stereo Windows0m

The following shows how to create and display a single-
buffered stereo image:

     /*
      * Create the stereo window, map it the screen,
      * and draw the left and right images
      */
     CreateStereoWindow( W, L, R, ... )

     MapWindow( W )

     <draw picture using L,R>





















			    -18-


1mDouble-Buffering Stereo Windows0m

Additional image buffers may be added to a stereo window to
allow double or multi-buffering of stereo images.  Simply
use the the 1mCreateImageBuffers 22mrequest.  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.

The 1mCreateImageBuffers 22mrequest will only create pairs of
left and right image buffers for stereo windows.  By always
pairing left and right image buffers together, implementa-
tions might be able to perform some type of optimization.
If an odd number of buffers is specified, a 1mValue 22merror is
generated.  All the rules mentioned at the start of this
proposal still apply to the image buffers supported by a
stereo window.

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 1mDisplayImageBuffers 22mrequest, but not both.

To double-buffer a stereo window:





































			    -19-


     /*
      * 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) <abort>

     /*
      * Map window to the screen
      */
     MapWindow( W )

     /*
      * Draw images using alternate buffers,
      * display every 1/10 of a second.
      */
     while animating
     {
	  <draw picture using L1,R1>
	  DisplayImageBuffers( [L1], 100, 0 )

	  <draw picture using L0,R0>
	  DisplayImageBuffers( [L0], 100, 0 )
     }

































			    -20-


1mMulti-Buffering Stereo Windows0m

To cycle through 4mN24m stereo images:

     /*
      * 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) <abort>

     /*
      * Map window to screen
      */
     MapWindow( W )

     /*
      * Draw the left and right halves of each image
      */
     foreach stereo image
	  <draw picture using L(i),R(i)>

     /*
      * Cycle through images every 1/10 of a second
      */
     while animating
     {
	  foreach stereo image
	       DisplayImageBuffers( [L(i)], 100, 0 )
     }



























			    -21-


1mProtocol Encoding0m

The official name of this extension is "Multi-Buffering".
When this string passed to 1mQueryExtension 22mthe information
returned should be interpreted as follows:

4mmajor-opcode24m   Specifies the major opcode of this extension.
	       The first byte of each extension request
	       should specify this value.

4mfirst-event24m    Specifies the code that will be returned when
	       1mClobberNotify 22mevents are generated.

4mfirst-error24m    Specifies the code that will be returned when
	       1mBuffer 22merrors are generated.

The following sections describe the protocol encoding for
this extension.

1mTYPES0m

BUFFER_INFO

4	VISUALID	  visual
2	CARD16		  max-buffers
1	CARD8		  depth
1			  unused


SETofBUFFER_EVENT

	#x00008000	  Exposure
	#x02000000	  ClobberNotify
	#x04000000	  UpdateNotify


1mEVENTS0m

1mClobberNotify0m

1	see 4mfirst-event24m	    code
1			       unused
2	CARD16		       sequence number
4	BUFFER		       buffer
1			       state
	0 Unclobbered
	1 PartiallyClobbered
	2 FullyClobbered
23			       unused


1mUpdateNotify0m











			    -22-


1	4mfirst-event24m+1     code
1			  unused
2	CARD16		  sequence number
4	BUFFER		  buffer
24			  unused


1mERRORS0m

1mBuffer0m

1	0		  Error
1	see 4mfirst-error24m   code
2	CARD16		  sequence number
4	CARD32		  bad resource id
2	CARD16		  minor-opcode
1	CARD8		  major-opcode
21			  unused













































			    -23-


1mREQUESTS0m

1mGetBufferVersion0m

1	see 4mmajor-opcode24m	major-opcode
1	0		   minor-opcode
2	1		   request length
->
1	1		   Reply
1			   unused
2	CARD16		   sequence number
4	0		   reply length
1	CARD8		   major version number
1	CARD8		   minor version number
22			   unused


1mCreateImageBuffers0m

1	see 4mmajor-opcode24m	major-opcode
1	1		   minor-opcode
2	3+n		   request length
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
->
1	1		   Reply
1			   unused
2	CARD16		   sequence number
4	0		   reply length
2	CARD16		   number-buffers
22			   unused


1mDestroyImageBuffers0m

1	see 4mmajor-opcode24m	major-opcode
1	2		   minor-opcode
2	2		   request length
4	WINDOW		   wid














			    -24-


1mDisplayImageBuffers0m

1	see 4mmajor-opcode24m	major-opcode
1	3		   minor-opcode
2	2+n		   request length
2	CARD16		   min-delay
2	CARD16		   max-delay
4n	LISTofBUFFER	   buffer-list


1mSetMultiBufferAttributes0m

1	 see 4mmajor-opcode24m	       major-opcode
1	 4			  minor-opcode
2	 3+n			  request length
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




































			    -25-


1mGetMultiBufferAttributes0m

1	see 4mmajor-opcode24m	major-opcode
1	5		   minor-opcode
2	2		   request length
4	WINDOW		   wid
->
1	1		   Reply
1			   unused
2	CARD16		   sequence number
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


1mSetBufferAttributes0m

1	 see 4mmajor-opcode24m	      major-opcode
1	 6			 minor-opcode
2	 3+n			 request length
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





















			    -26-


1mGetBufferAttributes0m

1	see 4mmajor-opcode24m	 major-opcode
1	7		    minor-opcode
2	2		    request length
4	BUFFER		    buffer
->
1	1		    Reply
1			    unused
2	CARD16		    sequence number
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


1mGetBufferInfo0m

1	see 4mmajor-opcode24m	 major-opcode
1	8		    minor-opcode
2	2		    request length
4	WINDOW		    root
->
1	1		    Reply
1			    unused
2	CARD16		    sequence number
4	2(n+m)		    reply length
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


























			    -27-


1mCreateStereoWindow0m

1	see 4mmajor-opcode24m	      major-opcode
1	9			 minor-opcode
2	11+n			 request length
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)
	4mencodings24m 4mare24m 4mthe24m 4msame0m
	4mas24m 4mfor24m 4mCreateWindow0m

4n	LISTofVALUE		 value-list
	4mencodings24m 4mare24m 4mthe24m 4msame0m
	4mas24m 4mfor24m 4mCreateWindow0m


1mClearImageBufferArea0m

1	see 4mmajor-opcode24m	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