Tk Source Code

Check-in [68e7ae9b]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix for bug 3410609; confirmed to work on UK keyboard.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-5-branch
Files: files | file ages | folders
SHA1: 68e7ae9b2c07f6875d840c8eba41bf5151184002
User & Date: dkf 2011-10-25 20:42:56
Context
2011-10-26
13:36
Update changes for Tk 8.5.11. check-in: d45e4314 user: dgp tags: core-8-5-branch
2011-10-25
20:47
Fix for bug 3410609; confirmed to work on UK keyboard. check-in: 63902eff user: dkf tags: trunk
20:42
Fix for bug 3410609; confirmed to work on UK keyboard. check-in: 68e7ae9b user: dkf tags: core-8-5-branch
2011-10-24
19:13
Implementation of TIP #382. check-in: a126d3d9 user: dgp tags: core-8-5-branch
2011-10-01
19:14
Tentative fix for bug 3410609 - use the keysym returned by XLookupString in preference to the raw one in the XEvent. Closed-Leaf check-in: 51167632 user: kennykb tags: bug-3410609
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.











1
2
3
4
5
6
7










2011-09-01  Donal K. Fellows  <[email protected]>

	* doc/photo.n: Correctly documented what the [$ph data] command
	produces without the -format option.

2011-08-16  Jan Nijtmans  <[email protected]>

>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2011-10-01  Kevin B. Kenny  <[email protected]>

	* generic/tkInt.h:	[Bug 3410609] Change the event mechanism
	* unix/tkUnixEvent.c:	for <KeyPress> events to use the keysym
	* unix/tkUnixKey.c:	returned by XLookupString in preference to
	the one that appears in the raw X event at any level. This change
	allows binding to ISO_Level3_Shift-ed characters, composed characters,
	and similar beasts. KeyRelease events still work as they did before,
	as does Tk with input methods disabled.

2011-09-01  Donal K. Fellows  <[email protected]>

	* doc/photo.n: Correctly documented what the [$ph data] command
	produces without the -format option.

2011-08-16  Jan Nijtmans  <[email protected]>

Changes to generic/tkInt.h.

860
861
862
863
864
865
866


867
868
869
870
871
872
873
    char *charValuePtr;		/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    int charValueLen;		/* Length of string in charValuePtr when that
				 * is non-NULL. */


} TkKeyEvent;

/*
 * The following structure is used as a two way map between integers and
 * strings, usually to map between an internal C representation and the
 * strings used in Tcl.
 */







>
>







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    char *charValuePtr;		/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    int charValueLen;		/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
} TkKeyEvent;

/*
 * The following structure is used as a two way map between integers and
 * strings, usually to map between an internal C representation and the
 * strings used in Tcl.
 */

Changes to unix/tkUnixEvent.c.

312
313
314
315
316
317
318

319
320
321
322
323
324
325
	}
	if (XFilterEvent(&event.x, w)) {
	    continue;
	}
	if (event.type == KeyPress || event.type == KeyRelease) {
	    event.k.charValuePtr = NULL;
	    event.k.charValueLen = 0;


	    /*
	     * Force the calling of the input method engine now. The results
	     * from it will be cached in the event so that they don't get lost
	     * (to a race condition with other XIM-handled key events) between
	     * entering the event queue and getting serviced. [Bug 1924761]
	     */







>







312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
	}
	if (XFilterEvent(&event.x, w)) {
	    continue;
	}
	if (event.type == KeyPress || event.type == KeyRelease) {
	    event.k.charValuePtr = NULL;
	    event.k.charValueLen = 0;
	    event.k.keysym = NoSymbol;

	    /*
	     * Force the calling of the input method engine now. The results
	     * from it will be cached in the event so that they don't get lost
	     * (to a race condition with other XIM-handled key events) between
	     * entering the event queue and getting serviced. [Bug 1924761]
	     */

Changes to unix/tkUnixKey.c.

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    {
	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		NULL, &status);

	if (status == XBufferOverflow) { /* Expand buffer and try again */
	    Tcl_DStringSetLength(dsPtr, len);
	    len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr), 
		    NULL, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
	/*
	 * Overallocate the dstring to the maximum stack amount.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);

	len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(&buf), Tcl_DStringLength(&buf), NULL,
		&status);

	/*
	 * If the buffer wasn't big enough, grow the buffer and try again.
	 */

	if (status == XBufferOverflow) {
	    Tcl_DStringSetLength(&buf, len);
	    len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(&buf), len, NULL, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}

	Tcl_DStringSetLength(&buf, len);
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);







|





|














|
|








|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
    {
	Status status;

#if X_HAVE_UTF8_STRING
	Tcl_DStringSetLength(dsPtr, TCL_DSTRING_STATIC_SIZE-1);
	len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr),
		&kePtr->keysym, &status);

	if (status == XBufferOverflow) { /* Expand buffer and try again */
	    Tcl_DStringSetLength(dsPtr, len);
	    len = Xutf8LookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(dsPtr), Tcl_DStringLength(dsPtr), 
		    &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}
	Tcl_DStringSetLength(dsPtr, len);
#else /* !X_HAVE_UTF8_STRING */
	/*
	 * Overallocate the dstring to the maximum stack amount.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);

	len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		Tcl_DStringValue(&buf), Tcl_DStringLength(&buf), 
                &kePtr->keysym, &status);

	/*
	 * If the buffer wasn't big enough, grow the buffer and try again.
	 */

	if (status == XBufferOverflow) {
	    Tcl_DStringSetLength(&buf, len);
	    len = XmbLookupString(winPtr->inputContext, &eventPtr->xkey,
		    Tcl_DStringValue(&buf), len, &kePtr->keysym, &status);
	}
	if ((status != XLookupChars) && (status != XLookupBoth)) {
	    len = 0;
	}

	Tcl_DStringSetLength(&buf, len);
	Tcl_ExternalToUtfDString(NULL, Tcl_DStringValue(&buf), len, dsPtr);
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, 0, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = Tcl_UniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	 * Note: XLookupString() normally returns a single ISO Latin 1 or
	 * ASCII control character.
	 */

	Tcl_DStringInit(&buf);
	Tcl_DStringSetLength(&buf, TCL_DSTRING_STATIC_SIZE-1);
	len = XLookupString(&eventPtr->xkey, Tcl_DStringValue(&buf),
		TCL_DSTRING_STATIC_SIZE, &kePtr->keysym, 0);
	Tcl_DStringValue(&buf)[len] = '\0';

	if (len == 1) {
	    len = Tcl_UniCharToUtf((unsigned char) Tcl_DStringValue(&buf)[0],
		    Tcl_DStringValue(dsPtr));
	    Tcl_DStringSetLength(dsPtr, len);
	} else {
273
274
275
276
277
278
279























280
281
282
283
284
285
286
KeySym
TkpGetKeySym(
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;
























    /*
     * Refresh the mapping information if it's stale
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
KeySym
TkpGetKeySym(
    TkDisplay *dispPtr,		/* Display in which to map keycode. */
    XEvent *eventPtr)		/* Description of X event. */
{
    KeySym sym;
    int index;
    TkKeyEvent* kePtr = (TkKeyEvent*) eventPtr;

#ifdef TK_USE_INPUT_METHODS
    /* 
     * If input methods are active, we may already have determined a keysym.
     * Return it.
     */

    if (eventPtr->type == KeyPress && dispPtr
	    && (dispPtr->flags & TK_DISPLAY_USE_IM)) {
	if (kePtr->charValuePtr == NULL) {
	    Tcl_DString ds;
	    TkWindow *winPtr = (TkWindow *)
		Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window);
	    Tcl_DStringInit(&ds);
	    (void) TkpGetString(winPtr, eventPtr, &ds);
	    Tcl_DStringFree(&ds);
	}
	if (kePtr->charValuePtr != NULL) {
	    return kePtr->keysym;
	}
    }
#endif

    /*
     * Refresh the mapping information if it's stale
     */

    if (dispPtr->bindInfoStale) {
	TkpInitKeymapInfo(dispPtr);