summaryrefslogtreecommitdiffstats
path: root/generic/tkBusy.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkBusy.c')
-rw-r--r--generic/tkBusy.c350
1 files changed, 27 insertions, 323 deletions
diff --git a/generic/tkBusy.c b/generic/tkBusy.c
index e8343e3..36e8c35 100644
--- a/generic/tkBusy.c
+++ b/generic/tkBusy.c
@@ -11,66 +11,23 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tkBusy.c,v 1.1 2008/10/18 14:22:22 dkf Exp $
+ * RCS: @(#) $Id: tkBusy.c,v 1.2 2008/10/20 10:50:20 dkf Exp $
*/
#include "tkInt.h"
+#include "tkBusy.h"
-#if !(defined(__WIN32__) || defined(MAC_OSX_TK))
-#include "tkUnixInt.h"
-#endif
-
-#ifdef WIN32
-#include <windows.h>
-extern HINSTANCE Tk_GetHINSTANCE(void);
-extern Window Tk_AttachHWND(Tk_Window tkwin, HWND hwnd);
-extern HWND Tk_GetHWND(Window window);
-
-#define DEF_BUSY_CURSOR "wait"
-#else
-#define DEF_BUSY_CURSOR "watch"
-#endif
-
/*
- * Types used in this file.
- */
-
-typedef struct {
- Display *display; /* Display of busy window */
- Tcl_Interp *interp; /* Interpreter where "busy" command was
- * created. It's used to key the searches in
- * the window hierarchy. See the "windows"
- * command. */
- Tk_Window tkBusy; /* Busy window: Transparent window used to
- * block delivery of events to windows
- * underneath it. */
- Tk_Window tkParent; /* Parent window of the busy window. It may be
- * the reference window (if the reference is a
- * toplevel) or a mutual ancestor of the
- * reference window */
- Tk_Window tkRef; /* Reference window of the busy window. It is
- * used to manage the size and position of the
- * busy window. */
- int x, y; /* Position of the reference window */
- int width, height; /* Size of the reference window. Retained to
- * know if the reference window has been
- * reconfigured to a new size. */
- int menuBar; /* Menu bar flag. */
- Tk_Cursor cursor; /* Cursor for the busy window. */
- Tcl_HashEntry *hashPtr; /* Used the delete the busy window entry out
- * of the global hash table. */
- Tcl_HashTable *tablePtr;
- Tk_OptionTable optionTable;
-} Busy;
-
-/*
- * Things about the busy system that may be configured.
+ * Things about the busy system that may be configured. Note that currently on
+ * OSX/Aqua, that's nothing at all.
*/
static Tk_OptionSpec busyOptionSpecs[] = {
+#ifndef MAC_OSX_TK
{TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor),
TK_OPTION_NULL_OK, 0, 0},
+#endif
{TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0}
};
@@ -78,13 +35,31 @@ static Tk_OptionSpec busyOptionSpecs[] = {
* Forward declarations of functions defined in this file.
*/
-static void DestroyBusy(char *dataPtr);
static void BusyEventProc(ClientData clientData,
XEvent *eventPtr);
static void BusyGeometryProc(ClientData clientData,
Tk_Window tkwin);
static void BusyCustodyProc(ClientData clientData,
Tk_Window tkwin);
+static int ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
+ int objc, Tcl_Obj *const objv[]);
+static Busy * CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
+static void DestroyBusy(char *dataPtr);
+static void DoConfigureNotify(Tk_FakeWin *winPtr);
+static inline Tk_Window FirstChild(Tk_Window parent);
+static int GetBusy(Tcl_HashTable *busyTablePtr,
+ Tcl_Interp *interp, Tcl_Obj *const windowObj,
+ Busy **busyPtrPtr);
+static int HoldBusy(Tcl_HashTable *busyTablePtr,
+ Tcl_Interp *interp, Tcl_Obj *const windowObj,
+ int configObjc, Tcl_Obj *const configObjv[]);
+static void MakeTransparentWindowExist(Tk_Window tkwin,
+ Window parent);
+static inline Tk_Window NextChild(Tk_Window tkwin);
+static void RefWinEventProc(ClientData clientData,
+ register XEvent *eventPtr);
+static inline void SetWindowInstanceData(Tk_Window tkwin,
+ ClientData instanceData);
/*
* The "busy" geometry manager definition.
@@ -134,273 +109,6 @@ SetWindowInstanceData(
/*
*----------------------------------------------------------------------
*
- * TkpShowBusyWindow, TkpHideBusyWindow, TkpMakeTransparentWindowExist,
- * TkpCreateBusy --
- *
- * Portability layer. Holds platform-specific gunk for the [tk busy]
- * command, including a wholly dummy implementation for OSX/Aqua. The
- * individual functions do the following:
- *
- * TkpShowBusyWindow --
- * Make the busy window appear.
- *
- * TkpHideBusyWindow --
- * Make the busy window go away.
- *
- * TkpMakeTransparentWindowExist --
- * Actually make a transparent window.
- *
- * TkpCreateBusy --
- * Creates the platform-specific part of a busy window structure.
- *
- *----------------------------------------------------------------------
- */
-
-#ifdef WIN32 /* Windows */
-
-void
-TkpShowBusyWindow(
- Busy *busyPtr)
-{
- HWND hWnd;
- POINT point;
- Display *display;
- Window window;
-
- if (busyPtr->tkBusy != NULL) {
- Tk_MapWindow(busyPtr->tkBusy);
- window = Tk_WindowId(busyPtr->tkBusy);
- display = Tk_Display(busyPtr->tkBusy);
- hWnd = Tk_GetHWND(window);
- display->request++;
- SetWindowPos(hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- }
-
- /*
- * Under Win32, cursors aren't associated with windows. Tk fakes this by
- * watching Motion events on its windows. So Tk will automatically change
- * the cursor when the pointer enters the Busy window. But Windows does
- * not immediately change the cursor; it waits for the cursor position to
- * change or a system call. We need to change the cursor before the
- * application starts processing, so set the cursor position redundantly
- * back to the current position.
- */
-
- GetCursorPos(&point);
- SetCursorPos(point.x, point.y);
-}
-
-void
-TkpHideBusyWindow(
- Busy *busyPtr)
-{
- POINT point;
-
- if (busyPtr->tkBusy != NULL) {
- Tk_UnmapWindow(busyPtr->tkBusy);
- }
-
- /*
- * Under Win32, cursors aren't associated with windows. Tk fakes this by
- * watching Motion events on its windows. So Tk will automatically change
- * the cursor when the pointer enters the Busy window. But Windows does
- * not immediately change the cursor: it waits for the cursor position to
- * change or a system call. We need to change the cursor before the
- * application starts processing, so set the cursor position redundantly
- * back to the current position.
- */
-
- GetCursorPos(&point);
- SetCursorPos(point.x, point.y);
-}
-
-void
-TkpMakeTransparentWindowExist(
- Tk_Window tkwin, /* Token for window. */
- Window parent) /* Parent window. */
-{
- TkWindow *winPtr = (TkWindow *) tkwin;
- HWND hParent;
- HWND hWnd;
- int style;
- DWORD exStyle;
-
- hParent = (HWND) parent;
- style = WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
- exStyle = WS_EX_TRANSPARENT | WS_EX_TOPMOST;
-#define TK_WIN_CHILD_CLASS_NAME "TkChild"
- hWnd = CreateWindowEx(exStyle, TK_WIN_CHILD_CLASS_NAME, NULL, style,
- Tk_X(tkwin), Tk_Y(tkwin), Tk_Width(tkwin), Tk_Height(tkwin),
- hParent, NULL, Tk_GetHINSTANCE(), NULL);
- winPtr->window = Tk_AttachHWND(tkwin, hWnd);
-}
-
-void
-TkpCreateBusy(
- Tk_FakeWin *winPtr,
- Tk_Window tkRef,
- Window* parentPtr,
- Tk_Window tkParent,
- Busy *busyPtr)
-{
- if (winPtr->flags & TK_REPARENTED) {
- /*
- * This works around a bug in the implementation of menubars for
- * non-MacIntosh window systems (Win32 and X11). Tk doesn't reset the
- * pointers to the parent window when the menu is reparented
- * (winPtr->parentPtr points to the wrong window). We get around this
- * by determining the parent via the native API calls.
- */
-
- HWND hWnd;
- RECT rect;
-
- hWnd = GetParent(Tk_GetHWND(Tk_WindowId(tkRef)));
- if (GetWindowRect(hWnd, &rect)) {
- busyPtr->width = rect.right - rect.left;
- busyPtr->height = rect.bottom - rect.top;
- }
- } else {
- *parentPtr = Tk_WindowId(tkParent);
- *parentPtr = (Window) Tk_GetHWND(*parentPtr);
- }
-}
-
-#elif defined(MAC_OSX_TK) /* Aqua */
-
-void
-TkpShowBusyWindow(
- Busy *busyPtr)
-{
-}
-
-void
-TkpHideBusyWindow(
- Busy *busyPtr)
-{
-}
-
-void
-TkpMakeTransparentWindowExist(
- Tk_Window tkwin, /* Token for window. */
- Window parent) /* Parent window. */
-{
-}
-
-void
-TkpCreateBusy(
- Tk_FakeWin *winPtr,
- Tk_Window tkRef,
- Window* parentPtr,
- Tk_Window tkParent,
- Busy *busyPtr)
-{
-}
-
-#else /* UNIX/X11 */
-
-void
-TkpShowBusyWindow(
- Busy *busyPtr)
-{
- if (busyPtr->tkBusy != NULL) {
- Tk_MapWindow(busyPtr->tkBusy);
-
- /*
- * Always raise the busy window just in case new sibling windows have
- * been created in the meantime. Can't use Tk_RestackWindow because it
- * doesn't work under Win32.
- */
-
- XRaiseWindow(Tk_Display(busyPtr->tkBusy),
- Tk_WindowId(busyPtr->tkBusy));
- }
-}
-
-void
-TkpHideBusyWindow(
- Busy *busyPtr)
-{
- if (busyPtr->tkBusy != NULL) {
- Tk_UnmapWindow(busyPtr->tkBusy);
- }
-}
-
-void
-TkpMakeTransparentWindowExist(
- Tk_Window tkwin, /* Token for window. */
- Window parent) /* Parent window. */
-{
- TkWindow *winPtr = (TkWindow *) tkwin;
- long int mask = CWDontPropagate | CWEventMask;
-
- /*
- * Ignore the important events while the window is mapped.
- */
-
-#define USER_EVENTS \
- (EnterWindowMask | LeaveWindowMask | KeyPressMask | KeyReleaseMask | \
- ButtonPressMask | ButtonReleaseMask | PointerMotionMask)
-#define PROP_EVENTS \
- (KeyPressMask | KeyReleaseMask | ButtonPressMask | \
- ButtonReleaseMask | PointerMotionMask)
-
- winPtr->atts.do_not_propagate_mask = PROP_EVENTS;
- winPtr->atts.event_mask = USER_EVENTS;
- winPtr->changes.border_width = 0;
- winPtr->depth = 0;
-
- winPtr->window = XCreateWindow(winPtr->display, parent,
- winPtr->changes.x, winPtr->changes.y,
- (unsigned) winPtr->changes.width, /* width */
- (unsigned) winPtr->changes.height, /* height */
- (unsigned) winPtr->changes.border_width, /* border_width */
- winPtr->depth, InputOnly, winPtr->visual, mask, &winPtr->atts);
-}
-
-static Window
-GetParent(
- Display *display,
- Window window)
-{
- Window root, parent;
- Window *dummy;
- unsigned int count;
-
- if (XQueryTree(display, window, &root, &parent, &dummy, &count) > 0) {
- XFree(dummy);
- return parent;
- }
- return None;
-}
-
-void
-TkpCreateBusy(
- Tk_FakeWin *winPtr,
- Tk_Window tkRef,
- Window* parentPtr,
- Tk_Window tkParent,
- Busy *busyPtr)
-{
- if (winPtr->flags & TK_REPARENTED) {
- /*
- * This works around a bug in the implementation of menubars for
- * non-MacIntosh window systems (Win32 and X11). Tk doesn't reset the
- * pointers to the parent window when the menu is reparented
- * (winPtr->parentPtr points to the wrong window). We get around this
- * by determining the parent via the native API calls.
- */
-
- *parentPtr = GetParent(Tk_Display(tkRef), Tk_WindowId(tkRef));
- } else {
- *parentPtr = Tk_WindowId(tkParent);
- }
-}
-#endif
-
-/*
- *----------------------------------------------------------------------
- *
* BusyCustodyProc --
*
* This procedure is invoked when the busy window has been stolen by
@@ -866,7 +574,7 @@ CreateBusy(
Tk_DestroyWindow(tkBusy);
return NULL;
}
- SetWindowInstanceData(tkBusy, (ClientData)busyPtr);
+ SetWindowInstanceData(tkBusy, busyPtr);
winPtr = (Tk_FakeWin *) tkRef;
TkpCreateBusy(winPtr, tkRef, &parent, tkParent, busyPtr);
@@ -888,11 +596,9 @@ CreateBusy(
*/
Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr);
-#ifndef MAC_OSX_TK
if (busyPtr->cursor != None) {
Tk_DefineCursor(tkBusy, busyPtr->cursor);
}
-#endif
/*
* Track the reference window to see if it is resized or destroyed.
@@ -928,7 +634,6 @@ ConfigureBusy(
int objc,
Tcl_Obj *const objv[])
{
-#ifndef MAC_OSX_TK
Tk_Cursor oldCursor = busyPtr->cursor;
if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc,
@@ -942,7 +647,6 @@ ConfigureBusy(
Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor);
}
}
-#endif
return TCL_OK;
}
@@ -1033,7 +737,7 @@ HoldBusy(
}
hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
if (isNew) {
- busyPtr = (Busy *) CreateBusy(interp, tkwin);
+ busyPtr = CreateBusy(interp, tkwin);
if (busyPtr == NULL) {
return TCL_ERROR;
}