1044 lines
25 KiB
C
1044 lines
25 KiB
C
/*
|
||
* tkMacSubwindows.c --
|
||
*
|
||
* Implements subwindows for the macintosh version of Tk.
|
||
*
|
||
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
|
||
*
|
||
* See the file "license.terms" for information on usage and redistribution
|
||
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
||
*
|
||
* SCCS: @(#) tkMacSubwindows.c 1.52 96/09/22 15:42:14
|
||
*/
|
||
|
||
#include "tkInt.h"
|
||
#include "X.h"
|
||
#include "Xlib.h"
|
||
#include <stdio.h>
|
||
|
||
#include <Windows.h>
|
||
#include <QDOffscreen.h>
|
||
#include "tkMacInt.h"
|
||
|
||
/*
|
||
* Temporary region that can be reused.
|
||
*/
|
||
static RgnHandle tmpRgn = NULL;
|
||
|
||
static void UpdateOffsets _ANSI_ARGS_((TkWindow *winPtr, int deltaX, int deltaY));
|
||
|
||
extern Tcl_HashTable windowTable;
|
||
void MacMoveWindow _ANSI_ARGS_((WindowRef window, int x, int y));
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMakeWindow --
|
||
*
|
||
* Creates an X Window (Mac subwindow).
|
||
*
|
||
* Results:
|
||
* The window id is returned.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
Window
|
||
TkMakeWindow(winPtr, parent)
|
||
TkWindow *winPtr;
|
||
Window parent;
|
||
{
|
||
MacDrawable *macWin;
|
||
XEvent event;
|
||
|
||
/*
|
||
* Allocate sub window
|
||
*/
|
||
macWin = (MacDrawable *) ckalloc(sizeof(MacDrawable));
|
||
if (macWin == NULL) {
|
||
winPtr->privatePtr = NULL;
|
||
return None;
|
||
}
|
||
macWin->winPtr = winPtr;
|
||
winPtr->privatePtr = macWin;
|
||
macWin->clipRgn = NewRgn();
|
||
macWin->aboveClipRgn = NewRgn();
|
||
macWin->referenceCount = 0;
|
||
macWin->flags = TK_CLIP_INVALID;
|
||
macWin->scrollWinPtr = NULL;
|
||
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
macWin->portPtr = (GWorldPtr) NULL; /* This will be set when we are mapped. */
|
||
macWin->toplevel = macWin;
|
||
macWin->xOff = 0;
|
||
macWin->yOff = 0;
|
||
} else {
|
||
macWin->portPtr = NULL;
|
||
macWin->xOff = winPtr->parentPtr->privatePtr->xOff +
|
||
winPtr->parentPtr->changes.border_width +
|
||
winPtr->changes.x;
|
||
macWin->yOff = winPtr->parentPtr->privatePtr->yOff +
|
||
winPtr->parentPtr->changes.border_width +
|
||
winPtr->changes.y;
|
||
macWin->toplevel = winPtr->parentPtr->privatePtr->toplevel;
|
||
}
|
||
|
||
macWin->toplevel->referenceCount++;
|
||
|
||
/*
|
||
* TODO: need general solution for visibility events.
|
||
*/
|
||
event.xany.serial = Tk_Display(winPtr)->request;
|
||
event.xany.send_event = False;
|
||
event.xany.display = Tk_Display(winPtr);
|
||
|
||
event.xvisibility.type = VisibilityNotify;
|
||
event.xvisibility.window = (Window) macWin;;
|
||
event.xvisibility.state = VisibilityUnobscured;
|
||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||
|
||
return (Window) macWin;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XDestroyWindow --
|
||
*
|
||
* Dealocates the given X Window.
|
||
*
|
||
* Results:
|
||
* The window id is returned.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XDestroyWindow(Display *display, Window window)
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
GWorldPtr destPort;
|
||
|
||
/*
|
||
* Remove any dangling pointers that may exist if
|
||
* the window we are deleting is being tracked by
|
||
* the grab code.
|
||
*/
|
||
TkMacPointerDeadWindow(macWin->winPtr);
|
||
TkMacSetScrollbarGrow(macWin->winPtr, false);
|
||
destPort = TkMacGetDrawablePort(window);
|
||
macWin->toplevel->referenceCount--;
|
||
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
DisposeRgn(macWin->clipRgn);
|
||
DisposeRgn(macWin->aboveClipRgn);
|
||
macWin->portPtr = NULL;
|
||
if (macWin->toplevel->referenceCount == 0) {
|
||
ckfree((char *) macWin->toplevel);
|
||
}
|
||
|
||
/*
|
||
* Delete the Mac window and remove it from the windowTable.
|
||
* The window could be NULL if the window was never mapped.
|
||
*/
|
||
if (destPort != NULL) {
|
||
Tcl_DeleteHashEntry(Tcl_FindHashEntry(&windowTable,
|
||
(char *) destPort));
|
||
DisposeWindow((WindowRef) destPort);
|
||
}
|
||
} else {
|
||
if (destPort != NULL) {
|
||
SetGWorld(destPort, NULL);
|
||
InvalRgn(macWin->aboveClipRgn); /* TODO: this may not be valid */
|
||
}
|
||
if (macWin->winPtr->parentPtr != NULL) {
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
}
|
||
DisposeRgn(macWin->clipRgn);
|
||
DisposeRgn(macWin->aboveClipRgn);
|
||
if (macWin->toplevel->referenceCount == 0) {
|
||
ckfree((char *) macWin->toplevel);
|
||
}
|
||
ckfree((char *) macWin);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XMapWindow --
|
||
*
|
||
* Map the given X Window to the screen. See X window documentation
|
||
* for more details.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* The subwindow or toplevel may appear on the screen.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XMapWindow(display, window)
|
||
Display *display;
|
||
Window window;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
XEvent event;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(window);
|
||
|
||
display->request++;
|
||
macWin->winPtr->flags |= TK_MAPPED;
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
ShowWindow((WindowRef) destPort);
|
||
|
||
/*
|
||
* We only need to send the MapNotify event
|
||
* for toplevel windows.
|
||
*/
|
||
event.xany.serial = display->request;
|
||
event.xany.send_event = False;
|
||
event.xany.display = display;
|
||
|
||
event.xmap.window = window;
|
||
event.xmap.type = MapNotify;
|
||
event.xmap.event = window;
|
||
event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
|
||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||
} else {
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
}
|
||
|
||
/*
|
||
* Generate damage for that area of the window
|
||
*/
|
||
SetGWorld(destPort, NULL);
|
||
TkMacUpdateClipRgn(macWin->winPtr);
|
||
InvalRgn(macWin->aboveClipRgn);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XUnmapWindow --
|
||
*
|
||
* Unmap the given X Window to the screen. See X window
|
||
* documentation for more details.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* The subwindow or toplevel may be removed from the screen.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XUnmapWindow(display, window)
|
||
Display *display;
|
||
Window window;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
XEvent event;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(window);
|
||
|
||
display->request++;
|
||
macWin->winPtr->flags &= ~TK_MAPPED;
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
HideWindow((WindowRef) destPort);
|
||
|
||
/*
|
||
* We only need to send the UnmapNotify event
|
||
* for toplevel windows.
|
||
*/
|
||
event.xany.serial = display->request;
|
||
event.xany.send_event = False;
|
||
event.xany.display = display;
|
||
|
||
event.xunmap.type = UnmapNotify;
|
||
event.xunmap.window = window;
|
||
event.xunmap.event = window;
|
||
event.xunmap.from_configure = false;
|
||
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
|
||
} else {
|
||
/*
|
||
* Generate damage for that area of the window.
|
||
*/
|
||
SetGWorld(destPort, NULL);
|
||
InvalRgn(macWin->aboveClipRgn); /* TODO: may not be valid */
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XResizeWindow --
|
||
*
|
||
* Resize a given X window. See X windows documentation for
|
||
* further details.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XResizeWindow(display, window, width, height)
|
||
Display *display;
|
||
Window window;
|
||
unsigned int width;
|
||
unsigned int height;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(window);
|
||
|
||
display->request++;
|
||
SetPort((GrafPtr) destPort);
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
/*
|
||
* NOTE: we are not adding the new space to the update
|
||
* regoin. It is currently assumed that Tk will need
|
||
* to completely redraw anway.
|
||
*/
|
||
SizeWindow((WindowRef) destPort, (short) width, (short) height, false);
|
||
InvalRgn(macWin->clipRgn);
|
||
InvalClipRgns(macWin->winPtr);
|
||
} else {
|
||
/* TODO: update all xOff & yOffs */
|
||
int deltaX, deltaY;
|
||
MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
|
||
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
|
||
deltaX = - macWin->xOff;
|
||
deltaY = - macWin->yOff;
|
||
deltaX += macParent->xOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.x;
|
||
deltaY += macParent->yOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.y;
|
||
UpdateOffsets(macWin->winPtr, deltaX, deltaY);
|
||
}
|
||
TkGenWMConfigureEvent((Tk_Window) macWin->winPtr, -1, -1,
|
||
macWin->winPtr->changes.width, macWin->winPtr->changes.height, TK_SIZE_CHANGED);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XMoveResizeWindow --
|
||
*
|
||
* Move or resize a given X window. See X windows documentation
|
||
* for further details.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XMoveResizeWindow(Display *display, Window window,
|
||
int x, int y,
|
||
unsigned int width, unsigned int height)
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(window);
|
||
|
||
SetPort((GrafPtr) destPort);
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
/*
|
||
* NOTE: we are not adding the new space to the update
|
||
* regoin. It is currently assumed that Tk will need
|
||
* to completely redraw anway.
|
||
*/
|
||
SizeWindow((WindowRef) destPort, (short) width, (short) height, false);
|
||
MacMoveWindow((WindowRef) destPort, x, y);
|
||
|
||
/* TODO: is the following right? */
|
||
InvalRgn(macWin->clipRgn);
|
||
InvalClipRgns(macWin->winPtr);
|
||
TkGenWMConfigureEvent((Tk_Window) macWin->winPtr, x, y, width, height, TK_BOTH_CHANGED);
|
||
} else {
|
||
int deltaX, deltaY;
|
||
Rect bounds;
|
||
MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
|
||
if (macParent == NULL) {
|
||
return; /* TODO: Probably should be a panic */
|
||
}
|
||
|
||
if (!EmptyRgn(macWin->clipRgn)) {
|
||
InvalRgn(macWin->clipRgn);
|
||
}
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
|
||
deltaX = - macWin->xOff;
|
||
deltaY = - macWin->yOff;
|
||
deltaX += macParent->xOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.x;
|
||
deltaY += macParent->yOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.y;
|
||
|
||
UpdateOffsets(macWin->winPtr, deltaX, deltaY);
|
||
TkMacWinBounds(macWin->winPtr, &bounds);
|
||
InvalRect(&bounds);
|
||
TkGenWMConfigureEvent((Tk_Window) macWin->winPtr,
|
||
macWin->winPtr->changes.x, macWin->winPtr->changes.y,
|
||
width, height, TK_BOTH_CHANGED);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XMoveWindow --
|
||
*
|
||
* Move a given X window. See X windows documentation for further
|
||
* details.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XMoveWindow(display, window, x, y)
|
||
Display* display;
|
||
Window window;
|
||
int x;
|
||
int y;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(window);
|
||
|
||
SetPort((GrafPtr) destPort);
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
/*
|
||
* NOTE: we are not adding the new space to the update
|
||
* regoin. It is currently assumed that Tk will need
|
||
* to completely redraw anway.
|
||
*/
|
||
MacMoveWindow((WindowRef) destPort, x, y);
|
||
|
||
/* TODO: is the following right? */
|
||
InvalRgn(macWin->clipRgn);
|
||
InvalClipRgns(macWin->winPtr);
|
||
TkGenWMConfigureEvent((Tk_Window) macWin->winPtr, x, y, -1, -1, TK_LOCATION_CHANGED);
|
||
} else {
|
||
int deltaX, deltaY;
|
||
Rect bounds;
|
||
MacDrawable *macParent = macWin->winPtr->parentPtr->privatePtr;
|
||
if (macParent == NULL) {
|
||
return; /* TODO: Probably should be a panic */
|
||
}
|
||
|
||
if (!EmptyRgn(macWin->clipRgn)) {
|
||
InvalRgn(macWin->clipRgn);
|
||
}
|
||
InvalClipRgns(macWin->winPtr->parentPtr);
|
||
|
||
deltaX = - macWin->xOff;
|
||
deltaY = - macWin->yOff;
|
||
deltaX += macParent->xOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.x;
|
||
deltaY += macParent->yOff +
|
||
macWin->winPtr->parentPtr->changes.border_width +
|
||
macWin->winPtr->changes.y;
|
||
|
||
UpdateOffsets(macWin->winPtr, deltaX, deltaY);
|
||
TkMacWinBounds(macWin->winPtr, &bounds);
|
||
InvalRect(&bounds);
|
||
TkGenWMConfigureEvent((Tk_Window) macWin->winPtr,
|
||
macWin->winPtr->changes.x, macWin->winPtr->changes.y, -1, -1, TK_LOCATION_CHANGED);
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XRaiseWindow --
|
||
*
|
||
* Change the stacking order of a window.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Changes the stacking order of the specified window.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XRaiseWindow(display, window)
|
||
Display* display;
|
||
Window window;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) window;
|
||
|
||
display->request++;
|
||
if (Tk_IsTopLevel(macWin->winPtr)) {
|
||
TkWmRestackToplevel(macWin->winPtr, Above, NULL);
|
||
} else {
|
||
/* TODO: this should generate damage */
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* XConfigureWindow --
|
||
*
|
||
* Change the size, position, stacking, or border of the specified
|
||
* window.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Changes the attributes of the specified window. Note that we
|
||
* ignore the passed in values and use the values stored in the
|
||
* TkWindow data structure.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
XConfigureWindow(display, w, value_mask, values)
|
||
Display* display;
|
||
Window w;
|
||
unsigned int value_mask;
|
||
XWindowChanges* values;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) w;
|
||
TkWindow *winPtr = macWin->winPtr;
|
||
|
||
display->request++;
|
||
|
||
/*
|
||
* Change the shape and/or position of the window.
|
||
*/
|
||
|
||
if (value_mask & (CWX|CWY|CWWidth|CWHeight)) {
|
||
XMoveResizeWindow(display, w, winPtr->changes.x, winPtr->changes.y,
|
||
winPtr->changes.width, winPtr->changes.height);
|
||
}
|
||
|
||
/*
|
||
* Change the stacking order of the window. Tk actuall keeps all
|
||
* the information we need for stacking order. All we need to do
|
||
* is make sure the clipping regions get updated and generate damage
|
||
* that will ensure things get drawn correctly.
|
||
*/
|
||
|
||
if (value_mask & CWStackMode) {
|
||
Rect bounds;
|
||
GWorldPtr destPort;
|
||
|
||
destPort = TkMacGetDrawablePort(w);
|
||
SetPort((GrafPtr) destPort);
|
||
InvalClipRgns(winPtr->parentPtr);
|
||
TkMacWinBounds(winPtr, &bounds);
|
||
InvalRect(&bounds);
|
||
}
|
||
|
||
/* TkGenWMMoveRequestEvent(macWin->winPtr,
|
||
macWin->winPtr->changes.x, macWin->winPtr->changes.y); */
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacUpdateClipRgn --
|
||
*
|
||
* This function updates the cliping regions for a given window
|
||
* and all of its children. Once updated the TK_CLIP_INVALID flag
|
||
* in the subwindow data structure is unset. The TK_CLIP_INVALID
|
||
* flag should always be unset before any drawing is attempted.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* The clip regions for the window and its children are updated.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TkMacUpdateClipRgn(winPtr)
|
||
TkWindow *winPtr;
|
||
{
|
||
RgnHandle rgn;
|
||
int x, y;
|
||
TkWindow *win2Ptr;
|
||
|
||
if (winPtr == NULL) {
|
||
return;
|
||
}
|
||
|
||
if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
|
||
rgn = winPtr->privatePtr->aboveClipRgn;
|
||
if (tmpRgn == NULL) {
|
||
tmpRgn = NewRgn();
|
||
}
|
||
|
||
/*
|
||
* Start with a region defined by the window bounds.
|
||
*/
|
||
x = winPtr->privatePtr->xOff;
|
||
y = winPtr->privatePtr->yOff;
|
||
SetRectRgn(rgn, (short) x, (short) y,
|
||
(short) (winPtr->changes.width + x),
|
||
(short) (winPtr->changes.height + y));
|
||
|
||
/*
|
||
* Clip away the area of any windows that may obscure this
|
||
* window. First, clip to the parents visable clip region.
|
||
* Second, clip away any siblings that are higher in the
|
||
* stacking order.
|
||
*/
|
||
if (!Tk_IsTopLevel(winPtr)) {
|
||
TkMacUpdateClipRgn(winPtr->parentPtr);
|
||
SectRgn(rgn,
|
||
winPtr->parentPtr->privatePtr->aboveClipRgn, rgn);
|
||
|
||
win2Ptr = winPtr->nextPtr;
|
||
while (win2Ptr != NULL) {
|
||
if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
|
||
win2Ptr = win2Ptr->nextPtr;
|
||
continue;
|
||
}
|
||
x = win2Ptr->privatePtr->xOff;
|
||
y = win2Ptr->privatePtr->yOff;
|
||
SetRectRgn(tmpRgn, (short) x, (short) y,
|
||
(short) (win2Ptr->changes.width + x),
|
||
(short) (win2Ptr->changes.height + y));
|
||
DiffRgn(rgn, tmpRgn, rgn);
|
||
|
||
win2Ptr = win2Ptr->nextPtr;
|
||
}
|
||
}
|
||
|
||
/*
|
||
* The final clip region is the aboveClip region (or visable
|
||
* region) minus all the children of this window.
|
||
*/
|
||
rgn = winPtr->privatePtr->clipRgn;
|
||
CopyRgn(winPtr->privatePtr->aboveClipRgn, rgn);
|
||
|
||
win2Ptr = winPtr->childList;
|
||
while (win2Ptr != NULL) {
|
||
if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {
|
||
win2Ptr = win2Ptr->nextPtr;
|
||
continue;
|
||
}
|
||
x = win2Ptr->privatePtr->xOff;
|
||
y = win2Ptr->privatePtr->yOff;
|
||
SetRectRgn(tmpRgn, (short) x, (short) y,
|
||
(short) (win2Ptr->changes.width + x),
|
||
(short) (win2Ptr->changes.height + y));
|
||
DiffRgn(rgn, tmpRgn, rgn);
|
||
|
||
win2Ptr = win2Ptr->nextPtr;
|
||
}
|
||
|
||
winPtr->privatePtr->flags &= ~TK_CLIP_INVALID;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacVisableClipRgn --
|
||
*
|
||
* This function returnd the Macintosh cliping region for the
|
||
* given window. A NULL Rgn means the window is not visable.
|
||
*
|
||
* Results:
|
||
* The region.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
RgnHandle
|
||
TkMacVisableClipRgn(winPtr)
|
||
TkWindow *winPtr;
|
||
{
|
||
if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
|
||
TkMacUpdateClipRgn(winPtr);
|
||
}
|
||
|
||
return winPtr->privatePtr->clipRgn;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacGetDrawablePort --
|
||
*
|
||
* This function returns the Graphics Port for a given X drawable.
|
||
*
|
||
* Results:
|
||
* A GWorld pointer. Either an off screen pixmap or a Window.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
GWorldPtr
|
||
TkMacGetDrawablePort(drawable)
|
||
Drawable drawable;
|
||
{
|
||
MacDrawable *macWin = (MacDrawable *) drawable;
|
||
|
||
if (macWin->clipRgn == NULL) {
|
||
return macWin->portPtr;
|
||
}
|
||
|
||
return macWin->toplevel->portPtr;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* InvalClipRgns --
|
||
*
|
||
* This function invalidates the clipping regions for a given
|
||
* window and all of its children. This function should be
|
||
* called whenever changes are made to subwindows that would
|
||
* effect the size or position of windows.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* The cliping regions for the window and its children are
|
||
* mark invalid. (Make sure they are valid before drawing.)
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
InvalClipRgns(winPtr)
|
||
TkWindow *winPtr;
|
||
{
|
||
TkWindow *childPtr;
|
||
|
||
/*
|
||
* If already marked we can stop because all
|
||
* decendants will also already be marked.
|
||
*/
|
||
if (winPtr->privatePtr->flags & TK_CLIP_INVALID) {
|
||
return;
|
||
}
|
||
|
||
winPtr->privatePtr->flags |= TK_CLIP_INVALID;
|
||
|
||
/*
|
||
* Invalidate clip regions for all children &
|
||
* thier decendants - unless the child is a toplevel.
|
||
*/
|
||
childPtr = winPtr->childList;
|
||
while (childPtr != NULL) {
|
||
if (!Tk_IsTopLevel(childPtr) && Tk_IsMapped(childPtr)) {
|
||
InvalClipRgns(childPtr);
|
||
}
|
||
childPtr = childPtr->nextPtr;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacWinBounds --
|
||
*
|
||
* Given a Tk window this function determines the windows
|
||
* bounds in relation to the Macintosh window's coordinate
|
||
* system. This is also the same coordinate system as the
|
||
* Tk toplevel window in which this window is contained.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TkMacWinBounds(winPtr, bounds)
|
||
TkWindow *winPtr;
|
||
Rect *bounds;
|
||
{
|
||
bounds->left = (short) winPtr->privatePtr->xOff;
|
||
bounds->top = (short) winPtr->privatePtr->yOff;
|
||
bounds->right = (short) (winPtr->privatePtr->xOff +
|
||
winPtr->changes.width);
|
||
bounds->bottom = (short) (winPtr->privatePtr->yOff +
|
||
winPtr->changes.height);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* MacMoveWindow --
|
||
*
|
||
* A replacement for the Macintosh MoveWindow function. This
|
||
* function adjusts the inputs to MoveWindow to offset the root of
|
||
* the window system. This has the effect of making the coords
|
||
* refer to the window dressing rather than the top of the content.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Moves the Macintosh window.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
MacMoveWindow(WindowRef window, int x, int y)
|
||
{
|
||
int xOffset, yOffset;
|
||
|
||
TkMacWindowOffset(window, &xOffset, &yOffset);
|
||
MoveWindow((WindowRef) window,
|
||
(short) (x + xOffset), (short) (y + yOffset), false);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* UpdateOffsets --
|
||
*
|
||
* Updates the X & Y offsets of the given TkWindow from the
|
||
* TopLevel it is a decendant of.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* The xOff & yOff fields for the Mac window datastructure
|
||
* is updated to the proper offset.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
static void
|
||
UpdateOffsets(winPtr, deltaX, deltaY)
|
||
TkWindow *winPtr;
|
||
int deltaX, deltaY;
|
||
{
|
||
TkWindow *childPtr;
|
||
|
||
winPtr->privatePtr->xOff += deltaX;
|
||
winPtr->privatePtr->yOff += deltaY;
|
||
|
||
childPtr = winPtr->childList;
|
||
while (childPtr != NULL) {
|
||
if (!Tk_IsTopLevel(childPtr)) {
|
||
UpdateOffsets(childPtr, deltaX, deltaY);
|
||
}
|
||
childPtr = childPtr->nextPtr;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tk_GetPixmap --
|
||
*
|
||
* Creates an in memory drawing surface.
|
||
*
|
||
* Results:
|
||
* Returns a handle to a new pixmap.
|
||
*
|
||
* Side effects:
|
||
* Allocates a new Macintosh GWorld.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
Pixmap
|
||
Tk_GetPixmap(display, d, width, height, depth)
|
||
Display *display; /* Display for new pixmap. */
|
||
Drawable d; /* Drawable where pixmap will be used. */
|
||
unsigned int width, height; /* Dimensions of pixmap. */
|
||
unsigned int depth; /* Bits per pixel for pixmap. */
|
||
{
|
||
QDErr err;
|
||
GWorldPtr gWorld;
|
||
Rect bounds;
|
||
MacDrawable *macPix;
|
||
PixMapHandle pixels;
|
||
|
||
display->request++;
|
||
macPix = (MacDrawable *) ckalloc(sizeof(MacDrawable));
|
||
macPix->winPtr = NULL;
|
||
macPix->xOff = 0;
|
||
macPix->yOff = 0;
|
||
macPix->clipRgn = NULL;
|
||
macPix->aboveClipRgn = NULL;
|
||
macPix->referenceCount = 0;
|
||
macPix->toplevel = NULL;
|
||
macPix->flags = 0;
|
||
macPix->scrollWinPtr = NULL;
|
||
|
||
bounds.top = bounds.left = 0;
|
||
bounds.right = (short) width;
|
||
bounds.bottom = (short) height;
|
||
|
||
/*
|
||
* Allocate memory for the off screen pixmap. If we fail
|
||
* try again from system memory. Eventually, we may have
|
||
* to panic.
|
||
*/
|
||
err = NewGWorld(&gWorld, 0, &bounds, NULL, NULL, 0);
|
||
if (err != noErr) {
|
||
err = NewGWorld(&gWorld, 0, &bounds, NULL, NULL, useTempMem);
|
||
}
|
||
if (err != noErr) {
|
||
panic("Out of memory: NewGWorld failed in Tk_GetPixmap");
|
||
}
|
||
|
||
/*
|
||
* Lock down the pixels so they don't move out from under us.
|
||
*/
|
||
pixels = GetGWorldPixMap(gWorld);
|
||
LockPixels(pixels);
|
||
macPix->portPtr = gWorld;
|
||
|
||
return (Pixmap) macPix;
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* Tk_FreePixmap --
|
||
*
|
||
* Release the resources associated with a pixmap.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* Deletes the Macintosh GWorld created by Tk_GetPixmap.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
Tk_FreePixmap(display, pixmap)
|
||
Display *display; /* Display. */
|
||
Pixmap pixmap; /* Pixmap to destroy */
|
||
{
|
||
MacDrawable *macPix = (MacDrawable *) pixmap;
|
||
PixMapHandle pixels;
|
||
|
||
display->request++;
|
||
pixels = GetGWorldPixMap(macPix->portPtr);
|
||
UnlockPixels(pixels);
|
||
DisposeGWorld(macPix->portPtr);
|
||
ckfree((char *) macPix);
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacSetScrollbarGrow --
|
||
*
|
||
* Sets a flag for a toplevel window indicating that the passed
|
||
* Tk scrollbar window will display the grow region for the
|
||
* toplevel window.
|
||
*
|
||
* Results:
|
||
* None.
|
||
*
|
||
* Side effects:
|
||
* A flag is set int windows toplevel parent.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
void
|
||
TkMacSetScrollbarGrow(winPtr, flag)
|
||
TkWindow *winPtr; /* Tk scrollbar window. */
|
||
int flag; /* Boolean value true or false. */
|
||
{
|
||
if (flag) {
|
||
winPtr->privatePtr->toplevel->flags |= TK_SCROLLBAR_GROW;
|
||
winPtr->privatePtr->toplevel->scrollWinPtr = winPtr;
|
||
} else if (winPtr->privatePtr->toplevel->scrollWinPtr == winPtr) {
|
||
winPtr->privatePtr->toplevel->flags &= ~TK_SCROLLBAR_GROW;
|
||
winPtr->privatePtr->toplevel->scrollWinPtr = NULL;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*----------------------------------------------------------------------
|
||
*
|
||
* TkMacGetScrollbarGrowWindow --
|
||
*
|
||
* Tests to see if a given window's toplevel window contains a
|
||
* scrollbar that will draw the GrowIcon for the window.
|
||
*
|
||
* Results:
|
||
* Boolean value.
|
||
*
|
||
* Side effects:
|
||
* None.
|
||
*
|
||
*----------------------------------------------------------------------
|
||
*/
|
||
|
||
TkWindow *
|
||
TkMacGetScrollbarGrowWindow(winPtr)
|
||
TkWindow *winPtr; /* Tk window. */
|
||
{
|
||
if (winPtr == NULL) return NULL;
|
||
return winPtr->privatePtr->toplevel->scrollWinPtr;
|
||
}
|