~ubuntu-branches/ubuntu/dapper/tk8.0/dapper-updates

« back to all changes in this revision

Viewing changes to mac/tkMacSubwindows.c

  • Committer: Bazaar Package Importer
  • Author(s): Mike Markley
  • Date: 2001-07-24 21:57:40 UTC
  • Revision ID: james.westby@ubuntu.com-20010724215740-r70t25rtmbqjil2h
Tags: upstream-8.0.5
ImportĀ upstreamĀ versionĀ 8.0.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * tkMacSubwindows.c --
 
3
 *
 
4
 *      Implements subwindows for the macintosh version of Tk.
 
5
 *
 
6
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 
7
 *
 
8
 * See the file "license.terms" for information on usage and redistribution
 
9
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
10
 *
 
11
 * RCS: @(#) $Id: tkMacSubwindows.c,v 1.4 1998/09/14 18:23:39 stanton Exp $
 
12
 */
 
13
 
 
14
#include "tkInt.h"
 
15
#include "X.h"
 
16
#include "Xlib.h"
 
17
#include <stdio.h>
 
18
 
 
19
#include <Windows.h>
 
20
#include <QDOffscreen.h>
 
21
#include "tkMacInt.h"
 
22
 
 
23
/*
 
24
 * Temporary region that can be reused.
 
25
 */
 
26
static RgnHandle tmpRgn = NULL;
 
27
 
 
28
static void UpdateOffsets _ANSI_ARGS_((TkWindow *winPtr, int deltaX, int deltaY));
 
29
 
 
30
void tkMacMoveWindow _ANSI_ARGS_((WindowRef window, int x, int y));
 
31
 
 
32
/*
 
33
 *----------------------------------------------------------------------
 
34
 *
 
35
 * XDestroyWindow --
 
36
 *
 
37
 *      Dealocates the given X Window.
 
38
 *
 
39
 * Results:
 
40
 *      The window id is returned.
 
41
 *
 
42
 * Side effects:
 
43
 *      None.
 
44
 *
 
45
 *----------------------------------------------------------------------
 
46
 */
 
47
 
 
48
void 
 
49
XDestroyWindow(
 
50
    Display* display,           /* Display. */
 
51
    Window window)              /* Window. */
 
52
{
 
53
    MacDrawable *macWin = (MacDrawable *) window;
 
54
    GWorldPtr destPort;
 
55
 
 
56
    /*
 
57
     * Remove any dangling pointers that may exist if
 
58
     * the window we are deleting is being tracked by
 
59
     * the grab code.
 
60
     */
 
61
 
 
62
    TkPointerDeadWindow(macWin->winPtr);
 
63
    macWin->toplevel->referenceCount--;
 
64
    
 
65
    
 
66
    if (Tk_IsTopLevel(macWin->winPtr)) {
 
67
        DisposeRgn(macWin->clipRgn);
 
68
        DisposeRgn(macWin->aboveClipRgn);
 
69
        
 
70
        /*
 
71
         * Delete the Mac window and remove it from the windowTable.
 
72
         * The window could be NULL if the window was never mapped.
 
73
         * However, we don't do this for embedded windows, they don't
 
74
         * go in the window list, and they do not own their portPtr's.
 
75
         */
 
76
         
 
77
        if (!(Tk_IsEmbedded(macWin->winPtr))) {
 
78
            destPort = TkMacGetDrawablePort(window);
 
79
            if (destPort != NULL) {
 
80
                TkMacWindowList *listPtr, *prevPtr;
 
81
            
 
82
                TkMacUnregisterMacWindow(destPort);
 
83
                DisposeWindow((WindowRef) destPort);
 
84
            
 
85
                for (listPtr = tkMacWindowListPtr, prevPtr = NULL;
 
86
                        tkMacWindowListPtr != NULL;
 
87
                        prevPtr = listPtr, listPtr = listPtr->nextPtr) {
 
88
                    if (listPtr->winPtr == macWin->winPtr) {
 
89
                        if (prevPtr == NULL) {
 
90
                            tkMacWindowListPtr = listPtr->nextPtr;
 
91
                        } else {
 
92
                            prevPtr->nextPtr = listPtr->nextPtr;
 
93
                        }
 
94
                        ckfree((char *) listPtr);
 
95
                        break;
 
96
                    }
 
97
                }
 
98
            }
 
99
        }
 
100
        
 
101
        macWin->portPtr = NULL;
 
102
        
 
103
        /*
 
104
         * Delay deletion of a toplevel data structure untill all
 
105
         * children have been deleted.
 
106
         */
 
107
        if (macWin->toplevel->referenceCount == 0) {
 
108
            ckfree((char *) macWin->toplevel);
 
109
        }
 
110
    } else {
 
111
        destPort = TkMacGetDrawablePort(window);
 
112
        if (destPort != NULL) {
 
113
            SetGWorld(destPort, NULL);
 
114
            TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
115
        }
 
116
        if (macWin->winPtr->parentPtr != NULL) {
 
117
            TkMacInvalClipRgns(macWin->winPtr->parentPtr);
 
118
        }
 
119
        DisposeRgn(macWin->clipRgn);
 
120
        DisposeRgn(macWin->aboveClipRgn);
 
121
        
 
122
        if (macWin->toplevel->referenceCount == 0) {
 
123
            ckfree((char *) macWin->toplevel);
 
124
        }
 
125
        ckfree((char *) macWin);
 
126
    }
 
127
}
 
128
 
 
129
/*
 
130
 *----------------------------------------------------------------------
 
131
 *
 
132
 * XMapWindow --
 
133
 *
 
134
 *      Map the given X Window to the screen.  See X window documentation 
 
135
 *  for more details.
 
136
 *
 
137
 * Results:
 
138
 *      None.
 
139
 *
 
140
 * Side effects:
 
141
 *      The subwindow or toplevel may appear on the screen.
 
142
 *
 
143
 *----------------------------------------------------------------------
 
144
 */
 
145
 
 
146
void 
 
147
XMapWindow(
 
148
    Display* display,           /* Display. */
 
149
    Window window)              /* Window. */
 
150
{
 
151
    MacDrawable *macWin = (MacDrawable *) window;
 
152
    XEvent event;
 
153
    GWorldPtr destPort;
 
154
 
 
155
    /*
 
156
     * Under certain situations it's possible for this function to be
 
157
     * called before the toplevel window it's associated with has actually
 
158
     * been mapped.  In that case we need to create the real Macintosh
 
159
     * window now as this function as well as other X functions assume that
 
160
     * the portPtr is valid.
 
161
     */
 
162
    if (!TkMacHostToplevelExists(macWin->toplevel->winPtr)) {
 
163
        TkMacMakeRealWindowExist(macWin->toplevel->winPtr);
 
164
    }
 
165
    destPort = TkMacGetDrawablePort(window);
 
166
 
 
167
    display->request++;
 
168
    macWin->winPtr->flags |= TK_MAPPED;
 
169
    if (Tk_IsTopLevel(macWin->winPtr)) {
 
170
        if (!Tk_IsEmbedded(macWin->winPtr)) {
 
171
            ShowWindow((WindowRef) destPort);
 
172
        }
 
173
 
 
174
        /* 
 
175
         * We only need to send the MapNotify event
 
176
         * for toplevel windows.
 
177
         */
 
178
        event.xany.serial = display->request;
 
179
        event.xany.send_event = False;
 
180
        event.xany.display = display;
 
181
        
 
182
        event.xmap.window = window;
 
183
        event.xmap.type = MapNotify;
 
184
        event.xmap.event = window;
 
185
        event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
 
186
        Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
 
187
    } else {
 
188
        TkMacInvalClipRgns(macWin->winPtr->parentPtr);
 
189
    }
 
190
 
 
191
    /* 
 
192
     * Generate damage for that area of the window 
 
193
     */
 
194
    SetGWorld(destPort, NULL);
 
195
    TkMacUpdateClipRgn(macWin->winPtr);
 
196
    TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
197
}
 
198
 
 
199
/*
 
200
 *----------------------------------------------------------------------
 
201
 *
 
202
 * XUnmapWindow --
 
203
 *
 
204
 *      Unmap the given X Window to the screen.  See X window
 
205
 *      documentation for more details.
 
206
 *
 
207
 * Results:
 
208
 *      None.
 
209
 *
 
210
 * Side effects:
 
211
 *      The subwindow or toplevel may be removed from the screen.
 
212
 *
 
213
 *----------------------------------------------------------------------
 
214
 */
 
215
 
 
216
void 
 
217
XUnmapWindow(
 
218
    Display* display,           /* Display. */
 
219
    Window window)              /* Window. */
 
220
{
 
221
    MacDrawable *macWin = (MacDrawable *) window;
 
222
    XEvent event;
 
223
    GWorldPtr destPort;
 
224
 
 
225
    destPort = TkMacGetDrawablePort(window);
 
226
 
 
227
    display->request++;
 
228
    macWin->winPtr->flags &= ~TK_MAPPED;
 
229
    if (Tk_IsTopLevel(macWin->winPtr)) {
 
230
        if (!Tk_IsEmbedded(macWin->winPtr)) {
 
231
            HideWindow((WindowRef) destPort);
 
232
        }
 
233
 
 
234
        /* 
 
235
         * We only need to send the UnmapNotify event
 
236
         * for toplevel windows.
 
237
         */
 
238
        event.xany.serial = display->request;
 
239
        event.xany.send_event = False;
 
240
        event.xany.display = display;
 
241
        
 
242
        event.xunmap.type = UnmapNotify;
 
243
        event.xunmap.window = window;
 
244
        event.xunmap.event = window;
 
245
        event.xunmap.from_configure = false;
 
246
        Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
 
247
    } else {
 
248
        /* 
 
249
         * Generate damage for that area of the window.
 
250
         */
 
251
        SetGWorld(destPort, NULL);
 
252
        TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW); /* TODO: may not be valid */
 
253
        TkMacInvalClipRgns(macWin->winPtr->parentPtr);
 
254
    }
 
255
}
 
256
 
 
257
/*
 
258
 *----------------------------------------------------------------------
 
259
 *
 
260
 * XResizeWindow --
 
261
 *
 
262
 *      Resize a given X window.  See X windows documentation for
 
263
 *      further details.
 
264
 *
 
265
 * Results:
 
266
 *      None.
 
267
 *
 
268
 * Side effects:
 
269
 *      None.
 
270
 *
 
271
 *----------------------------------------------------------------------
 
272
 */
 
273
 
 
274
void 
 
275
XResizeWindow(
 
276
    Display* display,           /* Display. */
 
277
    Window window,              /* Window. */
 
278
    unsigned int width,
 
279
    unsigned int height)
 
280
{
 
281
    MacDrawable *macWin = (MacDrawable *) window;
 
282
    GWorldPtr destPort;
 
283
 
 
284
    destPort = TkMacGetDrawablePort(window);
 
285
    if (destPort == NULL) {
 
286
        return;
 
287
    }
 
288
 
 
289
    display->request++;
 
290
    SetPort((GrafPtr) destPort);
 
291
    if (Tk_IsTopLevel(macWin->winPtr)) {
 
292
        if (!Tk_IsEmbedded(macWin->winPtr)) {
 
293
            /* 
 
294
             * NOTE: we are not adding the new space to the update
 
295
             * region.  It is currently assumed that Tk will need
 
296
             * to completely redraw anway.
 
297
             */
 
298
            SizeWindow((WindowRef) destPort,
 
299
                    (short) width, (short) height, false);
 
300
            TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
 
301
            TkMacInvalClipRgns(macWin->winPtr);
 
302
        } else {
 
303
            int deltaX, deltaY;
 
304
            
 
305
            /*
 
306
             * Find the Parent window -
 
307
             *    For an embedded window this will be its container.
 
308
             */
 
309
            TkWindow *contWinPtr;
 
310
            
 
311
            contWinPtr = TkpGetOtherWindow(macWin->winPtr);
 
312
            
 
313
            if (contWinPtr != NULL) {
 
314
                MacDrawable *macParent = contWinPtr->privatePtr;
 
315
 
 
316
                TkMacInvalClipRgns(macParent->winPtr);  
 
317
                TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
318
                
 
319
                deltaX = macParent->xOff +
 
320
                    macWin->winPtr->changes.x - macWin->xOff;
 
321
                deltaY = macParent->yOff +
 
322
                    macWin->winPtr->changes.y - macWin->yOff;
 
323
                
 
324
                UpdateOffsets(macWin->winPtr, deltaX, deltaY);
 
325
            } else {
 
326
                /*
 
327
                 * This is the case where we are embedded in
 
328
                 * another app.  At this point, we are assuming that
 
329
                 * the changes.x,y is not maintained, if you need
 
330
                 * the info get it from Tk_GetRootCoords,
 
331
                 * and that the toplevel sits at 0,0 when it is drawn.
 
332
                 */
 
333
                
 
334
                TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
335
                UpdateOffsets(macWin->winPtr, 0, 0);
 
336
            }
 
337
                 
 
338
        }   
 
339
    } else {
 
340
        /* TODO: update all xOff & yOffs */
 
341
        int deltaX, deltaY, parentBorderwidth;
 
342
        MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
 
343
        
 
344
        if (macParent == NULL) {
 
345
            return; /* TODO: Probably should be a panic */
 
346
        }
 
347
        
 
348
        TkMacInvalClipRgns(macParent->winPtr);  
 
349
        TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
350
 
 
351
        deltaX = - macWin->xOff;
 
352
        deltaY = - macWin->yOff;
 
353
 
 
354
        parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
 
355
        
 
356
        deltaX += macParent->xOff + parentBorderwidth +
 
357
            macWin->winPtr->changes.x;
 
358
        deltaY += macParent->yOff + parentBorderwidth +
 
359
            macWin->winPtr->changes.y;
 
360
        
 
361
        UpdateOffsets(macWin->winPtr, deltaX, deltaY);
 
362
    }
 
363
}
 
364
 
 
365
/*
 
366
 *----------------------------------------------------------------------
 
367
 *
 
368
 * XMoveResizeWindow --
 
369
 *
 
370
 *      Move or resize a given X window.  See X windows documentation
 
371
 *      for further details.
 
372
 *
 
373
 * Results:
 
374
 *      None.
 
375
 *
 
376
 * Side effects:
 
377
 *      None.
 
378
 *
 
379
 *----------------------------------------------------------------------
 
380
 */
 
381
 
 
382
void 
 
383
XMoveResizeWindow(
 
384
    Display* display,           /* Display. */
 
385
    Window window,              /* Window. */
 
386
    int x, int y,
 
387
    unsigned int width,
 
388
    unsigned int height)
 
389
{       
 
390
    MacDrawable *macWin = (MacDrawable *) window;
 
391
    GWorldPtr destPort;
 
392
 
 
393
    destPort = TkMacGetDrawablePort(window);
 
394
    if (destPort == NULL) {
 
395
        return;
 
396
    }
 
397
 
 
398
    SetPort((GrafPtr) destPort);
 
399
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {      
 
400
        /* 
 
401
         * NOTE: we are not adding the new space to the update
 
402
         * region.  It is currently assumed that Tk will need
 
403
         * to completely redraw anway.
 
404
         */
 
405
        
 
406
        SizeWindow((WindowRef) destPort,
 
407
                (short) width, (short) height, false);
 
408
        tkMacMoveWindow((WindowRef) destPort, x, y);
 
409
        
 
410
        /* TODO: is the following right? */
 
411
        TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
 
412
        TkMacInvalClipRgns(macWin->winPtr);
 
413
    } else {
 
414
        int deltaX, deltaY, parentBorderwidth;
 
415
        Rect bounds;
 
416
        MacDrawable *macParent;
 
417
        
 
418
        /*
 
419
         * Find the Parent window -
 
420
         *    For an embedded window this will be its container.
 
421
         */
 
422
         
 
423
        if (Tk_IsEmbedded(macWin->winPtr)) {
 
424
            TkWindow *contWinPtr;
 
425
            
 
426
            contWinPtr = TkpGetOtherWindow(macWin->winPtr);
 
427
            if (contWinPtr == NULL) {
 
428
                    panic("XMoveResizeWindow could not find container");
 
429
            }
 
430
            macParent = contWinPtr->privatePtr;
 
431
            
 
432
            /*
 
433
             * NOTE: Here we should handle out of process embedding.
 
434
             */
 
435
        
 
436
            
 
437
        } else {
 
438
            macParent = macWin->winPtr->parentPtr->privatePtr;   
 
439
            if (macParent == NULL) {
 
440
                return; /* TODO: Probably should be a panic */
 
441
            }
 
442
        }
 
443
                
 
444
        TkMacInvalClipRgns(macParent->winPtr);
 
445
        TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
446
 
 
447
        deltaX = - macWin->xOff;
 
448
        deltaY = - macWin->yOff;
 
449
        
 
450
        /*
 
451
         * If macWin->winPtr is an embedded window, don't offset by its
 
452
         *  parent's borderwidth...
 
453
         */
 
454
         
 
455
        if (!Tk_IsEmbedded(macWin->winPtr)) {
 
456
            parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
 
457
        } else {
 
458
            parentBorderwidth = 0;
 
459
        }
 
460
        deltaX += macParent->xOff + parentBorderwidth +
 
461
            macWin->winPtr->changes.x;
 
462
        deltaY += macParent->yOff + parentBorderwidth +
 
463
            macWin->winPtr->changes.y;
 
464
                
 
465
        UpdateOffsets(macWin->winPtr, deltaX, deltaY);
 
466
        TkMacWinBounds(macWin->winPtr, &bounds);
 
467
        InvalRect(&bounds);
 
468
    }
 
469
}
 
