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