1706f2543Smrg                            Generic Rootless Layer
2706f2543Smrg                                 Version 1.0
3706f2543Smrg                                July 13, 2004
4706f2543Smrg
5706f2543Smrg                               Torrey T. Lyons
6706f2543Smrg                              torrey@xfree86.org
7706f2543Smrg
8706f2543Smrg
9706f2543SmrgIntroduction
10706f2543Smrg
11706f2543Smrg        The generic rootless layer allows an X server to be implemented 
12706f2543Smrgon top of another window server in a cooperative manner. This allows the 
13706f2543SmrgX11 windows and native windows of the underlying window server to 
14706f2543Smrgcoexist on the same screen. The layer is called "rootless" because the root 
15706f2543Smrgwindow of the X server is generally not drawn. Instead, each top-level 
16706f2543Smrgchild of the root window is represented as a separate on-screen window by 
17706f2543Smrgthe underlying window server. The layer is referred to as "generic" 
18706f2543Smrgbecause it abstracts away the details of the underlying window system and 
19706f2543Smrgcontains code that is useful for any rootless X server. The code for the 
20706f2543Smrggeneric rootless layer is located in xc/programs/Xserver/miext/rootless. To 
21706f2543Smrgbuild a complete rootless X server requires a specific rootless 
22706f2543Smrgimplementation, which provides functions that allow the generic rootless 
23706f2543Smrglayer to interact with the underlying window system.
24706f2543Smrg
25706f2543Smrg
26706f2543SmrgConcepts
27706f2543Smrg
28706f2543Smrg        In the context of a rootless X server the term window is used to 
29706f2543Smrgmean many fundamentally different things. For X11 a window is a DDX 
30706f2543Smrgresource that describes a visible, or potentially visible, rectangle on the 
31706f2543Smrgscreen. A top-level window is a direct child of the root window. To avoid 
32706f2543Smrgconfusion, an on-screen native window of the underlying window system 
33706f2543Smrgis referred to as a "frame". The generic rootless layer associates each 
34706f2543Smrgmapped top-level X11 window with a frame. An X11 window may be said 
35706f2543Smrgto be "framed" if it or its top-level parent is represented by a frame.
36706f2543Smrg
37706f2543Smrg        The generic rootless layer models each frame as being backed at 
38706f2543Smrgall times by a backing buffer, which is periodically flushed to the screen. 
39706f2543SmrgIf the underlying window system does not provide a backing buffer for 
40706f2543Smrgframes, this must be done by the rootless implementation. The generic 
41706f2543Smrgrootless layer model does not assume it always has access to the frames' 
42706f2543Smrgbacking buffers. Any drawing to the buffer will be proceeded by a call to 
43706f2543Smrgthe rootless implementation's StartDrawing() function and StopDrawing() 
44706f2543Smrgwill be called when the drawing is concluded. The address of the frame's 
45706f2543Smrgbacking buffer is returned by the StartDrawing() function and it can 
46706f2543Smrgchange between successive calls.
47706f2543Smrg
48706f2543Smrg        Because each frame is assumed to have a backing buffer, the 
49706f2543Smrggeneric rootless layer will stop Expose events being generated when the 
50706f2543Smrgregions of visibility of a frame change on screen. This is similar to backing 
51706f2543Smrgstore, but backing buffers are different in that they always store a copy of 
52706f2543Smrgthe entire window contents, not just the obscured portions. The price paid 
53706f2543Smrgin increased memory consumption is made up by the greatly decreased 
54706f2543Smrgcomplexity in not having to track and record regions as they are obscured.
55706f2543Smrg
56706f2543Smrg
57706f2543SmrgRootless Implementation
58706f2543Smrg
59706f2543Smrg        The specifics of the underlying window system are provided to the 
60706f2543Smrggeneric rootless layer through rootless implementation functions, compile-
61706f2543Smrgtime options, and runtime parameters. The rootless implementation 
62706f2543Smrgfunctions are a list of functions that allow the generic rootless layer to 
63706f2543Smrgperform operations such as creating, destroying, moving, and resizing 
64706f2543Smrgframes. Some of the implementation functions are optional. A detailed 
65706f2543Smrgdescription of the rootless implementation functions is provided in 
66706f2543SmrgAppendix A.
67706f2543Smrg
68706f2543Smrg        By design, a rootless implementation should only have to include 
69706f2543Smrgthe rootless.h header file. The rootlessCommon.h file contains definitions 
70706f2543Smrginternal to the generic rootless layer. (If you find you need to use 
71706f2543SmrgrootlessCommon.h in your implementation, let the generic rootless layer 
72706f2543Smrgmaintainers know. This could be an area where the generic rootless layer 
73706f2543Smrgshould be generalized.) A rootless implementation should also modify 
74706f2543SmrgrootlessConfig.h to specify compile time options for its platform.
75706f2543Smrg
76706f2543Smrg        The following compile-time options are defined in 
77706f2543SmrgrootlessConfig.h:
78706f2543Smrg
79706f2543Smrg      o ROOTLESS_PROTECT_ALPHA: By default for a color bit depth of 24 and
80706f2543Smrg        32 bits per pixel, fb will overwrite the "unused" 8 bits to optimize
81706f2543Smrg        drawing speed. If this is true, the alpha channel of frames is
82706f2543Smrg        protected and is not modified when drawing to them. The bits 
83706f2543Smrg        containing the alpha channel are defined by the macro 
84706f2543Smrg        RootlessAlphaMask(bpp), which should return a bit mask for 
85706f2543Smrg        various bits per pixel.
86706f2543Smrg
87706f2543Smrg      o ROOTLESS_REDISPLAY_DELAY: Time in milliseconds between updates to
88706f2543Smrg        the underlying window server. Most operations will be buffered until
89706f2543Smrg        this time has expired.
90706f2543Smrg
91706f2543Smrg      o ROOTLESS_RESIZE_GRAVITY: If the underlying window system supports it,
92706f2543Smrg        some frame resizes can be optimized by relying on the frame contents
93706f2543Smrg        maintaining a particular gravity during the resize. In this way less
94706f2543Smrg        of the frame contents need to be preserved by the generic rootless
95706f2543Smrg        layer. If true, the generic rootless layer will pass gravity hints
96706f2543Smrg        during resizing and rely on the frame contents being preserved
97706f2543Smrg        accordingly.
98706f2543Smrg
99706f2543Smrg        The following runtime options are defined in rootless.h:
100706f2543Smrg
101706f2543Smrg      o rootlessGlobalOffsetX, rootlessGlobalOffsetY: These specify the global
102706f2543Smrg        offset that is applied to all screens when converting from
103706f2543Smrg        screen-local to global coordinates.
104706f2543Smrg
105706f2543Smrg      o rootless_CopyBytes_threshold, rootless_CopyWindow_threshold:
106706f2543Smrg        The minimum number of bytes or pixels for which to use the rootless
107706f2543Smrg        implementation's respective acceleration function. The rootless
108706f2543Smrg        acceleration functions are all optional so these will only be used
109706f2543Smrg        if the respective acceleration function pointer is not NULL.
110706f2543Smrg
111706f2543Smrg
112706f2543SmrgAccelerated Drawing
113706f2543Smrg
114706f2543Smrg	The rootless implementation typically does not have direct access 
115706f2543Smrgto the hardware. Its access to the graphics hardware is generally through 
116706f2543Smrgthe API of the underlying window system. This underlying API may not 
117706f2543Smrgoverlap well with the X11 drawing primitives. The generic rootless layer 
118706f2543Smrgfalls back to using fb for all its 2-D drawing. Providing optional rootless 
119706f2543Smrgimplementation acceleration functions can accelerate some graphics 
120706f2543Smrgprimitives and some window functions. Typically calling through to the 
121706f2543Smrgunderlying window systems API will not speed up these operations for 
122706f2543Smrgsmall enough areas. The rootless_*_threshold runtime options allow the 
123706f2543Smrgrootless implementation to provide hints for when the acceleration 
124706f2543Smrgfunctions should be used instead of fb.
125706f2543Smrg
126706f2543Smrg
127706f2543SmrgAlpha Channel Protection
128706f2543Smrg
129706f2543Smrg	If the bits per pixel is greater then the color bit depth, the contents 
130706f2543Smrgof the extra bits are undefined by the X11 protocol. Some window systems 
131706f2543Smrgwill use these extra bits as an alpha channel. The generic rootless layer can 
132706f2543Smrgbe configured to protect these bits and make sure they are not modified by 
133706f2543Smrgother parts of the X server. To protect the alpha channel 
134706f2543SmrgROOTLESS_PROTECT_ALPHA and RootlessAlphaMask(bpp) must be 
135706f2543Smrgset appropriately as described under the compile time options. This 
136706f2543Smrgensures that the X11 graphics primitives do not overwrite the alpha 
137706f2543Smrgchannel in an attempt to optimize drawing. In addition, the window 
138706f2543Smrgfunctions PaintWindow() and Composite() must be replaced by alpha 
139706f2543Smrgchannel safe variants. These are provided in rootless/safeAlpha.
140706f2543Smrg
141706f2543Smrg
142706f2543SmrgCredits
143706f2543Smrg
144706f2543Smrg	The generic rootless layer was originally conceived and developed 
145706f2543Smrgby Greg Parker as part of the XDarwin X server on Mac OS X. John 
146706f2543SmrgHarper made later optimizations to this code but removed its generic 
147706f2543Smrgindependence of the underlying window system. Torrey T. Lyons 
148706f2543Smrgreintroduced the generic abstractions and made the rootless code suitable 
149706f2543Smrgfor use by other X servers.
150706f2543Smrg
151706f2543Smrg
152706f2543SmrgAppendix A: Rootless Implementation Functions
153706f2543Smrg
154706f2543Smrg	The rootless implementation functions are defined in rootless.h. It 
155706f2543Smrgis intended that rootless.h contains the complete interface that is needed by 
156706f2543Smrgrootless implementations. The definitions contained in rootlessCommon.h 
157706f2543Smrgare intended for internal use by the generic rootless layer and are more 
158706f2543Smrglikely to change.
159706f2543Smrg
160706f2543Smrg	Most of these functions take a RootlessFrameID as a parameter. 
161706f2543SmrgThe RootlessFrameID is an opaque object that is returned by the 
162706f2543Smrgimplementation's CreateFrame() function. The generic rootless layer does 
163706f2543Smrgnot use this frame id other than to pass it back to the rootless 
164706f2543Smrgimplementation to indicate the frame to operate on.
165706f2543Smrg
166706f2543Smrg/*
167706f2543Smrg * Create a new frame.
168706f2543Smrg *  The frame is created unmapped.
169706f2543Smrg *
170706f2543Smrg *  pFrame      RootlessWindowPtr for this frame should be completely
171706f2543Smrg *              initialized before calling except for pFrame->wid, which
172706f2543Smrg *              is set by this function.
173706f2543Smrg *  pScreen     Screen on which to place the new frame
174706f2543Smrg *  newX, newY  Position of the frame.
175706f2543Smrg *  pNewShape   Shape for the frame (in frame-local coordinates). NULL for
176706f2543Smrg *              unshaped frames.
177706f2543Smrg */
178706f2543Smrgtypedef Bool (*RootlessCreateFrameProc)
179706f2543Smrg    (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
180706f2543Smrg     RegionPtr pNewShape);
181706f2543Smrg
182706f2543Smrg/*
183706f2543Smrg * Destroy a frame.
184706f2543Smrg *  Drawing is stopped and all updates are flushed before this is called.
185706f2543Smrg *
186706f2543Smrg *  wid         Frame id
187706f2543Smrg */
188706f2543Smrgtypedef void (*RootlessDestroyFrameProc)
189706f2543Smrg    (RootlessFrameID wid);
190706f2543Smrg
191706f2543Smrg/*
192706f2543Smrg * Move a frame on screen.
193706f2543Smrg *  Drawing is stopped and all updates are flushed before this is called.
194706f2543Smrg *
195706f2543Smrg *  wid         Frame id
196706f2543Smrg *  pScreen     Screen to move the new frame to
197706f2543Smrg *  newX, newY  New position of the frame
198706f2543Smrg */
199706f2543Smrgtypedef void (*RootlessMoveFrameProc) 
200706f2543Smrg    (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
201706f2543Smrg
202706f2543Smrg/*
203706f2543Smrg * Resize and move a frame.
204706f2543Smrg *  Drawing is stopped and all updates are flushed before this is called.
205706f2543Smrg *
206706f2543Smrg *  wid         Frame id
207706f2543Smrg *  pScreen     Screen to move the new frame to
208706f2543Smrg *  newX, newY  New position of the frame
209706f2543Smrg *  newW, newH  New size of the frame
210706f2543Smrg *  gravity     Gravity for window contents (rl_gravity_enum). This is always
211706f2543Smrg *              RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
212706f2543Smrg */
213706f2543Smrgtypedef void (*RootlessResizeFrameProc)
214706f2543Smrg    (RootlessFrameID wid, ScreenPtr pScreen,
215706f2543Smrg     int newX, int newY, unsigned int newW, unsigned int newH,
216706f2543Smrg     unsigned int gravity);
217706f2543Smrg
218706f2543Smrg/*
219706f2543Smrg * Change frame ordering (AKA stacking, layering).
220706f2543Smrg *  Drawing is stopped before this is called. Unmapped frames are mapped by
221706f2543Smrg *  setting their ordering.
222706f2543Smrg *
223706f2543Smrg *  wid         Frame id
224706f2543Smrg *  nextWid     Frame id of frame that is now above this one or NULL if this
225706f2543Smrg *              frame is at the top.
226706f2543Smrg */
227706f2543Smrgtypedef void (*RootlessRestackFrameProc)
228706f2543Smrg    (RootlessFrameID wid, RootlessFrameID nextWid);
229706f2543Smrg
230706f2543Smrg/*
231706f2543Smrg * Change frame's shape.
232706f2543Smrg *  Drawing is stopped before this is called.
233706f2543Smrg *
234706f2543Smrg *  wid         Frame id
235706f2543Smrg *  pNewShape   New shape for the frame (in frame-local coordinates)
236706f2543Smrg *              or NULL if now unshaped.
237706f2543Smrg */
238706f2543Smrgtypedef void (*RootlessReshapeFrameProc)
239706f2543Smrg    (RootlessFrameID wid, RegionPtr pNewShape);
240706f2543Smrg
241706f2543Smrg/*
242706f2543Smrg * Unmap a frame.
243706f2543Smrg *
244706f2543Smrg *  wid         Frame id
245706f2543Smrg */
246706f2543Smrgtypedef void (*RootlessUnmapFrameProc)
247706f2543Smrg    (RootlessFrameID wid);
248706f2543Smrg
249706f2543Smrg/*
250706f2543Smrg * Start drawing to a frame.
251706f2543Smrg *  Prepare a frame for direct access to its backing buffer.
252706f2543Smrg *
253706f2543Smrg *  wid         Frame id
254706f2543Smrg *  pixelData   Address of the backing buffer (returned)
255706f2543Smrg *  bytesPerRow Width in bytes of the backing buffer (returned)
256706f2543Smrg */
257706f2543Smrgtypedef void (*RootlessStartDrawingProc)
258706f2543Smrg    (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
259706f2543Smrg
260706f2543Smrg/*
261706f2543Smrg * Stop drawing to a frame.
262706f2543Smrg *  No drawing to the frame's backing buffer will occur until drawing
263706f2543Smrg *  is started again.
264706f2543Smrg *
265706f2543Smrg *  wid         Frame id
266706f2543Smrg *  flush       Flush drawing updates for this frame to the screen.
267706f2543Smrg */
268706f2543Smrgtypedef void (*RootlessStopDrawingProc)
269706f2543Smrg    (RootlessFrameID wid, Bool flush);
270706f2543Smrg
271706f2543Smrg/*
272706f2543Smrg * Flush drawing updates to the screen.
273706f2543Smrg *  Drawing is stopped before this is called.
274706f2543Smrg *
275706f2543Smrg *  wid         Frame id
276706f2543Smrg *  pDamage     Region containing all the changed pixels in frame-local
277706f2543Smrg *              coordinates. This is clipped to the window's clip.
278706f2543Smrg */
279706f2543Smrgtypedef void (*RootlessUpdateRegionProc)
280706f2543Smrg    (RootlessFrameID wid, RegionPtr pDamage);
281706f2543Smrg
282706f2543Smrg/*
283706f2543Smrg * Mark damaged rectangles as requiring redisplay to screen.
284706f2543Smrg *
285706f2543Smrg *  wid         Frame id
286706f2543Smrg *  nrects      Number of damaged rectangles
287706f2543Smrg *  rects       Array of damaged rectangles in frame-local coordinates
288706f2543Smrg *  shift_x,    Vector to shift rectangles by
289706f2543Smrg *   shift_y
290706f2543Smrg */
291706f2543Smrgtypedef void (*RootlessDamageRectsProc)
292706f2543Smrg    (RootlessFrameID wid, int nrects, const BoxRec *rects,
293706f2543Smrg     int shift_x, int shift_y);
294706f2543Smrg
295706f2543Smrg/*
296706f2543Smrg * Switch the window associated with a frame. (Optional)
297706f2543Smrg *  When a framed window is reparented, the frame is resized and set to
298706f2543Smrg *  use the new top-level parent. If defined this function will be called
299706f2543Smrg *  afterwards for implementation specific bookkeeping.
300706f2543Smrg *
301706f2543Smrg *  pFrame      Frame whose window has switched
302706f2543Smrg *  oldWin      Previous window wrapped by this frame
303706f2543Smrg */
304706f2543Smrgtypedef void (*RootlessSwitchWindowProc)
305706f2543Smrg    (RootlessWindowPtr pFrame, WindowPtr oldWin);
306706f2543Smrg
307706f2543Smrg/*
308706f2543Smrg * Copy bytes. (Optional)
309706f2543Smrg *  Source and destinate may overlap and the right thing should happen.
310706f2543Smrg *
311706f2543Smrg *  width       Bytes to copy per row
312706f2543Smrg *  height      Number of rows
313706f2543Smrg *  src         Source data
314706f2543Smrg *  srcRowBytes Width of source in bytes
315706f2543Smrg *  dst         Destination data
316706f2543Smrg *  dstRowBytes Width of destination in bytes
317706f2543Smrg */
318706f2543Smrgtypedef void (*RootlessCopyBytesProc)
319706f2543Smrg    (unsigned int width, unsigned int height,
320706f2543Smrg     const void *src, unsigned int srcRowBytes,
321706f2543Smrg     void *dst, unsigned int dstRowBytes);
322706f2543Smrg
323706f2543Smrg/*
324706f2543Smrg * Copy area in frame to another part of frame. (Optional)
325706f2543Smrg *
326706f2543Smrg *  wid         Frame id
327706f2543Smrg *  dstNrects   Number of rectangles to copy
328706f2543Smrg *  dstRects    Array of rectangles to copy
329706f2543Smrg *  dx, dy      Number of pixels away to copy area
330706f2543Smrg */
331706f2543Smrgtypedef void (*RootlessCopyWindowProc)
332706f2543Smrg    (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
333706f2543Smrg     int dx, int dy);
334706f2543Smrg
335