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