📄 tkcmds.c
字号:
/* * tkCmds.c -- * * This file contains a collection of Tk-related Tcl commands * that didn't fit in any particular file of the toolkit. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-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: @(#) tkCmds.c 1.125 97/05/20 16:16:33 */#include "tkPort.h"#include "tkInt.h"#include <errno.h>/* * Forward declarations for procedures defined later in this file: */static TkWindow * GetToplevel _ANSI_ARGS_((Tk_Window tkwin));static char * WaitVariableProc _ANSI_ARGS_((ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags));static void WaitVisibilityProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));static void WaitWindowProc _ANSI_ARGS_((ClientData clientData, XEvent *eventPtr));/* *---------------------------------------------------------------------- * * Tk_BellCmd -- * * This procedure is invoked to process the "bell" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intTk_BellCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window tkwin = (Tk_Window) clientData; size_t length; if ((argc != 1) && (argc != 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " ?-displayof window?\"", (char *) NULL); return TCL_ERROR; } if (argc == 3) { length = strlen(argv[1]); if ((length < 2) || (strncmp(argv[1], "-displayof", length) != 0)) { Tcl_AppendResult(interp, "bad option \"", argv[1], "\": must be -displayof", (char *) NULL); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, argv[2], tkwin); if (tkwin == NULL) { return TCL_ERROR; } } XBell(Tk_Display(tkwin), 0); XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset); XFlush(Tk_Display(tkwin)); return TCL_OK;}/* *---------------------------------------------------------------------- * * Tk_BindCmd -- * * This procedure is invoked to process the "bind" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intTk_BindCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window tkwin = (Tk_Window) clientData; TkWindow *winPtr; ClientData object; if ((argc < 2) || (argc > 4)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " window ?pattern? ?command?\"", (char *) NULL); return TCL_ERROR; } if (argv[1][0] == '.') { winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin); if (winPtr == NULL) { return TCL_ERROR; } object = (ClientData) winPtr->pathName; } else { winPtr = (TkWindow *) clientData; object = (ClientData) Tk_GetUid(argv[1]); } if (argc == 4) { int append = 0; unsigned long mask; if (argv[3][0] == 0) { return Tk_DeleteBinding(interp, winPtr->mainPtr->bindingTable, object, argv[2]); } if (argv[3][0] == '+') { argv[3]++; append = 1; } mask = Tk_CreateBinding(interp, winPtr->mainPtr->bindingTable, object, argv[2], argv[3], append); if (mask == 0) { return TCL_ERROR; } } else if (argc == 3) { char *command; command = Tk_GetBinding(interp, winPtr->mainPtr->bindingTable, object, argv[2]); if (command == NULL) { Tcl_ResetResult(interp); return TCL_OK; } interp->result = command; } else { Tk_GetAllBindings(interp, winPtr->mainPtr->bindingTable, object); } return TCL_OK;}/* *---------------------------------------------------------------------- * * TkBindEventProc -- * * This procedure is invoked by Tk_HandleEvent for each event; it * causes any appropriate bindings for that event to be invoked. * * Results: * None. * * Side effects: * Depends on what bindings have been established with the "bind" * command. * *---------------------------------------------------------------------- */voidTkBindEventProc(winPtr, eventPtr) TkWindow *winPtr; /* Pointer to info about window. */ XEvent *eventPtr; /* Information about event. */{#define MAX_OBJS 20 ClientData objects[MAX_OBJS], *objPtr; static Tk_Uid allUid = NULL; TkWindow *topLevPtr; int i, count; char *p; Tcl_HashEntry *hPtr; if ((winPtr->mainPtr == NULL) || (winPtr->mainPtr->bindingTable == NULL)) { return; } objPtr = objects; if (winPtr->numTags != 0) { /* * Make a copy of the tags for the window, replacing window names * with pointers to the pathName from the appropriate window. */ if (winPtr->numTags > MAX_OBJS) { objPtr = (ClientData *) ckalloc((unsigned) (winPtr->numTags * sizeof(ClientData))); } for (i = 0; i < winPtr->numTags; i++) { p = (char *) winPtr->tagPtr[i]; if (*p == '.') { hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->nameTable, p); if (hPtr != NULL) { p = ((TkWindow *) Tcl_GetHashValue(hPtr))->pathName; } else { p = NULL; } } objPtr[i] = (ClientData) p; } count = winPtr->numTags; } else { objPtr[0] = (ClientData) winPtr->pathName; objPtr[1] = (ClientData) winPtr->classUid; for (topLevPtr = winPtr; (topLevPtr != NULL) && !(topLevPtr->flags & TK_TOP_LEVEL); topLevPtr = topLevPtr->parentPtr) { /* Empty loop body. */ } if ((winPtr != topLevPtr) && (topLevPtr != NULL)) { count = 4; objPtr[2] = (ClientData) topLevPtr->pathName; } else { count = 3; } if (allUid == NULL) { allUid = Tk_GetUid("all"); } objPtr[count-1] = (ClientData) allUid; } Tk_BindEvent(winPtr->mainPtr->bindingTable, eventPtr, (Tk_Window) winPtr, count, objPtr); if (objPtr != objects) { ckfree((char *) objPtr); }}/* *---------------------------------------------------------------------- * * Tk_BindtagsCmd -- * * This procedure is invoked to process the "bindtags" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intTk_BindtagsCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window tkwin = (Tk_Window) clientData; TkWindow *winPtr, *winPtr2; int i, tagArgc; char *p, **tagArgv; if ((argc < 2) || (argc > 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " window ?tags?\"", (char *) NULL); return TCL_ERROR; } winPtr = (TkWindow *) Tk_NameToWindow(interp, argv[1], tkwin); if (winPtr == NULL) { return TCL_ERROR; } if (argc == 2) { if (winPtr->numTags == 0) { Tcl_AppendElement(interp, winPtr->pathName); Tcl_AppendElement(interp, winPtr->classUid); for (winPtr2 = winPtr; (winPtr2 != NULL) && !(winPtr2->flags & TK_TOP_LEVEL); winPtr2 = winPtr2->parentPtr) { /* Empty loop body. */ } if ((winPtr != winPtr2) && (winPtr2 != NULL)) { Tcl_AppendElement(interp, winPtr2->pathName); } Tcl_AppendElement(interp, "all"); } else { for (i = 0; i < winPtr->numTags; i++) { Tcl_AppendElement(interp, (char *) winPtr->tagPtr[i]); } } return TCL_OK; } if (winPtr->tagPtr != NULL) { TkFreeBindingTags(winPtr); } if (argv[2][0] == 0) { return TCL_OK; } if (Tcl_SplitList(interp, argv[2], &tagArgc, &tagArgv) != TCL_OK) { return TCL_ERROR; } winPtr->numTags = tagArgc; winPtr->tagPtr = (ClientData *) ckalloc((unsigned) (tagArgc * sizeof(ClientData))); for (i = 0; i < tagArgc; i++) { p = tagArgv[i]; if (p[0] == '.') { char *copy; /* * Handle names starting with "." specially: store a malloc'ed * string, rather than a Uid; at event time we'll look up the * name in the window table and use the corresponding window, * if there is one. */ copy = (char *) ckalloc((unsigned) (strlen(p) + 1)); strcpy(copy, p); winPtr->tagPtr[i] = (ClientData) copy; } else { winPtr->tagPtr[i] = (ClientData) Tk_GetUid(p); } } ckfree((char *) tagArgv); return TCL_OK;}/* *---------------------------------------------------------------------- * * TkFreeBindingTags -- * * This procedure is called to free all of the binding tags * associated with a window; typically it is only invoked where * there are window-specific tags. * * Results: * None. * * Side effects: * Any binding tags for winPtr are freed. * *---------------------------------------------------------------------- */voidTkFreeBindingTags(winPtr) TkWindow *winPtr; /* Window whose tags are to be released. */{ int i; char *p; for (i = 0; i < winPtr->numTags; i++) { p = (char *) (winPtr->tagPtr[i]); if (*p == '.') { /* * Names starting with "." are malloced rather than Uids, so * they have to be freed. */ ckfree(p); } } ckfree((char *) winPtr->tagPtr); winPtr->numTags = 0; winPtr->tagPtr = NULL;}/* *---------------------------------------------------------------------- * * Tk_DestroyCmd -- * * This procedure is invoked to process the "destroy" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */intTk_DestroyCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window window; Tk_Window tkwin = (Tk_Window) clientData; int i; for (i = 1; i < argc; i++) { window = Tk_NameToWindow(interp, argv[i], tkwin); if (window == NULL) { Tcl_ResetResult(interp); continue; } Tk_DestroyWindow(window); if (window == tkwin) { /* * We just deleted the main window for the application! This * makes it impossible to do anything more (tkwin isn't * valid anymore). */ break; } } return TCL_OK;}/* *---------------------------------------------------------------------- * * Tk_LowerCmd -- * * This procedure is invoked to process the "lower" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */intTk_LowerCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window mainwin = (Tk_Window) clientData; Tk_Window tkwin, other; if ((argc != 2) && (argc != 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " window ?belowThis?\"", (char *) NULL); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, argv[1], mainwin); if (tkwin == NULL) { return TCL_ERROR; } if (argc == 2) { other = NULL; } else { other = Tk_NameToWindow(interp, argv[2], mainwin); if (other == NULL) { return TCL_ERROR; } } if (Tk_RestackWindow(tkwin, Below, other) != TCL_OK) { Tcl_AppendResult(interp, "can't lower \"", argv[1], "\" below \"", argv[2], "\"", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * Tk_RaiseCmd -- * * This procedure is invoked to process the "raise" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. * *---------------------------------------------------------------------- */ /* ARGSUSED */intTk_RaiseCmd(clientData, interp, argc, argv) ClientData clientData; /* Main window associated with * interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int argc; /* Number of arguments. */ char **argv; /* Argument strings. */{ Tk_Window mainwin = (Tk_Window) clientData; Tk_Window tkwin, other; if ((argc != 2) && (argc != 3)) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " window ?aboveThis?\"", (char *) NULL); return TCL_ERROR; } tkwin = Tk_NameToWindow(interp, argv[1], mainwin); if (tkwin == NULL) { return TCL_ERROR; } if (argc == 2) { other = NULL; } else { other = Tk_NameToWindow(interp, argv[2], mainwin); if (other == NULL) { return TCL_ERROR; } } if (Tk_RestackWindow(tkwin, Above, other) != TCL_OK) { Tcl_AppendResult(interp, "can't raise \"", argv[1], "\" above \"", argv[2], "\"", (char *) NULL); return TCL_ERROR; } return TCL_OK;}/* *---------------------------------------------------------------------- * * Tk_TkObjCmd -- * * This procedure is invoked to process the "tk" Tcl command. * See the user documentation for details on what it does. * * Results: * A standard Tcl result. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -