OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tk/] [mac/] [tkMacSubwindows.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
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.1.1.1 2002-01-16 10:25:57 markom 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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.