470
 
 
471
/*
 
472
 *----------------------------------------------------------------------
 
473
 *
 
474
 * XMoveWindow --
 
475
 *
 
476
 *      Move a given X window.  See X windows documentation for further
 
477
 *  details.
 
478
 *
 
479
 * Results:
 
480
 *      None.
 
481
 *
 
482
 * Side effects:
 
483
 *      None.
 
484
 *
 
485
 *----------------------------------------------------------------------
 
486
 */
 
487
 
 
488
void 
 
489
XMoveWindow(
 
490
    Display* display,           /* Display. */
 
491
    Window window,              /* Window. */
 
492
    int x,
 
493
    int y)
 
494
{
 
495
    MacDrawable *macWin = (MacDrawable *) window;
 
496
    GWorldPtr destPort;
 
497
 
 
498
    destPort = TkMacGetDrawablePort(window);
 
499
    if (destPort == NULL) {
 
500
        return;
 
501
    }
 
502
 
 
503
    SetPort((GrafPtr) destPort);
 
504
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
 
505
        /* 
 
506
         * NOTE: we are not adding the new space to the update
 
507
         * region.  It is currently assumed that Tk will need
 
508
         * to completely redraw anway.
 
509
         */
 
510
        tkMacMoveWindow((WindowRef) destPort, x, y);
 
511
 
 
512
        /* TODO: is the following right? */
 
513
        TkMacInvalidateWindow(macWin, TK_WINDOW_ONLY);
 
514
        TkMacInvalClipRgns(macWin->winPtr);
 
515
    } else {
 
516
        int deltaX, deltaY, parentBorderwidth;
 
517
        Rect bounds;
 
518
        MacDrawable *macParent;
 
519
        
 
520
        /*
 
521
         * Find the Parent window -
 
522
         * For an embedded window this will be its container.
 
523
         */
 
524
         
 
525
        if (Tk_IsEmbedded(macWin->winPtr)) {
 
526
            TkWindow *contWinPtr;
 
527
            
 
528
            contWinPtr = TkpGetOtherWindow(macWin->winPtr);
 
529
            if (contWinPtr == NULL) {
 
530
                    panic("XMoveWindow could not find container");
 
531
            }
 
532
            macParent = contWinPtr->privatePtr;
 
533
            
 
534
            /*
 
535
             * NOTE: Here we should handle out of process embedding.
 
536
             */
 
537
                    
 
538
        } else {
 
539
            macParent = macWin->winPtr->parentPtr->privatePtr;   
 
540
            if (macParent == NULL) {
 
541
                return; /* TODO: Probably should be a panic */
 
542
            }
 
543
        }
 
544
 
 
545
        TkMacInvalClipRgns(macParent->winPtr);
 
546
        TkMacInvalidateWindow(macWin, TK_PARENT_WINDOW);
 
547
 
 
548
        deltaX = - macWin->xOff;
 
549
        deltaY = - macWin->yOff;
 
550
        
 
551
        /*
 
552
         * If macWin->winPtr is an embedded window, don't offset by its
 
553
         *  parent's borderwidth...
 
554
         */
 
555
         
 
556
        if (!Tk_IsEmbedded(macWin->winPtr)) {
 
557
            parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
 
558
        } else {
 
559
            parentBorderwidth = 0;
 
560
        }
 
561
        deltaX += macParent->xOff + parentBorderwidth +
 
562
            macWin->winPtr->changes.x;
 
563
        deltaY += macParent->yOff + parentBorderwidth +
 
564
            macWin->winPtr->changes.y;
 
565
                
 
566
        UpdateOffsets(macWin->winPtr, deltaX, deltaY);
 
567
        TkMacWinBounds(macWin->winPtr, &bounds);
 
568
        InvalRect(&bounds);
 
569
    }
 
570
}
 
571
 
 
572
/*
 
573
 *----------------------------------------------------------------------
 
574
 *
 
575
 * XRaiseWindow --
 
576
 *
 
577
 *      Change the stacking order of a window.
 
578
 *
 
579
 * Results:
 
580
 *      None.
 
581
 *
 
582
 * Side effects:
 
583
 *      Changes the stacking order of the specified window.
 
584
 *
 
585
 *----------------------------------------------------------------------
 
586
 */
 
587
 
 
588
void 
 
589
XRaiseWindow(
 
590
    Display* display,           /* Display. */
 
591
    Window window)              /* Window. */
 
592
{
 
593
    MacDrawable *macWin = (MacDrawable *) window;
 
594
    
 
595
    display->request++;
 
596
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
 
597
        TkWmRestackToplevel(macWin->winPtr, Above, NULL);
 
598
    } else {
 
599
        /* TODO: this should generate damage */
 
600
    }
 
601
}
 
602
 
 
603
/*
 
604
 *----------------------------------------------------------------------
 
605
 *
 
606
 * XConfigureWindow --
 
607
 *
 
608
 *      Change the size, position, stacking, or border of the specified
 
609
 *      window.
 
610
 *
 
611
 * Results:
 
612
 *      None.
 
613
 *
 
614
 * Side effects:
 
615
 *      Changes the attributes of the specified window.  Note that we
 
616
 *      ignore the passed in values and use the values stored in the
 
617
 *      TkWindow data structure.
 
618
 *
 
619
 *----------------------------------------------------------------------
 
620
 */
 
621
 
 
622
void
 
623
XConfigureWindow(
 
624
    Display* display,           /* Display. */
 
625
    Window w,                   /* Window. */
 
626
    unsigned int value_mask,
 
627
    XWindowChanges* values)
 
628
{
 
629
    MacDrawable *macWin = (MacDrawable *) w;
 
630
    TkWindow *winPtr = macWin->winPtr;
 
631
 
 
632
    display->request++;
 
633
 
 
634
    /*
 
635
     * Change the shape and/or position of the window.
 
636
     */
 
637
 
 
638
    if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
 
639
        XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
 
640
                winPtr->changes.width, winPtr->changes.height);
 
641
    }
 
642
 
 
643
    /*
 
644
     * Change the stacking order of the window.  Tk actuall keeps all
 
645
     * the information we need for stacking order.  All we need to do
 
646
     * is make sure the clipping regions get updated and generate damage
 
647
     * that will ensure things get drawn correctly.
 
648
     */
 
649
 
 
650
    if (value_mask & CWStackMode) {
 
651
        Rect bounds;
 
652
        GWorldPtr destPort;
 
653
        
 
654
        destPort = TkMacGetDrawablePort(w);
 
655
        if (destPort != NULL) {
 
656
            SetPort((GrafPtr) destPort);
 
657
            TkMacInvalClipRgns(winPtr->parentPtr);
 
658
            TkMacWinBounds(winPtr, &bounds);
 
659
            InvalRect(&bounds);
 
660
        }
 
661
    } 
 
662
 
 
663
    /* TkGenWMMoveRequestEvent(macWin->winPtr, 
 
664
            macWin->winPtr->changes.x, macWin->winPtr->changes.y); */
 
665
}
 
666
 
 
667
/*
 
668
 *----------------------------------------------------------------------
 
669
 *
 
670
 *  TkMacUpdateClipRgn --
 
671
 *
 
672
 *      This function updates the cliping regions for a given window
 
673
 *      and all of its children.  Once updated the TK_CLIP_INVALID flag
 
674
 *      in the subwindow data structure is unset.  The TK_CLIP_INVALID 
 
675
 *      flag should always be unset before any drawing is attempted.
 
676
 *
 
677
 * Results:
 
678
 *      None.
 
679
 *
 
680
 * Side effects:
 
681
 *      The clip regions for the window and its children are updated.
 
682
 *
 
683
 *----------------------------------------------------------------------
 
684
 */
 
685
 
 
686
void
 
687
TkMacUpdateClipRgn(
 
688
    TkWindow *winPtr)
 
689
{
 
690
    RgnHandle rgn;
 
691
    int x, y;
 
692
    TkWindow *win2Ptr;
 
693
 
 
694
    if (winPtr == NULL) {
 
695
        return;
 
696
    }
 
697
    
 
698
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
 
699
        rgn = winPtr->privatePtr->aboveClipRgn;
 
700
        if (tmpRgn == NULL) {
 
701
            tmpRgn = NewRgn();
 
702
        }
 
703
        
 
704
        /* 
 
705
         * Start with a region defined by the window bounds.  
 
706
         */
 
707
 
 
708
        x = winPtr->privatePtr->xOff;
 
709
        y = winPtr->privatePtr->yOff;
 
710
        SetRectRgn(rgn, (short) x, (short) y,
 
711
            (short) (winPtr->changes.width  + x), 
 
712
            (short) (winPtr->changes.height + y));
 
713
            
 
714
        /* 
 
715
         * Clip away the area of any windows that may obscure this
 
716
         * window.  
 
717
         * For a non-toplevel window, first, clip to the parents visable
 
718
         * clip region.
 
719
         * Second, clip away any siblings that are higher in the
 
720
         * stacking order.
 
721
         * For an embedded toplevel, just clip to the container's visible
 
722
         * clip region.  Remember, we only allow one contained window 
 
723
         * in a frame, and don't support any other widgets in the frame either.
 
724
         * This is not currently enforced, however.
 
725
         */
 
726
        
 
727
        if (!Tk_IsTopLevel(winPtr)) { 
 
728
            TkMacUpdateClipRgn(winPtr->parentPtr);
 
729
            SectRgn(rgn, 
 
730
                    winPtr->parentPtr->privatePtr->aboveClipRgn, rgn);
 
731
                                
 
732
            win2Ptr = winPtr->nextPtr;
 
733
            while (win2Ptr != NULL) {
 
734
                if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
 
735
                    win2Ptr = win2Ptr->nextPtr;
 
736
                    continue;
 
737
                }
 
738
                x = win2Ptr->privatePtr->xOff;
 
739
                y = win2Ptr->privatePtr->yOff;
 
740
                SetRectRgn(tmpRgn, (short) x, (short) y,
 
741
                        (short) (win2Ptr->changes.width  + x), 
 
742
                        (short) (win2Ptr->changes.height + y));
 
743
                DiffRgn(rgn, tmpRgn, rgn);
 
744
                                                          
 
745
                win2Ptr = win2Ptr->nextPtr;
 
746
            }
 
747
        } else if (Tk_IsEmbedded(winPtr)) {
 
748
            TkWindow *contWinPtr;
 
749
        
 
750
            contWinPtr = TkpGetOtherWindow(winPtr);
 
751
             
 
752
            if (contWinPtr != NULL) {
 
753
                TkMacUpdateClipRgn(contWinPtr);
 
754
                SectRgn(rgn, 
 
755
                        contWinPtr->privatePtr->aboveClipRgn, rgn);
 
756
            } else if (gMacEmbedHandler != NULL) {
 
757
                gMacEmbedHandler->getClipProc((Tk_Window) winPtr, tmpRgn);
 
758
                SectRgn(rgn, tmpRgn, rgn);
 
759
            }
 
760
            
 
761
            /*
 
762
             * NOTE: Here we should handle out of process embedding.
 
763
             */
 
764
                    
 
765
        }
 
766
        
 
767
        /* 
 
768
         * The final clip region is the aboveClip region (or visable
 
769
         * region) minus all the children of this window.
 
770
         * Alternatively, if the window is a container, we must also 
 
771
         * subtract the region of the embedded window.
 
772
         */
 
773
         
 
774
        rgn = winPtr->privatePtr->clipRgn;
 
775
        CopyRgn(winPtr->privatePtr->aboveClipRgn, rgn);
 
776
                
 
777
        win2Ptr = winPtr->childList;
 
778
        while (win2Ptr != NULL) {
 
779
            if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
 
780
                win2Ptr = win2Ptr->nextPtr;
 
781
                continue;
 
782
            }
 
783
            x = win2Ptr->privatePtr->xOff;
 
784
            y = win2Ptr->privatePtr->yOff;
 
785
            SetRectRgn(tmpRgn, (short) x, (short) y,
 
786
                    (short) (win2Ptr->changes.width  + x), 
 
787
                    (short) (win2Ptr->changes.height + y));
 
788
            DiffRgn(rgn, tmpRgn, rgn);
 
789
                                                          
 
790
            win2Ptr = win2Ptr->nextPtr;
 
791
        }
 
792
        
 
793
        if (Tk_IsContainer(winPtr)) {
 
794
            win2Ptr = TkpGetOtherWindow(winPtr);
 
795
            if (win2Ptr != NULL) {
 
796
                if (Tk_IsMapped(win2Ptr)) {
 
797
                    x = win2Ptr->privatePtr->xOff;
 
798
                    y = win2Ptr->privatePtr->yOff;
 
799
                    SetRectRgn(tmpRgn, (short) x, (short) y,
 
800
                            (short) (win2Ptr->changes.width  + x), 
 
801
                            (short) (win2Ptr->changes.height + y));
 
802
                    DiffRgn(rgn, tmpRgn, rgn);
 
803
                }
 
804
            } 
 
805
            
 
806
            /*
 
807
             * NOTE: Here we should handle out of process embedding.
 
808
             */
 
809
                    
 
810
        }
 
811
                
 
812
        winPtr->privatePtr->flags &= ~TK_CLIP_INVALID;
 
813
    }
 
814
}
 
815
 
 
816
/*
 
817
 *----------------------------------------------------------------------
 
818
 *
 
819
 * TkMacVisableClipRgn --
 
820
 *
 
821
 *      This function returnd the Macintosh cliping region for the 
 
822
 *      given window.  A NULL Rgn means the window is not visable.
 
823
 *
 
824
 * Results:
 
825
 *      The region.
 
826
 *
 
827
 * Side effects:
 
828
 *      None.
 
829
 *
 
830
 *----------------------------------------------------------------------
 
831
 */
 
832
 
 
833
RgnHandle
 
834
TkMacVisableClipRgn(
 
835
    TkWindow *winPtr)
 
836
{
 
837
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
 
838
        TkMacUpdateClipRgn(winPtr);
 
839
    }
 
840
 
 
841
    return winPtr->privatePtr->clipRgn;
 
842
}
 
843
 
 
844
/*
 
845
 *----------------------------------------------------------------------
 
846
 *
 
847
 * TkMacInvalidateWindow --
 
848
 *
 
849
 *      This function makes the window as invalid will generate damage
 
850
 *      for the window.
 
851
 *
 
852
 * Results:
 
853
 *      None.
 
854
 *
 
855
 * Side effects:
 
856
 *      Damage is created.
 
857
 *
 
858
 *----------------------------------------------------------------------
 
859
 */
 
860
 
 
861
void
 
862
TkMacInvalidateWindow(
 
863
    MacDrawable *macWin,        /* Make window that's causing damage. */
 
864
    int flag)                   /* Should be TK_WINDOW_ONLY or
 
865
                                 * TK_PARENT_WINDOW */
 
866
{
 
867
    
 
868
    if (flag == TK_WINDOW_ONLY) {
 
869
        InvalRgn(macWin->clipRgn);
 
870
    } else {
 
871
        if (!EmptyRgn(macWin->aboveClipRgn)) {
 
872
            InvalRgn(macWin->aboveClipRgn);
 
873
        }
 
874
    }
 
875
}
 
876
 
 
877
/*
 
878
 *----------------------------------------------------------------------
 
879
 *
 
880
 * TkMacGetDrawablePort --
 
881
 *
 
882
 *      This function returns the Graphics Port for a given X drawable.
 
883
 *
 
884
 * Results:
 
885
 *      A GWorld pointer.  Either an off screen pixmap or a Window.
 
886
 *
 
887
 * Side effects:
 
888
 *      None.
 
889
 *
 
890
 *----------------------------------------------------------------------
 
891
 */
 
892
 
 
893
GWorldPtr
 
894
TkMacGetDrawablePort(
 
895
    Drawable drawable)
 
896
{
 
897
    MacDrawable *macWin = (MacDrawable *) drawable;
 
898
    GWorldPtr resultPort = NULL;
 
899
    
 
900
    if (macWin == NULL) {
 
901
        return NULL;
 
902
    }
 
903
    
 
904
    /*
 
905
     * This is NULL for off-screen pixmaps.  Then the portPtr
 
906
     * always points to the off-screen port, and we don't
 
907
     * have to worry about containment
 
908
     */
 
909
     
 
910
    if (macWin->clipRgn == NULL) {
 
911
        return macWin->portPtr;
 
912
    }
 
913
    
 
914
    /*
 
915
     * If the Drawable is in an embedded window, use the Port of its container.
 
916
     *  
 
917
     * TRICKY POINT: we can have cases when a toplevel is being destroyed
 
918
     * where the winPtr for the toplevel has been freed, but the children 
 
919
     * are not all the way destroyed.  The children will call this function
 
920
     * as they are being destroyed, but Tk_IsEmbedded will return garbage.
 
921
     * So we check the copy of the TK_EMBEDDED flag we put into the 
 
922
     * toplevel's macWin flags.
 
923
     */
 
924
    
 
925
    if (!(macWin->toplevel->flags & TK_EMBEDDED)) {
 
926
        return macWin->toplevel->portPtr;
 
927
    } else {
 
928
        TkWindow *contWinPtr;
 
929
 
 
930
        contWinPtr = TkpGetOtherWindow(macWin->toplevel->winPtr);
 
931
        
 
932
        if (contWinPtr != NULL) {
 
933
            resultPort = TkMacGetDrawablePort((Drawable) contWinPtr->privatePtr);
 
934
        } else if (gMacEmbedHandler != NULL) {
 
935
            resultPort = gMacEmbedHandler->getPortProc(
 
936
                    (Tk_Window) macWin->winPtr);
 
937
        } 
 
938
        
 
939
        if (resultPort == NULL) {
 
940
            panic("TkMacGetDrawablePort couldn't find container");
 
941
            return NULL;
 
942
        }       
 
943
            
 
944
        /*
 
945
         * NOTE: Here we should handle out of process embedding.
 
946
         */
 
947
                    
 
948
    }
 
949
    return resultPort;
 
950
}
 
951
 
 
952
/*
 
953
 *----------------------------------------------------------------------
 
954
 *
 
955
 * TkMacInvalClipRgns --
 
956
 *
 
957
 *      This function invalidates the clipping regions for a given
 
958
 *      window and all of its children.  This function should be
 
959
 *      called whenever changes are made to subwindows that would
 
960
 *      effect the size or position of windows.
 
961
 *
 
962
 * Results:
 
963
 *      None.
 
964
 *
 
965
 * Side effects:
 
966
 *      The cliping regions for the window and its children are
 
967
 *      mark invalid.  (Make sure they are valid before drawing.)
 
968
 *
 
969
 *----------------------------------------------------------------------
 
970
 */
 
971
 
 
972
void
 
973
TkMacInvalClipRgns(
 
974
    TkWindow *winPtr)
 
975
{
 
976
    TkWindow *childPtr;
 
977
        
 
978
    /* 
 
979
     * If already marked we can stop because all 
 
980
     * decendants will also already be marked.
 
981
     */
 
982
    if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
 
983
        return;
 
984
    }
 
985
        
 
986
    winPtr->privatePtr->flags |= TK_CLIP_INVALID;
 
987
        
 
988
    /* 
 
989
     * Invalidate clip regions for all children & 
 
990
     * their decendants - unless the child is a toplevel.
 
991
     */
 
992
    childPtr = winPtr->childList;
 
993
    while (childPtr != NULL) {
 
994
        if (!Tk_IsTopLevel(childPtr) && Tk_IsMapped(childPtr)) {
 
995
            TkMacInvalClipRgns(childPtr);
 
996
        }
 
997
        childPtr = childPtr->nextPtr;
 
998
    }
 
999
    
 
1000
    /*
 
1001
     * Also, if the window is a container, mark its embedded window
 
1002
     */
 
1003
     
 
1004
    if (Tk_IsContainer(winPtr)) {
 
1005
        childPtr = TkpGetOtherWindow(winPtr);
 
1006
 
 
1007
        if (childPtr != NULL && Tk_IsMapped(childPtr)) {
 
1008
            TkMacInvalClipRgns(childPtr);
 
1009
        }
 
1010
        
 
1011
        /*
 
1012
         * NOTE: Here we should handle out of process embedding.
 
1013
         */
 
1014
                        
 
1015
    }               
 
1016
}
 
1017
 
 
1018
/*
 
1019
 *----------------------------------------------------------------------
 
1020
 *
 
1021
 * TkMacWinBounds --
 
1022
 *
 
1023
 *      Given a Tk window this function determines the windows
 
1024
 *      bounds in relation to the Macintosh window's coordinate
 
1025
 *      system.  This is also the same coordinate system as the
 
1026
 *      Tk toplevel window in which this window is contained.
 
1027
 *
 
1028
 * Results:
 
1029
 *      None.
 
1030
 *
 
1031
 * Side effects:
 
1032
 *      None.
 
1033
 *
 
1034
 *----------------------------------------------------------------------
 
1035
 */
 
1036
 
 
1037
void
 
1038
TkMacWinBounds(
 
1039
    TkWindow *winPtr,
 
1040
    Rect *bounds)
 
1041
{
 
1042
    bounds->left = (short) winPtr->privatePtr->xOff;
 
1043
    bounds->top = (short) winPtr->privatePtr->yOff;
 
1044
    bounds->right = (short) (winPtr->privatePtr->xOff +
 
1045
            winPtr->changes.width);
 
1046
    bounds->bottom = (short) (winPtr->privatePtr->yOff +
 
1047
            winPtr->changes.height);
 
1048
}
 
1049
 
 
1050
/*
 
1051
 *----------------------------------------------------------------------
 
1052
 *
 
1053
 * tkMacMoveWindow --
 
1054
 *
 
1055
 *      A replacement for the Macintosh MoveWindow function.  This
 
1056
 *      function adjusts the inputs to MoveWindow to offset the root of 
 
1057
 *      the window system.  This has the effect of making the coords 
 
1058
 *      refer to the window dressing rather than the top of the content.
 
1059
 *
 
1060
 * Results:
 
1061
 *      None.
 
1062
 *
 
1063
 * Side effects:
 
1064
 *      Moves the Macintosh window.
 
1065
 *
 
1066
 *----------------------------------------------------------------------
 
1067
 */
 
1068
 
 
1069
void 
 
1070
tkMacMoveWindow(
 
1071
    WindowRef window,
 
1072
    int x,
 
1073
    int y)
 
1074
{
 
1075
    int xOffset, yOffset;
 
1076
 
 
1077
    TkMacWindowOffset(window, &xOffset, &yOffset);
 
1078
    MoveWindow((WindowRef) window, 
 
1079
        (short) (x + xOffset), (short) (y + yOffset), false);
 
1080
}
 
1081
 
 
1082
/*
 
1083
 *----------------------------------------------------------------------
 
1084
 *
 
1085
 * UpdateOffsets --
 
1086
 *
 
1087
 *      Updates the X & Y offsets of the given TkWindow from the
 
1088
 *      TopLevel it is a decendant of.
 
1089
 *
 
1090
 * Results:
 
1091
 *      None.
 
1092
 *
 
1093
 * Side effects:
 
1094
 *      The xOff & yOff fields for the Mac window datastructure
 
1095
 *      is updated to the proper offset.
 
1096
 *
 
1097
 *----------------------------------------------------------------------
 
1098
 */
 
1099
 
 
1100
static void
 
1101
UpdateOffsets(
 
1102
    TkWindow *winPtr,
 
1103
    int deltaX,
 
1104
    int deltaY)
 
1105
{
 
1106
    TkWindow *childPtr;
 
1107
 
 
1108
    if (winPtr->privatePtr == NULL) {
 
1109
        /*
 
1110
         * We havn't called Tk_MakeWindowExist for this window yet.  The
 
1111
         * offset information will be postponed and calulated at that 
 
1112
         * time.  (This will usually only happen when a mapped parent is
 
1113
         * being moved but has child windows that have yet to be mapped.)
 
1114
         */
 
1115
        return;
 
1116
    }
 
1117
    
 
1118
    winPtr->privatePtr->xOff += deltaX;
 
1119
    winPtr->privatePtr->yOff += deltaY;
 
1120
 
 
1121
    childPtr = winPtr->childList;
 
1122
    while (childPtr != NULL) {
 
1123
        if (!Tk_IsTopLevel(childPtr)) {
 
1124
            UpdateOffsets(childPtr, deltaX, deltaY);
 
1125
        }
 
1126
        childPtr = childPtr->nextPtr;
 
1127
    }
 
1128
    
 
1129
    if (Tk_IsContainer(winPtr)) {
 
1130
        childPtr = TkpGetOtherWindow(winPtr);
 
1131
        if (childPtr != NULL) {
 
1132
            UpdateOffsets(childPtr,deltaX,deltaY);
 
1133
        }
 
1134
            
 
1135
        /*
 
1136
         * NOTE: Here we should handle out of process embedding.
 
1137
         */
 
1138
                    
 
1139
    }
 
1140
}
 
1141
 
 
1142
/*
 
1143
 *----------------------------------------------------------------------
 
1144
 *
 
1145
 * Tk_GetPixmap --
 
1146
 *
 
1147
 *      Creates an in memory drawing surface.
 
1148
 *
 
1149
 * Results:
 
1150
 *      Returns a handle to a new pixmap.
 
1151
 *
 
1152
 * Side effects:
 
1153
 *      Allocates a new Macintosh GWorld.
 
1154
 *
 
1155
 *----------------------------------------------------------------------
 
1156
 */
 
1157
 
 
1158
Pixmap
 
1159
Tk_GetPixmap(
 
1160
    Display *display,   /* Display for new pixmap (can be null). */
 
1161
    Drawable d,         /* Drawable where pixmap will be used (ignored). */
 
1162
    int width,          /* Dimensions of pixmap. */
 
1163
    int height,
 
1164
    int depth)          /* Bits per pixel for pixmap. */
 
1165
{
 
1166
    QDErr err;
 
1167
    GWorldPtr gWorld;
 
1168
    Rect bounds;
 
1169
    MacDrawable *macPix;
 
1170
    PixMapHandle pixels;
 
1171
    
 
1172
    if (display != NULL) {
 
1173
        display->request++;
 
1174
    }
 
1175
    macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
 
1176
    macPix->winPtr = NULL;
 
1177
    macPix->xOff = 0;
 
1178
    macPix->yOff = 0;
 
1179
    macPix->clipRgn = NULL;
 
1180
    macPix->aboveClipRgn = NULL;
 
1181
    macPix->referenceCount = 0;
 
1182
    macPix->toplevel = NULL;
 
1183
    macPix->flags = 0;
 
1184
 
 
1185
    bounds.top = bounds.left = 0;
 
1186
    bounds.right = (short) width;
 
1187
    bounds.bottom = (short) height;
 
1188
    if (depth != 1) {
 
1189
        depth = 0;
 
1190
    }
 
1191
 
 
1192
    /*
 
1193
     * Allocate memory for the off screen pixmap.  If we fail
 
1194
     * try again from system memory.  Eventually, we may have
 
1195
     * to panic.
 
1196
     */
 
1197
    err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, 0);
 
1198
    if (err != noErr) {
 
1199
        err = NewGWorld(&gWorld, depth, &bounds, NULL, NULL, useTempMem);
 
1200
    }
 
1201
    if (err != noErr) {
 
1202
        panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
 
1203
    }
 
1204
 
 
1205
    /*
 
1206
     * Lock down the pixels so they don't move out from under us.
 
1207
     */
 
1208
    pixels = GetGWorldPixMap(gWorld);
 
1209
    LockPixels(pixels);
 
1210
    macPix->portPtr = gWorld;
 
1211
 
 
1212
    return (Pixmap) macPix;
 
1213
}
 
1214
 
 
1215
/*
 
1216
 *----------------------------------------------------------------------
 
1217
 *
 
1218
 * Tk_FreePixmap --
 
1219
 *
 
1220
 *      Release the resources associated with a pixmap.
 
1221
 *
 
1222
 * Results:
 
1223
 *      None.
 
1224
 *
 
1225
 * Side effects:
 
1226
 *      Deletes the Macintosh GWorld created by Tk_GetPixmap.
 
1227
 *
 
1228
 *----------------------------------------------------------------------
 
1229
 */
 
1230
 
 
1231
void 
 
1232
Tk_FreePixmap(
 
1233
    Display *display,           /* Display. */
 
1234
    Pixmap pixmap)              /* Pixmap to destroy */
 
1235
{
 
1236
    MacDrawable *macPix = (MacDrawable *) pixmap;
 
1237
    PixMapHandle pixels;
 
1238
 
 
1239
    display->request++;
 
1240
    pixels = GetGWorldPixMap(macPix->portPtr);
 
1241
    UnlockPixels(pixels);
 
1242
    DisposeGWorld(macPix->portPtr);
 
1243
    ckfree((char *) macPix);
 
1244
}
 
1245