diff options
author | William Joye <wjoye@cfa.harvard.edu> | 2017-10-17 19:50:58 (GMT) |
---|---|---|
committer | William Joye <wjoye@cfa.harvard.edu> | 2017-10-17 19:50:58 (GMT) |
commit | 9b7a6c3507ea3383c60aaecb29f873c9b590ccca (patch) | |
tree | 82ce31ebd8f46803d969034f5aa3db8d7974493c /tk8.6/generic/tkBusy.c | |
parent | 87fca7325b97005eb44dcf3e198277640af66115 (diff) | |
download | blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.zip blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.tar.gz blt-9b7a6c3507ea3383c60aaecb29f873c9b590ccca.tar.bz2 |
rm tcl/tk 8.6.7
Diffstat (limited to 'tk8.6/generic/tkBusy.c')
-rw-r--r-- | tk8.6/generic/tkBusy.c | 932 |
1 files changed, 0 insertions, 932 deletions
diff --git a/tk8.6/generic/tkBusy.c b/tk8.6/generic/tkBusy.c deleted file mode 100644 index b36d453..0000000 --- a/tk8.6/generic/tkBusy.c +++ /dev/null @@ -1,932 +0,0 @@ -/* - * tkBusy.c -- - * - * This file provides functions that implement busy for Tk. - * - * Copyright 1993-1998 Lucent Technologies, Inc. - * - * The "busy" command was created by George Howlett. Adapted for - * integration into Tk by Jos Decoster and Donal K. Fellows. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tkInt.h" -#include "tkBusy.h" -#include "default.h" - -/* - * Things about the busy system that may be configured. Note that currently on - * OSX/Aqua, that's nothing at all. - */ - -static const 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, 0} -}; - -/* - * Forward declarations of functions defined in this file. - */ - -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(void *dataPtr); -static void DoConfigureNotify(Tk_FakeWin *winPtr); -static inline Tk_Window FirstChild(Tk_Window parent); -static Busy * GetBusy(Tcl_Interp *interp, - Tcl_HashTable *busyTablePtr, - Tcl_Obj *const windowObj); -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. - */ - -static Tk_GeomMgr busyMgrInfo = { - "busy", /* Name of geometry manager used by winfo */ - BusyGeometryProc, /* Procedure to for new geometry requests */ - BusyCustodyProc, /* Procedure when window is taken away */ -}; - -/* - * Helper functions, need to check if a Tcl/Tk alternative already exists. - */ - -static inline Tk_Window -FirstChild( - Tk_Window parent) -{ - struct TkWindow *parentPtr = (struct TkWindow *) parent; - - return (Tk_Window) parentPtr->childList; -} - -static inline Tk_Window -NextChild( - Tk_Window tkwin) -{ - struct TkWindow *winPtr = (struct TkWindow *) tkwin; - - if (winPtr == NULL) { - return NULL; - } - return (Tk_Window) winPtr->nextPtr; -} - -static inline void -SetWindowInstanceData( - Tk_Window tkwin, - ClientData instanceData) -{ - struct TkWindow *winPtr = (struct TkWindow *) tkwin; - - winPtr->instanceData = instanceData; -} - -/* - *---------------------------------------------------------------------- - * - * BusyCustodyProc -- - * - * This procedure is invoked when the busy window has been stolen by - * another geometry manager. The information and memory associated with - * the busy window is released. I don't know why anyone would try to pack - * a busy window, but this should keep everything sane, if it is. - * - * Results: - * None. - * - * Side effects: - * The Busy structure is freed at the next idle point. - * - *---------------------------------------------------------------------- - */ - -/* ARGSUSED */ -static void -BusyCustodyProc( - ClientData clientData, /* Information about the busy window. */ - Tk_Window tkwin) /* Not used. */ -{ - Busy *busyPtr = clientData; - - Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc, - busyPtr); - TkpHideBusyWindow(busyPtr); - busyPtr->tkBusy = NULL; - Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); -} - -/* - *---------------------------------------------------------------------- - * - * BusyGeometryProc -- - * - * This procedure is invoked by Tk_GeometryRequest for busy windows. - * Busy windows never request geometry, so it's unlikely that this - * function will ever be called;it exists simply as a place holder for - * the GeomProc in the Geometry Manager structure. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -/* ARGSUSED */ -static void -BusyGeometryProc( - ClientData clientData, /* Information about window that got new - * preferred geometry. */ - Tk_Window tkwin) /* Other Tk-related information about the - * window. */ -{ - /* Should never get here */ -} - -/* - *---------------------------------------------------------------------- - * - * DoConfigureNotify -- - * - * Generate a ConfigureNotify event describing the current configuration - * of a window. - * - * Results: - * None. - * - * Side effects: - * An event is generated and processed by Tk_HandleEvent. - * - *---------------------------------------------------------------------- - */ - -static void -DoConfigureNotify( - Tk_FakeWin *winPtr) /* Window whose configuration was just - * changed. */ -{ - XEvent event; - - event.type = ConfigureNotify; - event.xconfigure.serial = LastKnownRequestProcessed(winPtr->display); - event.xconfigure.send_event = False; - event.xconfigure.display = winPtr->display; - event.xconfigure.event = winPtr->window; - event.xconfigure.window = winPtr->window; - event.xconfigure.x = winPtr->changes.x; - event.xconfigure.y = winPtr->changes.y; - event.xconfigure.width = winPtr->changes.width; - event.xconfigure.height = winPtr->changes.height; - event.xconfigure.border_width = winPtr->changes.border_width; - if (winPtr->changes.stack_mode == Above) { - event.xconfigure.above = winPtr->changes.sibling; - } else { - event.xconfigure.above = None; - } - event.xconfigure.override_redirect = winPtr->atts.override_redirect; - Tk_HandleEvent(&event); -} - -/* - *---------------------------------------------------------------------- - * - * RefWinEventProc -- - * - * This procedure is invoked by the Tk dispatcher for the following - * events on the reference window. If the reference and parent windows - * are the same, only the first event is important. - * - * 1) ConfigureNotify The reference window has been resized or - * moved. Move and resize the busy window to be - * the same size and position of the reference - * window. - * - * 2) DestroyNotify The reference window was destroyed. Destroy - * the busy window and the free resources used. - * - * 3) MapNotify The reference window was (re)shown. Map the - * busy window again. - * - * 4) UnmapNotify The reference window was hidden. Unmap the - * busy window. - * - * Results: - * None. - * - * Side effects: - * When the reference window gets deleted, internal structures get - * cleaned up. When it gets resized, the busy window is resized - * accordingly. If it's displayed, the busy window is displayed. And when - * it's hidden, the busy window is unmapped. - * - *---------------------------------------------------------------------- - */ - -static void -RefWinEventProc( - ClientData clientData, /* Busy window record */ - register XEvent *eventPtr) /* Event which triggered call to routine */ -{ - register Busy *busyPtr = clientData; - - switch (eventPtr->type) { - case ReparentNotify: - case DestroyNotify: - /* - * Arrange for the busy structure to be removed at a proper time. - */ - - Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); - break; - - case ConfigureNotify: - if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) || - (busyPtr->height != Tk_Height(busyPtr->tkRef)) || - (busyPtr->x != Tk_X(busyPtr->tkRef)) || - (busyPtr->y != Tk_Y(busyPtr->tkRef))) { - int x, y; - - busyPtr->width = Tk_Width(busyPtr->tkRef); - busyPtr->height = Tk_Height(busyPtr->tkRef); - busyPtr->x = Tk_X(busyPtr->tkRef); - busyPtr->y = Tk_Y(busyPtr->tkRef); - - x = y = 0; - - if (busyPtr->tkParent != busyPtr->tkRef) { - Tk_Window tkwin; - - for (tkwin = busyPtr->tkRef; (tkwin != NULL) && - (!Tk_IsTopLevel(tkwin)); tkwin = Tk_Parent(tkwin)) { - if (tkwin == busyPtr->tkParent) { - break; - } - x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; - y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; - } - } - if (busyPtr->tkBusy != NULL) { - Tk_MoveResizeWindow(busyPtr->tkBusy, x, y, busyPtr->width, - busyPtr->height); - TkpShowBusyWindow(busyPtr); - } - } - break; - - case MapNotify: - if (busyPtr->tkParent != busyPtr->tkRef) { - TkpShowBusyWindow(busyPtr); - } - break; - - case UnmapNotify: - if (busyPtr->tkParent != busyPtr->tkRef) { - TkpHideBusyWindow(busyPtr); - } - break; - } -} - -/* - *---------------------------------------------------------------------- - * - * DestroyBusy -- - * - * This procedure is called from the Tk event dispatcher. It releases X - * resources and memory used by the busy window and updates the internal - * hash table. - * - * Results: - * None. - * - * Side effects: - * Memory and resources are released and the Tk event handler is removed. - * - *---------------------------------------------------------------------- - */ - -static void -DestroyBusy( - void *data) /* Busy window structure record */ -{ - register Busy *busyPtr = data; - - if (busyPtr->hashPtr != NULL) { - Tcl_DeleteHashEntry(busyPtr->hashPtr); - } - Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask, - RefWinEventProc, busyPtr); - - if (busyPtr->tkBusy != NULL) { - Tk_FreeConfigOptions(data, busyPtr->optionTable, busyPtr->tkBusy); - Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, - BusyEventProc, busyPtr); - Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr); - Tk_DestroyWindow(busyPtr->tkBusy); - } - ckfree(data); -} - -/* - *---------------------------------------------------------------------- - * - * BusyEventProc -- - * - * This procedure is invoked by the Tk dispatcher for events on the busy - * window itself. We're only concerned with destroy events. - * - * It might be necessary (someday) to watch resize events. Right now, I - * don't think there's any point in it. - * - * Results: - * None. - * - * Side effects: - * When a busy window is destroyed, all internal structures associated - * with it released at the next idle point. - * - *---------------------------------------------------------------------- - */ - -static void -BusyEventProc( - ClientData clientData, /* Busy window record */ - XEvent *eventPtr) /* Event which triggered call to routine */ -{ - Busy *busyPtr = clientData; - - if (eventPtr->type == DestroyNotify) { - busyPtr->tkBusy = NULL; - Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); - } -} - -/* - *---------------------------------------------------------------------- - * - * MakeTransparentWindowExist -- - * - * Similar to Tk_MakeWindowExist but instead creates a transparent window - * to block for user events from sibling windows. - * - * Differences from Tk_MakeWindowExist. - * - * 1. This is always a "busy" window. There's never a platform-specific - * class procedure to execute instead. - * 2. The window is transparent and never will contain children, so - * colormap information is irrelevant. - * - * Results: - * None. - * - * Side effects: - * When the procedure returns, the internal window associated with tkwin - * is guaranteed to exist. This may require the window's ancestors to be - * created too. - * - *---------------------------------------------------------------------- - */ - -static void -MakeTransparentWindowExist( - Tk_Window tkwin, /* Token for window. */ - Window parent) /* Parent window. */ -{ - TkWindow *winPtr = (TkWindow *) tkwin; - Tcl_HashEntry *hPtr; - int notUsed; - TkDisplay *dispPtr; - - if (winPtr->window != None) { - return; /* Window already exists. */ - } - - /* - * Create a transparent window and put it on top. - */ - - TkpMakeTransparentWindowExist(tkwin, parent); - - if (winPtr->window == None) { - return; /* Platform didn't make Window. */ - } - - dispPtr = winPtr->dispPtr; - hPtr = Tcl_CreateHashEntry(&dispPtr->winTable, (char *) winPtr->window, - ¬Used); - Tcl_SetHashValue(hPtr, winPtr); - winPtr->dirtyAtts = 0; - winPtr->dirtyChanges = 0; - - if (!(winPtr->flags & TK_TOP_HIERARCHY)) { - TkWindow *winPtr2; - - /* - * If any siblings higher up in the stacking order have already been - * created then move this window to its rightful position in the - * stacking order. - * - * NOTE: this code ignores any changes anyone might have made to the - * sibling and stack_mode field of the window's attributes, so it - * really isn't safe for these to be manipulated except by calling - * Tk_RestackWindow. - */ - - for (winPtr2 = winPtr->nextPtr; winPtr2 != NULL; - winPtr2 = winPtr2->nextPtr) { - if ((winPtr2->window != None) && - !(winPtr2->flags & (TK_TOP_HIERARCHY|TK_REPARENTED))) { - XWindowChanges changes; - - changes.sibling = winPtr2->window; - changes.stack_mode = Below; - XConfigureWindow(winPtr->display, winPtr->window, - CWSibling | CWStackMode, &changes); - break; - } - } - } - - /* - * Issue a ConfigureNotify event if there were deferred configuration - * changes (but skip it if the window is being deleted; the - * ConfigureNotify event could cause problems if we're being called from - * Tk_DestroyWindow under some conditions). - */ - - if ((winPtr->flags & TK_NEED_CONFIG_NOTIFY) - && !(winPtr->flags & TK_ALREADY_DEAD)) { - winPtr->flags &= ~TK_NEED_CONFIG_NOTIFY; - DoConfigureNotify((Tk_FakeWin *) tkwin); - } -} - -/* - *---------------------------------------------------------------------- - * - * CreateBusy -- - * - * Creates a child transparent window that obscures its parent window - * thereby effectively blocking device events. The size and position of - * the busy window is exactly that of the reference window. - * - * We want to create sibling to the window to be blocked. If the busy - * window is a child of the window to be blocked, Enter/Leave events can - * sneak through. Futhermore under WIN32, messages of transparent windows - * are sent directly to the parent. The only exception to this are - * toplevels, since we can't make a sibling. Fortunately, toplevel - * windows rarely receive events that need blocking. - * - * Results: - * Returns a pointer to the new busy window structure. - * - * Side effects: - * When the busy window is eventually displayed, it will screen device - * events (in the area of the reference window) from reaching its parent - * window and its children. User feed back can be achieved by changing - * the cursor. - * - *---------------------------------------------------------------------- - */ - -static Busy * -CreateBusy( - Tcl_Interp *interp, /* Interpreter to report error to */ - Tk_Window tkRef) /* Window hosting the busy window */ -{ - Busy *busyPtr; - int length, x, y; - const char *fmt; - char *name; - Tk_Window tkBusy, tkChild, tkParent; - Window parent; - Tk_FakeWin *winPtr; - - busyPtr = ckalloc(sizeof(Busy)); - x = y = 0; - length = strlen(Tk_Name(tkRef)); - name = ckalloc(length + 6); - if (Tk_IsTopLevel(tkRef)) { - fmt = "_Busy"; /* Child */ - tkParent = tkRef; - } else { - Tk_Window tkwin; - - fmt = "%s_Busy"; /* Sibling */ - tkParent = Tk_Parent(tkRef); - for (tkwin = tkRef; (tkwin != NULL) && !Tk_IsTopLevel(tkwin); - tkwin = Tk_Parent(tkwin)) { - if (tkwin == tkParent) { - break; - } - x += Tk_X(tkwin) + Tk_Changes(tkwin)->border_width; - y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width; - } - } - for (tkChild = FirstChild(tkParent); tkChild != NULL; - tkChild = NextChild(tkChild)) { - Tk_MakeWindowExist(tkChild); - } - sprintf(name, fmt, Tk_Name(tkRef)); - tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL); - ckfree(name); - - if (tkBusy == NULL) { - return NULL; - } - Tk_MakeWindowExist(tkRef); - busyPtr->display = Tk_Display(tkRef); - busyPtr->interp = interp; - busyPtr->tkRef = tkRef; - busyPtr->tkParent = tkParent; - busyPtr->tkBusy = tkBusy; - busyPtr->width = Tk_Width(tkRef); - busyPtr->height = Tk_Height(tkRef); - busyPtr->x = Tk_X(tkRef); - busyPtr->y = Tk_Y(tkRef); - busyPtr->cursor = None; - Tk_SetClass(tkBusy, "Busy"); - busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs); - if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable, - tkBusy) != TCL_OK) { - Tk_DestroyWindow(tkBusy); - return NULL; - } - SetWindowInstanceData(tkBusy, busyPtr); - winPtr = (Tk_FakeWin *) tkRef; - - TkpCreateBusy(winPtr, tkRef, &parent, tkParent, busyPtr); - - MakeTransparentWindowExist(tkBusy, parent); - - Tk_MoveResizeWindow(tkBusy, x, y, busyPtr->width, busyPtr->height); - - /* - * Only worry if the busy window is destroyed. - */ - - Tk_CreateEventHandler(tkBusy, StructureNotifyMask, BusyEventProc, - busyPtr); - - /* - * Indicate that the busy window's geometry is being managed. This will - * also notify us if the busy window is ever packed. - */ - - Tk_ManageGeometry(tkBusy, &busyMgrInfo, busyPtr); - if (busyPtr->cursor != None) { - Tk_DefineCursor(tkBusy, busyPtr->cursor); - } - - /* - * Track the reference window to see if it is resized or destroyed. - */ - - Tk_CreateEventHandler(tkRef, StructureNotifyMask, RefWinEventProc, - busyPtr); - return busyPtr; -} - -/* - *---------------------------------------------------------------------- - * - * ConfigureBusy -- - * - * This procedure is called from the Tk event dispatcher. It releases X - * resources and memory used by the busy window and updates the internal - * hash table. - * - * Results: - * None. - * - * Side effects: - * Memory and resources are released and the Tk event handler is removed. - * - *---------------------------------------------------------------------- - */ - -static int -ConfigureBusy( - Tcl_Interp *interp, - Busy *busyPtr, - int objc, - Tcl_Obj *const objv[]) -{ - Tk_Cursor oldCursor = busyPtr->cursor; - - if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc, - objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) { - return TCL_ERROR; - } - if (busyPtr->cursor != oldCursor) { - if (busyPtr->cursor == None) { - Tk_UndefineCursor(busyPtr->tkBusy); - } else { - Tk_DefineCursor(busyPtr->tkBusy, busyPtr->cursor); - } - } - - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * - * GetBusy -- - * - * Returns the busy window structure associated with the reference - * window, keyed by its path name. The clientData argument is the main - * window of the interpreter, used to search for the reference window in - * its own window hierarchy. - * - * Results: - * If path name represents a reference window with a busy window, a - * pointer to the busy window structure is returned. Otherwise, NULL is - * returned and an error message is left in interp->result. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static Busy * -GetBusy( - Tcl_Interp *interp, /* Interpreter to look up main window of. */ - Tcl_HashTable *busyTablePtr,/* Busy hash table */ - Tcl_Obj *const windowObj) /* Path name of parent window */ -{ - Tcl_HashEntry *hPtr; - Tk_Window tkwin; - - if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj, - &tkwin) != TCL_OK) { - return NULL; - } - hPtr = Tcl_FindHashEntry(busyTablePtr, (char *) tkwin); - if (hPtr == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't find busy window \"%s\"", Tcl_GetString(windowObj))); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY", - Tcl_GetString(windowObj), NULL); - return NULL; - } - return Tcl_GetHashValue(hPtr); -} - -/* - *---------------------------------------------------------------------- - * - * HoldBusy -- - * - * Creates (if necessary) and maps a busy window, thereby preventing - * device events from being be received by the parent window and its - * children. - * - * Results: - * Returns a standard TCL result. If path name represents a busy window, - * it is unmapped and TCL_OK is returned. Otherwise, TCL_ERROR is - * returned and an error message is left in interp->result. - * - * Side effects: - * The busy window is created and displayed, blocking events from the - * parent window and its children. - * - *---------------------------------------------------------------------- - */ - -static int -HoldBusy( - Tcl_HashTable *busyTablePtr,/* Busy hash table. */ - Tcl_Interp *interp, /* Interpreter to report errors to. */ - Tcl_Obj *const windowObj, /* Window name. */ - int configObjc, /* Option pairs. */ - Tcl_Obj *const configObjv[]) -{ - Tk_Window tkwin; - Tcl_HashEntry *hPtr; - Busy *busyPtr; - int isNew, result; - - if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj, - &tkwin) != TCL_OK) { - return TCL_ERROR; - } - hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew); - if (isNew) { - busyPtr = CreateBusy(interp, tkwin); - if (busyPtr == NULL) { - return TCL_ERROR; - } - Tcl_SetHashValue(hPtr, busyPtr); - busyPtr->hashPtr = hPtr; - } else { - busyPtr = Tcl_GetHashValue(hPtr); - } - - busyPtr->tablePtr = busyTablePtr; - result = ConfigureBusy(interp, busyPtr, configObjc, configObjv); - - /* - * Don't map the busy window unless the reference window is also currently - * displayed. - */ - - if (Tk_IsMapped(busyPtr->tkRef)) { - TkpShowBusyWindow(busyPtr); - } else { - TkpHideBusyWindow(busyPtr); - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_BusyObjCmd -- - * - * This function is invoked to process the "tk busy" Tcl command. See the - * user documentation for details on what it does. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -int -Tk_BusyObjCmd( - ClientData clientData, /* Main window associated with interpreter. */ - Tcl_Interp *interp, /* Current interpreter. */ - int objc, /* Number of arguments. */ - Tcl_Obj *const objv[]) /* Argument objects. */ -{ - Tk_Window tkwin = clientData; - Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable; - Busy *busyPtr; - Tcl_Obj *objPtr; - int index, result = TCL_OK; - static const char *const optionStrings[] = { - "cget", "configure", "current", "forget", "hold", "status", NULL - }; - enum options { - BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD, - BUSY_STATUS - }; - - if (objc < 2) { - Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?"); - return TCL_ERROR; - } - - /* - * [tk busy <window>] command shortcut. - */ - - if (Tcl_GetString(objv[1])[0] == '.') { - if (objc%2 == 1) { - Tcl_WrongNumArgs(interp, 1, objv, "window ?option value ...?"); - return TCL_ERROR; - } - return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2); - } - - if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, - sizeof(char *), "option", 0, &index) != TCL_OK) { - return TCL_ERROR; - } - switch ((enum options) index) { - case BUSY_CGET: - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window option"); - return TCL_ERROR; - } - busyPtr = GetBusy(interp, busyTablePtr, objv[2]); - if (busyPtr == NULL) { - return TCL_ERROR; - } - Tcl_Preserve(busyPtr); - objPtr = Tk_GetOptionValue(interp, (char *) busyPtr, - busyPtr->optionTable, objv[3], busyPtr->tkBusy); - if (objPtr == NULL) { - result = TCL_ERROR; - } else { - Tcl_SetObjResult(interp, objPtr); - } - Tcl_Release(busyPtr); - return result; - - case BUSY_CONFIGURE: - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?option? ?value ...?"); - return TCL_ERROR; - } - busyPtr = GetBusy(interp, busyTablePtr, objv[2]); - if (busyPtr == NULL) { - return TCL_ERROR; - } - Tcl_Preserve(busyPtr); - if (objc <= 4) { - objPtr = Tk_GetOptionInfo(interp, (char *) busyPtr, - busyPtr->optionTable, (objc == 4) ? objv[3] : NULL, - busyPtr->tkBusy); - if (objPtr == NULL) { - result = TCL_ERROR; - } else { - Tcl_SetObjResult(interp, objPtr); - } - } else { - result = ConfigureBusy(interp, busyPtr, objc-3, objv+3); - } - Tcl_Release(busyPtr); - return result; - - case BUSY_CURRENT: { - Tcl_HashEntry *hPtr; - Tcl_HashSearch cursor; - const char *pattern = (objc == 3 ? Tcl_GetString(objv[2]) : NULL); - - objPtr = Tcl_NewObj(); - for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL; - hPtr = Tcl_NextHashEntry(&cursor)) { - busyPtr = Tcl_GetHashValue(hPtr); - if (pattern == NULL || - Tcl_StringMatch(Tk_PathName(busyPtr->tkRef), pattern)) { - Tcl_ListObjAppendElement(interp, objPtr, - TkNewWindowObj(busyPtr->tkRef)); - } - } - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } - - case BUSY_FORGET: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - busyPtr = GetBusy(interp, busyTablePtr, objv[2]); - if (busyPtr == NULL) { - return TCL_ERROR; - } - TkpHideBusyWindow(busyPtr); - Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy); - return TCL_OK; - - case BUSY_HOLD: - if (objc < 3 || objc%2 != 1) { - Tcl_WrongNumArgs(interp, 2, objv, "window ?option value ...?"); - return TCL_ERROR; - } - return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3); - - case BUSY_STATUS: - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "window"); - return TCL_ERROR; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - GetBusy(interp, busyTablePtr, objv[2]) != NULL)); - return TCL_OK; - } - - Tcl_Panic("unhandled option: %d", index); - return TCL_ERROR; /* Unreachable */ -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ |