📄 tkwindow.c
字号:
/* * tkWindow.c -- * * This file provides basic window-manipulation procedures, * which are equivalent to procedures in Xlib (and even * invoke them) but also maintain the local Tk_Window * structure. * * Copyright (c) 1989-1994 The Regents of the University of California. * Copyright (c) 1994-1997 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: @(#) tkWindow.c 1.233 97/10/31 09:55:23 */#include "tkPort.h"#include "tkInt.h"/* * Count of number of main windows currently open in this process. */static int numMainWindows;/* * First in list of all main windows managed by this process. */TkMainInfo *tkMainWindowList = NULL;/* * List of all displays currently in use. */TkDisplay *tkDisplayList = NULL;/* * Have statics in this module been initialized? */static int initialized = 0;/* * The variables below hold several uid's that are used in many places * in the toolkit. */Tk_Uid tkDisabledUid = NULL;Tk_Uid tkActiveUid = NULL;Tk_Uid tkNormalUid = NULL;/* * Default values for "changes" and "atts" fields of TkWindows. Note * that Tk always requests all events for all windows, except StructureNotify * events on internal windows: these events are generated internally. */static XWindowChanges defChanges = { 0, 0, 1, 1, 0, 0, Above};#define ALL_EVENTS_MASK \ KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask| \ EnterWindowMask|LeaveWindowMask|PointerMotionMask|ExposureMask| \ VisibilityChangeMask|PropertyChangeMask|ColormapChangeMaskstatic XSetWindowAttributes defAtts= { None, /* background_pixmap */ 0, /* background_pixel */ CopyFromParent, /* border_pixmap */ 0, /* border_pixel */ NorthWestGravity, /* bit_gravity */ NorthWestGravity, /* win_gravity */ NotUseful, /* backing_store */ (unsigned) ~0, /* backing_planes */ 0, /* backing_pixel */ False, /* save_under */ ALL_EVENTS_MASK, /* event_mask */ 0, /* do_not_propagate_mask */ False, /* override_redirect */ CopyFromParent, /* colormap */ None /* cursor */};/* * The following structure defines all of the commands supported by * Tk, and the C procedures that execute them. */typedef struct { char *name; /* Name of command. */ Tcl_CmdProc *cmdProc; /* Command's string-based procedure. */ Tcl_ObjCmdProc *objProc; /* Command's object-based procedure. */ int isSafe; /* If !0, this command will be exposed in * a safe interpreter. Otherwise it will be * hidden in a safe interpreter. */} TkCmd;static TkCmd commands[] = { /* * Commands that are part of the intrinsics: */ {"bell", Tk_BellCmd, NULL, 0}, {"bind", Tk_BindCmd, NULL, 1}, {"bindtags", Tk_BindtagsCmd, NULL, 1}, {"clipboard", Tk_ClipboardCmd, NULL, 0}, {"destroy", Tk_DestroyCmd, NULL, 1}, {"event", Tk_EventCmd, NULL, 1}, {"focus", Tk_FocusCmd, NULL, 1}, {"font", NULL, Tk_FontObjCmd, 1}, {"grab", Tk_GrabCmd, NULL, 0}, {"grid", Tk_GridCmd, NULL, 1}, {"image", Tk_ImageCmd, NULL, 1}, {"lower", Tk_LowerCmd, NULL, 1}, {"option", Tk_OptionCmd, NULL, 1}, {"pack", Tk_PackCmd, NULL, 1}, {"place", Tk_PlaceCmd, NULL, 1}, {"raise", Tk_RaiseCmd, NULL, 1}, {"selection", Tk_SelectionCmd, NULL, 0}, {"tk", NULL, Tk_TkObjCmd, 0}, {"tkwait", Tk_TkwaitCmd, NULL, 1}, {"tk_chooseColor", Tk_ChooseColorCmd, NULL, 0}, {"tk_getOpenFile", Tk_GetOpenFileCmd, NULL, 0}, {"tk_getSaveFile", Tk_GetSaveFileCmd, NULL, 0}, {"tk_messageBox", Tk_MessageBoxCmd, NULL, 0}, {"update", Tk_UpdateCmd, NULL, 1}, {"winfo", NULL, Tk_WinfoObjCmd, 1}, {"wm", Tk_WmCmd, NULL, 0}, /* * Widget class commands. */ {"button", Tk_ButtonCmd, NULL, 1}, {"canvas", Tk_CanvasCmd, NULL, 1}, {"checkbutton", Tk_CheckbuttonCmd, NULL, 1}, {"entry", Tk_EntryCmd, NULL, 1}, {"frame", Tk_FrameCmd, NULL, 1}, {"label", Tk_LabelCmd, NULL, 1}, {"listbox", Tk_ListboxCmd, NULL, 1}, {"menu", Tk_MenuCmd, NULL, 0}, {"menubutton", Tk_MenubuttonCmd, NULL, 1}, {"message", Tk_MessageCmd, NULL, 1}, {"radiobutton", Tk_RadiobuttonCmd, NULL, 1}, {"scale", Tk_ScaleCmd, NULL, 1}, {"scrollbar", Tk_ScrollbarCmd, NULL, 1}, {"text", Tk_TextCmd, NULL, 1}, {"toplevel", Tk_ToplevelCmd, NULL, 0}, /* * Misc. */#ifdef MAC_TCL {"unsupported1", TkUnsupported1Cmd, NULL, 1},#endif {(char *) NULL, (int (*) _ANSI_ARGS_((ClientData, Tcl_Interp *, int, char **))) NULL, NULL, 0}}; /* * The variables and table below are used to parse arguments from * the "argv" variable in Tk_Init. */static int synchronize = 0;static char *name = NULL;static char *display = NULL;static char *geometry = NULL;static char *colormap = NULL;static char *use = NULL;static char *visual = NULL;static int rest = 0;static Tk_ArgvInfo argTable[] = { {"-colormap", TK_ARGV_STRING, (char *) NULL, (char *) &colormap, "Colormap for main window"}, {"-display", TK_ARGV_STRING, (char *) NULL, (char *) &display, "Display to use"}, {"-geometry", TK_ARGV_STRING, (char *) NULL, (char *) &geometry, "Initial geometry for window"}, {"-name", TK_ARGV_STRING, (char *) NULL, (char *) &name, "Name to use for application"}, {"-sync", TK_ARGV_CONSTANT, (char *) 1, (char *) &synchronize, "Use synchronous mode for display server"}, {"-visual", TK_ARGV_STRING, (char *) NULL, (char *) &visual, "Visual for main window"}, {"-use", TK_ARGV_STRING, (char *) NULL, (char *) &use, "Id of window in which to embed application"}, {"--", TK_ARGV_REST, (char *) 1, (char *) &rest, "Pass all remaining arguments through to script"}, {(char *) NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, (char *) NULL}};/* * Forward declarations to procedures defined later in this file: */static Tk_Window CreateTopLevelWindow _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window parent, char *name, char *screenName));static void DeleteWindowsExitProc _ANSI_ARGS_(( ClientData clientData));static TkDisplay * GetScreen _ANSI_ARGS_((Tcl_Interp *interp, char *screenName, int *screenPtr));static int Initialize _ANSI_ARGS_((Tcl_Interp *interp));static int NameWindow _ANSI_ARGS_((Tcl_Interp *interp, TkWindow *winPtr, TkWindow *parentPtr, char *name));static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr));static void UnlinkWindow _ANSI_ARGS_((TkWindow *winPtr));/* *---------------------------------------------------------------------- * * CreateTopLevelWindow -- * * Make a new window that will be at top-level (its parent will * be the root window of a screen). * * Results: * The return value is a token for the new window, or NULL if * an error prevented the new window from being created. If * NULL is returned, an error message will be left in * interp->result. * * Side effects: * A new window structure is allocated locally. An X * window is NOT initially created, but will be created * the first time the window is mapped. * *---------------------------------------------------------------------- */static Tk_WindowCreateTopLevelWindow(interp, parent, name, screenName) Tcl_Interp *interp; /* Interpreter to use for error reporting. */ Tk_Window parent; /* Token for logical parent of new window * (used for naming, options, etc.). May * be NULL. */ char *name; /* Name for new window; if parent is * non-NULL, must be unique among parent's * children. */ char *screenName; /* Name of screen on which to create * window. NULL means use DISPLAY environment * variable to determine. Empty string means * use parent's screen, or DISPLAY if no * parent. */{ register TkWindow *winPtr; register TkDisplay *dispPtr; int screenId; if (!initialized) { initialized = 1; tkActiveUid = Tk_GetUid("active"); tkDisabledUid = Tk_GetUid("disabled"); tkNormalUid = Tk_GetUid("normal"); /* * Create built-in image types. */ Tk_CreateImageType(&tkBitmapImageType); Tk_CreateImageType(&tkPhotoImageType); /* * Create built-in photo image formats. */ Tk_CreatePhotoImageFormat(&tkImgFmtGIF); Tk_CreatePhotoImageFormat(&tkImgFmtPPM); /* * Create exit handler to delete all windows when the application * exits. */ Tcl_CreateExitHandler(DeleteWindowsExitProc, (ClientData) NULL); } if ((parent != NULL) && (screenName != NULL) && (screenName[0] == '\0')) { dispPtr = ((TkWindow *) parent)->dispPtr; screenId = Tk_ScreenNumber(parent); } else { dispPtr = GetScreen(interp, screenName, &screenId); if (dispPtr == NULL) { return (Tk_Window) NULL; } } winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent); /* * Force the window to use a border pixel instead of border pixmap. * This is needed for the case where the window doesn't use the * default visual. In this case, the default border is a pixmap * inherited from the root window, which won't work because it will * have the wrong visual. */ winPtr->dirtyAtts |= CWBorderPixel; /* * (Need to set the TK_TOP_LEVEL flag immediately here; otherwise * Tk_DestroyWindow will core dump if it is called before the flag * has been set.) */ winPtr->flags |= TK_TOP_LEVEL; if (parent != NULL) { if (NameWindow(interp, winPtr, (TkWindow *) parent, name) != TCL_OK) { Tk_DestroyWindow((Tk_Window) winPtr); return (Tk_Window) NULL; } } TkWmNewWindow(winPtr); return (Tk_Window) winPtr;}/* *---------------------------------------------------------------------- * * GetScreen -- * * Given a string name for a display-plus-screen, find the * TkDisplay structure for the display and return the screen * number too. * * Results: * The return value is a pointer to information about the display, * or NULL if the display couldn't be opened. In this case, an * error message is left in interp->result. The location at * *screenPtr is overwritten with the screen number parsed from * screenName. * * Side effects: * A new connection is opened to the display if there is no * connection already. A new TkDisplay data structure is also * setup, if necessary. * *---------------------------------------------------------------------- */static TkDisplay *GetScreen(interp, screenName, screenPtr) Tcl_Interp *interp; /* Place to leave error message. */ char *screenName; /* Name for screen. NULL or empty means * use DISPLAY envariable. */ int *screenPtr; /* Where to store screen number. */{ register TkDisplay *dispPtr; char *p; int screenId; size_t length; /* * Separate the screen number from the rest of the display * name. ScreenName is assumed to have the syntax * <display>.<screen> with the dot and the screen being * optional. */ screenName = TkGetDefaultScreenName(interp, screenName); if (screenName == NULL) { interp->result = "no display name and no $DISPLAY environment variable"; return (TkDisplay *) NULL; } length = strlen(screenName); screenId = 0; p = screenName+length-1; while (isdigit(UCHAR(*p)) && (p != screenName)) { p--; } if ((*p == '.') && (p[1] != '\0')) { length = p - screenName; screenId = strtoul(p+1, (char **) NULL, 10); } /* * See if we already have a connection to this display. If not, * then open a new connection. */ for (dispPtr = tkDisplayList; ; dispPtr = dispPtr->nextPtr) { if (dispPtr == NULL) { dispPtr = TkpOpenDisplay(screenName); if (dispPtr == NULL) { Tcl_AppendResult(interp, "couldn't connect to display \"", screenName, "\"", (char *) NULL); return (TkDisplay *) NULL; } dispPtr->nextPtr = tkDisplayList; dispPtr->name = (char *) ckalloc((unsigned) (length+1)); dispPtr->lastEventTime = CurrentTime; strncpy(dispPtr->name, screenName, length); dispPtr->name[length] = '\0'; dispPtr->bindInfoStale = 1; dispPtr->modeModMask = 0; dispPtr->metaModMask = 0; dispPtr->altModMask = 0; dispPtr->numModKeyCodes = 0; dispPtr->modKeyCodes = NULL; OpenIM(dispPtr); dispPtr->errorPtr = NULL; dispPtr->deleteCount = 0; dispPtr->commTkwin = NULL; dispPtr->selectionInfoPtr = NULL; dispPtr->multipleAtom = None; dispPtr->clipWindow = NULL; dispPtr->clipboardActive = 0; dispPtr->clipboardAppPtr = NULL; dispPtr->clipTargetPtr = NULL; dispPtr->atomInit = 0; dispPtr->cursorFont = None; dispPtr->grabWinPtr = NULL; dispPtr->eventualGrabWinPtr = NULL; dispPtr->buttonWinPtr = NULL; dispPtr->serverWinPtr = NULL; dispPtr->firstGrabEventPtr = NULL; dispPtr->lastGrabEventPtr = NULL; dispPtr->grabFlags = 0; TkInitXId(dispPtr); dispPtr->destroyCount = 0; dispPtr->lastDestroyRequest = 0; dispPtr->cmapPtr = NULL; dispPtr->implicitWinPtr = NULL; dispPtr->focusPtr = NULL; dispPtr->stressPtr = NULL; dispPtr->delayedMotionPtr = NULL; Tcl_InitHashTable(&dispPtr->winTable, TCL_ONE_WORD_KEYS); dispPtr->refCount = 0; tkDisplayList = dispPtr; break; } if ((strncmp(dispPtr->name, screenName, length) == 0) && (dispPtr->name[length] == '\0')) { break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -