~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/darwin/quartz/xpr/xprFrame.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Xplugin rootless implementation frame functions
 
3
 */
 
4
/*
 
5
 * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
 
6
 * Copyright (c) 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
/* $XdotOrg: xserver/xorg/hw/darwin/quartz/xpr/xprFrame.c,v 1.5 2005/07/01 22:43:08 daniels Exp $ */
 
31
/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/xprFrame.c,v 1.4 2003/11/12 20:21:52 torrey Exp $ */
 
32
 
 
33
#include "xpr.h"
 
34
#include "rootlessCommon.h"
 
35
#include "Xplugin.h"
 
36
#include "x-hash.h"
 
37
#include "x-list.h"
 
38
#include "applewmExt.h"
 
39
 
 
40
#include "propertyst.h"
 
41
#include "dix.h"
 
42
#include <X11/Xatom.h>
 
43
#include "windowstr.h"
 
44
 
 
45
#include <pthread.h>
 
46
 
 
47
#define DEFINE_ATOM_HELPER(func,atom_name)                      \
 
48
static Atom func (void) {                                       \
 
49
    static int generation;                                      \
 
50
    static Atom atom;                                           \
 
51
    if (generation != serverGeneration) {                       \
 
52
        generation = serverGeneration;                          \
 
53
        atom = MakeAtom (atom_name, strlen (atom_name), TRUE);  \
 
54
    }                                                           \
 
55
    return atom;                                                \
 
56
}
 
57
 
 
58
DEFINE_ATOM_HELPER(xa_native_window_id, "_NATIVE_WINDOW_ID")
 
59
 
 
60
/* Maps xp_window_id -> RootlessWindowRec */
 
61
static x_hash_table *window_hash;
 
62
static pthread_mutex_t window_hash_mutex;
 
63
 
 
64
static Bool no_configure_window;
 
65
 
 
66
 
 
67
static inline xp_error
 
68
xprConfigureWindow(xp_window_id id, unsigned int mask,
 
69
                   const xp_window_changes *values)
 
70
{
 
71
    if (!no_configure_window)
 
72
        return xp_configure_window(id, mask, values);
 
73
    else
 
74
        return XP_Success;
 
75
}
 
76
 
 
77
 
 
78
static void
 
79
xprSetNativeProperty(RootlessWindowPtr pFrame)
 
80
{
 
81
    xp_error err;
 
82
    unsigned int native_id;
 
83
    long data;
 
84
 
 
85
    err = xp_get_native_window((xp_window_id) pFrame->wid, &native_id);
 
86
    if (err == Success)
 
87
    {
 
88
        /* FIXME: move this to AppleWM extension */
 
89
 
 
90
        data = native_id;
 
91
        ChangeWindowProperty(pFrame->win, xa_native_window_id(),
 
92
                             XA_INTEGER, 32, PropModeReplace, 1, &data, TRUE);
 
93
    }
 
94
}
 
95
 
 
96
 
 
97
/*
 
98
 * Create and display a new frame.
 
99
 */
 
100
Bool
 
101
xprCreateFrame(RootlessWindowPtr pFrame, ScreenPtr pScreen,
 
102
               int newX, int newY, RegionPtr pShape)
 
103
{
 
104
    WindowPtr pWin = pFrame->win;
 
105
    xp_window_changes wc;
 
106
    unsigned int mask = 0;
 
107
    xp_error err;
 
108
 
 
109
    wc.x = newX;
 
110
    wc.y = newY;
 
111
    wc.width = pFrame->width;
 
112
    wc.height = pFrame->height;
 
113
    wc.bit_gravity = XP_GRAVITY_NONE;
 
114
    mask |= XP_BOUNDS;
 
115
 
 
116
    if (pWin->drawable.depth == 8)
 
117
    {
 
118
        wc.depth = XP_DEPTH_INDEX8;
 
119
#if 0
 
120
        wc.colormap = xprColormapCallback;
 
121
        wc.colormap_data = pScreen;
 
122
        mask |= XP_COLORMAP;
 
123
#endif
 
124
    }
 
125
    else if (pWin->drawable.depth == 15)
 
126
        wc.depth = XP_DEPTH_RGB555;
 
127
    else if (pWin->drawable.depth == 24)
 
128
        wc.depth = XP_DEPTH_ARGB8888;
 
129
    else
 
130
        wc.depth = XP_DEPTH_NIL;
 
131
    mask |= XP_DEPTH;
 
132
 
 
133
    if (pShape != NULL)
 
134
    {
 
135
        wc.shape_nrects = REGION_NUM_RECTS(pShape);
 
136
        wc.shape_rects = REGION_RECTS(pShape);
 
137
        wc.shape_tx = wc.shape_ty = 0;
 
138
        mask |= XP_SHAPE;
 
139
    }
 
140
 
 
141
    err = xp_create_window(mask, &wc, (xp_window_id *) &pFrame->wid);
 
142
 
 
143
    if (err != Success)
 
144
    {
 
145
        return FALSE;
 
146
    }
 
147
 
 
148
    if (window_hash == NULL)
 
149
    {
 
150
        window_hash = x_hash_table_new(NULL, NULL, NULL, NULL);
 
151
        pthread_mutex_init(&window_hash_mutex, NULL);
 
152
    }
 
153
 
 
154
    pthread_mutex_lock(&window_hash_mutex);
 
155
    x_hash_table_insert(window_hash, pFrame->wid, pFrame);
 
156
    pthread_mutex_unlock(&window_hash_mutex);
 
157
 
 
158
    xprSetNativeProperty(pFrame);
 
159
 
 
160
    return TRUE;
 
161
}
 
162
 
 
163
 
 
164
/*
 
165
 * Destroy a frame.
 
166
 */
 
167
void
 
168
xprDestroyFrame(RootlessFrameID wid)
 
169
{
 
170
    pthread_mutex_lock(&window_hash_mutex);
 
171
    x_hash_table_remove(window_hash, wid);
 
172
    pthread_mutex_unlock(&window_hash_mutex);
 
173
 
 
174
    xp_destroy_window((xp_window_id) wid);
 
175
}
 
176
 
 
177
 
 
178
/*
 
179
 * Move a frame on screen.
 
180
 */
 
181
void
 
182
xprMoveFrame(RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY)
 
183
{
 
184
    xp_window_changes wc;
 
185
 
 
186
    wc.x = newX;
 
187
    wc.y = newY;
 
188
 
 
189
    xprConfigureWindow((xp_window_id) wid, XP_ORIGIN, &wc);
 
190
}
 
191
 
 
192
 
 
193
/*
 
194
 * Resize and move a frame.
 
195
 */
 
196
void
 
197
xprResizeFrame(RootlessFrameID wid, ScreenPtr pScreen,
 
198
               int newX, int newY, unsigned int newW, unsigned int newH,
 
199
               unsigned int gravity)
 
200
{
 
201
    xp_window_changes wc;
 
202
 
 
203
    wc.x = newX;
 
204
    wc.y = newY;
 
205
    wc.width = newW;
 
206
    wc.height = newH;
 
207
    wc.bit_gravity = gravity;
 
208
 
 
209
    /* It's unlikely that being async will save us anything here.
 
210
       But it can't hurt. */
 
211
 
 
212
    xprConfigureWindow((xp_window_id) wid, XP_BOUNDS, &wc);
 
213
}
 
214
 
 
215
 
 
216
/*
 
217
 * Change frame stacking.
 
218
 */
 
219
void
 
220
xprRestackFrame(RootlessFrameID wid, RootlessFrameID nextWid)
 
221
{
 
222
    xp_window_changes wc;
 
223
 
 
224
    /* Stack frame below nextWid it if it exists, or raise
 
225
       frame above everything otherwise. */
 
226
 
 
227
    if (nextWid == NULL)
 
228
    {
 
229
        wc.stack_mode = XP_MAPPED_ABOVE;
 
230
        wc.sibling = 0;
 
231
    }
 
232
    else
 
233
    {
 
234
        wc.stack_mode = XP_MAPPED_BELOW;
 
235
        wc.sibling = (xp_window_id) nextWid;
 
236
    }
 
237
 
 
238
    xprConfigureWindow((xp_window_id) wid, XP_STACKING, &wc);
 
239
}
 
240
 
 
241
 
 
242
/*
 
243
 * Change the frame's shape.
 
244
 */
 
245
void
 
246
xprReshapeFrame(RootlessFrameID wid, RegionPtr pShape)
 
247
{
 
248
    xp_window_changes wc;
 
249
 
 
250
    if (pShape != NULL)
 
251
    {
 
252
        wc.shape_nrects = REGION_NUM_RECTS(pShape);
 
253
        wc.shape_rects = REGION_RECTS(pShape);
 
254
    }
 
255
    else
 
256
    {
 
257
        wc.shape_nrects = -1;
 
258
        wc.shape_rects = NULL;
 
259
    }
 
260
 
 
261
    wc.shape_tx = wc.shape_ty = 0;
 
262
 
 
263
    xprConfigureWindow((xp_window_id) wid, XP_SHAPE, &wc);
 
264
}
 
265
 
 
266
 
 
267
/*
 
268
 * Unmap a frame.
 
269
 */
 
270
void
 
271
xprUnmapFrame(RootlessFrameID wid)
 
272
{
 
273
    xp_window_changes wc;
 
274
 
 
275
    wc.stack_mode = XP_UNMAPPED;
 
276
    wc.sibling = 0;
 
277
 
 
278
    xprConfigureWindow((xp_window_id) wid, XP_STACKING, &wc);
 
279
}
 
280
 
 
281
 
 
282
/*
 
283
 * Start drawing to a frame.
 
284
 *  Prepare for direct access to its backing buffer.
 
285
 */
 
286
void
 
287
xprStartDrawing(RootlessFrameID wid, char **pixelData, int *bytesPerRow)
 
288
{
 
289
    void *data[2];
 
290
    unsigned int rowbytes[2];
 
291
    xp_error err;
 
292
 
 
293
    err = xp_lock_window((xp_window_id) wid, NULL, NULL, data, rowbytes, NULL);
 
294
    if (err != Success)
 
295
        FatalError("Could not lock window %i for drawing.", (int) wid);
 
296
 
 
297
    *pixelData = data[0];
 
298
    *bytesPerRow = rowbytes[0];
 
299
}
 
300
 
 
301
 
 
302
/*
 
303
 * Stop drawing to a frame.
 
304
 */
 
305
void
 
306
xprStopDrawing(RootlessFrameID wid, Bool flush)
 
307
{
 
308
    xp_unlock_window((xp_window_id) wid, flush);
 
309
}
 
310
 
 
311
 
 
312
/*
 
313
 * Flush drawing updates to the screen.
 
314
 */
 
315
void
 
316
xprUpdateRegion(RootlessFrameID wid, RegionPtr pDamage)
 
317
{
 
318
    xp_flush_window((xp_window_id) wid);
 
319
}
 
320
 
 
321
 
 
322
/*
 
323
 * Mark damaged rectangles as requiring redisplay to screen.
 
324
 */
 
325
void
 
326
xprDamageRects(RootlessFrameID wid, int nrects, const BoxRec *rects,
 
327
               int shift_x, int shift_y)
 
328
{
 
329
    xp_mark_window((xp_window_id) wid, nrects, rects, shift_x, shift_y);
 
330
}
 
331
 
 
332
 
 
333
/*
 
334
 * Called after the window associated with a frame has been switched
 
335
 * to a new top-level parent.
 
336
 */
 
337
void
 
338
xprSwitchWindow(RootlessWindowPtr pFrame, WindowPtr oldWin)
 
339
{
 
340
    DeleteProperty(oldWin, xa_native_window_id());
 
341
 
 
342
    xprSetNativeProperty(pFrame);
 
343
}
 
344
 
 
345
 
 
346
/*
 
347
 * Called to check if the frame should be reordered when it is restacked.
 
348
 */
 
349
Bool xprDoReorderWindow(RootlessWindowPtr pFrame)
 
350
{
 
351
    WindowPtr pWin = pFrame->win;
 
352
 
 
353
    return AppleWMDoReorderWindow(pWin);
 
354
}
 
355
 
 
356
 
 
357
/*
 
358
 * Copy area in frame to another part of frame.
 
359
 *  Used to accelerate scrolling.
 
360
 */
 
361
void
 
362
xprCopyWindow(RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
 
363
              int dx, int dy)
 
364
{
 
365
    xp_copy_window((xp_window_id) wid, (xp_window_id) wid,
 
366
                   dstNrects, dstRects, dx, dy);
 
367
}
 
368
 
 
369
 
 
370
static RootlessFrameProcsRec xprRootlessProcs = {
 
371
    xprCreateFrame,
 
372
    xprDestroyFrame,
 
373
    xprMoveFrame,
 
374
    xprResizeFrame,
 
375
    xprRestackFrame,
 
376
    xprReshapeFrame,
 
377
    xprUnmapFrame,
 
378
    xprStartDrawing,
 
379
    xprStopDrawing,
 
380
    xprUpdateRegion,
 
381
    xprDamageRects,
 
382
    xprSwitchWindow,
 
383
    xprDoReorderWindow,
 
384
    xp_copy_bytes,
 
385
    xp_fill_bytes,
 
386
    xp_composite_pixels,
 
387
    xprCopyWindow
 
388
};
 
389
 
 
390
 
 
391
/*
 
392
 * Initialize XPR implementation
 
393
 */
 
394
Bool
 
395
xprInit(ScreenPtr pScreen)
 
396
{
 
397
    RootlessInit(pScreen, &xprRootlessProcs);
 
398
 
 
399
    rootless_CopyBytes_threshold = xp_copy_bytes_threshold;
 
400
    rootless_FillBytes_threshold = xp_fill_bytes_threshold;
 
401
    rootless_CompositePixels_threshold = xp_composite_area_threshold;
 
402
    rootless_CopyWindow_threshold = xp_scroll_area_threshold;
 
403
 
 
404
    no_configure_window = FALSE;
 
405
 
 
406
    return TRUE;
 
407
}
 
408
 
 
409
 
 
410
/*
 
411
 * Given the id of a physical window, try to find the top-level (or root)
 
412
 * X window that it represents.
 
413
 */
 
414
static WindowPtr
 
415
xprGetXWindow(xp_window_id wid)
 
416
{
 
417
    RootlessWindowRec *winRec;
 
418
 
 
419
    if (window_hash == NULL)
 
420
        return NULL;
 
421
 
 
422
    winRec = x_hash_table_lookup(window_hash, (void *) wid, NULL);
 
423
 
 
424
    return winRec != NULL ? winRec->win : NULL;
 
425
}
 
426
 
 
427
 
 
428
/*
 
429
 * The windowNumber is an AppKit window number. Returns TRUE if xpr is
 
430
 * displaying a window with that number.
 
431
 */
 
432
Bool
 
433
xprIsX11Window(void *nsWindow, int windowNumber)
 
434
{
 
435
    Bool ret;
 
436
    xp_window_id wid;
 
437
 
 
438
    if (window_hash == NULL)
 
439
        return FALSE;
 
440
 
 
441
    /* need to lock, since this function can be called by any thread */
 
442
 
 
443
    pthread_mutex_lock(&window_hash_mutex);
 
444
 
 
445
    if (xp_lookup_native_window(windowNumber, &wid))
 
446
        ret = xprGetXWindow(wid) != NULL;
 
447
    else
 
448
        ret = FALSE;
 
449
 
 
450
    pthread_mutex_unlock(&window_hash_mutex);
 
451
 
 
452
    return ret;
 
453
}
 
454
 
 
455
 
 
456
/*
 
457
 * xprHideWindows
 
458
 *  Hide or unhide all top level windows. This is called for application hide/
 
459
 *  unhide events if the window manager is not Apple-WM aware. Xplugin windows
 
460
 *  do not hide or unhide themselves.
 
461
 */
 
462
void
 
463
xprHideWindows(Bool hide)
 
464
{
 
465
    int screen;
 
466
    WindowPtr pRoot, pWin;
 
467
 
 
468
    for (screen = 0; screen < screenInfo.numScreens; screen++) {
 
469
        pRoot = WindowTable[screenInfo.screens[screen]->myNum];
 
470
        RootlessFrameID prevWid = NULL;
 
471
 
 
472
        for (pWin = pRoot->firstChild; pWin; pWin = pWin->nextSib) {
 
473
            RootlessWindowRec *winRec = WINREC(pWin);
 
474
 
 
475
            if (winRec != NULL) {
 
476
                if (hide) {
 
477
                    xprUnmapFrame(winRec->wid);
 
478
                } else {
 
479
                    BoxRec box;
 
480
 
 
481
                    xprRestackFrame(winRec->wid, prevWid);
 
482
                    prevWid = winRec->wid;
 
483
 
 
484
                    box.x1 = 0;
 
485
                    box.y1 = 0;
 
486
                    box.x2 = winRec->width;
 
487
                    box.y2 = winRec->height;
 
488
 
 
489
                    xprDamageRects(winRec->wid, 1, &box, 0, 0);
 
490
                    RootlessQueueRedisplay(screenInfo.screens[screen]);
 
491
                }
 
492
            }
 
493
        }
 
494
    }
 
495
}