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