1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun * Common internal rootless definitions and code 3*4882a593Smuzhiyun */ 4*4882a593Smuzhiyun /* 5*4882a593Smuzhiyun * Copyright (c) 2001 Greg Parker. All Rights Reserved. 6*4882a593Smuzhiyun * Copyright (c) 2002-2004 Torrey T. Lyons. All Rights Reserved. 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a 9*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"), 10*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation 11*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the 13*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions: 14*4882a593Smuzhiyun * 15*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be included in 16*4882a593Smuzhiyun * all copies or substantial portions of the Software. 17*4882a593Smuzhiyun * 18*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21*4882a593Smuzhiyun * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 22*4882a593Smuzhiyun * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 23*4882a593Smuzhiyun * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 24*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE. 25*4882a593Smuzhiyun * 26*4882a593Smuzhiyun * Except as contained in this notice, the name(s) of the above copyright 27*4882a593Smuzhiyun * holders shall not be used in advertising or otherwise to promote the sale, 28*4882a593Smuzhiyun * use or other dealings in this Software without prior written authorization. 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H 32*4882a593Smuzhiyun #include <dix-config.h> 33*4882a593Smuzhiyun #endif 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun #include <stdint.h> 36*4882a593Smuzhiyun #ifndef _ROOTLESSCOMMON_H 37*4882a593Smuzhiyun #define _ROOTLESSCOMMON_H 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #include "misc.h" 40*4882a593Smuzhiyun #include "rootless.h" 41*4882a593Smuzhiyun #include "fb.h" 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun #include "scrnintstr.h" 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun #include "picturestr.h" 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun // Debug output, or not. 48*4882a593Smuzhiyun #ifdef ROOTLESSDEBUG 49*4882a593Smuzhiyun #define RL_DEBUG_MSG ErrorF 50*4882a593Smuzhiyun #else 51*4882a593Smuzhiyun #define RL_DEBUG_MSG(a, ...) 52*4882a593Smuzhiyun #endif 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun // Global variables 55*4882a593Smuzhiyun extern DevPrivateKeyRec rootlessGCPrivateKeyRec; 56*4882a593Smuzhiyun 57*4882a593Smuzhiyun #define rootlessGCPrivateKey (&rootlessGCPrivateKeyRec) 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun extern DevPrivateKeyRec rootlessScreenPrivateKeyRec; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun #define rootlessScreenPrivateKey (&rootlessScreenPrivateKeyRec) 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun extern DevPrivateKeyRec rootlessWindowPrivateKeyRec; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun #define rootlessWindowPrivateKey (&rootlessWindowPrivateKeyRec) 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun extern DevPrivateKeyRec rootlessWindowOldPixmapPrivateKeyRec; 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun #define rootlessWindowOldPixmapPrivateKey (&rootlessWindowOldPixmapPrivateKeyRec) 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun // RootlessGCRec: private per-gc data 72*4882a593Smuzhiyun typedef struct { 73*4882a593Smuzhiyun const GCFuncs *originalFuncs; 74*4882a593Smuzhiyun const GCOps *originalOps; 75*4882a593Smuzhiyun } RootlessGCRec; 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun // RootlessScreenRec: per-screen private data 78*4882a593Smuzhiyun typedef struct _RootlessScreenRec { 79*4882a593Smuzhiyun // Rootless implementation functions 80*4882a593Smuzhiyun RootlessFrameProcsPtr imp; 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun // Wrapped screen functions 83*4882a593Smuzhiyun CreateScreenResourcesProcPtr CreateScreenResources; 84*4882a593Smuzhiyun CloseScreenProcPtr CloseScreen; 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun CreateWindowProcPtr CreateWindow; 87*4882a593Smuzhiyun DestroyWindowProcPtr DestroyWindow; 88*4882a593Smuzhiyun RealizeWindowProcPtr RealizeWindow; 89*4882a593Smuzhiyun UnrealizeWindowProcPtr UnrealizeWindow; 90*4882a593Smuzhiyun MoveWindowProcPtr MoveWindow; 91*4882a593Smuzhiyun ResizeWindowProcPtr ResizeWindow; 92*4882a593Smuzhiyun RestackWindowProcPtr RestackWindow; 93*4882a593Smuzhiyun ReparentWindowProcPtr ReparentWindow; 94*4882a593Smuzhiyun ChangeBorderWidthProcPtr ChangeBorderWidth; 95*4882a593Smuzhiyun PositionWindowProcPtr PositionWindow; 96*4882a593Smuzhiyun ChangeWindowAttributesProcPtr ChangeWindowAttributes; 97*4882a593Smuzhiyun PaintWindowProcPtr PaintWindow; 98*4882a593Smuzhiyun 99*4882a593Smuzhiyun CreateGCProcPtr CreateGC; 100*4882a593Smuzhiyun CopyWindowProcPtr CopyWindow; 101*4882a593Smuzhiyun GetImageProcPtr GetImage; 102*4882a593Smuzhiyun SourceValidateProcPtr SourceValidate; 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun MarkOverlappedWindowsProcPtr MarkOverlappedWindows; 105*4882a593Smuzhiyun ValidateTreeProcPtr ValidateTree; 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun SetShapeProcPtr SetShape; 108*4882a593Smuzhiyun 109*4882a593Smuzhiyun CompositeProcPtr Composite; 110*4882a593Smuzhiyun GlyphsProcPtr Glyphs; 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun InstallColormapProcPtr InstallColormap; 113*4882a593Smuzhiyun UninstallColormapProcPtr UninstallColormap; 114*4882a593Smuzhiyun StoreColorsProcPtr StoreColors; 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun void *pixmap_data; 117*4882a593Smuzhiyun unsigned int pixmap_data_size; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun ColormapPtr colormap; 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun void *redisplay_timer; 122*4882a593Smuzhiyun unsigned int redisplay_timer_set:1; 123*4882a593Smuzhiyun unsigned int redisplay_queued:1; 124*4882a593Smuzhiyun unsigned int redisplay_expired:1; 125*4882a593Smuzhiyun unsigned int colormap_changed:1; 126*4882a593Smuzhiyun } RootlessScreenRec, *RootlessScreenPtr; 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun // "Definition of the Porting Layer for the X11 Sample Server" says 129*4882a593Smuzhiyun // unwrap and rewrap of screen functions is unnecessary, but 130*4882a593Smuzhiyun // screen->CreateGC changes after a call to cfbCreateGC. 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun #define SCREEN_UNWRAP(screen, fn) \ 133*4882a593Smuzhiyun screen->fn = SCREENREC(screen)->fn; 134*4882a593Smuzhiyun 135*4882a593Smuzhiyun #define SCREEN_WRAP(screen, fn) \ 136*4882a593Smuzhiyun SCREENREC(screen)->fn = screen->fn; \ 137*4882a593Smuzhiyun screen->fn = Rootless##fn 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun // Accessors for screen and window privates 140*4882a593Smuzhiyun 141*4882a593Smuzhiyun #define SCREENREC(pScreen) ((RootlessScreenRec *) \ 142*4882a593Smuzhiyun dixLookupPrivate(&(pScreen)->devPrivates, rootlessScreenPrivateKey)) 143*4882a593Smuzhiyun 144*4882a593Smuzhiyun #define SETSCREENREC(pScreen, v) \ 145*4882a593Smuzhiyun dixSetPrivate(&(pScreen)->devPrivates, rootlessScreenPrivateKey, v) 146*4882a593Smuzhiyun 147*4882a593Smuzhiyun #define WINREC(pWin) ((RootlessWindowRec *) \ 148*4882a593Smuzhiyun dixLookupPrivate(&(pWin)->devPrivates, rootlessWindowPrivateKey)) 149*4882a593Smuzhiyun 150*4882a593Smuzhiyun #define SETWINREC(pWin, v) \ 151*4882a593Smuzhiyun dixSetPrivate(&(pWin)->devPrivates, rootlessWindowPrivateKey, v) 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun // Call a rootless implementation function. 154*4882a593Smuzhiyun // Many rootless implementation functions are allowed to be NULL. 155*4882a593Smuzhiyun #define CallFrameProc(pScreen, proc, params) \ 156*4882a593Smuzhiyun if (SCREENREC(pScreen)->frameProcs.proc) { \ 157*4882a593Smuzhiyun RL_DEBUG_MSG("calling frame proc " #proc " "); \ 158*4882a593Smuzhiyun SCREENREC(pScreen)->frameProcs.proc params; \ 159*4882a593Smuzhiyun } 160*4882a593Smuzhiyun 161*4882a593Smuzhiyun // BoxRec manipulators 162*4882a593Smuzhiyun // Copied from shadowfb 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun #define TRIM_BOX(box, pGC) { \ 165*4882a593Smuzhiyun BoxPtr extents = &pGC->pCompositeClip->extents;\ 166*4882a593Smuzhiyun if(box.x1 < extents->x1) box.x1 = extents->x1; \ 167*4882a593Smuzhiyun if(box.x2 > extents->x2) box.x2 = extents->x2; \ 168*4882a593Smuzhiyun if(box.y1 < extents->y1) box.y1 = extents->y1; \ 169*4882a593Smuzhiyun if(box.y2 > extents->y2) box.y2 = extents->y2; \ 170*4882a593Smuzhiyun } 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun #define TRANSLATE_BOX(box, pDraw) { \ 173*4882a593Smuzhiyun box.x1 += pDraw->x; \ 174*4882a593Smuzhiyun box.x2 += pDraw->x; \ 175*4882a593Smuzhiyun box.y1 += pDraw->y; \ 176*4882a593Smuzhiyun box.y2 += pDraw->y; \ 177*4882a593Smuzhiyun } 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun #define TRIM_AND_TRANSLATE_BOX(box, pDraw, pGC) { \ 180*4882a593Smuzhiyun TRANSLATE_BOX(box, pDraw); \ 181*4882a593Smuzhiyun TRIM_BOX(box, pGC); \ 182*4882a593Smuzhiyun } 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun #define BOX_NOT_EMPTY(box) \ 185*4882a593Smuzhiyun (((box.x2 - box.x1) > 0) && ((box.y2 - box.y1) > 0)) 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun // HUGE_ROOT and NORMAL_ROOT 188*4882a593Smuzhiyun // We don't want to clip windows to the edge of the screen. 189*4882a593Smuzhiyun // HUGE_ROOT temporarily makes the root window really big. 190*4882a593Smuzhiyun // This is needed as a wrapper around any function that calls 191*4882a593Smuzhiyun // SetWinSize or SetBorderSize which clip a window against its 192*4882a593Smuzhiyun // parents, including the root. 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun extern RegionRec rootlessHugeRoot; 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun #define HUGE_ROOT(pWin) \ 197*4882a593Smuzhiyun do { \ 198*4882a593Smuzhiyun WindowPtr _w = pWin; \ 199*4882a593Smuzhiyun while (_w->parent) \ 200*4882a593Smuzhiyun _w = _w->parent; \ 201*4882a593Smuzhiyun saveRoot = _w->winSize; \ 202*4882a593Smuzhiyun _w->winSize = rootlessHugeRoot; \ 203*4882a593Smuzhiyun } while (0) 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun #define NORMAL_ROOT(pWin) \ 206*4882a593Smuzhiyun do { \ 207*4882a593Smuzhiyun WindowPtr _w = pWin; \ 208*4882a593Smuzhiyun while (_w->parent) \ 209*4882a593Smuzhiyun _w = _w->parent; \ 210*4882a593Smuzhiyun _w->winSize = saveRoot; \ 211*4882a593Smuzhiyun } while (0) 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun // Returns TRUE if this window is a top-level window (i.e. child of the root) 214*4882a593Smuzhiyun // The root is not a top-level window. 215*4882a593Smuzhiyun #define IsTopLevel(pWin) \ 216*4882a593Smuzhiyun ((pWin) && (pWin)->parent && !(pWin)->parent->parent) 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun // Returns TRUE if this window is a root window 219*4882a593Smuzhiyun #define IsRoot(pWin) \ 220*4882a593Smuzhiyun ((pWin) == (pWin)->drawable.pScreen->root) 221*4882a593Smuzhiyun 222*4882a593Smuzhiyun /* 223*4882a593Smuzhiyun * SetPixmapBaseToScreen 224*4882a593Smuzhiyun * Move the given pixmap's base address to where pixel (0, 0) 225*4882a593Smuzhiyun * would be if the pixmap's actual data started at (x, y). 226*4882a593Smuzhiyun * Can't access the bits before the first word of the drawable's data in 227*4882a593Smuzhiyun * rootless mode, so make sure our base address is always 32-bit aligned. 228*4882a593Smuzhiyun */ 229*4882a593Smuzhiyun #define SetPixmapBaseToScreen(pix, _x, _y) { \ 230*4882a593Smuzhiyun PixmapPtr _pPix = (PixmapPtr) (pix); \ 231*4882a593Smuzhiyun _pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \ 232*4882a593Smuzhiyun ((int)(_x) * _pPix->drawable.bitsPerPixel/8 + \ 233*4882a593Smuzhiyun (int)(_y) * _pPix->devKind); \ 234*4882a593Smuzhiyun if (_pPix->drawable.bitsPerPixel != FB_UNIT) { \ 235*4882a593Smuzhiyun size_t _diff = ((size_t) _pPix->devPrivate.ptr) & \ 236*4882a593Smuzhiyun (FB_UNIT / CHAR_BIT - 1); \ 237*4882a593Smuzhiyun _pPix->devPrivate.ptr = (char *) (_pPix->devPrivate.ptr) - \ 238*4882a593Smuzhiyun _diff; \ 239*4882a593Smuzhiyun _pPix->drawable.x = _diff / \ 240*4882a593Smuzhiyun (_pPix->drawable.bitsPerPixel / CHAR_BIT); \ 241*4882a593Smuzhiyun } \ 242*4882a593Smuzhiyun } 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun // Returns TRUE if this window is visible inside a frame 245*4882a593Smuzhiyun // (e.g. it is visible and has a top-level or root parent) 246*4882a593Smuzhiyun Bool IsFramedWindow(WindowPtr pWin); 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun // Routines that cause regions to get redrawn. 249*4882a593Smuzhiyun // DamageRegion and DamageRect are in global coordinates. 250*4882a593Smuzhiyun // DamageBox is in window-local coordinates. 251*4882a593Smuzhiyun void RootlessDamageRegion(WindowPtr pWindow, RegionPtr pRegion); 252*4882a593Smuzhiyun void RootlessDamageRect(WindowPtr pWindow, int x, int y, int w, int h); 253*4882a593Smuzhiyun void RootlessDamageBox(WindowPtr pWindow, BoxPtr pBox); 254*4882a593Smuzhiyun void RootlessRedisplay(WindowPtr pWindow); 255*4882a593Smuzhiyun void RootlessRedisplayScreen(ScreenPtr pScreen); 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun void RootlessQueueRedisplay(ScreenPtr pScreen); 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /* Return the colormap currently installed on the given screen. */ 260*4882a593Smuzhiyun ColormapPtr RootlessGetColormap(ScreenPtr pScreen); 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun /* Convert colormap to ARGB. */ 263*4882a593Smuzhiyun Bool RootlessResolveColormap(ScreenPtr pScreen, int first_color, 264*4882a593Smuzhiyun int n_colors, uint32_t * colors); 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun void RootlessFlushWindowColormap(WindowPtr pWin); 267*4882a593Smuzhiyun void RootlessFlushScreenColormaps(ScreenPtr pScreen); 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun // Move a window to its proper location on the screen. 270*4882a593Smuzhiyun void RootlessRepositionWindow(WindowPtr pWin); 271*4882a593Smuzhiyun 272*4882a593Smuzhiyun // Move the window to it's correct place in the physical stacking order. 273*4882a593Smuzhiyun void RootlessReorderWindow(WindowPtr pWin); 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun void RootlessScreenExpose(ScreenPtr pScreen); 276*4882a593Smuzhiyun void RootlessHideAllWindows(void); 277*4882a593Smuzhiyun void RootlessShowAllWindows(void); 278*4882a593Smuzhiyun void RootlessUpdateRooted(Bool state); 279*4882a593Smuzhiyun 280*4882a593Smuzhiyun void RootlessEnableRoot(ScreenPtr pScreen); 281*4882a593Smuzhiyun void RootlessDisableRoot(ScreenPtr pScreen); 282*4882a593Smuzhiyun 283*4882a593Smuzhiyun void RootlessSetPixmapOfAncestors(WindowPtr pWin); 284*4882a593Smuzhiyun 285*4882a593Smuzhiyun #endif /* _ROOTLESSCOMMON_H */ 286