xref: /OK3568_Linux_fs/external/xserver/miext/rootless/README.txt (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun                            Generic Rootless Layer
2*4882a593Smuzhiyun                                 Version 1.0
3*4882a593Smuzhiyun                                July 13, 2004
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun                               Torrey T. Lyons
6*4882a593Smuzhiyun                              torrey@xfree86.org
7*4882a593Smuzhiyun
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunIntroduction
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun        The generic rootless layer allows an X server to be implemented
12*4882a593Smuzhiyunon top of another window server in a cooperative manner. This allows the
13*4882a593SmuzhiyunX11 windows and native windows of the underlying window server to
14*4882a593Smuzhiyuncoexist on the same screen. The layer is called "rootless" because the root
15*4882a593Smuzhiyunwindow of the X server is generally not drawn. Instead, each top-level
16*4882a593Smuzhiyunchild of the root window is represented as a separate on-screen window by
17*4882a593Smuzhiyunthe underlying window server. The layer is referred to as "generic"
18*4882a593Smuzhiyunbecause it abstracts away the details of the underlying window system and
19*4882a593Smuzhiyuncontains code that is useful for any rootless X server. The code for the
20*4882a593Smuzhiyungeneric rootless layer is located in xc/programs/Xserver/miext/rootless. To
21*4882a593Smuzhiyunbuild a complete rootless X server requires a specific rootless
22*4882a593Smuzhiyunimplementation, which provides functions that allow the generic rootless
23*4882a593Smuzhiyunlayer to interact with the underlying window system.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun
26*4882a593SmuzhiyunConcepts
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun        In the context of a rootless X server the term window is used to
29*4882a593Smuzhiyunmean many fundamentally different things. For X11 a window is a DDX
30*4882a593Smuzhiyunresource that describes a visible, or potentially visible, rectangle on the
31*4882a593Smuzhiyunscreen. A top-level window is a direct child of the root window. To avoid
32*4882a593Smuzhiyunconfusion, an on-screen native window of the underlying window system
33*4882a593Smuzhiyunis referred to as a "frame". The generic rootless layer associates each
34*4882a593Smuzhiyunmapped top-level X11 window with a frame. An X11 window may be said
35*4882a593Smuzhiyunto be "framed" if it or its top-level parent is represented by a frame.
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun        The generic rootless layer models each frame as being backed at
38*4882a593Smuzhiyunall times by a backing buffer, which is periodically flushed to the screen.
39*4882a593SmuzhiyunIf the underlying window system does not provide a backing buffer for
40*4882a593Smuzhiyunframes, this must be done by the rootless implementation. The generic
41*4882a593Smuzhiyunrootless layer model does not assume it always has access to the frames'
42*4882a593Smuzhiyunbacking buffers. Any drawing to the buffer will be proceeded by a call to
43*4882a593Smuzhiyunthe rootless implementation's StartDrawing() function and StopDrawing()
44*4882a593Smuzhiyunwill be called when the drawing is concluded. The address of the frame's
45*4882a593Smuzhiyunbacking buffer is returned by the StartDrawing() function and it can
46*4882a593Smuzhiyunchange between successive calls.
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun        Because each frame is assumed to have a backing buffer, the
49*4882a593Smuzhiyungeneric rootless layer will stop Expose events being generated when the
50*4882a593Smuzhiyunregions of visibility of a frame change on screen. This is similar to backing
51*4882a593Smuzhiyunstore, but backing buffers are different in that they always store a copy of
52*4882a593Smuzhiyunthe entire window contents, not just the obscured portions. The price paid
53*4882a593Smuzhiyunin increased memory consumption is made up by the greatly decreased
54*4882a593Smuzhiyuncomplexity in not having to track and record regions as they are obscured.
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun
57*4882a593SmuzhiyunRootless Implementation
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun        The specifics of the underlying window system are provided to the
60*4882a593Smuzhiyungeneric rootless layer through rootless implementation functions, compile-
61*4882a593Smuzhiyuntime options, and runtime parameters. The rootless implementation
62*4882a593Smuzhiyunfunctions are a list of functions that allow the generic rootless layer to
63*4882a593Smuzhiyunperform operations such as creating, destroying, moving, and resizing
64*4882a593Smuzhiyunframes. Some of the implementation functions are optional. A detailed
65*4882a593Smuzhiyundescription of the rootless implementation functions is provided in
66*4882a593SmuzhiyunAppendix A.
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun        By design, a rootless implementation should only have to include
69*4882a593Smuzhiyunthe rootless.h header file. The rootlessCommon.h file contains definitions
70*4882a593Smuzhiyuninternal to the generic rootless layer. (If you find you need to use
71*4882a593SmuzhiyunrootlessCommon.h in your implementation, let the generic rootless layer
72*4882a593Smuzhiyunmaintainers know. This could be an area where the generic rootless layer
73*4882a593Smuzhiyunshould be generalized.) A rootless implementation should also modify
74*4882a593SmuzhiyunrootlessConfig.h to specify compile time options for its platform.
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun        The following compile-time options are defined in
77*4882a593SmuzhiyunrootlessConfig.h:
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun      o ROOTLESS_PROTECT_ALPHA: By default for a color bit depth of 24 and
80*4882a593Smuzhiyun        32 bits per pixel, fb will overwrite the "unused" 8 bits to optimize
81*4882a593Smuzhiyun        drawing speed. If this is true, the alpha channel of frames is
82*4882a593Smuzhiyun        protected and is not modified when drawing to them. The bits
83*4882a593Smuzhiyun        containing the alpha channel are defined by the macro
84*4882a593Smuzhiyun        RootlessAlphaMask(bpp), which should return a bit mask for
85*4882a593Smuzhiyun        various bits per pixel.
86*4882a593Smuzhiyun
87*4882a593Smuzhiyun      o ROOTLESS_REDISPLAY_DELAY: Time in milliseconds between updates to
88*4882a593Smuzhiyun        the underlying window server. Most operations will be buffered until
89*4882a593Smuzhiyun        this time has expired.
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun      o ROOTLESS_RESIZE_GRAVITY: If the underlying window system supports it,
92*4882a593Smuzhiyun        some frame resizes can be optimized by relying on the frame contents
93*4882a593Smuzhiyun        maintaining a particular gravity during the resize. In this way less
94*4882a593Smuzhiyun        of the frame contents need to be preserved by the generic rootless
95*4882a593Smuzhiyun        layer. If true, the generic rootless layer will pass gravity hints
96*4882a593Smuzhiyun        during resizing and rely on the frame contents being preserved
97*4882a593Smuzhiyun        accordingly.
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun        The following runtime options are defined in rootless.h:
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun      o rootlessGlobalOffsetX, rootlessGlobalOffsetY: These specify the global
102*4882a593Smuzhiyun        offset that is applied to all screens when converting from
103*4882a593Smuzhiyun        screen-local to global coordinates.
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun      o rootless_CopyBytes_threshold, rootless_CopyWindow_threshold:
106*4882a593Smuzhiyun        The minimum number of bytes or pixels for which to use the rootless
107*4882a593Smuzhiyun        implementation's respective acceleration function. The rootless
108*4882a593Smuzhiyun        acceleration functions are all optional so these will only be used
109*4882a593Smuzhiyun        if the respective acceleration function pointer is not NULL.
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun
112*4882a593SmuzhiyunAccelerated Drawing
113*4882a593Smuzhiyun
114*4882a593Smuzhiyun	The rootless implementation typically does not have direct access
115*4882a593Smuzhiyunto the hardware. Its access to the graphics hardware is generally through
116*4882a593Smuzhiyunthe API of the underlying window system. This underlying API may not
117*4882a593Smuzhiyunoverlap well with the X11 drawing primitives. The generic rootless layer
118*4882a593Smuzhiyunfalls back to using fb for all its 2-D drawing. Providing optional rootless
119*4882a593Smuzhiyunimplementation acceleration functions can accelerate some graphics
120*4882a593Smuzhiyunprimitives and some window functions. Typically calling through to the
121*4882a593Smuzhiyununderlying window systems API will not speed up these operations for
122*4882a593Smuzhiyunsmall enough areas. The rootless_*_threshold runtime options allow the
123*4882a593Smuzhiyunrootless implementation to provide hints for when the acceleration
124*4882a593Smuzhiyunfunctions should be used instead of fb.
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun
127*4882a593SmuzhiyunAlpha Channel Protection
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	If the bits per pixel is greater then the color bit depth, the contents
130*4882a593Smuzhiyunof the extra bits are undefined by the X11 protocol. Some window systems
131*4882a593Smuzhiyunwill use these extra bits as an alpha channel. The generic rootless layer can
132*4882a593Smuzhiyunbe configured to protect these bits and make sure they are not modified by
133*4882a593Smuzhiyunother parts of the X server. To protect the alpha channel
134*4882a593SmuzhiyunROOTLESS_PROTECT_ALPHA and RootlessAlphaMask(bpp) must be
135*4882a593Smuzhiyunset appropriately as described under the compile time options. This
136*4882a593Smuzhiyunensures that the X11 graphics primitives do not overwrite the alpha
137*4882a593Smuzhiyunchannel in an attempt to optimize drawing. In addition, the window
138*4882a593Smuzhiyunfunctions PaintWindow() and Composite() must be replaced by alpha
139*4882a593Smuzhiyunchannel safe variants. These are provided in rootless/safeAlpha.
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun
142*4882a593SmuzhiyunCredits
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun	The generic rootless layer was originally conceived and developed
145*4882a593Smuzhiyunby Greg Parker as part of the XDarwin X server on Mac OS X. John
146*4882a593SmuzhiyunHarper made later optimizations to this code but removed its generic
147*4882a593Smuzhiyunindependence of the underlying window system. Torrey T. Lyons
148*4882a593Smuzhiyunreintroduced the generic abstractions and made the rootless code suitable
149*4882a593Smuzhiyunfor use by other X servers.
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun
152*4882a593SmuzhiyunAppendix A: Rootless Implementation Functions
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun	The rootless implementation functions are defined in rootless.h. It
155*4882a593Smuzhiyunis intended that rootless.h contains the complete interface that is needed by
156*4882a593Smuzhiyunrootless implementations. The definitions contained in rootlessCommon.h
157*4882a593Smuzhiyunare intended for internal use by the generic rootless layer and are more
158*4882a593Smuzhiyunlikely to change.
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun	Most of these functions take a RootlessFrameID as a parameter.
161*4882a593SmuzhiyunThe RootlessFrameID is an opaque object that is returned by the
162*4882a593Smuzhiyunimplementation's CreateFrame() function. The generic rootless layer does
163*4882a593Smuzhiyunnot use this frame id other than to pass it back to the rootless
164*4882a593Smuzhiyunimplementation to indicate the frame to operate on.
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun/*
167*4882a593Smuzhiyun * Create a new frame.
168*4882a593Smuzhiyun *  The frame is created unmapped.
169*4882a593Smuzhiyun *
170*4882a593Smuzhiyun *  pFrame      RootlessWindowPtr for this frame should be completely
171*4882a593Smuzhiyun *              initialized before calling except for pFrame->wid, which
172*4882a593Smuzhiyun *              is set by this function.
173*4882a593Smuzhiyun *  pScreen     Screen on which to place the new frame
174*4882a593Smuzhiyun *  newX, newY  Position of the frame.
175*4882a593Smuzhiyun *  pNewShape   Shape for the frame (in frame-local coordinates). NULL for
176*4882a593Smuzhiyun *              unshaped frames.
177*4882a593Smuzhiyun */
178*4882a593Smuzhiyuntypedef Bool (*RootlessCreateFrameProc)
179*4882a593Smuzhiyun    (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
180*4882a593Smuzhiyun     RegionPtr pNewShape);
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun/*
183*4882a593Smuzhiyun * Destroy a frame.
184*4882a593Smuzhiyun *  Drawing is stopped and all updates are flushed before this is called.
185*4882a593Smuzhiyun *
186*4882a593Smuzhiyun *  wid         Frame id
187*4882a593Smuzhiyun */
188*4882a593Smuzhiyuntypedef void (*RootlessDestroyFrameProc)
189*4882a593Smuzhiyun    (RootlessFrameID wid);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun/*
192*4882a593Smuzhiyun * Move a frame on screen.
193*4882a593Smuzhiyun *  Drawing is stopped and all updates are flushed before this is called.
194*4882a593Smuzhiyun *
195*4882a593Smuzhiyun *  wid         Frame id
196*4882a593Smuzhiyun *  pScreen     Screen to move the new frame to
197*4882a593Smuzhiyun *  newX, newY  New position of the frame
198*4882a593Smuzhiyun */
199*4882a593Smuzhiyuntypedef void (*RootlessMoveFrameProc)
200*4882a593Smuzhiyun    (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun/*
203*4882a593Smuzhiyun * Resize and move a frame.
204*4882a593Smuzhiyun *  Drawing is stopped and all updates are flushed before this is called.
205*4882a593Smuzhiyun *
206*4882a593Smuzhiyun *  wid         Frame id
207*4882a593Smuzhiyun *  pScreen     Screen to move the new frame to
208*4882a593Smuzhiyun *  newX, newY  New position of the frame
209*4882a593Smuzhiyun *  newW, newH  New size of the frame
210*4882a593Smuzhiyun *  gravity     Gravity for window contents (rl_gravity_enum). This is always
211*4882a593Smuzhiyun *              RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
212*4882a593Smuzhiyun */
213*4882a593Smuzhiyuntypedef void (*RootlessResizeFrameProc)
214*4882a593Smuzhiyun    (RootlessFrameID wid, ScreenPtr pScreen,
215*4882a593Smuzhiyun     int newX, int newY, unsigned int newW, unsigned int newH,
216*4882a593Smuzhiyun     unsigned int gravity);
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun/*
219*4882a593Smuzhiyun * Change frame ordering (AKA stacking, layering).
220*4882a593Smuzhiyun *  Drawing is stopped before this is called. Unmapped frames are mapped by
221*4882a593Smuzhiyun *  setting their ordering.
222*4882a593Smuzhiyun *
223*4882a593Smuzhiyun *  wid         Frame id
224*4882a593Smuzhiyun *  nextWid     Frame id of frame that is now above this one or NULL if this
225*4882a593Smuzhiyun *              frame is at the top.
226*4882a593Smuzhiyun */
227*4882a593Smuzhiyuntypedef void (*RootlessRestackFrameProc)
228*4882a593Smuzhiyun    (RootlessFrameID wid, RootlessFrameID nextWid);
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun/*
231*4882a593Smuzhiyun * Change frame's shape.
232*4882a593Smuzhiyun *  Drawing is stopped before this is called.
233*4882a593Smuzhiyun *
234*4882a593Smuzhiyun *  wid         Frame id
235*4882a593Smuzhiyun *  pNewShape   New shape for the frame (in frame-local coordinates)
236*4882a593Smuzhiyun *              or NULL if now unshaped.
237*4882a593Smuzhiyun */
238*4882a593Smuzhiyuntypedef void (*RootlessReshapeFrameProc)
239*4882a593Smuzhiyun    (RootlessFrameID wid, RegionPtr pNewShape);
240*4882a593Smuzhiyun
241*4882a593Smuzhiyun/*
242*4882a593Smuzhiyun * Unmap a frame.
243*4882a593Smuzhiyun *
244*4882a593Smuzhiyun *  wid         Frame id
245*4882a593Smuzhiyun */
246*4882a593Smuzhiyuntypedef void (*RootlessUnmapFrameProc)
247*4882a593Smuzhiyun    (RootlessFrameID wid);
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun/*
250*4882a593Smuzhiyun * Start drawing to a frame.
251*4882a593Smuzhiyun *  Prepare a frame for direct access to its backing buffer.
252*4882a593Smuzhiyun *
253*4882a593Smuzhiyun *  wid         Frame id
254*4882a593Smuzhiyun *  pixelData   Address of the backing buffer (returned)
255*4882a593Smuzhiyun *  bytesPerRow Width in bytes of the backing buffer (returned)
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyuntypedef void (*RootlessStartDrawingProc)
258*4882a593Smuzhiyun    (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun/*
261*4882a593Smuzhiyun * Stop drawing to a frame.
262*4882a593Smuzhiyun *  No drawing to the frame's backing buffer will occur until drawing
263*4882a593Smuzhiyun *  is started again.
264*4882a593Smuzhiyun *
265*4882a593Smuzhiyun *  wid         Frame id
266*4882a593Smuzhiyun *  flush       Flush drawing updates for this frame to the screen.
267*4882a593Smuzhiyun */
268*4882a593Smuzhiyuntypedef void (*RootlessStopDrawingProc)
269*4882a593Smuzhiyun    (RootlessFrameID wid, Bool flush);
270*4882a593Smuzhiyun
271*4882a593Smuzhiyun/*
272*4882a593Smuzhiyun * Flush drawing updates to the screen.
273*4882a593Smuzhiyun *  Drawing is stopped before this is called.
274*4882a593Smuzhiyun *
275*4882a593Smuzhiyun *  wid         Frame id
276*4882a593Smuzhiyun *  pDamage     Region containing all the changed pixels in frame-local
277*4882a593Smuzhiyun *              coordinates. This is clipped to the window's clip.
278*4882a593Smuzhiyun */
279*4882a593Smuzhiyuntypedef void (*RootlessUpdateRegionProc)
280*4882a593Smuzhiyun    (RootlessFrameID wid, RegionPtr pDamage);
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun/*
283*4882a593Smuzhiyun * Mark damaged rectangles as requiring redisplay to screen.
284*4882a593Smuzhiyun *
285*4882a593Smuzhiyun *  wid         Frame id
286*4882a593Smuzhiyun *  nrects      Number of damaged rectangles
287*4882a593Smuzhiyun *  rects       Array of damaged rectangles in frame-local coordinates
288*4882a593Smuzhiyun *  shift_x,    Vector to shift rectangles by
289*4882a593Smuzhiyun *   shift_y
290*4882a593Smuzhiyun */
291*4882a593Smuzhiyuntypedef void (*RootlessDamageRectsProc)
292*4882a593Smuzhiyun    (RootlessFrameID wid, int nrects, const BoxRec *rects,
293*4882a593Smuzhiyun     int shift_x, int shift_y);
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun/*
296*4882a593Smuzhiyun * Switch the window associated with a frame. (Optional)
297*4882a593Smuzhiyun *  When a framed window is reparented, the frame is resized and set to
298*4882a593Smuzhiyun *  use the new top-level parent. If defined this function will be called
299*4882a593Smuzhiyun *  afterwards for implementation specific bookkeeping.
300*4882a593Smuzhiyun *
301*4882a593Smuzhiyun *  pFrame      Frame whose window has switched
302*4882a593Smuzhiyun *  oldWin      Previous window wrapped by this frame
303*4882a593Smuzhiyun */
304*4882a593Smuzhiyuntypedef void (*RootlessSwitchWindowProc)
305*4882a593Smuzhiyun    (RootlessWindowPtr pFrame, WindowPtr oldWin);
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun/*
308*4882a593Smuzhiyun * Copy bytes. (Optional)
309*4882a593Smuzhiyun *  Source and destinate may overlap and the right thing should happen.
310*4882a593Smuzhiyun *
311*4882a593Smuzhiyun *  width       Bytes to copy per row
312*4882a593Smuzhiyun *  height      Number of rows
313*4882a593Smuzhiyun *  src         Source data
314*4882a593Smuzhiyun *  srcRowBytes Width of source in bytes
315*4882a593Smuzhiyun *  dst         Destination data
316*4882a593Smuzhiyun *  dstRowBytes Width of destination in bytes
317*4882a593Smuzhiyun */
318*4882a593Smuzhiyuntypedef void (*RootlessCopyBytesProc)
319*4882a593Smuzhiyun    (unsigned int width, unsigned int height,
320*4882a593Smuzhiyun     const void *src, unsigned int srcRowBytes,
321*4882a593Smuzhiyun     void *dst, unsigned int dstRowBytes);
322*4882a593Smuzhiyun
323*4882a593Smuzhiyun/*
324*4882a593Smuzhiyun * Copy area in frame to another part of frame. (Optional)
325*4882a593Smuzhiyun *
326*4882a593Smuzhiyun *  wid         Frame id
327*4882a593Smuzhiyun *  dstNrects   Number of rectangles to copy
328*4882a593Smuzhiyun *  dstRects    Array of rectangles to copy
329*4882a593Smuzhiyun *  dx, dy      Number of pixels away to copy area
330*4882a593Smuzhiyun */
331*4882a593Smuzhiyuntypedef void (*RootlessCopyWindowProc)
332*4882a593Smuzhiyun    (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
333*4882a593Smuzhiyun     int dx, int dy);
334*4882a593Smuzhiyun
335