diff options
Diffstat (limited to 'generic/tkBind.c')
-rw-r--r-- | generic/tkBind.c | 3030 |
1 files changed, 1485 insertions, 1545 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c index c8a5b78..c6df007 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -1,17 +1,17 @@ -/* +/* * tkBind.c -- * - * This file provides procedures that associate Tcl commands - * with X events or sequences of X events. + * This file provides functions that associate Tcl commands with X events + * or sequences of X events. * * Copyright (c) 1989-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkBind.c,v 1.35 2004/08/29 09:27:35 dkf Exp $ + * RCS: @(#) $Id: tkBind.c,v 1.36 2005/08/10 22:02:22 dkf Exp $ */ #include "tkPort.h" @@ -25,7 +25,6 @@ #include "tkUnixInt.h" #endif - /* * File structure: * @@ -46,111 +45,109 @@ * Non-package-specific helpers. */ - /* - * The following union is used to hold the detail information from an - * XEvent (including Tk's XVirtualEvent extension). + * The following union is used to hold the detail information from an XEvent + * (including Tk's XVirtualEvent extension). */ + typedef union { - KeySym keySym; /* KeySym that corresponds to xkey.keycode. */ - int button; /* Button that was pressed (xbutton.button). */ - Tk_Uid name; /* Tk_Uid of virtual event. */ - ClientData clientData; /* Used when type of Detail is unknown, and to - * ensure that all bytes of Detail are initialized - * when this structure is used in a hash key. */ + KeySym keySym; /* KeySym that corresponds to xkey.keycode. */ + int button; /* Button that was pressed (xbutton.button). */ + Tk_Uid name; /* Tk_Uid of virtual event. */ + ClientData clientData; /* Used when type of Detail is unknown, and to + * ensure that all bytes of Detail are + * initialized when this structure is used in + * a hash key. */ } Detail; /* - * The structure below represents a binding table. A binding table - * represents a domain in which event bindings may occur. It includes - * a space of objects relative to which events occur (usually windows, - * but not always), a history of recent events in the domain, and - * a set of mappings that associate particular Tcl commands with sequences - * of events in the domain. Multiple binding tables may exist at once, - * either because there are multiple applications open, or because there - * are multiple domains within an application with separate event - * bindings for each (for example, each canvas widget has a separate - * binding table for associating events with the items in the canvas). - * - * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much - * below 30. To see this, consider a triple mouse button click while - * the Shift key is down (and auto-repeating). There may be as many - * as 3 auto-repeat events after each mouse button press or release - * (see the first large comment block within Tk_BindEvent for more on - * this), for a total of 20 events to cover the three button presses - * and two intervening releases. If you reduce EVENT_BUFFER_SIZE too - * much, shift multi-clicks will be lost. - * + * The structure below represents a binding table. A binding table represents + * a domain in which event bindings may occur. It includes a space of objects + * relative to which events occur (usually windows, but not always), a history + * of recent events in the domain, and a set of mappings that associate + * particular Tcl commands with sequences of events in the domain. Multiple + * binding tables may exist at once, either because there are multiple + * applications open, or because there are multiple domains within an + * application with separate event bindings for each (for example, each canvas + * widget has a separate binding table for associating events with the items + * in the canvas). + * + * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much below 30. + * To see this, consider a triple mouse button click while the Shift key is + * down (and auto-repeating). There may be as many as 3 auto-repeat events + * after each mouse button press or release (see the first large comment block + * within Tk_BindEvent for more on this), for a total of 20 events to cover + * the three button presses and two intervening releases. If you reduce + * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost. */ #define EVENT_BUFFER_SIZE 30 typedef struct BindingTable { - XEvent eventRing[EVENT_BUFFER_SIZE];/* Circular queue of recent events - * (higher indices are for more recent - * events). */ - Detail detailRing[EVENT_BUFFER_SIZE];/* "Detail" information (keySym, - * button, Tk_Uid, or 0) for each - * entry in eventRing. */ - int curEvent; /* Index in eventRing of most recent - * event. Newer events have higher - * indices. */ - Tcl_HashTable patternTable; /* Used to map from an event to a - * list of patterns that may match that - * event. Keys are PatternTableKey - * structs, values are (PatSeq *). */ - Tcl_HashTable objectTable; /* Used to map from an object to a - * list of patterns associated with - * that object. Keys are ClientData, - * values are (PatSeq *). */ - Tcl_Interp *interp; /* Interpreter in which commands are - * executed. */ + XEvent eventRing[EVENT_BUFFER_SIZE]; + /* Circular queue of recent events (higher + * indices are for more recent events). */ + Detail detailRing[EVENT_BUFFER_SIZE]; + /* "Detail" information (keySym, button, + * Tk_Uid, or 0) for each entry in + * eventRing. */ + int curEvent; /* Index in eventRing of most recent event. + * Newer events have higher indices. */ + Tcl_HashTable patternTable; /* Used to map from an event to a list of + * patterns that may match that event. Keys + * are PatternTableKey structs, values are + * (PatSeq *). */ + Tcl_HashTable objectTable; /* Used to map from an object to a list of + * patterns associated with that object. Keys + * are ClientData, values are (PatSeq *). */ + Tcl_Interp *interp; /* Interpreter in which commands are + * executed. */ } BindingTable; /* - * The following structure represents virtual event table. A virtual event - * table provides a way to map from platform-specific physical events such - * as button clicks or key presses to virtual events such as <<Paste>>, + * The following structure represents virtual event table. A virtual event + * table provides a way to map from platform-specific physical events such as + * button clicks or key presses to virtual events such as <<Paste>>, * <<Close>>, or <<ScrollWindow>>. * * A virtual event is usually never part of the event stream, but instead is - * synthesized inline by matching low-level events. However, a virtual - * event may be generated by platform-specific code or by Tcl scripts. In - * that case, no lookup of the virtual event will need to be done using - * this table, because the virtual event is actually in the event stream. + * synthesized inline by matching low-level events. However, a virtual event + * may be generated by platform-specific code or by Tcl scripts. In that case, + * no lookup of the virtual event will need to be done using this table, + * because the virtual event is actually in the event stream. */ typedef struct VirtualEventTable { - Tcl_HashTable patternTable; /* Used to map from a physical event to - * a list of patterns that may match that - * event. Keys are PatternTableKey - * structs, values are (PatSeq *). */ - Tcl_HashTable nameTable; /* Used to map a virtual event name to - * the array of physical events that can - * trigger it. Keys are the Tk_Uid names - * of the virtual events, values are - * PhysicalsOwned structs. */ + Tcl_HashTable patternTable; /* Used to map from a physical event to a list + * of patterns that may match that event. Keys + * are PatternTableKey structs, values are + * (PatSeq *). */ + Tcl_HashTable nameTable; /* Used to map a virtual event name to the + * array of physical events that can trigger + * it. Keys are the Tk_Uid names of the + * virtual events, values are PhysicalsOwned + * structs. */ } VirtualEventTable; /* - * The following structure is used as a key in a patternTable for both - * binding tables and a virtual event tables. + * The following structure is used as a key in a patternTable for both binding + * tables and a virtual event tables. * - * In a binding table, the object field corresponds to the binding tag - * for the widget whose bindings are being accessed. + * In a binding table, the object field corresponds to the binding tag for the + * widget whose bindings are being accessed. * - * In a virtual event table, the object field is always NULL. Virtual - * events are a global definiton and are not tied to a particular - * binding tag. + * In a virtual event table, the object field is always NULL. Virtual events + * are a global definiton and are not tied to a particular binding tag. * - * The same key is used for both types of pattern tables so that the - * helper functions that traverse and match patterns will work for both - * binding tables and virtual event tables. + * The same key is used for both types of pattern tables so that the helper + * functions that traverse and match patterns will work for both binding + * tables and virtual event tables. */ + typedef struct PatternTableKey { ClientData object; /* For binding table, identifies the binding * tag of the object (or class of objects) - * relative to which the event occurred. - * For virtual event table, always NULL. */ + * relative to which the event occurred. For + * virtual event table, always NULL. */ int type; /* Type of event (from X). */ Detail detail; /* Additional information, such as keysym, * button, Tk_Uid, or 0 if nothing @@ -164,37 +161,34 @@ typedef struct PatternTableKey { typedef struct Pattern { int eventType; /* Type of X event, e.g. ButtonPress. */ - int needMods; /* Mask of modifiers that must be - * present (0 means no modifiers are - * required). */ - Detail detail; /* Additional information that must - * match event. Normally this is 0, - * meaning no additional information - * must match. For KeyPress and - * KeyRelease events, a keySym may - * be specified to select a - * particular keystroke (0 means any - * keystrokes). For button events, - * specifies a particular button (0 - * means any buttons are OK). For virtual - * events, specifies the Tk_Uid of the + int needMods; /* Mask of modifiers that must be present (0 + * means no modifiers are required). */ + Detail detail; /* Additional information that must match + * event. Normally this is 0, meaning no + * additional information must match. For + * KeyPress and KeyRelease events, a keySym + * may be specified to select a particular + * keystroke (0 means any keystrokes). For + * button events, specifies a particular + * button (0 means any buttons are OK). For + * virtual events, specifies the Tk_Uid of the * virtual event name (never 0). */ } Pattern; /* * The following structure defines a pattern sequence, which consists of one - * or more patterns. In order to trigger, a pattern sequence must match - * the most recent X events (first pattern to most recent event, next - * pattern to next event, and so on). It is used as the hash value in a - * patternTable for both binding tables and virtual event tables. - * - * In a binding table, it is the sequence of physical events that make up - * a binding for an object. - * - * In a virtual event table, it is the sequence of physical events that - * define a virtual event. - * - * The same structure is used for both types of pattern tables so that the + * or more patterns. In order to trigger, a pattern sequence must match the + * most recent X events (first pattern to most recent event, next pattern to + * next event, and so on). It is used as the hash value in a patternTable for + * both binding tables and virtual event tables. + * + * In a binding table, it is the sequence of physical events that make up a + * binding for an object. + * + * In a virtual event table, it is the sequence of physical events that define + * a virtual event. + * + * The same structure is used for both types of pattern tables so that the * helper functions that traverse and match patterns will work for both * binding tables and virtual event tables. */ @@ -202,57 +196,57 @@ typedef struct Pattern { typedef struct PatSeq { int numPats; /* Number of patterns in sequence (usually * 1). */ - TkBindEvalProc *eventProc; /* The procedure that will be invoked on - * the clientData when this pattern sequence + TkBindEvalProc *eventProc; /* The function that will be invoked on the + * clientData when this pattern sequence * matches. */ - TkBindFreeProc *freeProc; /* The procedure that will be invoked to + TkBindFreeProc *freeProc; /* The function that will be invoked to * release the clientData when this pattern * sequence is freed. */ ClientData clientData; /* Arbitray data passed to eventProc and * freeProc when sequence matches. */ int flags; /* Miscellaneous flag values; see below for * definitions. */ - int refCount; /* Number of times that this binding is in - * the midst of executing. If greater than 1, - * then a recursive invocation is happening. - * Only when this is zero can the binding - * actually be freed. */ - struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences - * that have the same initial pattern. NULL - * means end of list. */ - Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the - * initial pattern. This is the head of the - * list of which nextSeqPtr forms a part. */ - struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a + int refCount; /* Number of times that this binding is in the + * midst of executing. If greater than 1, then + * a recursive invocation is happening. Only + * when this is zero can the binding actually + * be freed. */ + struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences that + * have the same initial pattern. NULL means + * end of list. */ + Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the initial + * pattern. This is the head of the list of + * which nextSeqPtr forms a part. */ + struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a * virtual event table, identifies the array * of virtual events that can be triggered by * this event. */ - struct PatSeq *nextObjPtr; /* In a binding table, next in list of all + struct PatSeq *nextObjPtr; /* In a binding table, next in list of all * pattern sequences for the same object (NULL - * for end of list). Needed to implement - * Tk_DeleteAllBindings. In a virtual event + * for end of list). Needed to implement + * Tk_DeleteAllBindings. In a virtual event * table, always NULL. */ - Pattern pats[1]; /* Array of "numPats" patterns. Only one + Pattern pats[1]; /* Array of "numPats" patterns. Only one * element is declared here but in actuality - * enough space will be allocated for "numPats" - * patterns. To match, pats[0] must match - * event n, pats[1] must match event n-1, etc. + * enough space will be allocated for + * "numPats" patterns. To match, pats[0] must + * match event n, pats[1] must match event + * n-1, etc. */ } PatSeq; /* * Flag values for PatSeq structures: * - * PAT_NEARBY 1 means that all of the events matching - * this sequence must occur with nearby X - * and Y mouse coordinates and close in time. - * This is typically used to restrict multiple - * button presses. + * PAT_NEARBY 1 means that all of the events matching this sequence + * must occur with nearby X and Y mouse coordinates and + * close in time. This is typically used to restrict + * multiple button presses. * MARKED_DELETED 1 means that this binding has been marked as deleted * and removed from the binding table, but its memory - * could not be released because it was already queued for - * execution. When the binding is actually about to be - * executed, this flag will be checked and the binding + * could not be released because it was already queued + * for execution. When the binding is actually about to + * be executed, this flag will be checked and the binding * skipped if set. */ @@ -260,52 +254,49 @@ typedef struct PatSeq { #define MARKED_DELETED 0x2 /* - * Constants that define how close together two events must be - * in milliseconds or pixels to meet the PAT_NEARBY constraint: + * Constants that define how close together two events must be in milliseconds + * or pixels to meet the PAT_NEARBY constraint: */ #define NEARBY_PIXELS 5 #define NEARBY_MS 500 - /* * The following structure keeps track of all the virtual events that are - * associated with a particular physical event. It is pointed to by the - * voPtr field in a PatSeq in the patternTable of a virtual event table. + * associated with a particular physical event. It is pointed to by the voPtr + * field in a PatSeq in the patternTable of a virtual event table. */ typedef struct VirtualOwners { - int numOwners; /* Number of virtual events to trigger. */ - Tcl_HashEntry *owners[1]; /* Array of pointers to entries in - * nameTable. Enough space will - * actually be allocated for numOwners - * hash entries. */ + int numOwners; /* Number of virtual events to trigger. */ + Tcl_HashEntry *owners[1]; /* Array of pointers to entries in nameTable. + * Enough space will actually be allocated for + * numOwners hash entries. */ } VirtualOwners; /* - * The following structure is used in the nameTable of a virtual event - * table to associate a virtual event with all the physical events that can - * trigger it. + * The following structure is used in the nameTable of a virtual event table + * to associate a virtual event with all the physical events that can trigger + * it. */ typedef struct PhysicalsOwned { - int numOwned; /* Number of physical events owned. */ - PatSeq *patSeqs[1]; /* Array of pointers to physical event - * patterns. Enough space will actually - * be allocated to hold numOwned. */ + int numOwned; /* Number of physical events owned. */ + PatSeq *patSeqs[1]; /* Array of pointers to physical event + * patterns. Enough space will actually be + * allocated to hold numOwned. */ } PhysicalsOwned; /* - * One of the following structures exists for each interpreter. This - * structure keeps track of the current display and screen in the - * interpreter, so that a script can be invoked whenever the display/screen - * changes (the script does things like point tk::Priv at a display-specific - * structure). + * One of the following structures exists for each interpreter. This structure + * keeps track of the current display and screen in the interpreter, so that a + * script can be invoked whenever the display/screen changes (the script does + * things like point tk::Priv at a display-specific structure). */ typedef struct { - TkDisplay *curDispPtr; /* Display for last binding command invoked - * in this application. */ - int curScreenIndex; /* Index of screen for last binding command. */ + TkDisplay *curDispPtr; /* Display for last binding command invoked in + * this application. */ + int curScreenIndex; /* Index of screen for last binding command */ int bindingDepth; /* Number of active instances of Tk_BindEvent * in this application. */ } ScreenInfo; @@ -313,21 +304,21 @@ typedef struct { /* * The following structure is used to keep track of all the C bindings that * are awaiting invocation and whether the window they refer to has been - * destroyed. If the window is destroyed, then all pending callbacks for - * that window will be cancelled. The Tcl bindings will still all be - * invoked, however. + * destroyed. If the window is destroyed, then all pending callbacks for that + * window will be cancelled. The Tcl bindings will still all be invoked, + * however. */ typedef struct PendingBinding { struct PendingBinding *nextPtr; - /* Next in chain of pending bindings, in - * case a recursive binding evaluation is in + /* Next in chain of pending bindings, in case + * a recursive binding evaluation is in * progress. */ Tk_Window tkwin; /* The window that the following bindings * depend upon. */ - int deleted; /* Set to non-zero by window cleanup code - * if tkwin is deleted. */ - PatSeq *matchArray[5]; /* Array of pending C bindings. The actual + int deleted; /* Set to non-zero by window cleanup code if + * tkwin is deleted. */ + PatSeq *matchArray[5]; /* Array of pending C bindings. The actual * size of this depends on how many C bindings * matched the event passed to Tk_BindEvent. * THIS FIELD MUST BE THE LAST IN THE @@ -335,8 +326,8 @@ typedef struct PendingBinding { } PendingBinding; /* - * The following structure keeps track of all the information local to - * the binding package on a per interpreter basis. + * The following structure keeps track of all the information local to the + * binding package on a per interpreter basis. */ typedef struct BindInfo { @@ -344,30 +335,29 @@ typedef struct BindInfo { /* The virtual events that exist in this * interpreter. */ ScreenInfo screenInfo; /* Keeps track of the current display and - * screen, so it can be restored after - * a binding has executed. */ + * screen, so it can be restored after a + * binding has executed. */ PendingBinding *pendingList;/* The list of pending C bindings, kept in * case a C or Tcl binding causes the target * window to be deleted. */ - int deleted; /* 1 the application has been deleted but - * the structure has been preserved. */ + int deleted; /* 1 the application has been deleted but the + * structure has been preserved. */ } BindInfo; - + /* - * In X11R4 and earlier versions, XStringToKeysym is ridiculously - * slow. The data structure and hash table below, along with the - * code that uses them, implement a fast mapping from strings to - * keysyms. In X11R5 and later releases XStringToKeysym is plenty - * fast so this stuff isn't needed. The #define REDO_KEYSYM_LOOKUP - * is normally undefined, so that XStringToKeysym gets used. It - * can be set in the Makefile to enable the use of the hash table - * below. + * In X11R4 and earlier versions, XStringToKeysym is ridiculously slow. The + * data structure and hash table below, along with the code that uses them, + * implement a fast mapping from strings to keysyms. In X11R5 and later + * releases XStringToKeysym is plenty fast so this stuff isn't needed. The + * #define REDO_KEYSYM_LOOKUP is normally undefined, so that XStringToKeysym + * gets used. It can be set in the Makefile to enable the use of the hash + * table below. */ #ifdef REDO_KEYSYM_LOOKUP typedef struct { - char *name; /* Name of keysym. */ - KeySym value; /* Numeric identifier for keysym. */ + char *name; /* Name of keysym. */ + KeySym value; /* Numeric identifier for keysym. */ } KeySymInfo; static KeySymInfo keyArray[] = { #ifndef lint @@ -375,8 +365,8 @@ static KeySymInfo keyArray[] = { #endif {(char *) NULL, 0} }; -static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */ -static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */ +static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */ +static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */ #endif /* REDO_KEYSYM_LOOKUP */ /* @@ -388,16 +378,17 @@ static int initialized = 0; TCL_DECLARE_MUTEX(bindMutex) /* - * A hash table is kept to map from the string names of event - * modifiers to information about those modifiers. The structure - * for storing this information, and the hash table built at - * initialization time, are defined below. + * A hash table is kept to map from the string names of event modifiers to + * information about those modifiers. The structure for storing this + * information, and the hash table built at initialization time, are defined + * below. */ typedef struct { char *name; /* Name of modifier. */ - int mask; /* Button/modifier mask value, * such as Button1Mask. */ - int flags; /* Various flags; see below for + int mask; /* Button/modifier mask value, such as + * Button1Mask. */ + int flags; /* Various flags; see below for * definitions. */ } ModInfo; @@ -451,32 +442,29 @@ static ModInfo modArray[] = { {"Double", 0, DOUBLE}, {"Triple", 0, TRIPLE}, {"Quadruple", 0, QUADRUPLE}, - {"Any", 0, 0}, /* Ignored: historical relic. */ + {"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. + * 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. */ + 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. + * 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[] = { @@ -510,18 +498,18 @@ static EventInfo eventArray[] = { {"CirculateRequest", CirculateRequest, SubstructureRedirectMask}, {"ConfigureRequest", ConfigureRequest, SubstructureRedirectMask}, {"Create", CreateNotify, SubstructureNotifyMask}, - {"MapRequest", MapRequest, SubstructureRedirectMask}, + {"MapRequest", MapRequest, SubstructureRedirectMask}, {"ResizeRequest", ResizeRequest, ResizeRedirectMask}, {(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. + * 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 @@ -588,17 +576,16 @@ static int flagArray[TK_LASTEVENT] = { /* ClientMessage */ 0, /* MappingNotify */ 0, /* VirtualEvent */ VIRTUAL, - /* Activate */ ACTIVATE, + /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE, /* MouseWheel */ KEY }; /* - * The following table is used to map between the location where an - * generated event should be queued and the string used to specify the - * location. + * The following table is used to map between the location where an generated + * event should be queued and the string used to specify the location. */ - + static TkStateMap queuePosition[] = { {-1, "now"}, {TCL_QUEUE_HEAD, "head"}, @@ -608,10 +595,10 @@ static TkStateMap queuePosition[] = { }; /* - * 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. + * 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[] = { @@ -641,9 +628,9 @@ static TkStateMap circPlace[] = { }; static TkStateMap visNotify[] = { - {VisibilityUnobscured, "VisibilityUnobscured"}, - {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, - {VisibilityFullyObscured, "VisibilityFullyObscured"}, + {VisibilityUnobscured, "VisibilityUnobscured"}, + {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, + {VisibilityFullyObscured, "VisibilityFullyObscured"}, {-1, NULL} }; @@ -664,58 +651,52 @@ static TkStateMap propNotify[] = { }; /* - * Prototypes for local procedures defined in this file: + * Prototypes for local functions defined in this file: */ -static void ChangeScreen _ANSI_ARGS_((Tcl_Interp *interp, - char *dispName, int screenIndex)); -static int CreateVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, +static void ChangeScreen(Tcl_Interp *interp, char *dispName, + int screenIndex); +static int CreateVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString)); -static int DeleteVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, + char *eventString); +static int DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString)); -static void DeleteVirtualEventTable _ANSI_ARGS_(( - VirtualEventTable *vetPtr)); -static void ExpandPercents _ANSI_ARGS_((TkWindow *winPtr, - CONST char *before, XEvent *eventPtr, KeySym keySym, - Tcl_DString *dsPtr)); -static void FreeTclBinding _ANSI_ARGS_((ClientData clientData)); -static PatSeq * FindSequence _ANSI_ARGS_((Tcl_Interp *interp, + char *eventString); +static void DeleteVirtualEventTable(VirtualEventTable *vetPtr); +static void ExpandPercents(TkWindow *winPtr, CONST char *before, + XEvent *eventPtr,KeySym keySym,Tcl_DString *dsPtr); +static void FreeTclBinding(ClientData clientData); +static PatSeq * FindSequence(Tcl_Interp *interp, Tcl_HashTable *patternTablePtr, ClientData object, CONST 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 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 objc, - Tcl_Obj *CONST objv[])); -static void InitVirtualEventTable _ANSI_ARGS_(( - VirtualEventTable *vetPtr)); -static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr, + int allowVirtual, unsigned long *maskPtr); +static void GetAllVirtualEvents(Tcl_Interp *interp, + VirtualEventTable *vetPtr); +static char * GetField(char *p, char *copy, int size); +static void GetPatternString(PatSeq *psPtr, Tcl_DString *dsPtr); +static int GetVirtualEvent(Tcl_Interp *interp, + VirtualEventTable *vetPtr, char *virtString); +static Tk_Uid GetVirtualEventUid(Tcl_Interp *interp, + char *virtString); +static int HandleEventGenerate(Tcl_Interp *interp, Tk_Window main, + int objc, Tcl_Obj *CONST objv[]); +static void InitVirtualEventTable(VirtualEventTable *vetPtr); +static PatSeq * MatchPatterns(TkDisplay *dispPtr, BindingTable *bindPtr, PatSeq *psPtr, PatSeq *bestPtr, ClientData *objectPtr, - PatSeq **sourcePtrPtr)); -static int NameToWindow _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window main, Tcl_Obj *objPtr, - Tk_Window *tkwinPtr)); -static int ParseEventDescription _ANSI_ARGS_((Tcl_Interp *interp, + PatSeq **sourcePtrPtr); +static int NameToWindow(Tcl_Interp *interp, Tk_Window main, + Tcl_Obj *objPtr, Tk_Window *tkwinPtr); +static int ParseEventDescription(Tcl_Interp *interp, CONST char **eventStringPtr, Pattern *patPtr, - unsigned long *eventMaskPtr)); -static void DoWarp _ANSI_ARGS_((ClientData clientData)); + unsigned long *eventMaskPtr); +static void DoWarp(ClientData clientData); /* - * 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. + * The following define is used as a short circuit for the callback function + * 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) @@ -726,10 +707,9 @@ static void DoWarp _ANSI_ARGS_((ClientData clientData)); * * 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. + * This function 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. @@ -751,13 +731,12 @@ TkBindInit(mainPtr) } /* - * Initialize the static data structures used by the binding package. - * They are only initialized once, no matter how many interps are - * created. + * 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_MutexLock(&bindMutex); + Tcl_MutexLock(&bindMutex); if (!initialized) { Tcl_HashEntry *hPtr; ModInfo *modPtr; @@ -770,28 +749,28 @@ TkBindInit(mainPtr) 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); + hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); Tcl_SetHashValue(hPtr, kPtr->value); hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, - &dummy); + &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); + 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); + hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); Tcl_SetHashValue(hPtr, eiPtr); } initialized = 1; } - Tcl_MutexUnlock(&bindMutex); + Tcl_MutexUnlock(&bindMutex); } mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp); @@ -813,8 +792,8 @@ TkBindInit(mainPtr) * * TkBindFree -- * - * This procedure is called when an application is deleted. It - * deletes all the structures used by bindings and virtual events. + * This function is called when an application is deleted. It deletes all + * the structures used by bindings and virtual events. * * Results: * None. @@ -830,7 +809,7 @@ TkBindFree(mainPtr) TkMainInfo *mainPtr; /* The newly created application. */ { BindInfo *bindInfoPtr; - + Tk_DeleteBindingTable(mainPtr->bindingTable); mainPtr->bindingTable = NULL; @@ -849,8 +828,8 @@ TkBindFree(mainPtr) * 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_CreateBinding. + * The return value is a token for the new table, which must be passed to + * functions like Tk_CreateBinding. * * Side effects: * Memory is allocated for the new table. @@ -861,7 +840,7 @@ TkBindFree(mainPtr) Tk_BindingTable Tk_CreateBindingTable(interp) Tcl_Interp *interp; /* Interpreter to associate with the binding - * table: commands are executed in this + * table: commands are executed in this * interpreter. */ { BindingTable *bindPtr; @@ -888,9 +867,8 @@ Tk_CreateBindingTable(interp) * * Tk_DeleteBindingTable -- * - * Destroy a binding table and free up all its memory. - * The caller should not use bindingTable again after - * this procedure returns. + * Destroy a binding table and free up all its memory. The caller should + * not use bindingTable again after this function returns. * * Results: * None. @@ -903,8 +881,8 @@ Tk_CreateBindingTable(interp) void Tk_DeleteBindingTable(bindingTable) - Tk_BindingTable bindingTable; /* Token for the binding table to - * destroy. */ + Tk_BindingTable bindingTable; + /* Token for the binding table to destroy. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *nextPtr; @@ -912,8 +890,7 @@ Tk_DeleteBindingTable(bindingTable) Tcl_HashSearch search; /* - * Find and delete all of the patterns associated with the binding - * table. + * Find and delete all of the patterns associated with the binding table. */ for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search); @@ -932,8 +909,7 @@ Tk_DeleteBindingTable(bindingTable) } /* - * Clean up the rest of the information associated with the - * binding table. + * Clean up the rest of the information associated with the binding table. */ Tcl_DeleteHashTable(&bindPtr->patternTable); @@ -946,23 +922,21 @@ Tk_DeleteBindingTable(bindingTable) * * Tk_CreateBinding -- * - * Add a binding to a binding table, so that future calls to - * Tk_BindEvent may execute the command in the binding. + * Add a binding to a binding table, so that future calls to Tk_BindEvent + * may execute the command in the binding. * * Results: - * The return value is 0 if an error occurred while setting - * up the binding. In this case, an error message will be - * left in the interp's result. If all went well then the return - * value is a mask of the event types that must be made - * available to Tk_BindEvent in order to properly detect when - * this binding triggers. This value can be used to determine + * The return value is 0 if an error occurred while setting up the + * binding. In this case, an error message will be left in the interp's + * result. If all went well then the return value is a mask of the event + * types that must be made available to Tk_BindEvent in order to properly + * detect when this binding triggers. This value can be used to determine * what events to select for in a window, for example. * * Side effects: - * An existing binding on the same event sequence may be - * replaced. - * The new binding may cause future calls to Tk_BindEvent to - * behave differently than they did previously. + * An existing binding on the same event sequence may be replaced. The + * new binding may cause future calls to Tk_BindEvent to behave + * differently than they did previously. * *-------------------------------------------------------------- */ @@ -980,7 +954,7 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) * binding triggers. */ int append; /* 0 means replace any existing binding for * eventString; 1 means append to that - * binding. If the existing binding is for a + * binding. If the existing binding is for a * callback function and not a Tcl command * string, the existing binding will always be * replaced. */ @@ -998,12 +972,11 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) if (psPtr->eventProc == NULL) { int new; Tcl_HashEntry *hPtr; - + /* - * This pattern sequence was just created. - * Link the pattern into the list associated with the object, so - * that if the object goes away, these bindings will all - * automatically be deleted. + * This pattern sequence was just created. Link the pattern into the + * list associated with the object, so that if the object goes away, + * these bindings will all automatically be deleted. */ hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object, @@ -1049,23 +1022,22 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) /* *--------------------------------------------------------------------------- * - * TkCreateBindingProcedure -- + * TkCreateBindingFunction -- * * Add a C binding to a binding table, so that future calls to - * Tk_BindEvent may callback the procedure in the binding. + * Tk_BindEvent may callback the function in the binding. * * Results: - * The return value is 0 if an error occurred while setting - * up the binding. In this case, an error message will be - * left in the interp's result. If all went well then the return - * value is a mask of the event types that must be made - * available to Tk_BindEvent in order to properly detect when - * this binding triggers. This value can be used to determine + + * The return value is 0 if an error occurred while setting up the + * binding. In this case, an error message will be left in the interp's + * result. If all went well then the return value is a mask of the event + * types that must be made available to Tk_BindEvent in order to properly + * detect when this binding triggers. This value can be used to determine * what events to select for in a window, for example. * * Side effects: - * Any existing binding on the same event sequence will be - * replaced. + * Any existing binding on the same event sequence will be replaced. * *--------------------------------------------------------------------------- */ @@ -1080,10 +1052,10 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, * associated. */ CONST char *eventString; /* String describing event sequence that * triggers binding. */ - TkBindEvalProc *eventProc; /* Procedure to invoke when binding - * triggers. Must not be NULL. */ - TkBindFreeProc *freeProc; /* Procedure to invoke when binding is - * freed. May be NULL for no procedure. */ + TkBindEvalProc *eventProc; /* Function to invoke when binding triggers. + * Must not be NULL. */ + TkBindFreeProc *freeProc; /* Function to invoke when binding is freed. + * May be NULL for no function. */ ClientData clientData; /* Arbitrary ClientData to pass to eventProc * and freeProc. */ { @@ -1099,12 +1071,11 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, if (psPtr->eventProc == NULL) { int new; Tcl_HashEntry *hPtr; - + /* - * This pattern sequence was just created. - * Link the pattern into the list associated with the object, so - * that if the object goes away, these bindings will all - * automatically be deleted. + * This pattern sequence was just created. Link the pattern into the + * list associated with the object, so that if the object goes away, + * these bindings will all automatically be deleted. */ hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object, @@ -1140,24 +1111,25 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, * Remove an event binding from a binding table. * * Results: - * The result is a standard Tcl return value. If an error - * occurs then the interp's result will contain an error message. + * The result is a standard Tcl return value. If an error occurs then the + * interp's result will contain an error message. * * Side effects: - * The binding given by object and eventString is removed - * from bindingTable. + * The binding given by object and eventString is removed from + * bindingTable. * *-------------------------------------------------------------- */ int Tk_DeleteBinding(interp, bindingTable, object, eventString) - Tcl_Interp *interp; /* Used for error reporting. */ - Tk_BindingTable bindingTable; /* Table in which to delete binding. */ - ClientData object; /* Token for object with which binding - * is associated. */ - CONST char *eventString; /* String describing event sequence - * that triggers binding. */ + Tcl_Interp *interp; /* Used for error reporting. */ + Tk_BindingTable bindingTable; + /* Table in which to delete binding. */ + ClientData object; /* Token for object with which binding is + * associated. */ + CONST char *eventString; /* String describing event sequence that + * triggers binding. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; @@ -1172,8 +1144,8 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) } /* - * Unlink the binding from the list for its object, then from the - * list for its pattern. + * Unlink the binding from the list for its object, then from the list for + * its pattern. */ hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object); @@ -1231,13 +1203,12 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) * Return the command associated with a given event string. * * Results: - * The return value is a pointer to the command string - * associated with eventString for object in the domain - * given by bindingTable. If there is no binding for - * eventString, or if eventString is improperly formed, - * then NULL is returned and an error message is left in - * the interp's result. The return value is semi-static: it - * will persist until the binding is changed or deleted. + * The return value is a pointer to the command string associated with + * eventString for object in the domain given by bindingTable. If there + * is no binding for eventString, or if eventString is improperly formed, + * then NULL is returned and an error message is left in the interp's + * result. The return value is semi-static: it will persist until the + * binding is changed or deleted. * * Side effects: * None. @@ -1247,13 +1218,13 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) CONST char * Tk_GetBinding(interp, bindingTable, object, eventString) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_BindingTable bindingTable; /* Table in which to look for - * binding. */ - ClientData object; /* Token for object with which binding - * is associated. */ - CONST char *eventString; /* String describing event sequence - * that triggers binding. */ + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_BindingTable bindingTable; + /* Table in which to look for binding. */ + ClientData object; /* Token for object with which binding is + * associated. */ + CONST char *eventString; /* String describing event sequence that + * triggers binding. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; @@ -1275,14 +1246,14 @@ Tk_GetBinding(interp, bindingTable, object, eventString) * * Tk_GetAllBindings -- * - * Return a list of event strings for all the bindings - * associated with a given object. + * Return a list of event strings for all the bindings associated with a + * given object. * * Results: - * There is no return value. The interp's result is modified to - * hold a Tcl list with one entry for each binding associated - * with object in bindingTable. Each entry in the list - * contains the event string associated with one binding. + * There is no return value. The interp's result is modified to hold a + * Tcl list with one entry for each binding associated with object in + * bindingTable. Each entry in the list contains the event string + * associated with one binding. * * Side effects: * None. @@ -1292,12 +1263,10 @@ Tk_GetBinding(interp, bindingTable, object, eventString) void Tk_GetAllBindings(interp, bindingTable, object) - Tcl_Interp *interp; /* Interpreter returning result or - * error. */ - Tk_BindingTable bindingTable; /* Table in which to look for - * bindings. */ - ClientData object; /* Token for object. */ - + Tcl_Interp *interp; /* Interpreter returning result or error. */ + Tk_BindingTable bindingTable; + /* Table in which to look for bindings. */ + ClientData object; /* Token for object. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; @@ -1311,11 +1280,11 @@ Tk_GetAllBindings(interp, bindingTable, object) Tcl_DStringInit(&ds); for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = psPtr->nextObjPtr) { - /* - * For each binding, output information about each of the - * patterns in its sequence. + /* + * For each binding, output information about each of the patterns in + * its sequence. */ - + Tcl_DStringSetLength(&ds, 0); GetPatternString(psPtr, &ds); Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); @@ -1328,12 +1297,11 @@ Tk_GetAllBindings(interp, bindingTable, object) * * Tk_DeleteAllBindings -- * - * Remove all bindings associated with a given object in a - * given binding table. + * Remove all bindings associated with a given object in a given binding + * table. * * Results: - * All bindings associated with object are removed from - * bindingTable. + * All bindings associated with object are removed from bindingTable. * * Side effects: * None. @@ -1343,9 +1311,9 @@ Tk_GetAllBindings(interp, bindingTable, object) void Tk_DeleteAllBindings(bindingTable, object) - Tk_BindingTable bindingTable; /* Table in which to delete - * bindings. */ - ClientData object; /* Token for object. */ + Tk_BindingTable bindingTable; + /* Table in which to delete bindings. */ + ClientData object; /* Token for object. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; @@ -1361,9 +1329,9 @@ Tk_DeleteAllBindings(bindingTable, object) nextPtr = psPtr->nextObjPtr; /* - * Be sure to remove each binding from its hash chain in the - * pattern table. If this is the last pattern in the chain, - * then delete the hash entry too. + * Be sure to remove each binding from its hash chain in the pattern + * table. If this is the last pattern in the chain, then delete the + * hash entry too. */ prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); @@ -1401,11 +1369,10 @@ Tk_DeleteAllBindings(bindingTable, object) * * Tk_BindEvent -- * - * This procedure is invoked to process an X event. The - * event is added to those recorded for the binding table. - * Then each of the objects at *objectPtr is checked in - * order to see if it has a binding that matches the recent - * events. If so, the most specific binding is invoked for + * This function is invoked to process an X event. The event is added to + * those recorded for the binding table. Then each of the objects at + * *objectPtr is checked in order to see if it has a binding that matches + * the recent events. If so, the most specific binding is invoked for * each object. * * Results: @@ -1414,32 +1381,32 @@ Tk_DeleteAllBindings(bindingTable, object) * Side effects: * Depends on the command associated with the matching binding. * - * All Tcl bindings scripts for each object are accumulated before - * the first binding is evaluated. If the action of a Tcl binding - * is to change or delete a binding, or delete the window associated - * with the binding, all the original Tcl binding scripts will still - * fire. Contrast this with C binding procedures. If a pending C - * binding (one that hasn't fired yet, but is queued to be fired for - * this window) is deleted, it will not be called, and if it is - * changed, then the new binding procedure will be called. If the - * window itself is deleted, no further C binding procedures will be - * called for this window. When both Tcl binding scripts and C binding - * procedures are interleaved, the above rules still apply. + * All Tcl bindings scripts for each object are accumulated before the + * first binding is evaluated. If the action of a Tcl binding is to + * change or delete a binding, or delete the window associated with the + * binding, all the original Tcl binding scripts will still fire. + * Contrast this with C binding functions. If a pending C binding (one + * that hasn't fired yet, but is queued to be fired for this window) is + * deleted, it will not be called, and if it is changed, then the new + * binding function will be called. If the window itself is deleted, no + * further C binding functions will be called for this window. When both + * Tcl binding scripts and C binding functions are interleaved, the above + * rules still apply. * *--------------------------------------------------------------------------- */ void Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) - Tk_BindingTable bindingTable; /* Table in which to look for - * bindings. */ - XEvent *eventPtr; /* What actually happened. */ - Tk_Window tkwin; /* Window on display where event - * occurred (needed in order to - * locate display information). */ - int numObjects; /* Number of objects at *objectPtr. */ - ClientData *objectPtr; /* Array of one or more objects - * to check for a matching binding. */ + Tk_BindingTable bindingTable; + /* Table in which to look for bindings. */ + XEvent *eventPtr; /* What actually happened. */ + Tk_Window tkwin; /* Window on display where event occurred + * (needed in order to locate display + * information). */ + int numObjects; /* Number of objects at *objectPtr. */ + ClientData *objectPtr; /* Array of one or more objects to check for a + * matching binding. */ { BindingTable *bindPtr; TkDisplay *dispPtr; @@ -1459,10 +1426,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) TkWindow *winPtr = (TkWindow *)tkwin; PatternTableKey key; Tk_ClassModalProc *modalProc; + /* - * Ignore events on windows that don't have names: these are windows - * like wrapper windows that shouldn't be visible to the - * application. + * Ignore events on windows that don't have names: these are windows like + * wrapper windows that shouldn't be visible to the application. */ if (winPtr->pathName == NULL) { @@ -1470,13 +1437,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } /* - * Ignore the event completely if it is an Enter, Leave, FocusIn, - * or FocusOut event with detail NotifyInferior. The reason for - * ignoring these events is that we don't want transitions between - * a window and its children to visible to bindings on the parent: - * this would cause problems for mega-widgets, since the internal - * structure of a mega-widget isn't supposed to be visible to - * people watching the parent. + * Ignore the event completely if it is an Enter, Leave, FocusIn, or + * FocusOut event with detail NotifyInferior. The reason for ignoring + * these events is that we don't want transitions between a window and its + * children to visible to bindings on the parent: this would cause + * problems for mega-widgets, since the internal structure of a + * mega-widget isn't supposed to be visible to people watching the parent. */ if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) { @@ -1495,20 +1461,19 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; /* - * Add the new event to the ring of saved events for the - * binding table. Two tricky points: + * Add the new event to the ring of saved events for the binding table. + * Two tricky points: * - * 1. Combine consecutive MotionNotify events. Do this by putting - * the new event *on top* of the previous event. + * 1. Combine consecutive MotionNotify events. Do this by putting the new + * event *on top* of the previous event. * 2. If a modifier key is held down, it auto-repeats to generate - * continuous KeyPress and KeyRelease events. These can flush - * the event ring so that valuable information is lost (such - * as repeated button clicks). To handle this, check for the - * special case of a modifier KeyPress arriving when the previous - * two events are a KeyRelease and KeyPress of the same key. - * If this happens, mark the most recent event (the KeyRelease) - * invalid and put the new event on top of the event before that - * (the KeyPress). + * continuous KeyPress and KeyRelease events. These can flush the event + * ring so that valuable information is lost (such as repeated button + * clicks). To handle this, check for the special case of a modifier + * KeyPress arriving when the previous two events are a KeyRelease and + * KeyPress of the same key. If this happens, mark the most recent + * event (the KeyRelease) invalid and put the new event on top of the + * event before that (the KeyPress). */ if ((eventPtr->type == MotionNotify) @@ -1518,6 +1483,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) */ } else if (eventPtr->type == KeyPress) { int i; + for (i = 0; ; i++) { if (i >= dispPtr->numModKeyCodes) { goto advanceRingPointer; @@ -1544,7 +1510,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) bindPtr->eventRing[bindPtr->curEvent].type = -1; bindPtr->curEvent = i; } else { - advanceRingPointer: + + advanceRingPointer: bindPtr->curEvent++; if (bindPtr->curEvent >= EVENT_BUFFER_SIZE) { bindPtr->curEvent = 0; @@ -1581,9 +1548,9 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) veptPtr = &bindInfoPtr->virtualEventTable.patternTable; - key.object = NULL; - key.type = ringPtr->type; - key.detail = detail; + key.object = NULL; + key.type = ringPtr->type; + key.detail = detail; hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { @@ -1594,19 +1561,19 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) key.detail.clientData = 0; hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { - vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); + vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); } } } /* - * Loop over all the binding tags, finding the binding script or - * callback for each one. Append all of the binding scripts, with - * %-sequences expanded, to "scripts", with null characters separating - * the scripts for each object. Append all the callbacks to the array - * of pending callbacks. + * Loop over all the binding tags, finding the binding script or callback + * for each one. Append all of the binding scripts, with %-sequences + * expanded, to "scripts", with null characters separating the scripts for + * each object. Append all the callbacks to the array of pending + * callbacks. */ - + pendingPtr = &staticPending; matchCount = 0; matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *); @@ -1621,10 +1588,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) /* * Match the new event against those recorded in the pattern table, - * saving the longest matching pattern. For events with details - * (button and key events), look for a binding for the specific - * key or button. First see if the event matches a physical event - * that the object is interested in, then look for a virtual event. + * saving the longest matching pattern. For events with details + * (button and key events), look for a binding for the specific key or + * button. First see if the event matches a physical event that the + * object is interested in, then look for a virtual event. */ key.object = *objectPtr; @@ -1632,7 +1599,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) key.detail = detail; hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { - matchPtr = MatchPatterns(dispPtr, bindPtr, + matchPtr = MatchPatterns(dispPtr, bindPtr, (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL, &sourcePtr); } @@ -1644,7 +1611,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) /* * If no match was found, look for a binding for all keys or buttons - * (detail of 0). Again, first match on a virtual event. + * (detail of 0). Again, first match on a virtual event. */ if ((detail.clientData != 0) && (matchPtr == NULL)) { @@ -1657,12 +1624,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } if (vMatchNoDetailList != NULL) { - matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList, + matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList, matchPtr, objectPtr, &sourcePtr); } } - + if (matchPtr != NULL) { if (sourcePtr->eventProc == NULL) { Tcl_Panic("Tk_BindEvent: missing command"); @@ -1674,7 +1641,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount >= matchSpace) { PendingBinding *new; unsigned int oldSize, newSize; - + oldSize = sizeof(staticPending) - sizeof(staticPending.matchArray) + matchSpace * sizeof(PatSeq*); @@ -1693,9 +1660,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) pendingPtr->matchArray[matchCount] = sourcePtr; matchCount++; } + /* - * A "" is added to the scripts string to separate the - * various scripts that should be invoked. + * A "" is added to the scripts string to separate the various + * scripts that should be invoked. */ Tcl_DStringAppend(&scripts, "", 1); @@ -1706,29 +1674,28 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } /* - * Now go back through and evaluate the binding for each object, - * in order, dealing with "break" and "continue" exceptions - * appropriately. + * Now go back through and evaluate the binding for each object, in order, + * dealing with "break" and "continue" exceptions appropriately. * * There are two tricks here: - * 1. Bindings can be invoked from in the middle of Tcl commands, - * where the interp's result is significant (for example, a widget - * might be deleted because of an error in creating it, so the - * result contains an error message that is eventually going to - * be returned by the creating command). To preserve the result, - * we save it in a dynamic string. - * 2. The binding's action can potentially delete the binding, - * so bindPtr may not point to anything valid once the action - * completes. Thus we have to save bindPtr->interp in a - * local variable in order to restore the result. + * 1. Bindings can be invoked from in the middle of Tcl commands, where + * the interp's result is significant (for example, a widget might be + * deleted because of an error in creating it, so the result contains + * an error message that is eventually going to be returned by the + * creating command). To preserve the result, we save it in a dynamic + * string. + * 2. The binding's action can potentially delete the binding, so bindPtr + * may not point to anything valid once the action completes. Thus we + * have to save bindPtr->interp in a local variable in order to restore + * the result. */ interp = bindPtr->interp; Tcl_DStringInit(&savedResult); /* - * Save information about the current screen, then invoke a script - * if the screen has changed. + * Save information about the current screen, then invoke a script if the + * screen has changed. */ Tcl_DStringGetResult(interp, &savedResult); @@ -1745,9 +1712,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0) { /* * Remember the list of pending C binding callbacks, so we can mark - * them as deleted and not call them if the act of evaluating a C - * or Tcl binding deletes a C binding callback or even the whole - * window. + * them as deleted and not call them if the act of evaluating a C or + * Tcl binding deletes a C binding callback or even the whole window. */ pendingPtr->nextPtr = bindInfoPtr->pendingList; @@ -1755,11 +1721,11 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) pendingPtr->deleted = 0; bindInfoPtr->pendingList = pendingPtr; } - + /* - * Save the current value of the TK_DEFER_MODAL flag so we can - * restore it at the end of the loop. Clear the flag so we can - * detect any recursive requests for a modal loop. + * Save the current value of the TK_DEFER_MODAL flag so we can restore it + * at the end of the loop. Clear the flag so we can detect any recursive + * requests for a modal loop. */ flags = winPtr->flags; @@ -1770,16 +1736,15 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) i = 0; /* - * Be carefule when dereferencing screenPtr or bindInfoPtr. If we - * evaluate something that destroys ".", bindInfoPtr would have been - * freed, but we can tell that by first checking to see if - * winPtr->mainPtr == NULL. + * Be carefule when dereferencing screenPtr or bindInfoPtr. If we evaluate + * something that destroys ".", bindInfoPtr would have been freed, but we + * can tell that by first checking to see if winPtr->mainPtr == NULL. */ Tcl_Preserve((ClientData) bindInfoPtr); while (p < end) { int code; - + if (!bindInfoPtr->deleted) { screenPtr->bindingDepth++; } @@ -1787,7 +1752,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (*p == '\0') { PatSeq *psPtr; - + psPtr = pendingPtr->matchArray[i]; i++; code = TCL_OK; @@ -1815,7 +1780,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (code != TCL_OK) { if (code == TCL_CONTINUE) { /* - * Do nothing: just go on to the next command. + * Do nothing: just go on to the next command. */ } else if (code == TCL_BREAK) { break; @@ -1829,13 +1794,13 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0 && !pendingPtr->deleted) { /* - * Restore the original modal flag value and invoke the modal loop - * if needed. + * Restore the original modal flag value and invoke the modal loop if + * needed. */ deferModal = winPtr->flags & TK_DEFER_MODAL; - winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL) - | (flags & TK_DEFER_MODAL); + winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL) + | (flags & TK_DEFER_MODAL); if (deferModal) { modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc); if (modalProc != NULL) { @@ -1846,12 +1811,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0) && ((oldDispPtr != screenPtr->curDispPtr) - || (oldScreen != screenPtr->curScreenIndex))) { - + || (oldScreen != screenPtr->curScreenIndex))) { /* - * Some other binding script is currently executing, but its - * screen is no longer current. Change the current display - * back again. + * Some other binding script is currently executing, but its screen is + * no longer current. Change the current display back again. */ screenPtr->curDispPtr = oldDispPtr; @@ -1864,10 +1827,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0) { if (!bindInfoPtr->deleted) { /* - * Delete the pending list from the list of pending scripts - * for this window. + * Delete the pending list from the list of pending scripts for + * this window. */ - + PendingBinding **curPtrPtr; for (curPtrPtr = &bindInfoPtr->pendingList; ; ) { @@ -1890,8 +1853,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) * * TkBindDeadWindow -- * - * This procedure is invoked when it is determined that a window is - * dead. It cleans up bind-related information about the window + * This function is invoked when it is determined that a window is dead. + * It cleans up bind-related information about the window * * Results: * None. @@ -1901,7 +1864,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) * *--------------------------------------------------------------------------- */ - + void TkBindDeadWindow(winPtr) TkWindow *winPtr; /* The window that is being deleted. */ @@ -1910,11 +1873,13 @@ TkBindDeadWindow(winPtr) PendingBinding *curPtr; /* - * Certain special windows like those used for send and clipboard - * have no mainPtr. + * Certain special windows like those used for send and clipboard have no + * mainPtr. */ - if (winPtr->mainPtr == NULL) - return; + + if (winPtr->mainPtr == NULL) { + return; + } bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; curPtr = bindInfoPtr->pendingList; @@ -1931,33 +1896,34 @@ TkBindDeadWindow(winPtr) * * MatchPatterns -- * - * Given a list of pattern sequences and a list of recent events, - * return the pattern sequence that best matches the event list, - * if there is one. + * Given a list of pattern sequences and a list of recent events, return + * the pattern sequence that best matches the event list, if there is + * one. * - * This procedure is used in two different ways. In the simplest - * use, "object" is NULL and psPtr is a list of pattern sequences, - * each of which corresponds to a binding. In this case, the - * procedure finds the pattern sequences that match the event list - * and returns the most specific of those, if there is more than one. + * This function is used in two different ways. In the simplest use, + * "object" is NULL and psPtr is a list of pattern sequences, each of + * which corresponds to a binding. In this case, the function finds the + * pattern sequences that match the event list and returns the most + * specific of those, if there is more than one. * - * In the second case, psPtr is a list of pattern sequences, each - * of which corresponds to a definition for a virtual binding. - * In order for one of these sequences to "match", it must match - * the events (as above) but in addition there must be a binding - * for its associated virtual event on the current object. The - * "object" argument indicates which object the binding must be for. + * In the second case, psPtr is a list of pattern sequences, each of + * which corresponds to a definition for a virtual binding. In order for + * one of these sequences to "match", it must match the events (as above) + * but in addition there must be a binding for its associated virtual + * event on the current object. The "object" argument indicates which + * object the binding must be for. * * Results: - * The return value is NULL if bestPtr is NULL and no pattern matches - * the recent events from bindPtr. Otherwise the return value is - * the most specific pattern sequence among bestPtr and all those - * at psPtr that match the event list and object. If a pattern - * sequence other than bestPtr is returned, then *bestCommandPtr - * is filled in with a pointer to the command from the best sequence. + + * The return value is NULL if bestPtr is NULL and no pattern matches the + * recent events from bindPtr. Otherwise the return value is the most + * specific pattern sequence among bestPtr and all those at psPtr that + * match the event list and object. If a pattern sequence other than + * bestPtr is returned, then *bestCommandPtr is filled in with a pointer + * to the command from the best sequence. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -1967,22 +1933,22 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) BindingTable *bindPtr; /* Information about binding table, such as * ring of recent events. */ PatSeq *psPtr; /* List of pattern sequences. */ - PatSeq *bestPtr; /* The best match seen so far, from a - * previous call to this procedure. NULL - * means no prior best match. */ - ClientData *objectPtr; /* If NULL, the sequences at psPtr - * correspond to "normal" bindings. If - * non-NULL, the sequences at psPtr correspond - * to virtual bindings; in order to match each - * sequence must correspond to a virtual - * binding for which a binding exists for - * object in bindPtr. */ + PatSeq *bestPtr; /* The best match seen so far, from a previous + * call to this function. NULL means no prior + * best match. */ + ClientData *objectPtr; /* If NULL, the sequences at psPtr correspond + * to "normal" bindings. If non-NULL, the + * sequences at psPtr correspond to virtual + * bindings; in order to match each sequence + * must correspond to a virtual binding for + * which a binding exists for object in + * bindPtr. */ PatSeq **sourcePtrPtr; /* Filled with the pattern sequence that * contains the eventProc and clientData - * associated with the best match. If this + * associated with the best match. If this * differs from the return value, it is the * virtual event that most closely matched the - * return value (a physical event). Not + * return value (a physical event). Not * modified unless a result other than bestPtr * is returned. */ { @@ -2003,8 +1969,8 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) int modMask; /* - * Iterate over all the patterns in a sequence to be - * sure that they all match. + * Iterate over all the patterns in a sequence to be sure that they + * all match. */ eventPtr = &bindPtr->eventRing[bindPtr->curEvent]; @@ -2019,21 +1985,21 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) } if (eventPtr->xany.type != patPtr->eventType) { /* - * Most of the event types are considered superfluous - * in that they are ignored if they occur in the middle - * of a pattern sequence and have mismatching types. The - * only ones that cannot be ignored are ButtonPress and - * ButtonRelease events (if the next event in the pattern - * is a KeyPress or KeyRelease) and KeyPress and KeyRelease - * events (if the next pattern event is a ButtonPress or - * ButtonRelease). Here are some tricky cases to consider: + * Most of the event types are considered superfluous in that + * they are ignored if they occur in the middle of a pattern + * sequence and have mismatching types. The only ones that + * cannot be ignored are ButtonPress and ButtonRelease events + * (if the next event in the pattern is a KeyPress or + * KeyRelease) and KeyPress and KeyRelease events (if the next + * pattern event is a ButtonPress or ButtonRelease). Here are + * some tricky cases to consider: * 1. Double-Button or Double-Key events. * 2. Double-ButtonRelease or Double-KeyRelease events. - * 3. The arrival of various events like Enter and Leave - * and FocusIn and GraphicsExpose between two button - * presses or key presses. - * 4. Modifier keys like Shift and Control shouldn't - * generate conflicts with button events. + * 3. The arrival of various events like Enter and Leave and + * FocusIn and GraphicsExpose between two button presses or + * key presses. + * 4. Modifier keys like Shift and Control shouldn't generate + * conflicts with button events. */ if ((patPtr->eventType == KeyPress) @@ -2067,27 +2033,25 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) goto nextEvent; } if (eventPtr->xany.type == CreateNotify - && eventPtr->xcreatewindow.parent != window) { + && eventPtr->xcreatewindow.parent != window) { goto nextSequence; - } else - if (eventPtr->xany.window != window) { + } else if (eventPtr->xany.window != window) { goto nextSequence; } /* - * Note: it's important for the keysym check to go before - * the modifier check, so we can ignore unwanted modifier - * keys before choking on the modifier check. + * Note: it's important for the keysym check to go before the + * modifier check, so we can ignore unwanted modifier keys before + * choking on the modifier check. */ if ((patPtr->detail.clientData != 0) && (patPtr->detail.clientData != detailPtr->clientData)) { /* - * The detail appears not to match. However, if the event - * is a KeyPress for a modifier key then just ignore the - * event. Otherwise event sequences like "aD" never match - * because the shift key goes down between the "a" and the - * "D". + * The detail appears not to match. However, if the event is a + * KeyPress for a modifier key then just ignore the event. + * Otherwise event sequences like "aD" never match because the + * shift key goes down between the "a" and the "D". */ if (eventPtr->xany.type == KeyPress) { @@ -2149,7 +2113,7 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) } patPtr++; patCount--; - nextEvent: + nextEvent: if (eventPtr == bindPtr->eventRing) { eventPtr = &bindPtr->eventRing[EVENT_BUFFER_SIZE-1]; detailPtr = &bindPtr->detailRing[EVENT_BUFFER_SIZE-1]; @@ -2169,9 +2133,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) PatternTableKey key; /* - * The sequence matches the physical constraints. - * Is this object interested in any of the virtual events - * that correspond to this sequence? + * The sequence matches the physical constraints. Is this object + * interested in any of the virtual events that correspond to this + * sequence? */ voPtr = psPtr->voPtr; @@ -2182,9 +2146,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) key.detail.clientData = 0; for (iVirt = 0; iVirt < voPtr->numOwners; iVirt++) { - Tcl_HashEntry *hPtr = voPtr->owners[iVirt]; + Tcl_HashEntry *hPtr = voPtr->owners[iVirt]; - key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr, + key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr, hPtr); hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); @@ -2212,14 +2176,15 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) * The physical event matches a virtual event's definition, but * the tag isn't interested in it. */ + goto nextSequence; } - match: + match: /* - * This sequence matches. If we've already got another match, - * pick whichever is most specific. Detail is most important, - * then needMods. + * This sequence matches. If we've already got another match, pick + * whichever is most specific. Detail is most important, then + * needMods. */ if (bestPtr != NULL) { @@ -2255,28 +2220,27 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) /* * Tie goes to current best pattern. * - * (1) For virtual vs. virtual, the least recently defined - * virtual wins, because virtuals are examined in order of - * definition. This order is _not_ guaranteed in the - * documentation. + * (1) For virtual vs. virtual, the least recently defined virtual + * wins, because virtuals are examined in order of definition. + * This order is _not_ guaranteed in the documentation. * - * (2) For virtual vs. physical, the physical wins because all - * the physicals are examined before the virtuals. This order - * is guaranteed in the documentation. + * (2) For virtual vs. physical, the physical wins because all the + * physicals are examined before the virtuals. This order is + * guaranteed in the documentation. * * (3) For physical vs. physical pattern, the most recently * defined physical wins, because physicals are examined in - * reverse order of definition. This order is guaranteed in - * the documentation. + * reverse order of definition. This order is guaranteed in the + * documentation. */ - goto nextSequence; + goto nextSequence; } - newBest: + newBest: bestPtr = matchPtr; bestSourcePtr = sourcePtr; - nextSequence: + nextSequence: continue; } @@ -2290,13 +2254,12 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) * * ExpandPercents -- * - * Given a command and an event, produce a new command - * by replacing % constructs in the original command - * with information from the X event. + * Given a command and an event, produce a new command by replacing % + * constructs in the original command with information from the X event. * * Results: - * The new expanded command is appended to the dynamic string - * given by dsPtr. + * The new expanded command is appended to the dynamic string given by + * dsPtr. * * Side effects: * None. @@ -2306,12 +2269,12 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) static void ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) - TkWindow *winPtr; /* Window where event occurred: needed to - * get input context. */ - CONST char *before; /* Command containing percent expressions - * to be replaced. */ - XEvent *eventPtr; /* X event containing information to be - * used in % replacements. */ + TkWindow *winPtr; /* Window where event occurred: needed to get + * input context. */ + CONST char *before; /* Command containing percent expressions to + * be replaced. */ + XEvent *eventPtr; /* X event containing information to be used + * in % replacements. */ KeySym keySym; /* KeySym: only relevant for KeyPress and * KeyRelease events). */ Tcl_DString *dsPtr; /* Dynamic string in which to append new @@ -2332,10 +2295,11 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) } else { flags = 0; } + while (1) { /* - * Find everything up to the next % character and append it - * to the result string. + * Find everything up to the next % character and append it to the + * result string. */ for (string = before; (*string != 0) && (*string != '%'); string++) { @@ -2350,331 +2314,336 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) } /* - * There's a percent sequence here. Process it. + * There's a percent sequence here. Process it. */ number = 0; string = "??"; switch (before[1]) { - case '#': - number = eventPtr->xany.serial; - goto doNumber; - case 'a': - if (flags & CONFIG) { - TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); - string = numStorage; - } - goto doString; - case 'b': - if (flags & BUTTON) { - number = eventPtr->xbutton.button; - goto doNumber; - } - goto doString; - case 'c': - if (flags & EXPOSE) { - number = eventPtr->xexpose.count; - goto doNumber; - } - goto doString; - case 'd': - if (flags & (CROSSING|FOCUS)) { - if (flags & FOCUS) { - number = eventPtr->xfocus.detail; - } else { - number = eventPtr->xcrossing.detail; - } - string = TkFindStateString(notifyDetail, number); - } else if (flags & CONFIGREQ) { - if (eventPtr->xconfigurerequest.value_mask & CWStackMode) { - string = TkFindStateString(configureRequestDetail, - eventPtr->xconfigurerequest.detail); - } else { - string = ""; - } - } else if (flags & VIRTUAL) { - XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr; - - if (vePtr->user_data != NULL) { - string = Tcl_GetString(vePtr->user_data); - } else { - string = ""; - } - } - goto doString; - case 'f': - if (flags & CROSSING) { - number = eventPtr->xcrossing.focus; - goto doNumber; - } - goto doString; - case 'h': - if (flags & EXPOSE) { - number = eventPtr->xexpose.height; - } else if (flags & (CONFIG)) { - number = eventPtr->xconfigure.height; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.height; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.height; - } else if (flags & RESIZEREQ) { - number = eventPtr->xresizerequest.height; - } else { - goto doString; - } - goto doNumber; - case 'i': - if (flags & CREATE) { - TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window); - } else if (flags & CONFIGREQ) { - TkpPrintWindowId(numStorage, eventPtr->xconfigurerequest.window); - } else if (flags & MAPREQ) { - TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window); - } else { - TkpPrintWindowId(numStorage, eventPtr->xany.window); - } + case '#': + number = eventPtr->xany.serial; + goto doNumber; + case 'a': + if (flags & CONFIG) { + TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); string = numStorage; - goto doString; - case 'k': - if (flags & KEY) { - number = eventPtr->xkey.keycode; - goto doNumber; - } - goto doString; - case 'm': - if (flags & CROSSING) { - number = eventPtr->xcrossing.mode; - string = TkFindStateString(notifyMode, number); - } else if (flags & FOCUS) { - number = eventPtr->xfocus.mode; - string = TkFindStateString(notifyMode, number); - } - goto doString; - case 'o': - if (flags & CREATE) { - number = eventPtr->xcreatewindow.override_redirect; - } else if (flags & MAP) { - number = eventPtr->xmap.override_redirect; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.override_redirect; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.override_redirect; - } else { - goto doString; - } - goto doNumber; - case 'p': - if (flags & CIRC) { - string = TkFindStateString(circPlace, eventPtr->xcirculate.place); - } else if (flags & CIRCREQ) { - string = TkFindStateString(circPlace, eventPtr->xcirculaterequest.place); - } - goto doString; - case 's': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.state; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.state; - } else if (flags & PROP) { - string = TkFindStateString(propNotify, - eventPtr->xproperty.state); - goto doString; - } else if (flags & VISIBILITY) { - string = TkFindStateString(visNotify, - eventPtr->xvisibility.state); - goto doString; - } else { - goto doString; - } - goto doNumber; - case 't': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = (int) eventPtr->xkey.time; - } else if (flags & CROSSING) { - number = (int) eventPtr->xcrossing.time; - } else if (flags & PROP) { - number = (int) eventPtr->xproperty.time; - } else { - goto doString; - } + } + goto doString; + case 'b': + if (flags & BUTTON) { + number = eventPtr->xbutton.button; goto doNumber; - case 'v': - number = eventPtr->xconfigurerequest.value_mask; + } + goto doString; + case 'c': + if (flags & EXPOSE) { + number = eventPtr->xexpose.count; goto doNumber; - case 'w': - if (flags & EXPOSE) { - number = eventPtr->xexpose.width; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.width; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.width; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.width; - } else if (flags & RESIZEREQ) { - number = eventPtr->xresizerequest.width; + } + goto doString; + case 'd': + if (flags & (CROSSING|FOCUS)) { + if (flags & FOCUS) { + number = eventPtr->xfocus.detail; } else { - goto doString; + number = eventPtr->xcrossing.detail; } - goto doNumber; - case 'x': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.x; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.x; - } else if (flags & EXPOSE) { - number = eventPtr->xexpose.x; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - number = eventPtr->xcreatewindow.x; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.x; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.x; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.x; + string = TkFindStateString(notifyDetail, number); + } else if (flags & CONFIGREQ) { + if (eventPtr->xconfigurerequest.value_mask & CWStackMode) { + string = TkFindStateString(configureRequestDetail, + eventPtr->xconfigurerequest.detail); } else { - goto doString; + string = ""; } - goto doNumber; - case 'y': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.y; - } else if (flags & EXPOSE) { - number = eventPtr->xexpose.y; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - number = eventPtr->xcreatewindow.y; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.y; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.y; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.y; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.y; + } else if (flags & VIRTUAL) { + XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr; + + if (vePtr->user_data != NULL) { + string = Tcl_GetString(vePtr->user_data); } else { - goto doString; + string = ""; } + } + goto doString; + case 'f': + if (flags & CROSSING) { + number = eventPtr->xcrossing.focus; goto doNumber; - case 'A': - if (flags & KEY) { - Tcl_DStringFree(&buf); - string = TkpGetString(winPtr, eventPtr, &buf); - } + } + goto doString; + case 'h': + if (flags & EXPOSE) { + number = eventPtr->xexpose.height; + } else if (flags & (CONFIG)) { + number = eventPtr->xconfigure.height; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.height; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.height; + } else if (flags & RESIZEREQ) { + number = eventPtr->xresizerequest.height; + } else { goto doString; - case 'B': - if (flags & CREATE) { - number = eventPtr->xcreatewindow.border_width; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.border_width; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.border_width; - } else { - goto doString; - } + } + goto doNumber; + case 'i': + if (flags & CREATE) { + TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window); + } else if (flags & CONFIGREQ) { + TkpPrintWindowId(numStorage, + eventPtr->xconfigurerequest.window); + } else if (flags & MAPREQ) { + TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window); + } else { + TkpPrintWindowId(numStorage, eventPtr->xany.window); + } + string = numStorage; + goto doString; + case 'k': + if (flags & KEY) { + number = eventPtr->xkey.keycode; goto doNumber; - case 'D': - /* - * This is used only by the MouseWheel event. - */ - if (flags & KEY) { - number = eventPtr->xkey.keycode; - goto doNumber; - } + } + goto doString; + case 'm': + if (flags & CROSSING) { + number = eventPtr->xcrossing.mode; + string = TkFindStateString(notifyMode, number); + } else if (flags & FOCUS) { + number = eventPtr->xfocus.mode; + string = TkFindStateString(notifyMode, number); + } + goto doString; + case 'o': + if (flags & CREATE) { + number = eventPtr->xcreatewindow.override_redirect; + } else if (flags & MAP) { + number = eventPtr->xmap.override_redirect; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.override_redirect; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.override_redirect; + } else { goto doString; - case 'E': - number = (int) eventPtr->xany.send_event; - goto doNumber; - case 'K': - if (flags & KEY) { - char *name; - - name = TkKeysymToString(keySym); - if (name != NULL) { - string = name; - } - } + } + goto doNumber; + case 'p': + if (flags & CIRC) { + string = TkFindStateString(circPlace, + eventPtr->xcirculate.place); + } else if (flags & CIRCREQ) { + string = TkFindStateString(circPlace, + eventPtr->xcirculaterequest.place); + } + goto doString; + case 's': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.state; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.state; + } else if (flags & PROP) { + string = TkFindStateString(propNotify, + eventPtr->xproperty.state); goto doString; - case 'N': - if (flags & KEY) { - number = (int) keySym; - goto doNumber; - } + } else if (flags & VISIBILITY) { + string = TkFindStateString(visNotify, + eventPtr->xvisibility.state); goto doString; - case 'P': - if (flags & PROP) { - string = Tk_GetAtomName((Tk_Window) winPtr, eventPtr->xproperty.atom); - } + } else { goto doString; - case 'R': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - TkpPrintWindowId(numStorage, eventPtr->xkey.root); - string = numStorage; - } + } + goto doNumber; + case 't': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = (int) eventPtr->xkey.time; + } else if (flags & CROSSING) { + number = (int) eventPtr->xcrossing.time; + } else if (flags & PROP) { + number = (int) eventPtr->xproperty.time; + } else { goto doString; - case 'S': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow); - string = numStorage; - } + } + goto doNumber; + case 'v': + number = eventPtr->xconfigurerequest.value_mask; + goto doNumber; + case 'w': + if (flags & EXPOSE) { + number = eventPtr->xexpose.width; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.width; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.width; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.width; + } else if (flags & RESIZEREQ) { + number = eventPtr->xresizerequest.width; + } else { goto doString; - case 'T': - number = eventPtr->type; + } + goto doNumber; + case 'x': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.x; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.x; + } else if (flags & EXPOSE) { + number = eventPtr->xexpose.x; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + number = eventPtr->xcreatewindow.x; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.x; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.x; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.x; + } else { + goto doString; + } + goto doNumber; + case 'y': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.y; + } else if (flags & EXPOSE) { + number = eventPtr->xexpose.y; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + number = eventPtr->xcreatewindow.y; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.y; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.y; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.y; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.y; + } else { + goto doString; + } + goto doNumber; + case 'A': + if (flags & KEY) { + Tcl_DStringFree(&buf); + string = TkpGetString(winPtr, eventPtr, &buf); + } + goto doString; + case 'B': + if (flags & CREATE) { + number = eventPtr->xcreatewindow.border_width; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.border_width; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.border_width; + } else { + goto doString; + } + goto doNumber; + case 'D': + /* + * This is used only by the MouseWheel event. + */ + + if (flags & KEY) { + number = eventPtr->xkey.keycode; + goto doNumber; + } + goto doString; + case 'E': + number = (int) eventPtr->xany.send_event; + goto doNumber; + case 'K': + if (flags & KEY) { + char *name; + + name = TkKeysymToString(keySym); + if (name != NULL) { + string = name; + } + } + goto doString; + case 'N': + if (flags & KEY) { + number = (int) keySym; goto doNumber; - case 'W': { + } + goto doString; + case 'P': + if (flags & PROP) { + string = Tk_GetAtomName((Tk_Window) winPtr, + eventPtr->xproperty.atom); + } + goto doString; + case 'R': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + TkpPrintWindowId(numStorage, eventPtr->xkey.root); + string = numStorage; + } + goto doString; + case 'S': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow); + string = numStorage; + } + goto doString; + case 'T': + number = eventPtr->type; + goto doNumber; + case 'W': { + Tk_Window tkwin; + + tkwin = Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); + if (tkwin != NULL) { + string = Tk_PathName(tkwin); + } else { + string = "??"; + } + goto doString; + } + case 'X': + if (flags & KEY_BUTTON_MOTION_CROSSING) { Tk_Window tkwin; + int x, y; + int width, height; + number = eventPtr->xkey.x_root; tkwin = Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window); if (tkwin != NULL) { - string = Tk_PathName(tkwin); - } else { - string = "??"; + Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); + number -= x; } - goto doString; + goto doNumber; } - case 'X': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - Tk_Window tkwin; - int x, y; - int width, height; - - number = eventPtr->xkey.x_root; - tkwin = Tk_IdToWindow(eventPtr->xany.display, - eventPtr->xany.window); - if (tkwin != NULL) { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= x; - } - goto doNumber; - } - goto doString; - case 'Y': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - Tk_Window tkwin; - int x, y; - int width, height; - - number = eventPtr->xkey.y_root; - tkwin = Tk_IdToWindow(eventPtr->xany.display, - eventPtr->xany.window); - if (tkwin != NULL) { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= y; - } - goto doNumber; + goto doString; + case 'Y': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + Tk_Window tkwin; + int x, y; + int width, height; + + number = eventPtr->xkey.y_root; + tkwin = Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); + if (tkwin != NULL) { + Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); + number -= y; } - goto doString; - default: - numStorage[0] = before[1]; - numStorage[1] = '\0'; - string = numStorage; - goto doString; + goto doNumber; + } + goto doString; + default: + numStorage[0] = before[1]; + numStorage[1] = '\0'; + string = numStorage; + goto doString; } - doNumber: + doNumber: sprintf(numStorage, "%d", number); string = numStorage; - doString: + doString: spaceNeeded = Tcl_ScanElement(string, &cvtFlags); length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); @@ -2692,28 +2661,27 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) * * ChangeScreen -- * - * This procedure is invoked whenever the current screen changes - * in an application. It invokes a Tcl procedure named - * "tk::ScreenChanged", passing it the screen name as argument. - * tk::ScreenChanged does things like making the tk::Priv variable - * point to an array for the current display. + * This function is invoked whenever the current screen changes in an + * application. It invokes a Tcl function named "tk::ScreenChanged", + * passing it the screen name as argument. tk::ScreenChanged does things + * like making the tk::Priv variable point to an array for the current + * display. * * Results: * None. * * Side effects: - * Depends on what tk::ScreenChanged does. If an error occurs - * them bgerror will be invoked. + * Depends on what tk::ScreenChanged does. If an error occurs them + * bgerror will be invoked. * *---------------------------------------------------------------------- */ static void ChangeScreen(interp, dispName, screenIndex) - Tcl_Interp *interp; /* Interpreter in which to invoke - * command. */ - char *dispName; /* Name of new display. */ - int screenIndex; /* Index of new screen. */ + Tcl_Interp *interp; /* Interpreter in which to invoke command. */ + char *dispName; /* Name of new display. */ + int screenIndex; /* Index of new screen. */ { Tcl_DString cmd; int code; @@ -2738,8 +2706,8 @@ ChangeScreen(interp, dispName, screenIndex) * * Tk_EventCmd -- * - * This procedure is invoked to process the "event" Tcl command. - * It is used to define and generate events. + * This function is invoked to process the "event" Tcl command. It is + * used to define and generate events. * * Results: * A standard Tcl result. @@ -2783,64 +2751,61 @@ Tk_EventObjCmd(clientData, interp, objc, objv) } switch ((enum options) index) { - case EVENT_ADD: { - int i; - char *name, *event; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "virtual sequence ?sequence ...?"); - return TCL_ERROR; - } - name = Tcl_GetStringFromObj(objv[2], NULL); - for (i = 3; i < objc; i++) { - event = Tcl_GetStringFromObj(objv[i], NULL); - if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { - return TCL_ERROR; - } - } - break; + case EVENT_ADD: { + int i; + char *name, *event; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual sequence ?sequence ...?"); + return TCL_ERROR; } - case EVENT_DELETE: { - int i; - char *name, *event; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, - "virtual ?sequence sequence ...?"); + name = Tcl_GetStringFromObj(objv[2], NULL); + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { return TCL_ERROR; } - name = Tcl_GetStringFromObj(objv[2], NULL); - if (objc == 3) { - return DeleteVirtualEvent(interp, vetPtr, name, NULL); - } - for (i = 3; i < objc; i++) { - event = Tcl_GetStringFromObj(objv[i], NULL); - if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { - return TCL_ERROR; - } - } - break; } - case EVENT_GENERATE: { - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); - return TCL_ERROR; - } - return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); + break; + } + case EVENT_DELETE: { + int i; + char *name, *event; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual ?sequence sequence ...?"); + return TCL_ERROR; } - case EVENT_INFO: { - if (objc == 2) { - GetAllVirtualEvents(interp, vetPtr); - return TCL_OK; - } else if (objc == 3) { - return GetVirtualEvent(interp, vetPtr, - Tcl_GetStringFromObj(objv[2], NULL)); - } else { - Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); + name = Tcl_GetStringFromObj(objv[2], NULL); + if (objc == 3) { + return DeleteVirtualEvent(interp, vetPtr, name, NULL); + } + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { return TCL_ERROR; } } + break; + } + case EVENT_GENERATE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); + return TCL_ERROR; + } + return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); + case EVENT_INFO: + if (objc == 2) { + GetAllVirtualEvents(interp, vetPtr); + return TCL_OK; + } else if (objc == 3) { + return GetVirtualEvent(interp, vetPtr, Tcl_GetString(objv[2])); + } else { + Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); + return TCL_ERROR; + } } return TCL_OK; } @@ -2850,8 +2815,8 @@ Tk_EventObjCmd(clientData, interp, objc, objv) * * InitVirtualEventTable -- * - * Given storage for a virtual event table, set up the fields to - * prepare a new domain in which virtual events may be defined. + * Given storage for a virtual event table, set up the fields to prepare + * a new domain in which virtual events may be defined. * * Results: * None. @@ -2864,8 +2829,8 @@ Tk_EventObjCmd(clientData, interp, objc, objv) static void InitVirtualEventTable(vetPtr) - VirtualEventTable *vetPtr; /* Pointer to virtual event table. Memory - * is supplied by the caller. */ + VirtualEventTable *vetPtr; /* Pointer to virtual event table. Memory is + * supplied by the caller. */ { Tcl_InitHashTable(&vetPtr->patternTable, sizeof(PatternTableKey) / sizeof(int)); @@ -2877,7 +2842,7 @@ InitVirtualEventTable(vetPtr) * * DeleteVirtualEventTable -- * - * Delete the contents of a virtual event table. The caller is + * Delete the contents of a virtual event table. The caller is * responsible for freeing any memory used by the table itself. * * Results: @@ -2910,7 +2875,7 @@ DeleteVirtualEventTable(vetPtr) hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree((char *) Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(&vetPtr->nameTable); } @@ -2920,19 +2885,17 @@ DeleteVirtualEventTable(vetPtr) * * CreateVirtualEvent -- * - * Add a new definition for a virtual event. If the virtual event - * is already defined, the new definition augments those that - * already exist. + * Add a new definition for a virtual event. If the virtual event is + * already defined, the new definition augments those that already exist. * * Results: - * The return value is TCL_ERROR if an error occured while - * creating the virtual binding. In this case, an error message - * will be left in the interp's result. If all went well then the - * return value is TCL_OK. + * The return value is TCL_ERROR if an error occured while creating the + * virtual binding. In this case, an error message will be left in the + * interp's result. If all went well then the return value is TCL_OK. * * Side effects: - * The virtual event may cause future calls to Tk_BindEvent to - * behave differently than they did previously. + * The virtual event may cause future calls to Tk_BindEvent to behave + * differently than they did previously. * *---------------------------------------------------------------------- */ @@ -2940,7 +2903,7 @@ DeleteVirtualEventTable(vetPtr) static int CreateVirtualEvent(interp, vetPtr, virtString, eventString) Tcl_Interp *interp; /* Used for error reporting. */ - VirtualEventTable *vetPtr;/* Table in which to augment virtual event. */ + VirtualEventTable *vetPtr; /* Table in which to augment virtual event. */ char *virtString; /* Name of new virtual event. */ char *eventString; /* String describing physical event that * triggers virtual event. */ @@ -2952,10 +2915,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) PhysicalsOwned *poPtr; VirtualOwners *voPtr; Tk_Uid virtUid; - + virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } /* @@ -2965,7 +2928,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) psPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString, 1, 0, &eventMask); if (psPtr == NULL) { - return TCL_ERROR; + return TCL_ERROR; } /* @@ -2983,20 +2946,21 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) poPtr = (PhysicalsOwned *) ckalloc(sizeof(PhysicalsOwned)); poPtr->numOwned = 0; } else { - /* + /* * See if this virtual event is already defined for this physical * event and just return if it is. */ int i; + for (i = 0; i < poPtr->numOwned; i++) { if (poPtr->patSeqs[i] == psPtr) { - return TCL_OK; + return TCL_OK; } } poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr, sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *)); - } + } Tcl_SetHashValue(vhPtr, (ClientData) poPtr); poPtr->patSeqs[poPtr->numOwned] = psPtr; poPtr->numOwned++; @@ -3007,10 +2971,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) voPtr = psPtr->voPtr; if (voPtr == NULL) { - voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners)); + voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners)); voPtr->numOwners = 0; } else { - voPtr = (VirtualOwners *) ckrealloc((char *) voPtr, + voPtr = (VirtualOwners *) ckrealloc((char *) voPtr, sizeof(VirtualOwners) + voPtr->numOwners * sizeof(Tcl_HashEntry *)); } @@ -3026,20 +2990,20 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) * * DeleteVirtualEvent -- * - * Remove the definition of a given virtual event. If the - * event string is NULL, all definitions of the virtual event - * will be removed. Otherwise, just the specified definition - * of the virtual event will be removed. + * Remove the definition of a given virtual event. If the event string is + * NULL, all definitions of the virtual event will be removed. + * Otherwise, just the specified definition of the virtual event will be + * removed. * * Results: - * The result is a standard Tcl return value. If an error - * occurs then the interp's result will contain an error message. - * It is not an error to attempt to delete a virtual event that - * does not exist or a definition that does not exist. + * The result is a standard Tcl return value. If an error occurs then the + * interp's result will contain an error message. It is not an error to + * attempt to delete a virtual event that does not exist or a definition + * that does not exist. * * Side effects: - * The virtual event given by virtString may be removed from the - * virtual event table. + * The virtual event given by virtString may be removed from the virtual + * event table. * *-------------------------------------------------------------- */ @@ -3047,7 +3011,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) static int DeleteVirtualEvent(interp, vetPtr, virtString, eventString) Tcl_Interp *interp; /* Used for error reporting. */ - VirtualEventTable *vetPtr;/* Table in which to delete event. */ + VirtualEventTable *vetPtr; /* Table in which to delete event. */ char *virtString; /* String describing event sequence that * triggers binding. */ char *eventString; /* The event sequence that should be deleted, @@ -3062,12 +3026,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } - + vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid); if (vhPtr == NULL) { - return TCL_OK; + return TCL_OK; } poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr); @@ -3076,10 +3040,9 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) unsigned long eventMask; /* - * Delete only the specific physical event associated with the - * virtual event. If the physical event doesn't already exist, or - * the virtual event doesn't own that physical event, return w/o - * doing anything. + * Delete only the specific physical event associated with the virtual + * event. If the physical event doesn't already exist, or the virtual + * event doesn't own that physical event, return w/o doing anything. */ eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL, @@ -3087,7 +3050,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if (eventPSPtr == NULL) { CONST char *string; - string = Tcl_GetStringResult(interp); + string = Tcl_GetStringResult(interp); return (string[0] != '\0') ? TCL_ERROR : TCL_OK; } } @@ -3097,7 +3060,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if ((eventPSPtr == NULL) || (psPtr == eventPSPtr)) { int iVirt; VirtualOwners *voPtr; - + /* * Remove association between this physical event and the given * virtual event that it triggers. @@ -3115,10 +3078,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) voPtr->numOwners--; if (voPtr->numOwners == 0) { /* - * Removed last reference to this physical event, so - * remove it from physical->virtual map. + * Removed last reference to this physical event, so remove it + * from physical->virtual map. */ + PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); + if (prevPtr == psPtr) { if (psPtr->nextSeqPtr == NULL) { Tcl_DeleteHashEntry(psPtr->hPtr); @@ -3142,23 +3107,23 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) } else { /* * This physical event still triggers some other virtual - * event(s). Consolidate the list of virtual owners for - * this physical event so it no longer triggers the - * given virtual event. + * event(s). Consolidate the list of virtual owners for this + * physical event so it no longer triggers the given virtual + * event. */ + voPtr->owners[iVirt] = voPtr->owners[voPtr->numOwners]; } /* - * Now delete the virtual event's reference to the physical - * event. + * Now delete the virtual event's reference to the physical event. */ poPtr->numOwned--; if (eventPSPtr != NULL && poPtr->numOwned != 0) { - /* - * Just deleting this one physical event. Consolidate list - * of owned physical events and return. + /* + * Just deleting this one physical event. Consolidate list of + * owned physical events and return. */ poPtr->patSeqs[iPhys] = poPtr->patSeqs[poPtr->numOwned]; @@ -3169,10 +3134,10 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if (poPtr->numOwned == 0) { /* - * All the physical events for this virtual event were deleted, - * either because there was only one associated physical event or - * because the caller was deleting the entire virtual event. Now - * the virtual event itself should be deleted. + * All the physical events for this virtual event were deleted, either + * because there was only one associated physical event or because the + * caller was deleting the entire virtual event. Now the virtual event + * itself should be deleted. */ ckfree((char *) poPtr); @@ -3186,16 +3151,16 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) * * GetVirtualEvent -- * - * Return the list of physical events that can invoke the - * given virtual event. + * Return the list of physical events that can invoke the given virtual + * event. * * Results: * The return value is TCL_OK and the interp's result is filled with the * string representation of the physical events associated with the * virtual event; if there are no physical events for the given virtual - * event, the interp's result is filled with and empty string. If the - * virtual event string is improperly formed, then TCL_ERROR is - * returned and an error message is left in the interp's result. + * event, the interp's result is filled with and empty string. If the + * virtual event string is improperly formed, then TCL_ERROR is returned + * and an error message is left in the interp's result. * * Side effects: * None. @@ -3206,7 +3171,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) static int GetVirtualEvent(interp, vetPtr, virtString) Tcl_Interp *interp; /* Interpreter for reporting. */ - VirtualEventTable *vetPtr;/* Table in which to look for event. */ + VirtualEventTable *vetPtr; /* Table in which to look for event. */ char *virtString; /* String describing virtual event. */ { Tcl_HashEntry *vhPtr; @@ -3217,12 +3182,12 @@ GetVirtualEvent(interp, vetPtr, virtString) virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid); if (vhPtr == NULL) { - return TCL_OK; + return TCL_OK; } Tcl_DStringInit(&ds); @@ -3243,13 +3208,12 @@ GetVirtualEvent(interp, vetPtr, virtString) * * GetAllVirtualEvents -- * - * Return a list that contains the names of all the virtual - * event defined. + * Return a list that contains the names of all the virtual event + * defined. * * Results: - * There is no return value. The interp's result is modified to - * hold a Tcl list with one entry for each virtual event in - * nameTable. + * There is no return value. The interp's result is modified to hold a + * Tcl list with one entry for each virtual event in nameTable. * * Side effects: * None. @@ -3270,11 +3234,11 @@ GetAllVirtualEvents(interp, vetPtr) hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_DStringSetLength(&ds, 0); + Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, "<<", 2); Tcl_DStringAppend(&ds, Tcl_GetHashKey(hPtr->tablePtr, hPtr), -1); Tcl_DStringAppend(&ds, ">>", 2); - Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); + Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); } Tcl_DStringFree(&ds); @@ -3285,36 +3249,36 @@ GetAllVirtualEvents(interp, vetPtr) * * HandleEventGenerate -- * - * Helper function for the "event generate" command. Generate and - * process an XEvent, constructed from information parsed from the - * event description string and its optional arguments. + * Helper function for the "event generate" command. Generate and process + * an XEvent, constructed from information parsed from the event + * description string and its optional arguments. * * argv[0] contains name of the target window. * argv[1] contains pattern string for one event (e.g, <Control-v>). - * argv[2..argc-1] contains -field/option pairs for specifying - * additional detail in the generated event. + * argv[2..argc-1] contains -field/option pairs for specifying additional + * detail in the generated event. * - * Either virtual or physical events can be generated this way. - * The event description string must contain the specification - * for only one event. + * Either virtual or physical events can be generated this way. The event + * description string must contain the specification for only one event. * * Results: * None. * * Side effects: - * When constructing the event, - * event.xany.serial is filled with the current X serial number. - * event.xany.window is filled with the target window. - * event.xany.display is filled with the target window's display. + * When constructing the event, + * event.xany.serial is filled with the current X serial number. + * event.xany.window is filled with the target window. + * event.xany.display is filled with the target window's display. * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * - * The event may be handled sychronously or asynchronously, depending - * on the value specified by the optional "-when" option. The - * default setting is synchronous. + * The event may be handled sychronously or asynchronously, depending on + * the value specified by the optional "-when" option. The default + * setting is synchronous. * *--------------------------------------------------------------------------- */ + static int HandleEventGenerate(interp, mainWin, objc, objv) Tcl_Interp *interp; /* Interp for errors return and name lookup. */ @@ -3322,7 +3286,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { - XEvent event; + XEvent event; CONST char *p; char *name, *windowName; int count, flags, synch, i, number, warp; @@ -3366,7 +3330,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) char *name; name = Tcl_GetStringFromObj(objv[0], NULL); - Tcl_AppendResult(interp, "window id \"", name, + Tcl_AppendResult(interp, "window id \"", name, "\" doesn't exist in this application", (char *) NULL); return TCL_ERROR; } @@ -3398,16 +3362,17 @@ HandleEventGenerate(interp, mainWin, objc, objv) if (windowName[0]) { event.xany.window = Tk_WindowId(tkwin); } else { - event.xany.window = RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); + event.xany.window = + RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); } event.xany.display = Tk_Display(tkwin); flags = flagArray[event.xany.type]; if (flags & DESTROY) { /* - * Event DesotryNotify should be generated by destroying - * the window. + * Event DesotryNotify should be generated by destroying the window. */ + Tk_DestroyWindow(tkwin); return TCL_OK; } @@ -3431,8 +3396,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) } /* - * Process the remaining arguments to fill in additional fields - * of the event. + * Process the remaining arguments to fill in additional fields of the + * event. */ synch = 1; @@ -3441,7 +3406,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) for (i = 2; i < objc; i += 2) { Tcl_Obj *optionPtr, *valuePtr; int index; - + optionPtr = objv[i]; valuePtr = objv[i + 1]; @@ -3451,10 +3416,10 @@ HandleEventGenerate(interp, mainWin, objc, objv) } if (objc & 1) { /* - * This test occurs after Tcl_GetIndexFromObj() so that - * "event generate <Button> -xyz" will return the error message - * that "-xyz" is a bad option, rather than that the value - * for "-xyz" is missing. + * This test occurs after Tcl_GetIndexFromObj() so that "event + * generate <Button> -xyz" will return the error message that + * "-xyz" is a bad option, rather than that the value for "-xyz" + * is missing. */ Tcl_AppendResult(interp, "value for \"", @@ -3464,406 +3429,378 @@ HandleEventGenerate(interp, mainWin, objc, objv) } switch ((enum field) index) { - case EVENT_WARP: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { - return TCL_ERROR; - } - if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { - goto badopt; - } - break; + case EVENT_WARP: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { + return TCL_ERROR; } - case EVENT_WHEN: { - pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, - queuePosition, valuePtr); - if ((int) pos < -1) { - return TCL_ERROR; - } - synch = 0; - if ((int) pos == -1) { - synch = 1; - } - break; + if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { + goto badopt; } - case EVENT_ABOVE: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CONFIG) { - event.xconfigure.above = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_WHEN: + pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, + queuePosition, valuePtr); + if ((int) pos < -1) { + return TCL_ERROR; } - case EVENT_BORDER: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.border_width = number; - } else { - goto badopt; - } - break; + synch = 0; + if ((int) pos == -1) { + synch = 1; } - case EVENT_BUTTON: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & BUTTON) { - event.xbutton.button = number; - } else { - goto badopt; - } - break; + break; + case EVENT_ABOVE: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; } - case EVENT_COUNT: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & EXPOSE) { - event.xexpose.count = number; - } else { - goto badopt; - } - break; + if (flags & CONFIG) { + event.xconfigure.above = Tk_WindowId(tkwin2); + } else { + goto badopt; } - case EVENT_DATA: - if (flags & VIRTUAL) { - /* - * Do not increment reference count until after - * parsing completes and we know that the event - * generation is really going to happen. - */ - userDataObj = valuePtr; - } else { - goto badopt; - } - break; - case EVENT_DELTA: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; - } - break; + break; + case EVENT_BORDER: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_DETAIL: { - number = TkFindStateNumObj(interp, optionPtr, notifyDetail, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & FOCUS) { - event.xfocus.detail = number; - } else if (flags & CROSSING) { - event.xcrossing.detail = number; - } else { - goto badopt; - } - break; + if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.border_width = number; + } else { + goto badopt; } - case EVENT_FOCUS: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CROSSING) { - event.xcrossing.focus = number; - } else { - goto badopt; - } - break; + break; + case EVENT_BUTTON: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_HEIGHT: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & EXPOSE) { - event.xexpose.height = number; - } else if (flags & CONFIG) { - event.xconfigure.height = number; - } else { - goto badopt; - } - break; + if (flags & BUTTON) { + event.xbutton.button = number; + } else { + goto badopt; } - case EVENT_KEYCODE: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; - } - break; + break; + case EVENT_COUNT: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.count = number; + } else { + goto badopt; } - case EVENT_KEYSYM: { - KeySym keysym; - char *value; + break; + case EVENT_DATA: + if (flags & VIRTUAL) { + /* + * Do not increment reference count until after parsing + * completes and we know that the event generation is really + * going to happen. + */ - value = Tcl_GetStringFromObj(valuePtr, NULL); - keysym = TkStringToKeysym(value); - if (keysym == NoSymbol) { - Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", - (char *) NULL); - return TCL_ERROR; - } + userDataObj = valuePtr; + } else { + goto badopt; + } + break; + case EVENT_DELTA: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; + case EVENT_DETAIL: + number = TkFindStateNumObj(interp, optionPtr, notifyDetail, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & FOCUS) { + event.xfocus.detail = number; + } else if (flags & CROSSING) { + event.xcrossing.detail = number; + } else { + goto badopt; + } + break; + case EVENT_FOCUS: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & CROSSING) { + event.xcrossing.focus = number; + } else { + goto badopt; + } + break; + case EVENT_HEIGHT: + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, + &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.height = number; + } else if (flags & CONFIG) { + event.xconfigure.height = number; + } else { + goto badopt; + } + break; + case EVENT_KEYCODE: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; + case EVENT_KEYSYM: { + KeySym keysym; + char *value; + + value = Tcl_GetStringFromObj(valuePtr, NULL); + keysym = TkStringToKeysym(value); + if (keysym == NoSymbol) { + Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", + (char *) NULL); + return TCL_ERROR; + } - TkpSetKeycodeAndState(tkwin, keysym, &event); - if (event.xkey.keycode == 0) { - Tcl_AppendResult(interp, "no keycode for keysym \"", value, - "\"", (char *) NULL); - return TCL_ERROR; - } - if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { - goto badopt; - } - break; + TkpSetKeycodeAndState(tkwin, keysym, &event); + if (event.xkey.keycode == 0) { + Tcl_AppendResult(interp, "no keycode for keysym \"", value, + "\"", (char *) NULL); + return TCL_ERROR; } - case EVENT_MODE: { - number = TkFindStateNumObj(interp, optionPtr, notifyMode, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CROSSING) { - event.xcrossing.mode = number; - } else if (flags & FOCUS) { - event.xfocus.mode = number; - } else { - goto badopt; - } - break; + if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { + goto badopt; } - case EVENT_OVERRIDE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CREATE) { - event.xcreatewindow.override_redirect = number; - } else if (flags & MAP) { - event.xmap.override_redirect = number; - } else if (flags & REPARENT) { - event.xreparent.override_redirect = number; - } else if (flags & CONFIG) { - event.xconfigure.override_redirect = number; - } else { - goto badopt; - } - break; + break; + } + case EVENT_MODE: + number = TkFindStateNumObj(interp,optionPtr,notifyMode,valuePtr); + if (number < 0) { + return TCL_ERROR; } - case EVENT_PLACE: { - number = TkFindStateNumObj(interp, optionPtr, circPlace, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CIRC) { - event.xcirculate.place = number; - } else { - goto badopt; - } - break; + if (flags & CROSSING) { + event.xcrossing.mode = number; + } else if (flags & FOCUS) { + event.xfocus.mode = number; + } else { + goto badopt; } - case EVENT_ROOT: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.root = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_OVERRIDE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_ROOTX: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x_root = number; - } else { - goto badopt; - } - break; + if (flags & CREATE) { + event.xcreatewindow.override_redirect = number; + } else if (flags & MAP) { + event.xmap.override_redirect = number; + } else if (flags & REPARENT) { + event.xreparent.override_redirect = number; + } else if (flags & CONFIG) { + event.xconfigure.override_redirect = number; + } else { + goto badopt; } - case EVENT_ROOTY: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y_root = number; - } else { - goto badopt; - } - break; + break; + case EVENT_PLACE: + number = TkFindStateNumObj(interp, optionPtr, circPlace, valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & CIRC) { + event.xcirculate.place = number; + } else { + goto badopt; + } + break; + case EVENT_ROOT: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.root = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_ROOTX: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x_root = number; + } else { + goto badopt; + } + break; + case EVENT_ROOTY: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y_root = number; + } else { + goto badopt; } - case EVENT_SEND: { - CONST char *value; + break; + case EVENT_SEND: { + CONST char *value; - value = Tcl_GetStringFromObj(valuePtr, NULL); - if (isdigit(UCHAR(value[0]))) { - /* - * Allow arbitrary integer values for the field; they - * are needed by a few of the tests in the Tk test suite. - */ + value = Tcl_GetStringFromObj(valuePtr, NULL); + if (isdigit(UCHAR(value[0]))) { + /* + * Allow arbitrary integer values for the field; they are + * needed by a few of the tests in the Tk test suite. + */ - if (Tcl_GetIntFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - } else { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - } - event.xany.send_event = number; - break; - } - case EVENT_SERIAL: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - event.xany.serial = number; - break; - } - case EVENT_STATE: { - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - event.xkey.state = number; - } else { - event.xcrossing.state = number; - } - } else if (flags & VISIBILITY) { - number = TkFindStateNumObj(interp, optionPtr, visNotify, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - event.xvisibility.state = number; - } else { - goto badopt; - } - break; - } - case EVENT_SUBWINDOW: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + } else { + if (Tcl_GetBooleanFromObj(interp,valuePtr,&number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.subwindow = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; } - case EVENT_TIME: { + event.xany.send_event = number; + break; + } + case EVENT_SERIAL: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + event.xany.serial = number; + break; + case EVENT_STATE: + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.time = (Time) number; - } else if (flags & PROP) { - event.xproperty.time = (Time) number; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + event.xkey.state = number; } else { - goto badopt; + event.xcrossing.state = number; } - break; - } - case EVENT_WIDTH: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { + } else if (flags & VISIBILITY) { + number = TkFindStateNumObj(interp, optionPtr, visNotify, + valuePtr); + if (number < 0) { return TCL_ERROR; } - if (flags & EXPOSE) { - event.xexpose.width = number; - } else if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.width = number; - } else { - goto badopt; - } - break; + event.xvisibility.state = number; + } else { + goto badopt; } - case EVENT_WINDOW: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG - |GRAVITY|CIRC)) { - event.xcreatewindow.window = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_SUBWINDOW: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; } - case EVENT_X: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x = number; - /* - * Only modify rootx as well if it hasn't been changed. - */ - if (event.xkey.x_root == -1) { - int rootX, rootY; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.subwindow = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_TIME: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.time = (Time) number; + } else if (flags & PROP) { + event.xproperty.time = (Time) number; + } else { + goto badopt; + } + break; + case EVENT_WIDTH: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.width = number; + } else if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.width = number; + } else { + goto badopt; + } + break; + case EVENT_WINDOW: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) { + event.xcreatewindow.window = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_X: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x = number; - Tk_GetRootCoords(tkwin, &rootX, &rootY); - event.xkey.x_root = rootX + number; - } - } else if (flags & EXPOSE) { - event.xexpose.x = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.x = number; - } else if (flags & REPARENT) { - event.xreparent.x = number; - } else { - goto badopt; + /* + * Only modify rootx as well if it hasn't been changed. + */ + + if (event.xkey.x_root == -1) { + int rootX, rootY; + + Tk_GetRootCoords(tkwin, &rootX, &rootY); + event.xkey.x_root = rootX + number; } - break; + } else if (flags & EXPOSE) { + event.xexpose.x = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.x = number; + } else if (flags & REPARENT) { + event.xreparent.x = number; + } else { + goto badopt; } - case EVENT_Y: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y = number; - /* - * Only modify rooty as well if it hasn't been changed. - */ - if (event.xkey.y_root == -1) { - int rootX, rootY; + break; + case EVENT_Y: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y = number; - Tk_GetRootCoords(tkwin, &rootX, &rootY); - event.xkey.y_root = rootY + number; - } - } else if (flags & EXPOSE) { - event.xexpose.y = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.y = number; - } else if (flags & REPARENT) { - event.xreparent.y = number; - } else { - goto badopt; + /* + * Only modify rooty as well if it hasn't been changed. + */ + + if (event.xkey.y_root == -1) { + int rootX, rootY; + + Tk_GetRootCoords(tkwin, &rootX, &rootY); + event.xkey.y_root = rootY + number; } - break; + } else if (flags & EXPOSE) { + event.xexpose.y = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.y = number; + } else if (flags & REPARENT) { + event.xreparent.y = number; + } else { + goto badopt; } + break; } continue; - - badopt: + + badopt: Tcl_AppendResult(interp, name, " event doesn't accept \"", Tcl_GetStringFromObj(optionPtr, NULL), "\" option", NULL); return TCL_ERROR; @@ -3872,23 +3809,31 @@ HandleEventGenerate(interp, mainWin, objc, objv) XVirtualEvent *vePtr = (XVirtualEvent *) &event; /* - * Must be virtual event to set that variable to non-NULL. - * Now we want to install the object into the event. Note - * that we must incr the refcount before firing it into the - * low-level event subsystem; the refcount will be decremented - * once the event has been processed. + * Must be virtual event to set that variable to non-NULL. Now we want + * to install the object into the event. Note that we must incr the + * refcount before firing it into the low-level event subsystem; the + * refcount will be decremented once the event has been processed. */ + vePtr->user_data = userDataObj; Tcl_IncrRefCount(userDataObj); } + + /* + * Now we have constructed the event, inject it into the event handling + * code. + */ + if (synch != 0) { Tk_HandleEvent(&event); } else { Tk_QueueWindowEvent(&event, pos); } + /* - * We only allow warping if the window is mapped + * We only allow warping if the window is mapped. */ + if ((warp != 0) && Tk_IsMapped(tkwin)) { TkDisplay *dispPtr; dispPtr = TkGetDisplay(event.xmotion.display); @@ -3902,8 +3847,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) } Tcl_ResetResult(interp); return TCL_OK; - } + static int NameToWindow(interp, mainWin, objPtr, tkwinPtr) Tcl_Interp *interp; /* Interp for error return and name lookup. */ @@ -3925,7 +3870,7 @@ NameToWindow(interp, mainWin, objPtr, tkwinPtr) } else { /* * Check for the winPtr being valid, even if it looks ok to - * TkpScanWindowId. [Bug #411307] + * TkpScanWindowId. [Bug #411307] */ if ((TkpScanWindowId(NULL, name, &id) != TCL_OK) || @@ -3961,7 +3906,7 @@ DoWarp(clientData) TkDisplay *dispPtr = (TkDisplay *) clientData; XWarpPointer(dispPtr->display, (Window) None, (Window) dispPtr->warpWindow, - 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); + 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); XForceScreenSaver(dispPtr->display, ScreenSaverReset); dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } @@ -3971,20 +3916,21 @@ DoWarp(clientData) * * GetVirtualEventUid -- * - * Determine if the given string is in the proper format for a - * virtual event. + * Determine if the given string is in the proper format for a virtual + * event. * * Results: - * The return value is NULL if the virtual event string was - * not in the proper format. In this case, an error message - * will be left in the interp's result. Otherwise the return - * value is a Tk_Uid that represents the virtual event. + * The return value is NULL if the virtual event string was not in the + * proper format. In this case, an error message will be left in the + * interp's result. Otherwise the return value is a Tk_Uid that + * represents the virtual event. * * Side effects: * None. * *------------------------------------------------------------------------- */ + static Tk_Uid GetVirtualEventUid(interp, virtString) Tcl_Interp *interp; @@ -3997,9 +3943,9 @@ GetVirtualEventUid(interp, virtString) if (length < 5 || virtString[0] != '<' || virtString[1] != '<' || virtString[length - 2] != '>' || virtString[length - 1] != '>') { - Tcl_AppendResult(interp, "virtual event \"", virtString, + Tcl_AppendResult(interp, "virtual event \"", virtString, "\" is badly formed", (char *) NULL); - return NULL; + return NULL; } virtString[length - 2] = '\0'; uid = Tk_GetUid(virtString + 2); @@ -4007,27 +3953,24 @@ GetVirtualEventUid(interp, virtString) return uid; } - /* *---------------------------------------------------------------------- * * FindSequence -- * - * Find the entry in the pattern table that corresponds to a - * particular pattern string, and return a pointer to that - * entry. + * Find the entry in the pattern table that corresponds to a particular + * pattern string, and return a pointer to that entry. * * Results: - * The return value is normally a pointer to the PatSeq - * in patternTable that corresponds to eventString. If an error - * was found while parsing eventString, or if "create" is 0 and - * no pattern sequence previously existed, then NULL is returned - * and the interp's result contains a message describing the problem. - * If no pattern sequence previously existed for eventString, then - * a new one is created with a NULL command field. In a successful - * return, *maskPtr is filled in with a mask of the event types - * on which the pattern sequence depends. + * The return value is normally a pointer to the PatSeq in patternTable + * that corresponds to eventString. If an error was found while parsing + * eventString, or if "create" is 0 and no pattern sequence previously + * existed, then NULL is returned and the interp's result contains a + * message describing the problem. If no pattern sequence previously + * existed for eventString, then a new one is created with a NULL command + * field. In a successful return, *maskPtr is filled in with a mask of + * the event types on which the pattern sequence depends. * * Side effects: * A new pattern sequence may be allocated. @@ -4038,26 +3981,22 @@ GetVirtualEventUid(interp, virtString) static PatSeq * FindSequence(interp, patternTablePtr, object, eventString, create, allowVirtual, maskPtr) - Tcl_Interp *interp; /* Interpreter to use for error - * reporting. */ - Tcl_HashTable *patternTablePtr; /* Table to use for lookup. */ + Tcl_Interp *interp; /* Interpreter to use for error reporting. */ + Tcl_HashTable *patternTablePtr; + /* Table to use for lookup. */ ClientData object; /* For binding table, token for object with - * which binding is associated. - * For virtual event table, NULL. */ - CONST char *eventString; /* String description of pattern to - * match on. See user documentation - * for details. */ - int create; /* 0 means don't create the entry if - * it doesn't already exist. Non-zero - * means create. */ - int allowVirtual; /* 0 means that virtual events are not - * allowed in the sequence. Non-zero - * otherwise. */ - unsigned long *maskPtr; /* *maskPtr is filled in with the event - * types on which this pattern sequence - * depends. */ + * which binding is associated. For virtual + * event table, NULL. */ + CONST char *eventString; /* String description of pattern to match on. + * See user documentation for details. */ + int create; /* 0 means don't create the entry if it + * doesn't already exist. Non-zero means + * create. */ + int allowVirtual; /* 0 means that virtual events are not allowed + * in the sequence. Non-zero otherwise. */ + unsigned long *maskPtr; /* *maskPtr is filled in with the event types + * on which this pattern sequence depends. */ { - Pattern pats[EVENT_BUFFER_SIZE]; int numPats, virtualFound; CONST char *p; @@ -4071,10 +4010,9 @@ FindSequence(interp, patternTablePtr, object, eventString, create, /* *------------------------------------------------------------- - * Step 1: parse the pattern string to produce an array - * of Patterns. The array is generated backwards, so - * that the lowest-indexed pattern corresponds to the last - * event that must occur. + * Step 1: parse the pattern string to produce an array of Patterns. The + * array is generated backwards, so that the lowest-indexed pattern + * corresponds to the last event that must occur. *------------------------------------------------------------- */ @@ -4099,7 +4037,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (eventMask & VirtualEventMask) { if (allowVirtual == 0) { - Tcl_SetResult(interp, + Tcl_SetResult(interp, "virtual event not allowed in definition of another virtual event", TCL_STATIC); return NULL; @@ -4121,8 +4059,8 @@ FindSequence(interp, patternTablePtr, object, eventString, create, /* *------------------------------------------------------------- - * Step 2: find the sequence in the binding table if it exists, - * and add a new sequence to the table if it doesn't. + * Step 2: find the sequence in the binding table if it exists, and add a + * new sequence to the table if it doesn't. *------------------------------------------------------------- */ @@ -4135,7 +4073,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, TCL_STATIC); return NULL; } - + patPtr = &pats[EVENT_BUFFER_SIZE-numPats]; memset(&key, 0, sizeof(key)); key.object = object; @@ -4158,14 +4096,15 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (new) { Tcl_DeleteHashEntry(hPtr); } + /* - * No binding exists for the sequence, so return an empty error. - * This is a special error that the caller will check for in order - * to silently ignore this case. This is a hack that maintains - * backward compatibility for Tk_GetBinding but the various "bind" - * commands silently ignore missing bindings. + * No binding exists for the sequence, so return an empty error. This + * is a special error that the caller will check for in order to + * silently ignore this case. This is a hack that maintains backward + * compatibility for Tk_GetBinding but the various "bind" commands + * silently ignore missing bindings. */ - + return NULL; } psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq) @@ -4184,7 +4123,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, memcpy((VOID *) psPtr->pats, (VOID *) patPtr, sequenceSize); - done: + done: *maskPtr = eventMask; return psPtr; } @@ -4194,34 +4133,31 @@ FindSequence(interp, patternTablePtr, object, eventString, create, * * ParseEventDescription -- * - * Fill Pattern buffer with information about event from - * event string. + * Fill Pattern buffer with information about event from event string. * * Results: - * Leaves error message in interp and returns 0 if there was an - * error due to a badly formed event string. Returns 1 if proper - * event was specified, 2 if Double modifier was used in event - * string, or 3 if Triple was used. + * Leaves error message in interp and returns 0 if there was an error due + * to a badly formed event string. Returns 1 if proper event was + * specified, 2 if Double modifier was used in event string, or 3 if + * Triple was used. * * Side effects: * On exit, eventStringPtr points to rest of event string (after the - * closing '>', so that this procedure can be called repeatedly to - * parse all the events in the entire sequence. + * closing '>', so that this function can be called repeatedly to parse + * all the events in the entire sequence. * *--------------------------------------------------------------------------- */ static int -ParseEventDescription(interp, eventStringPtr, patPtr, - eventMaskPtr) +ParseEventDescription(interp, eventStringPtr, patPtr, eventMaskPtr) Tcl_Interp *interp; /* For error messages. */ - CONST char **eventStringPtr;/* On input, holds a pointer to start of - * event string. On exit, gets pointer to - * rest of string after parsed event. */ + CONST char **eventStringPtr;/* On input, holds a pointer to start of event + * string. On exit, gets pointer to rest of + * string after parsed event. */ Pattern *patPtr; /* Filled with the pattern parsed from the * event string. */ unsigned long *eventMaskPtr;/* Filled with event mask of matched event. */ - { char *p; unsigned long eventMask; @@ -4240,7 +4176,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr, eventMask = 0; count = 1; - + /* * Handle simple ASCII characters. */ @@ -4258,7 +4194,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr, patPtr->detail.keySym = *p; } else { char buf[64]; - + sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p); Tcl_SetResult(interp, buf, TCL_VOLATILE); count = 0; @@ -4270,8 +4206,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } /* - * A fancier event description. This can be either a virtual event - * or a physical event. + * A fancier event description. This can be either a virtual event or a + * physical event. * * A virtual event description consists of: * @@ -4282,30 +4218,29 @@ ParseEventDescription(interp, eventStringPtr, patPtr, * A physical event description consists of: * * 1. open angle bracket. - * 2. any number of modifiers, each followed by spaces - * or dashes. + * 2. any number of modifiers, each followed by spaces or dashes. * 3. an optional event name. - * 4. an option button or keysym name. Either this or - * item 3 *must* be present; if both are present - * then they are separated by spaces or dashes. + * 4. an option button or keysym name. Either this or item 3 *must* be + * present; if both are present then they are separated by spaces or + * dashes. * 5. a close angle bracket. */ p++; if (*p == '<') { /* - * This is a virtual event: soak up all the characters up to - * the next '>'. + * This is a virtual event: soak up all the characters up to the next + * '>'. */ - char *field = p + 1; + char *field = p + 1; p = strchr(field, '>'); if (p == field) { Tcl_SetResult(interp, "virtual event \"<<>>\" is badly formed", TCL_STATIC); count = 0; goto done; - } + } if ((p == NULL) || (p[1] != '>')) { Tcl_SetResult(interp, "missing \">\" in virtual binding", TCL_STATIC); @@ -4328,9 +4263,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, if (*p == '>') { /* * This solves the problem of, e.g., <Control-M> being - * misinterpreted as Control + Meta + missing keysym - * instead of Control + KeyPress + M. + * misinterpreted as Control + Meta + missing keysym instead of + * Control + KeyPress + M. */ + break; } hPtr = Tcl_FindHashEntry(&modTable, field); @@ -4378,7 +4314,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } patPtr->detail.button = (*field - '0'); } else { - getKeysym: + + getKeysym: patPtr->detail.keySym = TkStringToKeysym(field); if (patPtr->detail.keySym == NoSymbol) { Tcl_AppendResult(interp, "bad event type or keysym \"", @@ -4423,10 +4360,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } p++; -end: + end: *eventStringPtr += (p - Tcl_DStringValue(©)); *eventMaskPtr |= eventMask; -done: + done: Tcl_DStringFree(©); return count; } @@ -4436,17 +4373,15 @@ done: * * GetField -- * - * Used to parse pattern descriptions. Copies up to - * size characters from p to copy, stopping at end of - * string, space, "-", ">", or whenever size is - * exceeded. + * Used to parse pattern descriptions. Copies up to size characters from + * p to copy, stopping at end of string, space, "-", ">", or whenever + * size is exceeded. * * Results: - * The return value is a pointer to the character just - * after the last one copied (usually "-" or space or - * ">", but could be anything if size was exceeded). - * Also places NULL-terminated string (up to size - * character, including NULL), at copy. + * The return value is a pointer to the character just after the last one + * copied (usually "-" or space or ">", but could be anything if size was + * exceeded). Also places NULL-terminated string (up to size character, + * including NULL), at copy. * * Side effects: * None. @@ -4456,10 +4391,9 @@ done: static char * GetField(p, copy, size) - char *p; /* Pointer to part of pattern. */ - char *copy; /* Place to copy field. */ - int size; /* Maximum number of characters to - * copy. */ + char *p; /* Pointer to part of pattern. */ + char *copy; /* Place to copy field. */ + int size; /* Maximum number of characters to copy. */ { while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '>') && (*p != '-') && (size > 1)) { @@ -4477,18 +4411,19 @@ GetField(p, copy, size) * * GetPatternString -- * - * Produce a string version of the given event, for displaying to - * the user. + * Produce a string version of the given event, for displaying to the + * user. * * Results: * The string is left in dsPtr. * * Side effects: - * It is the caller's responsibility to initialize the DString before - * and to free it after calling this procedure. + * It is the caller's responsibility to initialize the DString before and + * to free it after calling this function. * *--------------------------------------------------------------------------- */ + static void GetPatternString(psPtr, dsPtr) PatSeq *psPtr; @@ -4513,7 +4448,7 @@ GetPatternString(psPtr, dsPtr) */ if ((patPtr->eventType == KeyPress) - && ((psPtr->flags & PAT_NEARBY) == 0) + && ((psPtr->flags & PAT_NEARBY) == 0) && (patPtr->needMods == 0) && (patPtr->detail.keySym < 128) && isprint(UCHAR(patPtr->detail.keySym)) @@ -4537,9 +4472,9 @@ GetPatternString(psPtr, dsPtr) } /* - * It's a more general event specification. First check - * for "Double", "Triple", "Quadruple", then modifiers, - * then event type, then keysym or button detail. + * It's a more general event specification. First check for "Double", + * "Triple", "Quadruple", then modifiers, then event type, then keysym + * or button detail. */ Tcl_DStringAppend(dsPtr, "<", 1); @@ -4605,8 +4540,8 @@ GetPatternString(psPtr, dsPtr) * * EvalTclBinding -- * - * The procedure that is invoked by Tk_BindEvent when a Tcl binding - * is fired. + * The function that is invoked by Tk_BindEvent when a Tcl binding is + * fired. * * Results: * A standard Tcl result code, the result of globally evaluating the @@ -4630,12 +4565,11 @@ FreeTclBinding(clientData) * * TkStringToKeysym -- * - * This procedure finds the keysym associated with a given keysym - * name. + * This function finds the keysym associated with a given keysym name. * * Results: - * The return value is the keysym that corresponds to name, or - * NoSymbol if there is no such keysym. + * The return value is the keysym that corresponds to name, or NoSymbol + * if there is no such keysym. * * Side effects: * None. @@ -4670,12 +4604,11 @@ TkStringToKeysym(name) * * TkKeysymToString -- * - * This procedure finds the keysym name associated with a given - * keysym. + * This function finds the keysym name associated with a given keysym. * * Results: - * The return value is a pointer to a static string containing - * the name of the given keysym, or NULL if there is no known name. + * The return value is a pointer to a static string containing the name + * of the given keysym, or NULL if there is no known name. * * Side effects: * None. @@ -4703,13 +4636,13 @@ TkKeysymToString(keysym) * * TkCopyAndGlobalEval -- * - * This procedure makes a copy of a script then calls Tcl_GlobalEval - * to evaluate it. It's used in situations where the execution of - * a command may cause the original command string to be reallocated. + * This function makes a copy of a script then calls Tcl_GlobalEval to + * evaluate it. It's used in situations where the execution of a command + * may cause the original command string to be reallocated. * * Results: - * Returns the result of evaluating script, including both a standard - * Tcl completion code and a string in the interp's result. + * Returns the result of evaluating script, including both a standard Tcl + * completion code and a string in the interp's result. * * Side effects: * None. @@ -4719,9 +4652,8 @@ TkKeysymToString(keysym) int TkCopyAndGlobalEval(interp, script) - Tcl_Interp *interp; /* Interpreter in which to evaluate - * script. */ - char *script; /* Script to evaluate. */ + Tcl_Interp *interp; /* Interpreter in which to evaluate script. */ + char *script; /* Script to evaluate. */ { Tcl_DString buffer; int code; @@ -4738,13 +4670,13 @@ TkCopyAndGlobalEval(interp, script) * * TkpGetBindingXEvent -- * - * This procedure returns the XEvent associated with the - * currently executing binding. This procedure can only - * be invoked while a binding is executing. + * This function returns the XEvent associated with the currently + * executing binding. This function can only be invoked while a binding + * is executing. * * Results: - * Returns a pointer to the XEvent that caused the - * current binding code to be run. + * Returns a pointer to the XEvent that caused the current binding code + * to be run. * * Side effects: * None. @@ -4754,9 +4686,17 @@ TkCopyAndGlobalEval(interp, script) XEvent * TkpGetBindingXEvent(interp) - Tcl_Interp *interp; /* Interpreter. */ + Tcl_Interp *interp; /* Interpreter. */ { TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); BindingTable *bindPtr = (BindingTable *) winPtr->mainPtr->bindingTable; return &(bindPtr->eventRing[bindPtr->curEvent]); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |