summaryrefslogtreecommitdiff
path: root/miext/rootless/rootless.h
blob: 5224dca2bb44193031f908b70afa4d114baeda86 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
/*
 * External interface to generic rootless mode
 */
/*
 * Copyright (c) 2001 Greg Parker. All Rights Reserved.
 * Copyright (c) 2002-2003 Torrey T. Lyons. All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE ABOVE LISTED COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name(s) of the above copyright
 * holders shall not be used in advertising or otherwise to promote the sale,
 * use or other dealings in this Software without prior written authorization.
 */

#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif

#ifndef _ROOTLESS_H
#define _ROOTLESS_H

#include "rootlessConfig.h"
#include "mi.h"
#include "gcstruct.h"

/*
   Each top-level rootless window has a one-to-one correspondence to a physical
   on-screen window. The physical window is refered to as a "frame".
 */

typedef void * RootlessFrameID;

/*
 * RootlessWindowRec
 *  This structure stores the per-frame data used by the rootless code.
 *  Each top-level X window has one RootlessWindowRec associated with it.
 */
typedef struct _RootlessWindowRec {
    // Position and size includes the window border
    // Position is in per-screen coordinates
    int x, y;
    unsigned int width, height;
    unsigned int borderWidth;

    RootlessFrameID wid;	// implementation specific frame id
    WindowPtr win;		// underlying X window

    // Valid only when drawing (ie. is_drawing is set)
    char *pixelData;
    int bytesPerRow;

    PixmapPtr pixmap;

#ifdef ROOTLESS_TRACK_DAMAGE
    RegionRec damage;
#endif

    unsigned int is_drawing :1;	// Currently drawing?
    unsigned int is_reorder_pending :1;
    unsigned int is_offscreen :1;
    unsigned int is_obscured :1;
} RootlessWindowRec, *RootlessWindowPtr;


/* Offset for screen-local to global coordinate transforms */
#ifdef ROOTLESS_GLOBAL_COORDS
extern int rootlessGlobalOffsetX;
extern int rootlessGlobalOffsetY;
#endif

/* The minimum number of bytes or pixels for which to use the
   implementation's accelerated functions. */
extern unsigned int rootless_CopyBytes_threshold;
extern unsigned int rootless_FillBytes_threshold;
extern unsigned int rootless_CompositePixels_threshold;
extern unsigned int rootless_CopyWindow_threshold;

/* Operations used by CompositePixels */
enum rl_composite_op_enum {
    RL_COMPOSITE_SRC = 0,
    RL_COMPOSITE_OVER,
};

/* Data formats for depth field and composite functions */
enum rl_depth_enum {
    RL_DEPTH_NIL = 0,			/* null source when compositing */
    RL_DEPTH_ARGB8888,
    RL_DEPTH_RGB555,
    RL_DEPTH_A8,			/* for masks when compositing */
    RL_DEPTH_INDEX8,
};

/* Macro to form the composite function for CompositePixels */
#define RL_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \
    (((op) << 24) | ((src_depth) << 16) \
     | ((mask_depth) << 8) | ((dest_depth) << 0))

/* Gravity for window contents during resizing */
enum rl_gravity_enum {
    RL_GRAVITY_NONE             = 0,	/* no gravity, fill everything */
    RL_GRAVITY_NORTH_WEST       = 1,	/* anchor to top-left corner */
    RL_GRAVITY_NORTH_EAST       = 2,	/* anchor to top-right corner */
    RL_GRAVITY_SOUTH_EAST       = 3,	/* anchor to bottom-right corner */
    RL_GRAVITY_SOUTH_WEST       = 4,	/* anchor to bottom-left corner */
};


/*------------------------------------------
   Rootless Implementation Functions
  ------------------------------------------*/

/*
 * Create a new frame.
 *  The frame is created unmapped.
 *
 *  pFrame      RootlessWindowPtr for this frame should be completely
 *              initialized before calling except for pFrame->wid, which
 *              is set by this function.
 *  pScreen     Screen on which to place the new frame
 *  newX, newY  Position of the frame. These will be identical to pFrame-x,
 *              pFrame->y unless ROOTLESS_GLOBAL_COORDS is set.
 *  pNewShape   Shape for the frame (in frame-local coordinates). NULL for
 *              unshaped frames.
 */
typedef Bool (*RootlessCreateFrameProc)
    (RootlessWindowPtr pFrame, ScreenPtr pScreen, int newX, int newY,
     RegionPtr pNewShape);

/*
 * Destroy a frame.
 *  Drawing is stopped and all updates are flushed before this is called.
 *
 *  wid         Frame id
 */
typedef void (*RootlessDestroyFrameProc)
    (RootlessFrameID wid);

/*
 * Move a frame on screen.
 *  Drawing is stopped and all updates are flushed before this is called.
 *
 *  wid         Frame id
 *  pScreen     Screen to move the new frame to
 *  newX, newY  New position of the frame
 */
typedef void (*RootlessMoveFrameProc) 
    (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);

/*
 * Resize and move a frame.
 *  Drawing is stopped and all updates are flushed before this is called.
 *
 *  wid         Frame id
 *  pScreen     Screen to move the new frame to
 *  newX, newY  New position of the frame
 *  newW, newH  New size of the frame
 *  gravity     Gravity for window contents (rl_gravity_enum). This is always
 *              RL_GRAVITY_NONE unless ROOTLESS_RESIZE_GRAVITY is set.
 */
typedef void (*RootlessResizeFrameProc)
    (RootlessFrameID wid, ScreenPtr pScreen,
     int newX, int newY, unsigned int newW, unsigned int newH,
     unsigned int gravity);

/*
 * Change frame ordering (AKA stacking, layering).
 *  Drawing is stopped before this is called. Unmapped frames are mapped by
 *  setting their ordering.
 *
 *  wid         Frame id
 *  nextWid     Frame id of frame that is now above this one or NULL if this
 *              frame is at the top.
 */
typedef void (*RootlessRestackFrameProc)
    (RootlessFrameID wid, RootlessFrameID nextWid);

/*
 * Change frame's shape.
 *  Drawing is stopped before this is called.
 *
 *  wid         Frame id
 *  pNewShape   New shape for the frame (in frame-local coordinates)
 *              or NULL if now unshaped.
 */
typedef void (*RootlessReshapeFrameProc)
    (RootlessFrameID wid, RegionPtr pNewShape);

/*
 * Unmap a frame.
 *
 *  wid         Frame id
 */
typedef void (*RootlessUnmapFrameProc)
    (RootlessFrameID wid);

/*
 * Start drawing to a frame.
 *  Prepare a frame for direct access to its backing buffer.
 *
 *  wid         Frame id
 *  pixelData   Address of the backing buffer (returned)
 *  bytesPerRow Width in bytes of the backing buffer (returned)
 */
typedef void (*RootlessStartDrawingProc)
    (RootlessFrameID wid, char **pixelData, int *bytesPerRow);

/*
 * Stop drawing to a frame.
 *  No drawing to the frame's backing buffer will occur until drawing
 *  is started again.
 *
 *  wid         Frame id
 *  flush       Flush drawing updates for this frame to the screen. This
 *              will always be FALSE if ROOTLESS_TRACK_DAMAGE is set.
 */
typedef void (*RootlessStopDrawingProc)
    (RootlessFrameID wid, Bool flush);

/*
 * Flush drawing updates to the screen.
 *  Drawing is stopped before this is called.
 *
 *  wid         Frame id
 *  pDamage     Region containing all the changed pixels in frame-lcoal
 *              coordinates. This is clipped to the window's clip. This
 *              will be NULL if ROOTLESS_TRACK_DAMAGE is not set.
 */
typedef void (*RootlessUpdateRegionProc)
    (RootlessFrameID wid, RegionPtr pDamage);

/*
 * Mark damaged rectangles as requiring redisplay to screen.
 *  This will only be called if ROOTLESS_TRACK_DAMAGE is not set.
 *
 *  wid         Frame id
 *  nrects      Number of damaged rectangles
 *  rects       Array of damaged rectangles in frame-local coordinates
 *  shift_x,    Vector to shift rectangles by
 *   shift_y
 */
typedef void (*RootlessDamageRectsProc)
    (RootlessFrameID wid, int nrects, const BoxRec *rects,
     int shift_x, int shift_y);

/*
 * Switch the window associated with a frame. (Optional)
 *  When a framed window is reparented, the frame is resized and set to
 *  use the new top-level parent. If defined this function will be called
 *  afterwards for implementation specific bookkeeping.
 *
 *  pFrame      Frame whose window has switched
 *  oldWin      Previous window wrapped by this frame
 */
typedef void (*RootlessSwitchWindowProc)
    (RootlessWindowPtr pFrame, WindowPtr oldWin);

/*
 * Check if window should be reordered. (Optional)
 *  The underlying window system may animate windows being ordered in.
 *  We want them to be mapped but remain ordered out until the animation
 *  completes. If defined this function will be called to check if a
 *  framed window should be reordered now. If this function returns
 *  FALSE, the window will still be mapped from the X11 perspective, but
 *  the RestackFrame function will not be called for its frame.
 *
 *  pFrame      Frame to reorder
 */
typedef Bool (*RootlessDoReorderWindowProc)
    (RootlessWindowPtr pFrame);

/*
 * Copy bytes. (Optional)
 *  Source and destinate may overlap and the right thing should happen.
 *
 *  width       Bytes to copy per row
 *  height      Number of rows
 *  src         Source data
 *  srcRowBytes Width of source in bytes
 *  dst         Destination data
 *  dstRowBytes Width of destination in bytes
 */
typedef void (*RootlessCopyBytesProc)
    (unsigned int width, unsigned int height,
     const void *src, unsigned int srcRowBytes,
     void *dst, unsigned int dstRowBytes);

/*
 * Fill memory with 32-bit pattern. (Optional)
 *
 *  width       Bytes to fill per row
 *  height      Number of rows
 *  value       32-bit pattern to fill with
 *  dst         Destination data
 *  dstRowBytes Width of destination in bytes
 */
typedef void (*RootlessFillBytesProc)
    (unsigned int width, unsigned int height, unsigned int value,
     void *dst, unsigned int dstRowBytes);

/*
 * Composite pixels from source and mask to destination. (Optional)
 *
 *  width, height   Size of area to composite to in pizels
 *  function        Composite function built with RL_COMPOSITE_FUNCTION
 *  src             Source data
 *  srcRowBytes     Width of source in bytes (Passing NULL means source
 *                  is a single pixel.
 *  mask            Mask data
 *  maskRowBytes    Width of mask in bytes
 *  dst             Destination data
 *  dstRowBytes     Width of destination in bytes
 *
 *  For src and dst, the first element of the array is the color data. If
 *  the second element is non-null it implies there is alpha data (which
 *  may be meshed or planar). Data without alpha is assumed to be opaque.
 *
 *  An X11 error code is returned.
 */
typedef int (*RootlessCompositePixelsProc)
    (unsigned int width, unsigned int height, unsigned int function,
     void *src[2], unsigned int srcRowBytes[2],
     void *mask, unsigned int maskRowBytes,
     void *dst[2], unsigned int dstRowBytes[2]);

/*
 * Copy area in frame to another part of frame. (Optional)
 *
 *  wid         Frame id
 *  dstNrects   Number of rectangles to copy
 *  dstRects    Array of rectangles to copy
 *  dx, dy      Number of pixels away to copy area
 */
typedef void (*RootlessCopyWindowProc)
    (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
     int dx, int dy);

/*
 * Rootless implementation function list
 */
typedef struct _RootlessFrameProcs {
    RootlessCreateFrameProc CreateFrame;
    RootlessDestroyFrameProc DestroyFrame;

    RootlessMoveFrameProc MoveFrame;
    RootlessResizeFrameProc ResizeFrame;
    RootlessRestackFrameProc RestackFrame;
    RootlessReshapeFrameProc ReshapeFrame;
    RootlessUnmapFrameProc UnmapFrame;

    RootlessStartDrawingProc StartDrawing;
    RootlessStopDrawingProc StopDrawing;
    RootlessUpdateRegionProc UpdateRegion;
#ifndef ROOTLESS_TRACK_DAMAGE
    RootlessDamageRectsProc DamageRects;
#endif

    /* Optional frame functions */
    RootlessSwitchWindowProc SwitchWindow;
    RootlessDoReorderWindowProc DoReorderWindow;

    /* Optional acceleration functions */
    RootlessCopyBytesProc CopyBytes;
    RootlessFillBytesProc FillBytes;
    RootlessCompositePixelsProc CompositePixels;
    RootlessCopyWindowProc CopyWindow;
} RootlessFrameProcsRec, *RootlessFrameProcsPtr;


/*
 * Initialize rootless mode on the given screen.
 */
Bool RootlessInit(ScreenPtr pScreen, RootlessFrameProcsPtr procs);

/*
 * Initialize acceleration for rootless mode on a given screen.
 *  Note: RootlessAccelInit() must be called before DamageSetup()
 *  and RootlessInit() must be called afterwards.
 */
Bool RootlessAccelInit(ScreenPtr pScreen);

/*
 * Return the frame ID for the physical window displaying the given window. 
 *
 *  create      If true and the window has no frame, attempt to create one
 */
RootlessFrameID RootlessFrameForWindow(WindowPtr pWin, Bool create);

/*
 * Return the top-level parent of a window.
 *  The root is the top-level parent of itself, even though the root is
 *  not otherwise considered to be a top-level window.
 */
WindowPtr TopLevelParent(WindowPtr pWindow);

/*
 * Prepare a window for direct access to its backing buffer.
 */
void RootlessStartDrawing(WindowPtr pWindow);

/*
 * Finish drawing to a window's backing buffer.
 *
 *  flush       If true and ROOTLESS_TRACK_DAMAGE is set, damaged areas
 *              are flushed to the screen.
 */
void RootlessStopDrawing(WindowPtr pWindow, Bool flush);

/*
 * Alocate a new screen pixmap.
 *  miCreateScreenResources does not do this properly with a null
 *  framebuffer pointer.
 */
void RootlessUpdateScreenPixmap(ScreenPtr pScreen);

/*
 * Reposition all windows on a screen to their correct positions.
 */
void RootlessRepositionWindows(ScreenPtr pScreen);

/*
 * Bring all windows to the front of the Aqua stack
 */
void RootlessOrderAllWindows (void);
#endif /* _ROOTLESS_H */