summaryrefslogtreecommitdiffstats
path: root/generic/tkBind.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tkBind.c')
-rw-r--r--generic/tkBind.c831
1 files changed, 208 insertions, 623 deletions
diff --git a/generic/tkBind.c b/generic/tkBind.c
index abdee59..10998fe 100644
--- a/generic/tkBind.c
+++ b/generic/tkBind.c
@@ -29,13 +29,10 @@
*
* Init/Free this package.
*
- * Tcl "bind" command (actually located in tkCmds.c).
- * "bind" command implementation.
- * "bind" implementation helpers.
+ * Tcl "bind" command (actually located in tkCmds.c) core implementation, plus
+ * helpers.
*
- * Tcl "event" command.
- * "event" command implementation.
- * "event" implementation helpers.
+ * Tcl "event" command implementation, plus helpers.
*
* Package-specific common helpers.
*
@@ -79,7 +76,7 @@ typedef union {
*/
#define EVENT_BUFFER_SIZE 30
-typedef struct BindingTable {
+typedef struct Tk_BindingTable_ {
XEvent eventRing[EVENT_BUFFER_SIZE];
/* Circular queue of recent events (higher
* indices are for more recent events). */
@@ -108,12 +105,12 @@ typedef struct BindingTable {
*
* 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,
+ * may be generated by platform-specific code or by Tcl commands. 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 {
+typedef struct {
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
@@ -140,7 +137,7 @@ typedef struct VirtualEventTable {
* tables and virtual event tables.
*/
-typedef struct PatternTableKey {
+typedef struct {
ClientData object; /* For binding table, identifies the binding
* tag of the object (or class of objects)
* relative to which the event occurred. For
@@ -156,7 +153,7 @@ typedef struct PatternTableKey {
* events as part of the process of converting X events into Tcl commands.
*/
-typedef struct Pattern {
+typedef struct {
int eventType; /* Type of X event, e.g. ButtonPress. */
int needMods; /* Mask of modifiers that must be present (0
* means no modifiers are required). */
@@ -193,21 +190,10 @@ typedef struct Pattern {
typedef struct PatSeq {
int numPats; /* Number of patterns in sequence (usually
* 1). */
- TkBindEvalProc *eventProc; /* The function that will be invoked on the
- * clientData when this pattern sequence
- * matches. */
- 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. */
+ char *script; /* Binding script to evaluate when sequence
+ * matches (ckalloc()ed) */
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. */
@@ -238,16 +224,9 @@ typedef struct PatSeq {
* 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
- * skipped if set.
*/
#define PAT_NEARBY 0x1
-#define MARKED_DELETED 0x2
/*
* Constants that define how close together two events must be in milliseconds
@@ -275,7 +254,7 @@ typedef struct VirtualOwners {
* to associate a virtual event with all the physical events that can trigger
* it.
*/
-typedef struct PhysicalsOwned {
+typedef struct {
int numOwned; /* Number of physical events owned. */
PatSeq *patSeqs[1]; /* Array of pointers to physical event
* patterns. Enough space will actually be
@@ -285,7 +264,7 @@ typedef struct 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
+ * command can be invoked whenever the display/screen changes (the command does
* things like point tk::Priv at a display-specific structure).
*/
@@ -298,44 +277,17 @@ typedef struct {
} ScreenInfo;
/*
- * 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.
- */
-
-typedef struct PendingBinding {
- struct PendingBinding *nextPtr;
- /* 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
- * size of this depends on how many C bindings
- * matched the event passed to Tk_BindEvent.
- * THIS FIELD MUST BE THE LAST IN THE
- * STRUCTURE. */
-} PendingBinding;
-
-/*
* The following structure keeps track of all the information local to the
* binding package on a per interpreter basis.
*/
-typedef struct BindInfo {
+typedef struct TkBindInfo_ {
VirtualEventTable virtualEventTable;
/* 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. */
- 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. */
} BindInfo;
@@ -352,10 +304,10 @@ typedef struct BindInfo {
#ifdef REDO_KEYSYM_LOOKUP
typedef struct {
- char *name; /* Name of keysym. */
+ const char *name; /* Name of keysym. */
KeySym value; /* Numeric identifier for keysym. */
} KeySymInfo;
-static KeySymInfo keyArray[] = {
+static const KeySymInfo keyArray[] = {
#ifndef lint
#include "ks_names.h"
#endif
@@ -381,7 +333,7 @@ TCL_DECLARE_MUTEX(bindMutex)
*/
typedef struct {
- char *name; /* Name of modifier. */
+ const char *name; /* Name of modifier. */
int mask; /* Button/modifier mask value, such as
* Button1Mask. */
int flags; /* Various flags; see below for
@@ -405,7 +357,7 @@ typedef struct {
#define QUADRUPLE 4
#define MULT_CLICKS 7
-static ModInfo modArray[] = {
+static const ModInfo modArray[] = {
{"Control", ControlMask, 0},
{"Shift", ShiftMask, 0},
{"Lock", LockMask, 0},
@@ -450,7 +402,7 @@ static Tcl_HashTable modTable;
*/
typedef struct {
- char *name; /* Name of event. */
+ const char *name; /* Name of event. */
int type; /* Event type for X, such as ButtonPress. */
int eventMask; /* Mask bits (for XSelectInput) for this event
* type. */
@@ -463,7 +415,7 @@ typedef struct {
* unless you've asked about button events.
*/
-static EventInfo eventArray[] = {
+static const EventInfo eventArray[] = {
{"Key", KeyPress, KeyPressMask},
{"KeyPress", KeyPress, KeyPressMask},
{"KeyRelease", KeyRelease, KeyPressMask|KeyReleaseMask},
@@ -535,7 +487,7 @@ static Tcl_HashTable eventTable;
#define KEY_BUTTON_MOTION_VIRTUAL (KEY|BUTTON|MOTION|VIRTUAL)
#define KEY_BUTTON_MOTION_CROSSING (KEY|BUTTON|MOTION|VIRTUAL|CROSSING)
-static int flagArray[TK_LASTEVENT] = {
+static const int flagArray[TK_LASTEVENT] = {
/* Not used */ 0,
/* Not used */ 0,
/* KeyPress */ KEY,
@@ -654,14 +606,13 @@ static void ChangeScreen(Tcl_Interp *interp, char *dispName,
int screenIndex);
static int CreateVirtualEvent(Tcl_Interp *interp,
VirtualEventTable *vetPtr, char *virtString,
- char *eventString);
+ const char *eventString);
static int DeleteVirtualEvent(Tcl_Interp *interp,
VirtualEventTable *vetPtr, char *virtString,
- char *eventString);
+ const 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,
@@ -671,7 +622,7 @@ static void GetAllVirtualEvents(Tcl_Interp *interp,
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);
+ VirtualEventTable *vetPtr, Tcl_Obj *virtName);
static Tk_Uid GetVirtualEventUid(Tcl_Interp *interp,
char *virtString);
static int HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
@@ -687,15 +638,6 @@ static int ParseEventDescription(Tcl_Interp *interp,
const char **eventStringPtr, Pattern *patPtr,
unsigned long *eventMaskPtr);
static void DoWarp(ClientData clientData);
-
-/*
- * 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)
/*
*---------------------------------------------------------------------------
@@ -734,11 +676,11 @@ TkBindInit(
Tcl_MutexLock(&bindMutex);
if (!initialized) {
Tcl_HashEntry *hPtr;
- ModInfo *modPtr;
- EventInfo *eiPtr;
+ const ModInfo *modPtr;
+ const EventInfo *eiPtr;
int newEntry;
#ifdef REDO_KEYSYM_LOOKUP
- KeySymInfo *kPtr;
+ const KeySymInfo *kPtr;
Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS);
Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS);
@@ -771,14 +713,13 @@ TkBindInit(
mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp);
- bindInfoPtr = (BindInfo *) ckalloc(sizeof(BindInfo));
+ bindInfoPtr = ckalloc(sizeof(BindInfo));
InitVirtualEventTable(&bindInfoPtr->virtualEventTable);
bindInfoPtr->screenInfo.curDispPtr = NULL;
bindInfoPtr->screenInfo.curScreenIndex = -1;
bindInfoPtr->screenInfo.bindingDepth = 0;
- bindInfoPtr->pendingList = NULL;
bindInfoPtr->deleted = 0;
- mainPtr->bindInfo = (TkBindInfo) bindInfoPtr;
+ mainPtr->bindInfo = bindInfoPtr;
TkpInitializeMenuBindings(mainPtr->interp, mainPtr->bindingTable);
}
@@ -809,10 +750,10 @@ TkBindFree(
Tk_DeleteBindingTable(mainPtr->bindingTable);
mainPtr->bindingTable = NULL;
- bindInfoPtr = (BindInfo *) mainPtr->bindInfo;
+ bindInfoPtr = mainPtr->bindInfo;
DeleteVirtualEventTable(&bindInfoPtr->virtualEventTable);
bindInfoPtr->deleted = 1;
- Tcl_EventuallyFree((ClientData) bindInfoPtr, TCL_DYNAMIC);
+ Tcl_EventuallyFree(bindInfoPtr, TCL_DYNAMIC);
mainPtr->bindInfo = NULL;
}
@@ -839,14 +780,13 @@ Tk_CreateBindingTable(
* table: commands are executed in this
* interpreter. */
{
- BindingTable *bindPtr;
+ BindingTable *bindPtr = ckalloc(sizeof(BindingTable));
int i;
/*
* Create and initialize a new binding table.
*/
- bindPtr = (BindingTable *) ckalloc(sizeof(BindingTable));
for (i = 0; i < EVENT_BUFFER_SIZE; i++) {
bindPtr->eventRing[i].type = -1;
}
@@ -855,7 +795,7 @@ Tk_CreateBindingTable(
sizeof(PatternTableKey)/sizeof(int));
Tcl_InitHashTable(&bindPtr->objectTable, TCL_ONE_WORD_KEYS);
bindPtr->interp = interp;
- return (Tk_BindingTable) bindPtr;
+ return bindPtr;
}
/*
@@ -877,10 +817,8 @@ Tk_CreateBindingTable(
void
Tk_DeleteBindingTable(
- Tk_BindingTable bindingTable)
- /* Token for the binding table to destroy. */
+ Tk_BindingTable bindPtr) /* Token for the binding table to destroy. */
{
- BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr, *nextPtr;
Tcl_HashEntry *hPtr;
Tcl_HashSearch search;
@@ -891,16 +829,10 @@ Tk_DeleteBindingTable(
for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search);
hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
- psPtr != NULL; psPtr = nextPtr) {
+ for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = nextPtr) {
nextPtr = psPtr->nextSeqPtr;
- psPtr->flags |= MARKED_DELETED;
- if (psPtr->refCount == 0) {
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- ckfree((char *) psPtr);
- }
+ ckfree(psPtr->script);
+ ckfree(psPtr);
}
}
@@ -910,7 +842,7 @@ Tk_DeleteBindingTable(
Tcl_DeleteHashTable(&bindPtr->patternTable);
Tcl_DeleteHashTable(&bindPtr->objectTable);
- ckfree((char *) bindPtr);
+ ckfree(bindPtr);
}
/*
@@ -940,13 +872,12 @@ Tk_DeleteBindingTable(
unsigned long
Tk_CreateBinding(
Tcl_Interp *interp, /* Used for error reporting. */
- Tk_BindingTable bindingTable,
- /* Table in which to create binding. */
+ Tk_BindingTable bindPtr, /* Table in which to create binding. */
ClientData object, /* Token for object with which binding is
* associated. */
const char *eventString, /* String describing event sequence that
* triggers binding. */
- const char *command, /* Contains Tcl command to execute when
+ const char *script, /* Contains Tcl script to execute when
* binding triggers. */
int append) /* 0 means replace any existing binding for
* eventString; 1 means append to that
@@ -955,12 +886,11 @@ Tk_CreateBinding(
* string, the existing binding will always be
* replaced. */
{
- BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr;
unsigned long eventMask;
char *newStr, *oldStr;
- if (!*command) {
+ if (!*script) {
/* Silently ignore empty scripts -- see SF#3006842 */
return 1;
}
@@ -969,7 +899,7 @@ Tk_CreateBinding(
if (psPtr == NULL) {
return 0;
}
- if (psPtr->eventProc == NULL) {
+ if (psPtr->script == NULL) {
int isNew;
Tcl_HashEntry *hPtr;
@@ -984,120 +914,29 @@ Tk_CreateBinding(
if (isNew) {
psPtr->nextObjPtr = NULL;
} else {
- psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
+ psPtr->nextObjPtr = Tcl_GetHashValue(hPtr);
}
Tcl_SetHashValue(hPtr, psPtr);
- } else if (psPtr->eventProc != EvalTclBinding) {
- /*
- * Free existing procedural binding.
- */
-
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- psPtr->clientData = NULL;
- append = 0;
}
- oldStr = (char *) psPtr->clientData;
+ oldStr = psPtr->script;
if ((append != 0) && (oldStr != NULL)) {
- size_t length;
+ size_t length1 = strlen(oldStr), length2 = strlen(script);
- length = strlen(oldStr) + strlen(command) + 2;
- newStr = (char *) ckalloc((unsigned) length);
- sprintf(newStr, "%s\n%s", oldStr, command);
+ newStr = ckalloc(length1 + length2 + 2);
+ memcpy(newStr, oldStr, length1);
+ newStr[length1] = '\n';
+ memcpy(newStr+length1+1, script, length2+1);
} else {
- newStr = (char *) ckalloc((unsigned) strlen(command) + 1);
- strcpy(newStr, command);
+ size_t length = strlen(script);
+
+ newStr = ckalloc(length + 1);
+ memcpy(newStr, script, length+1);
}
if (oldStr != NULL) {
ckfree(oldStr);
}
- psPtr->eventProc = EvalTclBinding;
- psPtr->freeProc = FreeTclBinding;
- psPtr->clientData = (ClientData) newStr;
- return eventMask;
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TkCreateBindingProcedure --
- *
- * Add a C binding to a binding table, so that future calls to
- * 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
- * what events to select for in a window, for example.
- *
- * Side effects:
- * Any existing binding on the same event sequence will be replaced.
- *
- *---------------------------------------------------------------------------
- */
-
-unsigned long
-TkCreateBindingProcedure(
- Tcl_Interp *interp, /* Used for error reporting. */
- Tk_BindingTable bindingTable,
- /* Table in which to create binding. */
- ClientData object, /* Token for object with which binding is
- * associated. */
- const char *eventString, /* String describing event sequence that
- * triggers binding. */
- 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. */
-{
- BindingTable *bindPtr = (BindingTable *) bindingTable;
- PatSeq *psPtr;
- unsigned long eventMask;
-
- psPtr = FindSequence(interp, &bindPtr->patternTable, object, eventString,
- 1, 1, &eventMask);
- if (psPtr == NULL) {
- return 0;
- }
- if (psPtr->eventProc == NULL) {
- int isNew;
- 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.
- */
-
- hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object,
- &isNew);
- if (isNew) {
- psPtr->nextObjPtr = NULL;
- } else {
- psPtr->nextObjPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
- }
- Tcl_SetHashValue(hPtr, psPtr);
- } else {
- /*
- * Free existing callback.
- */
-
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- }
-
- psPtr->eventProc = eventProc;
- psPtr->freeProc = freeProc;
- psPtr->clientData = clientData;
+ psPtr->script = newStr;
return eventMask;
}
@@ -1122,14 +961,12 @@ TkCreateBindingProcedure(
int
Tk_DeleteBinding(
Tcl_Interp *interp, /* Used for error reporting. */
- Tk_BindingTable bindingTable,
- /* Table in which to delete binding. */
+ Tk_BindingTable bindPtr, /* 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;
unsigned long eventMask;
Tcl_HashEntry *hPtr;
@@ -1150,7 +987,7 @@ Tk_DeleteBinding(
if (hPtr == NULL) {
Tcl_Panic("Tk_DeleteBinding couldn't find object table entry");
}
- prevPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
+ prevPtr = Tcl_GetHashValue(hPtr);
if (prevPtr == psPtr) {
Tcl_SetHashValue(hPtr, psPtr->nextObjPtr);
} else {
@@ -1164,7 +1001,7 @@ Tk_DeleteBinding(
}
}
}
- prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
+ prevPtr = Tcl_GetHashValue(psPtr->hPtr);
if (prevPtr == psPtr) {
if (psPtr->nextSeqPtr == NULL) {
Tcl_DeleteHashEntry(psPtr->hPtr);
@@ -1183,13 +1020,8 @@ Tk_DeleteBinding(
}
}
- psPtr->flags |= MARKED_DELETED;
- if (psPtr->refCount == 0) {
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- ckfree((char *) psPtr);
- }
+ ckfree(psPtr->script);
+ ckfree(psPtr);
return TCL_OK;
}
@@ -1198,10 +1030,10 @@ Tk_DeleteBinding(
*
* Tk_GetBinding --
*
- * Return the command associated with a given event string.
+ * Return the script associated with a given event string.
*
* Results:
- * The return value is a pointer to the command string associated with
+ * The return value is a pointer to the script 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
@@ -1217,14 +1049,12 @@ Tk_DeleteBinding(
const char *
Tk_GetBinding(
Tcl_Interp *interp, /* Interpreter for error reporting. */
- Tk_BindingTable bindingTable,
- /* Table in which to look for binding. */
+ Tk_BindingTable bindPtr, /* 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;
unsigned long eventMask;
@@ -1233,10 +1063,7 @@ Tk_GetBinding(
if (psPtr == NULL) {
return NULL;
}
- if (psPtr->eventProc == EvalTclBinding) {
- return (const char *) psPtr->clientData;
- }
- return "";
+ return psPtr->script;
}
/*
@@ -1262,11 +1089,9 @@ Tk_GetBinding(
void
Tk_GetAllBindings(
Tcl_Interp *interp, /* Interpreter returning result or error. */
- Tk_BindingTable bindingTable,
- /* Table in which to look for bindings. */
+ Tk_BindingTable bindPtr, /* Table in which to look for bindings. */
ClientData object) /* Token for object. */
{
- BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr;
Tcl_HashEntry *hPtr;
Tcl_DString ds;
@@ -1276,7 +1101,7 @@ Tk_GetAllBindings(
return;
}
Tcl_DStringInit(&ds);
- for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
+ for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = psPtr->nextObjPtr) {
/*
* For each binding, output information about each of the patterns in
@@ -1309,11 +1134,9 @@ Tk_GetAllBindings(
void
Tk_DeleteAllBindings(
- Tk_BindingTable bindingTable,
- /* Table in which to delete bindings. */
+ Tk_BindingTable bindPtr, /* Table in which to delete bindings. */
ClientData object) /* Token for object. */
{
- BindingTable *bindPtr = (BindingTable *) bindingTable;
PatSeq *psPtr, *prevPtr;
PatSeq *nextPtr;
Tcl_HashEntry *hPtr;
@@ -1322,7 +1145,7 @@ Tk_DeleteAllBindings(
if (hPtr == NULL) {
return;
}
- for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
+ for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = nextPtr) {
nextPtr = psPtr->nextObjPtr;
@@ -1332,7 +1155,7 @@ Tk_DeleteAllBindings(
* hash entry too.
*/
- prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
+ prevPtr = Tcl_GetHashValue(psPtr->hPtr);
if (prevPtr == psPtr) {
if (psPtr->nextSeqPtr == NULL) {
Tcl_DeleteHashEntry(psPtr->hPtr);
@@ -1350,14 +1173,8 @@ Tk_DeleteAllBindings(
}
}
}
- psPtr->flags |= MARKED_DELETED;
-
- if (psPtr->refCount == 0) {
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- ckfree((char *) psPtr);
- }
+ ckfree(psPtr->script);
+ ckfree(psPtr);
}
Tcl_DeleteHashEntry(hPtr);
}
@@ -1377,27 +1194,19 @@ Tk_DeleteAllBindings(
* None.
*
* Side effects:
- * Depends on the command associated with the matching binding.
+ * Depends on the script associated with the matching binding.
*
- * All Tcl bindings scripts for each object are accumulated before the
+ * All Tcl binding 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(
- Tk_BindingTable bindingTable,
- /* Table in which to look for bindings. */
+ Tk_BindingTable bindPtr, /* 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
@@ -1406,23 +1215,19 @@ Tk_BindEvent(
ClientData *objectPtr) /* Array of one or more objects to check for a
* matching binding. */
{
- BindingTable *bindPtr;
TkDisplay *dispPtr;
ScreenInfo *screenPtr;
BindInfo *bindInfoPtr;
TkDisplay *oldDispPtr;
XEvent *ringPtr;
PatSeq *vMatchDetailList, *vMatchNoDetailList;
- int flags, oldScreen, i, deferModal;
- unsigned int matchCount, matchSpace;
+ int flags, oldScreen;
Tcl_Interp *interp;
Tcl_DString scripts, savedResult;
Detail detail;
char *p, *end;
- PendingBinding staticPending, *pendingPtr;
TkWindow *winPtr = (TkWindow *) tkwin;
PatternTableKey key;
- Tk_ClassModalProc *modalProc;
/*
* Ignore events on windows that don't have names: these are windows like
@@ -1453,9 +1258,8 @@ Tk_BindEvent(
}
}
- bindPtr = (BindingTable *) bindingTable;
dispPtr = ((TkWindow *) tkwin)->dispPtr;
- bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
+ bindInfoPtr = winPtr->mainPtr->bindInfo;
/*
* Add the new event to the ring of saved events for the binding table.
@@ -1515,7 +1319,7 @@ Tk_BindEvent(
}
}
ringPtr = &bindPtr->eventRing[bindPtr->curEvent];
- memcpy((void *) ringPtr, (void *) eventPtr, sizeof(XEvent));
+ memcpy(ringPtr, eventPtr, sizeof(XEvent));
detail.clientData = 0;
flags = flagArray[ringPtr->type];
if (flags & KEY) {
@@ -1549,14 +1353,14 @@ Tk_BindEvent(
hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
if (hPtr != NULL) {
- vMatchDetailList = (PatSeq *) Tcl_GetHashValue(hPtr);
+ vMatchDetailList = Tcl_GetHashValue(hPtr);
}
if (key.detail.clientData != 0) {
key.detail.clientData = 0;
hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key);
if (hPtr != NULL) {
- vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr);
+ vMatchNoDetailList = Tcl_GetHashValue(hPtr);
}
}
}
@@ -1565,13 +1369,9 @@ Tk_BindEvent(
* 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.
+ * each object.
*/
- pendingPtr = &staticPending;
- matchCount = 0;
- matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *);
Tcl_DStringInit(&scripts);
for ( ; numObjects > 0; numObjects--, objectPtr++) {
@@ -1591,9 +1391,8 @@ Tk_BindEvent(
key.detail = detail;
hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key);
if (hPtr != NULL) {
- matchPtr = MatchPatterns(dispPtr, bindPtr,
- (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL,
- &sourcePtr);
+ matchPtr = MatchPatterns(dispPtr, bindPtr, Tcl_GetHashValue(hPtr),
+ matchPtr, NULL, &sourcePtr);
}
if (vMatchDetailList != NULL) {
@@ -1611,47 +1410,18 @@ Tk_BindEvent(
hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key);
if (hPtr != NULL) {
matchPtr = MatchPatterns(dispPtr, bindPtr,
- (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL,
- &sourcePtr);
+ Tcl_GetHashValue(hPtr), matchPtr, NULL, &sourcePtr);
}
if (vMatchNoDetailList != NULL) {
matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList,
matchPtr, objectPtr, &sourcePtr);
}
-
}
if (matchPtr != NULL) {
- if (sourcePtr->eventProc == NULL) {
- Tcl_Panic("Tk_BindEvent: missing command");
- }
- if (sourcePtr->eventProc == EvalTclBinding) {
- ExpandPercents(winPtr, (char *) sourcePtr->clientData,
- eventPtr, detail.keySym, &scripts);
- } else {
- if (matchCount >= matchSpace) {
- PendingBinding *newPtr;
- unsigned int oldSize, newSize;
-
- oldSize = sizeof(staticPending)
- - sizeof(staticPending.matchArray)
- + matchSpace * sizeof(PatSeq*);
- matchSpace *= 2;
- newSize = sizeof(staticPending)
- - sizeof(staticPending.matchArray)
- + matchSpace * sizeof(PatSeq*);
- newPtr = (PendingBinding *) ckalloc(newSize);
- memcpy((void *) newPtr, (void *) pendingPtr, oldSize);
- if (pendingPtr != &staticPending) {
- ckfree((char *) pendingPtr);
- }
- pendingPtr = newPtr;
- }
- sourcePtr->refCount++;
- pendingPtr->matchArray[matchCount] = sourcePtr;
- matchCount++;
- }
+ ExpandPercents(winPtr, sourcePtr->script, eventPtr,
+ detail.keySym, &scripts);
/*
* A "" is added to the scripts string to separate the various
@@ -1701,31 +1471,8 @@ Tk_BindEvent(
ChangeScreen(interp, dispPtr->name, screenPtr->curScreenIndex);
}
- 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.
- */
-
- pendingPtr->nextPtr = bindInfoPtr->pendingList;
- pendingPtr->tkwin = tkwin;
- 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.
- */
-
- flags = winPtr->flags;
- winPtr->flags &= ~TK_DEFER_MODAL;
-
p = Tcl_DStringValue(&scripts);
end = p + Tcl_DStringLength(&scripts);
- i = 0;
/*
* Be carefule when dereferencing screenPtr or bindInfoPtr. If we evaluate
@@ -1733,8 +1480,9 @@ Tk_BindEvent(
* can tell that by first checking to see if winPtr->mainPtr == NULL.
*/
- Tcl_Preserve((ClientData) bindInfoPtr);
+ Tcl_Preserve(bindInfoPtr);
while (p < end) {
+ int len = (int) strlen(p);
int code;
if (!bindInfoPtr->deleted) {
@@ -1742,31 +1490,8 @@ Tk_BindEvent(
}
Tcl_AllowExceptions(interp);
- if (*p == '\0') {
- PatSeq *psPtr;
-
- psPtr = pendingPtr->matchArray[i];
- i++;
- code = TCL_OK;
- if ((pendingPtr->deleted == 0)
- && ((psPtr->flags & MARKED_DELETED) == 0)) {
- code = (*psPtr->eventProc)(psPtr->clientData, interp, eventPtr,
- tkwin, detail.keySym);
- }
- psPtr->refCount--;
- if ((psPtr->refCount == 0) && (psPtr->flags & MARKED_DELETED)) {
- if (psPtr->freeProc != NULL) {
- (*psPtr->freeProc)(psPtr->clientData);
- }
- ckfree((char *) psPtr);
- }
- } else {
- int len = (int) strlen(p);
-
- code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL);
- p += len;
- }
- p++;
+ code = Tcl_EvalEx(interp, p, len, TCL_EVAL_GLOBAL);
+ p += len + 1;
if (!bindInfoPtr->deleted) {
screenPtr->bindingDepth--;
@@ -1780,29 +1505,12 @@ Tk_BindEvent(
break;
} else {
Tcl_AddErrorInfo(interp, "\n (command bound to event)");
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, code);
break;
}
}
}
- if (matchCount > 0 && !pendingPtr->deleted) {
- /*
- * 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);
- if (deferModal) {
- modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc);
- if (modalProc != NULL) {
- (*modalProc)(tkwin, eventPtr);
- }
- }
- }
-
if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0)
&& ((oldDispPtr != screenPtr->curDispPtr)
|| (oldScreen != screenPtr->curScreenIndex))) {
@@ -1818,71 +1526,7 @@ Tk_BindEvent(
Tcl_DStringResult(interp, &savedResult);
Tcl_DStringFree(&scripts);
- if (matchCount > 0) {
- if (!bindInfoPtr->deleted) {
- /*
- * Delete the pending list from the list of pending scripts for
- * this window.
- */
-
- PendingBinding **curPtrPtr;
-
- for (curPtrPtr = &bindInfoPtr->pendingList; ; ) {
- if (*curPtrPtr == pendingPtr) {
- *curPtrPtr = pendingPtr->nextPtr;
- break;
- }
- curPtrPtr = &(*curPtrPtr)->nextPtr;
- }
- }
- if (pendingPtr != &staticPending) {
- ckfree((char *) pendingPtr);
- }
- }
- Tcl_Release((ClientData) bindInfoPtr);
-}
-
-/*
- *---------------------------------------------------------------------------
- *
- * TkBindDeadWindow --
- *
- * This function is invoked when it is determined that a window is dead.
- * It cleans up bind-related information about the window
- *
- * Results:
- * None.
- *
- * Side effects:
- * Any pending C bindings for this window are cancelled.
- *
- *---------------------------------------------------------------------------
- */
-
-void
-TkBindDeadWindow(
- TkWindow *winPtr) /* The window that is being deleted. */
-{
- BindInfo *bindInfoPtr;
- PendingBinding *curPtr;
-
- /*
- * Certain special windows like those used for send and clipboard have no
- * mainPtr.
- */
-
- if (winPtr->mainPtr == NULL) {
- return;
- }
-
- bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo;
- curPtr = bindInfoPtr->pendingList;
- while (curPtr != NULL) {
- if (curPtr->tkwin == (Tk_Window) winPtr) {
- curPtr->deleted = 1;
- }
- curPtr = curPtr->nextPtr;
- }
+ Tcl_Release(bindInfoPtr);
}
/*
@@ -1921,6 +1565,7 @@ TkBindDeadWindow(
*
*----------------------------------------------------------------------
*/
+
static PatSeq *
MatchPatterns(
TkDisplay *dispPtr, /* Display from which the event came. */
@@ -2144,7 +1789,7 @@ MatchPatterns(
* virtual event's definition.
*/
- PatSeq *virtMatchPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
+ PatSeq *virtMatchPtr = Tcl_GetHashValue(hPtr);
if ((virtMatchPtr->numPats != 1)
|| (virtMatchPtr->nextSeqPtr != NULL)) {
@@ -2533,7 +2178,7 @@ ExpandPercents(
goto doNumber;
case 'K':
if ((flags & KEY) && (eventPtr->type != MouseWheelEvent)) {
- char *name = TkKeysymToString(keySym);
+ const char *name = TkKeysymToString(keySym);
if (name != NULL) {
string = name;
@@ -2662,23 +2307,18 @@ ChangeScreen(
char *dispName, /* Name of new display. */
int screenIndex) /* Index of new screen. */
{
- Tcl_DString cmd;
+ Tcl_Obj *cmdObj = Tcl_ObjPrintf("::tk::ScreenChanged %s.%d",
+ dispName, screenIndex);
int code;
- char screen[TCL_INTEGER_SPACE];
-
- Tcl_DStringInit(&cmd);
- Tcl_DStringAppend(&cmd, "tk::ScreenChanged ", 18);
- Tcl_DStringAppend(&cmd, dispName, -1);
- sprintf(screen, ".%d", screenIndex);
- Tcl_DStringAppend(&cmd, screen, -1);
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd), Tcl_DStringLength(&cmd),
- TCL_EVAL_GLOBAL);
- Tcl_DStringFree(&cmd);
+
+ Tcl_IncrRefCount(cmdObj);
+ code = Tcl_GlobalEvalObj(interp, cmdObj);
if (code != TCL_OK) {
Tcl_AddErrorInfo(interp,
"\n (changing screen in event binding)");
- Tcl_BackgroundError(interp);
+ Tcl_BackgroundException(interp, code);
}
+ Tcl_DecrRefCount(cmdObj);
}
/*
@@ -2705,11 +2345,13 @@ Tk_EventObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int index;
- Tk_Window tkwin;
- VirtualEventTable *vetPtr;
- TkBindInfo bindInfo;
- static const char *optionStrings[] = {
+ int index, i;
+ char *name;
+ const char *event;
+ Tk_Window tkwin = clientData;
+ TkBindInfo bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
+ VirtualEventTable *vetPtr = &bindInfo->virtualEventTable;
+ static const char *const optionStrings[] = {
"add", "delete", "generate", "info",
NULL
};
@@ -2717,9 +2359,6 @@ Tk_EventObjCmd(
EVENT_ADD, EVENT_DELETE, EVENT_GENERATE, EVENT_INFO
};
- tkwin = (Tk_Window) clientData;
- bindInfo = ((TkWindow *) tkwin)->mainPtr->bindInfo;
- vetPtr = &((BindInfo *) bindInfo)->virtualEventTable;
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "option ?arg?");
@@ -2731,10 +2370,7 @@ Tk_EventObjCmd(
}
switch ((enum options) index) {
- case EVENT_ADD: {
- int i;
- char *name, *event;
-
+ case EVENT_ADD:
if (objc < 4) {
Tcl_WrongNumArgs(interp, 2, objv,
"virtual sequence ?sequence ...?");
@@ -2748,14 +2384,9 @@ Tk_EventObjCmd(
}
}
break;
- }
- case EVENT_DELETE: {
- int i;
- char *name, *event;
-
+ case EVENT_DELETE:
if (objc < 3) {
- Tcl_WrongNumArgs(interp, 2, objv,
- "virtual ?sequence sequence ...?");
+ Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");
return TCL_ERROR;
}
name = Tcl_GetString(objv[2]);
@@ -2769,10 +2400,10 @@ Tk_EventObjCmd(
}
}
break;
- }
case EVENT_GENERATE:
if (objc < 4) {
- Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?");
+ Tcl_WrongNumArgs(interp, 2, objv,
+ "window event ?-option value ...?");
return TCL_ERROR;
}
return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2);
@@ -2781,7 +2412,7 @@ Tk_EventObjCmd(
GetAllVirtualEvents(interp, vetPtr);
return TCL_OK;
} else if (objc == 3) {
- return GetVirtualEvent(interp, vetPtr, Tcl_GetString(objv[2]));
+ return GetVirtualEvent(interp, vetPtr, objv[2]);
} else {
Tcl_WrongNumArgs(interp, 2, objv, "?virtual?");
return TCL_ERROR;
@@ -2844,18 +2475,18 @@ DeleteVirtualEventTable(
hPtr = Tcl_FirstHashEntry(&vetPtr->patternTable, &search);
for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- psPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
+ psPtr = Tcl_GetHashValue(hPtr);
for ( ; psPtr != NULL; psPtr = nextPtr) {
nextPtr = psPtr->nextSeqPtr;
- ckfree((char *) psPtr->voPtr);
- ckfree((char *) psPtr);
+ ckfree(psPtr->voPtr);
+ ckfree(psPtr);
}
}
Tcl_DeleteHashTable(&vetPtr->patternTable);
hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search);
for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
- ckfree((char *) Tcl_GetHashValue(hPtr));
+ ckfree(Tcl_GetHashValue(hPtr));
}
Tcl_DeleteHashTable(&vetPtr->nameTable);
}
@@ -2885,7 +2516,7 @@ CreateVirtualEvent(
Tcl_Interp *interp, /* Used for error reporting. */
VirtualEventTable *vetPtr, /* Table in which to augment virtual event. */
char *virtString, /* Name of new virtual event. */
- char *eventString) /* String describing physical event that
+ const char *eventString) /* String describing physical event that
* triggers virtual event. */
{
PatSeq *psPtr;
@@ -2921,9 +2552,9 @@ CreateVirtualEvent(
* Make virtual event own the physical event.
*/
- poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
+ poPtr = Tcl_GetHashValue(vhPtr);
if (poPtr == NULL) {
- poPtr = (PhysicalsOwned *) ckalloc(sizeof(PhysicalsOwned));
+ poPtr = ckalloc(sizeof(PhysicalsOwned));
poPtr->numOwned = 0;
} else {
/*
@@ -2938,10 +2569,10 @@ CreateVirtualEvent(
return TCL_OK;
}
}
- poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr,
- sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *));
+ poPtr = ckrealloc(poPtr, sizeof(PhysicalsOwned)
+ + poPtr->numOwned * sizeof(PatSeq *));
}
- Tcl_SetHashValue(vhPtr, (ClientData) poPtr);
+ Tcl_SetHashValue(vhPtr, poPtr);
poPtr->patSeqs[poPtr->numOwned] = psPtr;
poPtr->numOwned++;
@@ -2951,11 +2582,10 @@ CreateVirtualEvent(
voPtr = psPtr->voPtr;
if (voPtr == NULL) {
- voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners));
+ voPtr = ckalloc(sizeof(VirtualOwners));
voPtr->numOwners = 0;
} else {
- voPtr = (VirtualOwners *) ckrealloc((char *) voPtr,
- sizeof(VirtualOwners)
+ voPtr = ckrealloc(voPtr, sizeof(VirtualOwners)
+ voPtr->numOwners * sizeof(Tcl_HashEntry *));
}
psPtr->voPtr = voPtr;
@@ -2994,7 +2624,7 @@ DeleteVirtualEvent(
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,
+ const char *eventString) /* The event sequence that should be deleted,
* or NULL to delete all event sequences for
* the entire virtual event. */
{
@@ -3013,7 +2643,7 @@ DeleteVirtualEvent(
if (vhPtr == NULL) {
return TCL_OK;
}
- poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
+ poPtr = Tcl_GetHashValue(vhPtr);
eventPSPtr = NULL;
if (eventString != NULL) {
@@ -3062,7 +2692,7 @@ DeleteVirtualEvent(
* from physical->virtual map.
*/
- PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr);
+ PatSeq *prevPtr = Tcl_GetHashValue(psPtr->hPtr);
if (prevPtr == psPtr) {
if (psPtr->nextSeqPtr == NULL) {
@@ -3082,8 +2712,8 @@ DeleteVirtualEvent(
}
}
}
- ckfree((char *) psPtr->voPtr);
- ckfree((char *) psPtr);
+ ckfree(psPtr->voPtr);
+ ckfree(psPtr);
} else {
/*
* This physical event still triggers some other virtual
@@ -3120,7 +2750,7 @@ DeleteVirtualEvent(
* itself should be deleted.
*/
- ckfree((char *) poPtr);
+ ckfree(poPtr);
Tcl_DeleteHashEntry(vhPtr);
}
return TCL_OK;
@@ -3152,7 +2782,7 @@ static int
GetVirtualEvent(
Tcl_Interp *interp, /* Interpreter for reporting. */
VirtualEventTable *vetPtr, /* Table in which to look for event. */
- char *virtString) /* String describing virtual event. */
+ Tcl_Obj *virtName) /* String describing virtual event. */
{
Tcl_HashEntry *vhPtr;
Tcl_DString ds;
@@ -3160,7 +2790,7 @@ GetVirtualEvent(
PhysicalsOwned *poPtr;
Tk_Uid virtUid;
- virtUid = GetVirtualEventUid(interp, virtString);
+ virtUid = GetVirtualEventUid(interp, Tcl_GetString(virtName));
if (virtUid == NULL) {
return TCL_ERROR;
}
@@ -3172,7 +2802,7 @@ GetVirtualEvent(
Tcl_DStringInit(&ds);
- poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr);
+ poPtr = Tcl_GetHashValue(vhPtr);
for (iPhys = 0; iPhys < poPtr->numOwned; iPhys++) {
Tcl_DStringSetLength(&ds, 0);
GetPatternString(poPtr->patSeqs[iPhys], &ds);
@@ -3268,7 +2898,7 @@ HandleEventGenerate(
{
union {XEvent general; XVirtualEvent virtual;} event;
const char *p;
- char *name, *windowName;
+ const char *name, *windowName;
int count, flags, synch, i, number, warp;
Tcl_QueuePosition pos;
Pattern pat;
@@ -3276,7 +2906,8 @@ HandleEventGenerate(
TkWindow *mainPtr;
unsigned long eventMask;
Tcl_Obj *userDataObj;
- static const char *fieldStrings[] = {
+
+ static const char *const fieldStrings[] = {
"-when", "-above", "-borderwidth", "-button",
"-count", "-data", "-delta", "-detail",
"-focus", "-height",
@@ -3332,7 +2963,7 @@ HandleEventGenerate(
return TCL_ERROR;
}
- memset((void *) &event, 0, sizeof(event));
+ memset(&event, 0, sizeof(event));
event.general.xany.type = pat.eventType;
event.general.xany.serial = NextRequest(Tk_Display(tkwin));
event.general.xany.send_event = False;
@@ -3372,6 +3003,11 @@ HandleEventGenerate(
event.general.xkey.y_root = -1;
}
+ if (event.general.xany.type == FocusIn
+ || event.general.xany.type == FocusOut) {
+ event.general.xany.send_event = GENERATED_FOCUS_EVENT_MAGIC;
+ }
+
/*
* Process the remaining arguments to fill in additional fields of the
* event.
@@ -3536,7 +3172,7 @@ HandleEventGenerate(
break;
case EVENT_KEYSYM: {
KeySym keysym;
- char *value;
+ const char *value;
value = Tcl_GetString(valuePtr);
keysym = TkStringToKeysym(value);
@@ -3724,7 +3360,7 @@ HandleEventGenerate(
if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
return TCL_ERROR;
}
- if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) {
+ if (flags & KEY_BUTTON_MOTION_CROSSING) {
event.general.xkey.x = number;
/*
@@ -3782,8 +3418,16 @@ HandleEventGenerate(
Tcl_GetString(optionPtr), "\" option", NULL);
return TCL_ERROR;
}
+
+ /*
+ * Don't generate events for windows that don't exist yet.
+ */
+
+ if (!event.general.xany.window) {
+ goto done;
+ }
+
if (userDataObj != NULL) {
- XVirtualEvent *vePtr = (XVirtualEvent *) &event;
/*
* Must be virtual event to set that variable to non-NULL. Now we want
@@ -3792,7 +3436,7 @@ HandleEventGenerate(
* refcount will be decremented once the event has been processed.
*/
- vePtr->user_data = userDataObj;
+ event.virtual.user_data = userDataObj;
Tcl_IncrRefCount(userDataObj);
}
@@ -3815,13 +3459,17 @@ HandleEventGenerate(
TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);
if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
- Tcl_DoWhenIdle(DoWarp, (ClientData) dispPtr);
+ Tcl_DoWhenIdle(DoWarp, dispPtr);
dispPtr->flags |= TK_DISPLAY_IN_WARP;
}
- dispPtr->warpWindow = event.general.xany.window;
- dispPtr->warpX = event.general.xkey.x;
- dispPtr->warpY = event.general.xkey.y;
+ dispPtr->warpWindow = Tk_IdToWindow(Tk_Display(mainWin),
+ event.general.xmotion.window);
+ dispPtr->warpMainwin = mainWin;
+ dispPtr->warpX = event.general.xmotion.x;
+ dispPtr->warpY = event.general.xmotion.y;
}
+
+ done:
Tcl_ResetResult(interp);
return TCL_OK;
}
@@ -3833,32 +3481,36 @@ NameToWindow(
Tcl_Obj *objPtr, /* Contains name or id string of window. */
Tk_Window *tkwinPtr) /* Filled with token for window. */
{
- char *name;
+ const char *name = Tcl_GetString(objPtr);
Tk_Window tkwin;
- Window id;
- name = Tcl_GetString(objPtr);
if (name[0] == '.') {
tkwin = Tk_NameToWindow(interp, name, mainWin);
if (tkwin == NULL) {
return TCL_ERROR;
}
- *tkwinPtr = tkwin;
} else {
+ Window id;
+
/*
* Check for the winPtr being valid, even if it looks ok to
* TkpScanWindowId. [Bug #411307]
*/
- if ((TkpScanWindowId(NULL, name, &id) != TCL_OK) ||
- ((*tkwinPtr = Tk_IdToWindow(Tk_Display(mainWin), id))
- == NULL)) {
- Tcl_AppendResult(interp, "bad window name/identifier \"",
- name, "\"", NULL);
- return TCL_ERROR;
+ if (TkpScanWindowId(NULL, name, &id) != TCL_OK) {
+ goto badWindow;
+ }
+ tkwin = Tk_IdToWindow(Tk_Display(mainWin), id);
+ if (tkwin == NULL) {
+ goto badWindow;
}
}
+ *tkwinPtr = tkwin;
return TCL_OK;
+
+ badWindow:
+ Tcl_AppendResult(interp, "bad window name/identifier \"",name,"\"", NULL);
+ return TCL_ERROR;
}
/*
@@ -3876,14 +3528,14 @@ NameToWindow(
*
*-------------------------------------------------------------------------
*/
+
static void
DoWarp(
ClientData clientData)
{
- TkDisplay *dispPtr = (TkDisplay *) clientData;
+ TkDisplay *dispPtr = clientData;
- XWarpPointer(dispPtr->display, (Window) None, (Window) dispPtr->warpWindow,
- 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY);
+ TkpWarpPointer(dispPtr);
XForceScreenSaver(dispPtr->display, ScreenSaverReset);
dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}
@@ -4058,12 +3710,11 @@ FindSequence(
hPtr = Tcl_CreateHashEntry(patternTablePtr, (char *) &key, &isNew);
sequenceSize = numPats*sizeof(Pattern);
if (!isNew) {
- for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL;
+ for (psPtr = Tcl_GetHashValue(hPtr); psPtr != NULL;
psPtr = psPtr->nextSeqPtr) {
if ((numPats == psPtr->numPats)
&& ((flags & PAT_NEARBY) == (psPtr->flags & PAT_NEARBY))
- && (memcmp((char *) patPtr, (char *) psPtr->pats,
- sequenceSize) == 0)) {
+ && (memcmp(patPtr, psPtr->pats, sequenceSize) == 0)) {
goto done;
}
}
@@ -4083,21 +3734,17 @@ FindSequence(
return NULL;
}
- psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq)
- + (numPats-1)*sizeof(Pattern)));
+ psPtr = ckalloc(sizeof(PatSeq) + (numPats-1)*sizeof(Pattern));
psPtr->numPats = numPats;
- psPtr->eventProc = NULL;
- psPtr->freeProc = NULL;
- psPtr->clientData = NULL;
+ psPtr->script = NULL;
psPtr->flags = flags;
- psPtr->refCount = 0;
- psPtr->nextSeqPtr = (PatSeq *) Tcl_GetHashValue(hPtr);
+ psPtr->nextSeqPtr = Tcl_GetHashValue(hPtr);
psPtr->hPtr = hPtr;
psPtr->voPtr = NULL;
psPtr->nextObjPtr = NULL;
Tcl_SetHashValue(hPtr, psPtr);
- memcpy((void *) psPtr->pats, (void *) patPtr, sequenceSize);
+ memcpy(psPtr->pats, patPtr, sequenceSize);
done:
*maskPtr = eventMask;
@@ -4169,10 +3816,8 @@ ParseEventDescription(
if (isprint(UCHAR(*p))) {
patPtr->detail.keySym = *p;
} else {
- char buf[64];
-
- sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p);
- Tcl_SetResult(interp, buf, TCL_VOLATILE);
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "bad ASCII character 0x%x", UCHAR(*p)));
count = 0;
goto done;
}
@@ -4251,7 +3896,7 @@ ParseEventDescription(
if (hPtr == NULL) {
break;
}
- modPtr = (ModInfo *) Tcl_GetHashValue(hPtr);
+ modPtr = Tcl_GetHashValue(hPtr);
patPtr->needMods |= modPtr->mask;
if (modPtr->flags & MULT_CLICKS) {
int i = modPtr->flags & MULT_CLICKS;
@@ -4269,7 +3914,7 @@ ParseEventDescription(
eventFlags = 0;
hPtr = Tcl_FindHashEntry(&eventTable, field);
if (hPtr != NULL) {
- EventInfo *eiPtr = (EventInfo *) Tcl_GetHashValue(hPtr);
+ const EventInfo *eiPtr = Tcl_GetHashValue(hPtr);
patPtr->eventType = eiPtr->type;
eventFlags = flagArray[eiPtr->type];
@@ -4412,8 +4057,8 @@ GetPatternString(
Pattern *patPtr;
char c, buffer[TCL_INTEGER_SPACE];
int patsLeft, needMods;
- ModInfo *modPtr;
- EventInfo *eiPtr;
+ const ModInfo *modPtr;
+ const EventInfo *eiPtr;
/*
* The order of the patterns in the sequence is backwards from the order
@@ -4458,22 +4103,21 @@ GetPatternString(
Tcl_DStringAppend(dsPtr, "<", 1);
if ((psPtr->flags & PAT_NEARBY) && (patsLeft > 1)
- && (memcmp((char *) patPtr, (char *) (patPtr-1),
- sizeof(Pattern)) == 0)) {
+ && (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
patsLeft--;
patPtr--;
- if ((patsLeft > 1) && (memcmp((char *) patPtr,
- (char *) (patPtr-1), sizeof(Pattern)) == 0)) {
+ if ((patsLeft > 1) &&
+ (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
patsLeft--;
patPtr--;
- if ((patsLeft > 1) && (memcmp((char *) patPtr,
- (char *) (patPtr-1), sizeof(Pattern)) == 0)) {
- patsLeft--;
- patPtr--;
- Tcl_DStringAppend(dsPtr, "Quadruple-", 10);
- } else {
- Tcl_DStringAppend(dsPtr, "Triple-", 7);
- }
+ if ((patsLeft > 1) &&
+ (memcmp(patPtr, patPtr-1, sizeof(Pattern)) == 0)) {
+ patsLeft--;
+ patPtr--;
+ Tcl_DStringAppend(dsPtr, "Quadruple-", 10);
+ } else {
+ Tcl_DStringAppend(dsPtr, "Triple-", 7);
+ }
} else {
Tcl_DStringAppend(dsPtr, "Double-", 7);
}
@@ -4501,7 +4145,8 @@ GetPatternString(
if (patPtr->detail.clientData != 0) {
if ((patPtr->eventType == KeyPress)
|| (patPtr->eventType == KeyRelease)) {
- char *string = TkKeysymToString(patPtr->detail.keySym);
+ const char *string = TkKeysymToString(patPtr->detail.keySym);
+
if (string != NULL) {
Tcl_DStringAppend(dsPtr, string, -1);
}
@@ -4516,31 +4161,6 @@ GetPatternString(
}
/*
- *---------------------------------------------------------------------------
- *
- * EvalTclBinding --
- *
- * 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
- * percent-substitued binding string.
- *
- * Side effects:
- * Normal side effects due to eval.
- *
- *---------------------------------------------------------------------------
- */
-
-static void
-FreeTclBinding(
- ClientData clientData)
-{
- ckfree((char *) clientData);
-}
-
-/*
*----------------------------------------------------------------------
*
* TkStringToKeysym --
@@ -4559,7 +4179,7 @@ FreeTclBinding(
KeySym
TkStringToKeysym(
- char *name) /* Name of a keysym. */
+ const char *name) /* Name of a keysym. */
{
#ifdef REDO_KEYSYM_LOOKUP
Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&keySymTable, name);
@@ -4595,7 +4215,7 @@ TkStringToKeysym(
*----------------------------------------------------------------------
*/
-char *
+const char *
TkKeysymToString(
KeySym keysym)
{
@@ -4603,7 +4223,7 @@ TkKeysymToString(
Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&nameTable, (char *)keysym);
if (hPtr != NULL) {
- return (char *) Tcl_GetHashValue(hPtr);
+ return Tcl_GetHashValue(hPtr);
}
#endif /* REDO_KEYSYM_LOOKUP */
@@ -4613,41 +4233,6 @@ TkKeysymToString(
/*
*----------------------------------------------------------------------
*
- * TkCopyAndGlobalEval --
- *
- * 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.
- *
- * Side effects:
- * Any; depends on script.
- *
- *----------------------------------------------------------------------
- */
-
-int
-TkCopyAndGlobalEval(
- Tcl_Interp *interp, /* Interpreter in which to evaluate script. */
- char *script) /* Script to evaluate. */
-{
- Tcl_DString buffer;
- int code;
-
- Tcl_DStringInit(&buffer);
- Tcl_DStringAppend(&buffer, script, -1);
- code = Tcl_EvalEx(interp, Tcl_DStringValue(&buffer),
- Tcl_DStringLength(&buffer), TCL_EVAL_GLOBAL);
- Tcl_DStringFree(&buffer);
- return code;
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TkpGetBindingXEvent --
*
* This function returns the XEvent associated with the currently
@@ -4669,7 +4254,7 @@ TkpGetBindingXEvent(
Tcl_Interp *interp) /* Interpreter. */
{
TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
- BindingTable *bindPtr = (BindingTable *) winPtr->mainPtr->bindingTable;
+ BindingTable *bindPtr = winPtr->mainPtr->bindingTable;
return &(bindPtr->eventRing[bindPtr->curEvent]);
}