📄 tkbind.c
字号:
{"Lock", LockMask, 0}, {"Meta", META_MASK, 0}, {"M", META_MASK, 0}, {"Alt", ALT_MASK, 0}, {"B1", Button1Mask, 0}, {"Button1", Button1Mask, 0}, {"B2", Button2Mask, 0}, {"Button2", Button2Mask, 0}, {"B3", Button3Mask, 0}, {"Button3", Button3Mask, 0}, {"B4", Button4Mask, 0}, {"Button4", Button4Mask, 0}, {"B5", Button5Mask, 0}, {"Button5", Button5Mask, 0}, {"Mod1", Mod1Mask, 0}, {"M1", Mod1Mask, 0}, {"Command", Mod1Mask, 0}, {"Mod2", Mod2Mask, 0}, {"M2", Mod2Mask, 0}, {"Option", Mod2Mask, 0}, {"Mod3", Mod3Mask, 0}, {"M3", Mod3Mask, 0}, {"Mod4", Mod4Mask, 0}, {"M4", Mod4Mask, 0}, {"Mod5", Mod5Mask, 0}, {"M5", Mod5Mask, 0}, {"Double", 0, DOUBLE}, {"Triple", 0, TRIPLE}, {"Any", 0, 0}, /* Ignored: historical relic. */ {NULL, 0, 0}};static Tcl_HashTable modTable;/* * This module also keeps a hash table mapping from event names * to information about those events. The structure, an array * to use to initialize the hash table, and the hash table are * all defined below. */typedef struct { char *name; /* Name of event. */ int type; /* Event type for X, such as * ButtonPress. */ int eventMask; /* Mask bits (for XSelectInput) * for this event type. */} EventInfo;/* * Note: some of the masks below are an OR-ed combination of * several masks. This is necessary because X doesn't report * up events unless you also ask for down events. Also, X * doesn't report button state in motion events unless you've * asked about button events. */static EventInfo eventArray[] = { {"Key", KeyPress, KeyPressMask}, {"KeyPress", KeyPress, KeyPressMask}, {"KeyRelease", KeyRelease, KeyPressMask|KeyReleaseMask}, {"Button", ButtonPress, ButtonPressMask}, {"ButtonPress", ButtonPress, ButtonPressMask}, {"ButtonRelease", ButtonRelease, ButtonPressMask|ButtonReleaseMask}, {"Motion", MotionNotify, ButtonPressMask|PointerMotionMask}, {"Enter", EnterNotify, EnterWindowMask}, {"Leave", LeaveNotify, LeaveWindowMask}, {"FocusIn", FocusIn, FocusChangeMask}, {"FocusOut", FocusOut, FocusChangeMask}, {"Expose", Expose, ExposureMask}, {"Visibility", VisibilityNotify, VisibilityChangeMask}, {"Destroy", DestroyNotify, StructureNotifyMask}, {"Unmap", UnmapNotify, StructureNotifyMask}, {"Map", MapNotify, StructureNotifyMask}, {"Reparent", ReparentNotify, StructureNotifyMask}, {"Configure", ConfigureNotify, StructureNotifyMask}, {"Gravity", GravityNotify, StructureNotifyMask}, {"Circulate", CirculateNotify, StructureNotifyMask}, {"Property", PropertyNotify, PropertyChangeMask}, {"Colormap", ColormapNotify, ColormapChangeMask}, {"Activate", ActivateNotify, ActivateMask}, {"Deactivate", DeactivateNotify, ActivateMask}, {(char *) NULL, 0, 0}};static Tcl_HashTable eventTable;/* * The defines and table below are used to classify events into * various groups. The reason for this is that logically identical * fields (e.g. "state") appear at different places in different * types of events. The classification masks can be used to figure * out quickly where to extract information from events. */#define KEY 0x1#define BUTTON 0x2#define MOTION 0x4#define CROSSING 0x8#define FOCUS 0x10#define EXPOSE 0x20#define VISIBILITY 0x40#define CREATE 0x80#define DESTROY 0x100#define UNMAP 0x200#define MAP 0x400#define REPARENT 0x800#define CONFIG 0x1000#define GRAVITY 0x2000#define CIRC 0x4000#define PROP 0x8000#define COLORMAP 0x10000#define VIRTUAL 0x20000#define ACTIVATE 0x40000#define KEY_BUTTON_MOTION_VIRTUAL (KEY|BUTTON|MOTION|VIRTUAL)static int flagArray[TK_LASTEVENT] = { /* Not used */ 0, /* Not used */ 0, /* KeyPress */ KEY, /* KeyRelease */ KEY, /* ButtonPress */ BUTTON, /* ButtonRelease */ BUTTON, /* MotionNotify */ MOTION, /* EnterNotify */ CROSSING, /* LeaveNotify */ CROSSING, /* FocusIn */ FOCUS, /* FocusOut */ FOCUS, /* KeymapNotify */ 0, /* Expose */ EXPOSE, /* GraphicsExpose */ EXPOSE, /* NoExpose */ 0, /* VisibilityNotify */ VISIBILITY, /* CreateNotify */ CREATE, /* DestroyNotify */ DESTROY, /* UnmapNotify */ UNMAP, /* MapNotify */ MAP, /* MapRequest */ 0, /* ReparentNotify */ REPARENT, /* ConfigureNotify */ CONFIG, /* ConfigureRequest */ 0, /* GravityNotify */ GRAVITY, /* ResizeRequest */ 0, /* CirculateNotify */ CIRC, /* CirculateRequest */ 0, /* PropertyNotify */ PROP, /* SelectionClear */ 0, /* SelectionRequest */ 0, /* SelectionNotify */ 0, /* ColormapNotify */ COLORMAP, /* ClientMessage */ 0, /* MappingNotify */ 0, /* VirtualEvent */ VIRTUAL, /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE};/* * The following tables are used as a two-way map between X's internal * numeric values for fields in an XEvent and the strings used in Tcl. The * tables are used both when constructing an XEvent from user input and * when providing data from an XEvent to the user. */static TkStateMap notifyMode[] = { {NotifyNormal, "NotifyNormal"}, {NotifyGrab, "NotifyGrab"}, {NotifyUngrab, "NotifyUngrab"}, {NotifyWhileGrabbed, "NotifyWhileGrabbed"}, {-1, NULL}};static TkStateMap notifyDetail[] = { {NotifyAncestor, "NotifyAncestor"}, {NotifyVirtual, "NotifyVirtual"}, {NotifyInferior, "NotifyInferior"}, {NotifyNonlinear, "NotifyNonlinear"}, {NotifyNonlinearVirtual, "NotifyNonlinearVirtual"}, {NotifyPointer, "NotifyPointer"}, {NotifyPointerRoot, "NotifyPointerRoot"}, {NotifyDetailNone, "NotifyDetailNone"}, {-1, NULL}};static TkStateMap circPlace[] = { {PlaceOnTop, "PlaceOnTop"}, {PlaceOnBottom, "PlaceOnBottom"}, {-1, NULL}};static TkStateMap visNotify[] = { {VisibilityUnobscured, "VisibilityUnobscured"}, {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, {VisibilityFullyObscured, "VisibilityFullyObscured"}, {-1, NULL}};/* * Prototypes for local procedures defined in this file: */static void ChangeScreen _ANSI_ARGS_((Tcl_Interp *interp, char *dispName, int screenIndex));static int CreateVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, char *eventString));static int DeleteVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, char *eventString));static void DeleteVirtualEventTable _ANSI_ARGS_(( VirtualEventTable *vetPtr));static void ExpandPercents _ANSI_ARGS_((TkWindow *winPtr, char *before, XEvent *eventPtr, KeySym keySym, Tcl_DString *dsPtr));static void FreeTclBinding _ANSI_ARGS_((ClientData clientData));static PatSeq * FindSequence _ANSI_ARGS_((Tcl_Interp *interp, Tcl_HashTable *patternTablePtr, ClientData object, char *eventString, int create, int allowVirtual, unsigned long *maskPtr));static void GetAllVirtualEvents _ANSI_ARGS_((Tcl_Interp *interp, VirtualEventTable *vetPtr));static char * GetField _ANSI_ARGS_((char *p, char *copy, int size));static KeySym GetKeySym _ANSI_ARGS_((TkDisplay *dispPtr, XEvent *eventPtr));static void GetPatternString _ANSI_ARGS_((PatSeq *psPtr, Tcl_DString *dsPtr));static int GetVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString));static Tk_Uid GetVirtualEventUid _ANSI_ARGS_((Tcl_Interp *interp, char *virtString));static int HandleEventGenerate _ANSI_ARGS_((Tcl_Interp *interp, Tk_Window main, int argc, char **argv));static void InitKeymapInfo _ANSI_ARGS_((TkDisplay *dispPtr));static void InitVirtualEventTable _ANSI_ARGS_(( VirtualEventTable *vetPtr));static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr, BindingTable *bindPtr, PatSeq *psPtr, PatSeq *bestPtr, ClientData *objectPtr, PatSeq **sourcePtrPtr));static int ParseEventDescription _ANSI_ARGS_((Tcl_Interp *interp, char **eventStringPtr, Pattern *patPtr, unsigned long *eventMaskPtr));/* * The following define is used as a short circuit for the callback * procedure to evaluate a TclBinding. The actual evaluation of the * binding is handled inline, because special things have to be done * with a Tcl binding before evaluation time. */#define EvalTclBinding ((TkBindEvalProc *) 1)/* *--------------------------------------------------------------------------- * * TkBindInit -- * * This procedure is called when an application is created. It * initializes all the structures used by bindings and virtual * events. It must be called before any other functions in this * file are called. * * Results: * None. * * Side effects: * Memory allocated. * *--------------------------------------------------------------------------- */voidTkBindInit(mainPtr) TkMainInfo *mainPtr; /* The newly created application. */{ BindInfo *bindInfoPtr; if (sizeof(XEvent) < sizeof(XVirtualEvent)) { panic("TkBindInit: virtual events can't be supported"); } /* * Initialize the static data structures used by the binding package. * They are only initialized once, no matter how many interps are * created. */ if (!initialized) { Tcl_HashEntry *hPtr; ModInfo *modPtr; EventInfo *eiPtr; int dummy;#ifdef REDO_KEYSYM_LOOKUP KeySymInfo *kPtr; Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->name != NULL; kPtr++) { hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); Tcl_SetHashValue(hPtr, kPtr->value); hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, &dummy); Tcl_SetHashValue(hPtr, kPtr->name); }#endif /* REDO_KEYSYM_LOOKUP */ Tcl_InitHashTable(&modTable, TCL_STRING_KEYS); for (modPtr = modArray; modPtr->name != NULL; modPtr++) { hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &dummy); Tcl_SetHashValue(hPtr, modPtr); } Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS); for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); Tcl_SetHashValue(hPtr, eiPtr); } initialized = 1; } mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp); bindInfoPtr = (BindInfo *) ckalloc(sizeof(BindInfo)); InitVirtualEventTable(&bindInfoPtr->virtualEventTable); bindInfoPtr->screenInfo.curDispPtr = NULL; bindInfoPtr->screenInfo.curScreenIndex = -1; bindInfoPtr->screenInfo.bindingDepth = 0; bindInfoPtr->pendingList = NULL; mainPtr->bindInfo = (TkBindInfo) bindInfoPtr; TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable);}/* *--------------------------------------------------------------------------- * * TkBindFree -- * * This procedure is called when an application is deleted. It * deletes all the structures used by bindings and virtual events. * * Results: * None. * * Side effects: * Memory freed. * *--------------------------------------------------------------------------- */voidTkBindFree(mainPtr) TkMainInfo *mainPtr; /* The newly created application. */{ BindInfo *bindInfoPtr; Tk_DeleteBindingTable(mainPtr->bindingTable); mainPtr->bindingTable = NULL; bindInfoPtr = (BindInfo *) mainPtr->bindInfo; DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable); mainPtr->bindInfo = NULL;}/* *-------------------------------------------------------------- * * Tk_CreateBindingTable -- * * Set up a new domain in which event bindings may be created. * * Results: * The return value is a token for the new table, which must * be passed to procedures like Tk_CreatBinding. * * Side effects: * Memory is allocated for the new table. * *-------------------------------------------------------------- */Tk_BindingTableTk_CreateBindingTable(interp) Tcl_Interp *interp; /* Interpreter to associate with the binding * table: commands are executed in this * interpreter. */{ BindingTable *bindPtr; int i; /* * Create and initialize a new binding table. */ bindPtr = (BindingTable *) ckalloc(sizeof(BindingTable)); for (i = 0; i < EVENT_BUFFER_SIZE; i++) { bindPtr->eventRing[i].type = -1; } bindPtr->curEvent = 0; Tcl_InitHashTable(&bindPtr->patternTable, sizeof(PatternTableKey)/sizeof(int)); Tcl_InitHashTable(&bindPtr->objectTable, TCL_ONE_WORD_KEYS); bindPtr->interp = interp; return (Tk_BindingTable) bindPtr;}/* *-------------------------------------------------------------- * * Tk_DeleteBindingTable -- *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -