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