1/*
2 * External interface to generic rootless mode
3 */
4/*
5 * Copyright (c) 2001 Greg Parker. All Rights Reserved.
6 * Copyright (c) 2002-2003 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#ifndef _ROOTLESS_H
36#define _ROOTLESS_H
37
38#include "rootlessConfig.h"
39#include "mi.h"
40#include "gcstruct.h"
41
42/*
43   Each top-level rootless window has a one-to-one correspondence to a physical
44   on-screen window. The physical window is referred to as a "frame".
45 */
46
47typedef void *RootlessFrameID;
48
49/*
50 * RootlessWindowRec
51 *  This structure stores the per-frame data used by the rootless code.
52 *  Each top-level X window has one RootlessWindowRec associated with it.
53 */
54typedef struct _RootlessWindowRec {
55    // Position and size includes the window border
56    // Position is in per-screen coordinates
57    int x, y;
58    unsigned int width, height;
59    unsigned int borderWidth;
60    int level;
61
62    RootlessFrameID wid;        // implementation specific frame id
63    WindowPtr win;              // underlying X window
64
65    // Valid only when drawing (ie. is_drawing is set)
66    char *pixelData;
67    int bytesPerRow;
68
69    PixmapPtr pixmap;
70
71    unsigned int is_drawing:1;  // Currently drawing?
72    unsigned int is_reorder_pending:1;
73    unsigned int is_offscreen:1;
74    unsigned int is_obscured:1;
75} RootlessWindowRec, *RootlessWindowPtr;
76
77/* Offset for screen-local to global coordinate transforms */
78extern int rootlessGlobalOffsetX;
79extern int rootlessGlobalOffsetY;
80
81/* The minimum number of bytes or pixels for which to use the
82   implementation's accelerated functions. */
83extern unsigned int rootless_CopyBytes_threshold;
84extern unsigned int rootless_CopyWindow_threshold;
85
86/* Gravity for window contents during resizing */
87enum rl_gravity_enum {
88    RL_GRAVITY_NONE = 0,        /* no gravity, fill everything */
89    RL_GRAVITY_NORTH_WEST = 1,  /* anchor to top-left corner */
90    RL_GRAVITY_NORTH_EAST = 2,  /* anchor to top-right corner */
91    RL_GRAVITY_SOUTH_EAST = 3,  /* anchor to bottom-right corner */
92    RL_GRAVITY_SOUTH_WEST = 4,  /* anchor to bottom-left corner */
93};
94
95/*------------------------------------------
96   Rootless Implementation Functions
97  ------------------------------------------*/
98
99/*
100 * Create a new frame.
101 *  The frame is created unmapped.
102 *
103 *  pFrame      RootlessWindowPtr for this frame should be completely
104 *              initialized before calling except for pFrame->wid, which
105 *              is set by this function.
106 *  pScreen     Screen on which to place the new frame
107 *  newX, newY  Position of the frame.
108 *  pNewShape   Shape for the frame (in frame-local coordinates). NULL for
109 *              unshaped frames.
110 */
111typedef Bool (*RootlessCreateFrameProc)
112 (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
113  RegionPtr pNewShape);
114
115/*
116 * Destroy a frame.
117 *  Drawing is stopped and all updates are flushed before this is called.
118 *
119 *  wid         Frame id
120 */
121typedef void (*RootlessDestroyFrameProc)
122 (RootlessFrameID wid);
123
124/*
125 * Move a frame on screen.
126 *  Drawing is stopped and all updates are flushed before this is called.
127 *
128 *  wid         Frame id
129 *  pScreen     Screen to move the new frame to
130 *  newX, newY  New position of the frame
131 */
132typedef void (*RootlessMoveFrameProc)
133 (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
134
135/*
136 * Resize and move a frame.
137 *  Drawing is stopped and all updates are flushed before this is called.
138 *
139 *  wid         Frame id
140 *  pScreen     Screen to move the new frame to
141 *  newX, newY  New position of the frame
142 *  newW, newH  New size of the frame
143 *  gravity     Gravity for window contents (rl_gravity_enum). This is always
144 *              RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
145 */
146typedef void (*RootlessResizeFrameProc)
147 (RootlessFrameID wid, ScreenPtr pScreen,
148  int newX, int newY, unsigned int newW, unsigned int newH,
149  unsigned int gravity);
150
151/*
152 * Change frame ordering (AKA stacking, layering).
153 *  Drawing is stopped before this is called. Unmapped frames are mapped by
154 *  setting their ordering.
155 *
156 *  wid         Frame id
157 *  nextWid     Frame id of frame that is now above this one or NULL if this
158 *              frame is at the top.
159 */
160typedef void (*RootlessRestackFrameProc)
161 (RootlessFrameID wid, RootlessFrameID nextWid);
162
163/*
164 * Change frame's shape.
165 *  Drawing is stopped before this is called.
166 *
167 *  wid         Frame id
168 *  pNewShape   New shape for the frame (in frame-local coordinates)
169 *              or NULL if now unshaped.
170 */
171typedef void (*RootlessReshapeFrameProc)
172 (RootlessFrameID wid, RegionPtr pNewShape);
173
174/*
175 * Unmap a frame.
176 *
177 *  wid         Frame id
178 */
179typedef void (*RootlessUnmapFrameProc)
180 (RootlessFrameID wid);
181
182/*
183 * Start drawing to a frame.
184 *  Prepare a frame for direct access to its backing buffer.
185 *
186 *  wid         Frame id
187 *  pixelData   Address of the backing buffer (returned)
188 *  bytesPerRow Width in bytes of the backing buffer (returned)
189 */
190typedef void (*RootlessStartDrawingProc)
191 (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
192
193/*
194 * Stop drawing to a frame.
195 *  No drawing to the frame's backing buffer will occur until drawing
196 *  is started again.
197 *
198 *  wid         Frame id
199 *  flush       Flush drawing updates for this frame to the screen.
200 */
201typedef void (*RootlessStopDrawingProc)
202 (RootlessFrameID wid, Bool flush);
203
204/*
205 * Flush drawing updates to the screen.
206 *  Drawing is stopped before this is called.
207 *
208 *  wid         Frame id
209 *  pDamage     Region containing all the changed pixels in frame-lcoal
210 *              coordinates. This is clipped to the window's clip.
211 */
212typedef void (*RootlessUpdateRegionProc)
213 (RootlessFrameID wid, RegionPtr pDamage);
214
215/*
216 * Mark damaged rectangles as requiring redisplay to screen.
217 *
218 *  wid         Frame id
219 *  nrects      Number of damaged rectangles
220 *  rects       Array of damaged rectangles in frame-local coordinates
221 *  shift_x,    Vector to shift rectangles by
222 *   shift_y
223 */
224typedef void (*RootlessDamageRectsProc)
225 (RootlessFrameID wid, int nrects, const BoxRec * rects,
226  int shift_x, int shift_y);
227
228/*
229 * Switch the window associated with a frame. (Optional)
230 *  When a framed window is reparented, the frame is resized and set to
231 *  use the new top-level parent. If defined this function will be called
232 *  afterwards for implementation specific bookkeeping.
233 *
234 *  pFrame      Frame whose window has switched
235 *  oldWin      Previous window wrapped by this frame
236 */
237typedef void (*RootlessSwitchWindowProc)
238 (RootlessWindowPtr pFrame, WindowPtr oldWin);
239
240/*
241 * Check if window should be reordered. (Optional)
242 *  The underlying window system may animate windows being ordered in.
243 *  We want them to be mapped but remain ordered out until the animation
244 *  completes. If defined this function will be called to check if a
245 *  framed window should be reordered now. If this function returns
246 *  FALSE, the window will still be mapped from the X11 perspective, but
247 *  the RestackFrame function will not be called for its frame.
248 *
249 *  pFrame      Frame to reorder
250 */
251typedef Bool (*RootlessDoReorderWindowProc)
252 (RootlessWindowPtr pFrame);
253
254/*
255 * Copy bytes. (Optional)
256 *  Source and destinate may overlap and the right thing should happen.
257 *
258 *  width       Bytes to copy per row
259 *  height      Number of rows
260 *  src         Source data
261 *  srcRowBytes Width of source in bytes
262 *  dst         Destination data
263 *  dstRowBytes Width of destination in bytes
264 */
265typedef void (*RootlessCopyBytesProc)
266 (unsigned int width, unsigned int height,
267  const void *src, unsigned int srcRowBytes,
268  void *dst, unsigned int dstRowBytes);
269
270/*
271 * Copy area in frame to another part of frame. (Optional)
272 *
273 *  wid         Frame id
274 *  dstNrects   Number of rectangles to copy
275 *  dstRects    Array of rectangles to copy
276 *  dx, dy      Number of pixels away to copy area
277 */
278typedef void (*RootlessCopyWindowProc)
279 (RootlessFrameID wid, int dstNrects, const BoxRec * dstRects, int dx, int dy);
280
281typedef void (*RootlessHideWindowProc)
282 (RootlessFrameID wid);
283
284typedef void (*RootlessUpdateColormapProc)
285 (RootlessFrameID wid, ScreenPtr pScreen);
286
287/*
288 * Rootless implementation function list
289 */
290typedef struct _RootlessFrameProcs {
291    RootlessCreateFrameProc CreateFrame;
292    RootlessDestroyFrameProc DestroyFrame;
293
294    RootlessMoveFrameProc MoveFrame;
295    RootlessResizeFrameProc ResizeFrame;
296    RootlessRestackFrameProc RestackFrame;
297    RootlessReshapeFrameProc ReshapeFrame;
298    RootlessUnmapFrameProc UnmapFrame;
299
300    RootlessStartDrawingProc StartDrawing;
301    RootlessStopDrawingProc StopDrawing;
302    RootlessUpdateRegionProc UpdateRegion;
303    RootlessDamageRectsProc DamageRects;
304
305    /* Optional frame functions */
306    RootlessSwitchWindowProc SwitchWindow;
307    RootlessDoReorderWindowProc DoReorderWindow;
308    RootlessHideWindowProc HideWindow;
309    RootlessUpdateColormapProc UpdateColormap;
310
311    /* Optional acceleration functions */
312    RootlessCopyBytesProc CopyBytes;
313    RootlessCopyWindowProc CopyWindow;
314} RootlessFrameProcsRec, *RootlessFrameProcsPtr;
315
316/*
317 * Initialize rootless mode on the given screen.
318 */
319Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs);
320
321/*
322 * Return the frame ID for the physical window displaying the given window.
323 *
324 *  create      If true and the window has no frame, attempt to create one
325 */
326RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create);
327
328/*
329 * Return the top-level parent of a window.
330 *  The root is the top-level parent of itself, even though the root is
331 *  not otherwise considered to be a top-level window.
332 */
333WindowPtr TopLevelParent(WindowPtr pWindow);
334
335/*
336 * Prepare a window for direct access to its backing buffer.
337 */
338void RootlessStartDrawing(WindowPtr pWindow);
339
340/*
341 * Finish drawing to a window's backing buffer.
342 *
343 *  flush       If true, damaged areas are flushed to the screen.
344 */
345void RootlessStopDrawing(WindowPtr pWindow, Bool flush);
346
347/*
348 * Allocate a new screen pixmap.
349 *  miCreateScreenResources does not do this properly with a null
350 *  framebuffer pointer.
351 */
352void RootlessUpdateScreenPixmap(ScreenPtr pScreen);
353
354/*
355 * Reposition all windows on a screen to their correct positions.
356 */
357void RootlessRepositionWindows(ScreenPtr pScreen);
358
359/*
360 * Bring all windows to the front of the native stack
361 */
362void RootlessOrderAllWindows(Bool include_unhitable);
363#endif                          /* _ROOTLESS_H */
364