Tk Source Code

Check-in [5693e0dc]
Login

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

Overview
Comment:Fix [7d967c68]: Tk application fault when ibud-daemon IME is restarted
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5693e0dc1ee6a6fc492d7f4784dc7ada0af1d97c
User & Date: jan.nijtmans 2017-02-05 19:30:58
Context
2017-02-10
11:39
Fix [7d967c68a0] follow-up: Tk applications segmentation fault when ibus-daemon IME is restarted. Patch by Brad Lanam. check-in: 835bc95b user: jan.nijtmans tags: trunk
2017-02-05
19:30
Fix [7d967c68]: Tk application fault when ibud-daemon IME is restarted check-in: 5693e0dc user: jan.nijtmans tags: trunk
19:29
Fix [7d967c68]: Tk application fault when ibud-daemon IME is restarted check-in: c9224070 user: jan.nijtmans tags: core-8-6-branch
17:35
Fix [c0dbdd3ff3]: Tk Compatibility Fonts block access to system fonts check-in: 678fdae0 user: fvogel tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tk.h.

813
814
815
816
817
818
819



820
821
822
823
824
825
826
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
    char *dummy20;		/* geometryMaster */



} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.







>
>
>







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
    char *dummy20;		/* geometryMaster */
#ifdef TK_USE_INPUT_METHODS
    int dummy21;
#endif /* TK_USE_INPUT_METHODS */
} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.

Changes to generic/tkEvent.c.

352
353
354
355
356
357
358

359
360
361
362
363
364
365
    }


    if (winPtr->inputContext == NULL) {
	/* XCreateIC failed. */
	return;
    }


    /*
     * Adjust the window's event mask if the IM requires it.
     */
    XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL);
    if ((winPtr->atts.event_mask & im_event_mask) != im_event_mask) {
	winPtr->atts.event_mask |= im_event_mask;







>







352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
    }


    if (winPtr->inputContext == NULL) {
	/* XCreateIC failed. */
	return;
    }
    winPtr->ximGeneration = dispPtr->ximGeneration;

    /*
     * Adjust the window's event mask if the IM requires it.
     */
    XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL);
    if ((winPtr->atts.event_mask & im_event_mask) != im_event_mask) {
	winPtr->atts.event_mask |= im_event_mask;
1284
1285
1286
1287
1288
1289
1290








1291
1292
1293
1294
1295
1296
1297


1298
1299
1300
1301
1302
1303
1304
1305
     * Create the input context for the window if it hasn't already been done
     * (XFilterEvent needs this context). When the event is a FocusIn event,
     * set the input context focus to the receiving window. This code is only
     * ever active for X11.
     */

#ifdef TK_USE_INPUT_METHODS








    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
	if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
	    winPtr->flags |= TK_CHECKED_IC;
	    if (winPtr->dispPtr->inputMethod != NULL) {
		CreateXIC(winPtr);
	    }
	}


	if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) {
	    XSetICFocus(winPtr->inputContext);
	}
    }
#endif /*TK_USE_INPUT_METHODS*/

    /*
     * For events where it hasn't already been done, update the current time







>
>
>
>
>
>
>
>







>
>
|







1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
     * Create the input context for the window if it hasn't already been done
     * (XFilterEvent needs this context). When the event is a FocusIn event,
     * set the input context focus to the receiving window. This code is only
     * ever active for X11.
     */

#ifdef TK_USE_INPUT_METHODS
    /*
     * If the XIC has been invalidated, it must be recreated.
     */
    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
	winPtr->flags &= ~TK_CHECKED_IC;
	winPtr->inputContext = NULL;
    }

    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) {
	if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) {
	    winPtr->flags |= TK_CHECKED_IC;
	    if (winPtr->dispPtr->inputMethod != NULL) {
		CreateXIC(winPtr);
	    }
	}
	if ((eventPtr->type == FocusIn) &&
		(winPtr->dispPtr->inputMethod != NULL) &&
		(winPtr->inputContext != NULL)) {
	    XSetICFocus(winPtr->inputContext);
	}
    }
#endif /*TK_USE_INPUT_METHODS*/

    /*
     * For events where it hasn't already been done, update the current time

Changes to generic/tkInt.h.

504
505
506
507
508
509
510



511
512
513
514
515
516
517
    unsigned int flags;		/* Various flag values: these are all defined
				 * in below. */
    TkCaret caret;		/* Information about the caret for this
				 * display. This is not a pointer. */

    int iconDataSize;		/* Size of default iconphoto image data. */
    unsigned char *iconDataPtr;	/* Default iconphoto image data, if set. */



} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	Indicates that we should collapse motion events on this display
 *  TK_DISPLAY_USE_IM:			(default on, set via tk.tcl)







>
>
>







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
    unsigned int flags;		/* Various flag values: these are all defined
				 * in below. */
    TkCaret caret;		/* Information about the caret for this
				 * display. This is not a pointer. */

    int iconDataSize;		/* Size of default iconphoto image data. */
    unsigned char *iconDataPtr;	/* Default iconphoto image data, if set. */
#ifdef TK_USE_INPUT_METHODS
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	Indicates that we should collapse motion events on this display
 *  TK_DISPLAY_USE_IM:			(default on, set via tk.tcl)
805
806
807
808
809
810
811



812
813
814
815
816
817
818
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
    char *geometryMaster;



} TkWindow;

/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */








>
>
>







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
    char *geometryMaster;
#ifdef TK_USE_INPUT_METHODS
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;

/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */

Changes to generic/tkWindow.c.

351
352
353
354
355
356
357



358
359
360
361
362
363
364

    winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent);

    /*
     * Set the flags specified in the call.
     */




    winPtr->flags |= flags;

    /*
     * Force the window to use a border pixel instead of border pixmap. This
     * is needed for the case where the window doesn't use the default visual.
     * In this case, the default border is a pixmap inherited from the root
     * window, which won't work because it will have the wrong visual.







>
>
>







351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

    winPtr = TkAllocWindow(dispPtr, screenId, (TkWindow *) parent);

    /*
     * Set the flags specified in the call.
     */

#ifdef TK_USE_INPUT_METHODS
    winPtr->ximGeneration = 0;
#endif /*TK_USE_INPUT_METHODS*/
    winPtr->flags |= flags;

    /*
     * Force the window to use a border pixel instead of border pixmap. This
     * is needed for the case where the window doesn't use the default visual.
     * In this case, the default border is a pixmap inherited from the root
     * window, which won't work because it will have the wrong visual.
468
469
470
471
472
473
474



475
476
477
478
479
480
481
	    tsdPtr->displayList = dispPtr;

	    dispPtr->lastEventTime = CurrentTime;
	    dispPtr->bindInfoStale = 1;
	    dispPtr->cursorFont = None;
	    dispPtr->warpWindow = NULL;
	    dispPtr->multipleAtom = None;




	    /*
	     * By default we do want to collapse motion events in
	     * Tk_QueueWindowEvent.
	     */

	    dispPtr->flags |= TK_DISPLAY_COLLAPSE_MOTION_EVENTS;







>
>
>







471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
	    tsdPtr->displayList = dispPtr;

	    dispPtr->lastEventTime = CurrentTime;
	    dispPtr->bindInfoStale = 1;
	    dispPtr->cursorFont = None;
	    dispPtr->warpWindow = NULL;
	    dispPtr->multipleAtom = None;
#ifdef TK_USE_INPUT_METHODS
	    dispPtr->ximGeneration = 0;
#endif /*TK_USE_INPUT_METHODS*/

	    /*
	     * By default we do want to collapse motion events in
	     * Tk_QueueWindowEvent.
	     */

	    dispPtr->flags |= TK_DISPLAY_COLLAPSE_MOTION_EVENTS;
1438
1439
1440
1441
1442
1443
1444
1445

1446
1447
1448

1449
1450
1451
1452
1453
1454
1455
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable,
		(char *) winPtr->window));
	winPtr->window = None;
    }
    UnlinkWindow(winPtr);
    TkEventDeadWindow(winPtr);
#ifdef TK_USE_INPUT_METHODS
    if (winPtr->inputContext != NULL) {

	XDestroyIC(winPtr->inputContext);
	winPtr->inputContext = NULL;
    }

#endif /* TK_USE_INPUT_METHODS */
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    TkOptionDeadWindow(winPtr);
    TkSelDeadWindow(winPtr);
    TkGrabDeadWindow(winPtr);







|
>

<

>







1444
1445
1446
1447
1448
1449
1450
1451
1452
1453

1454
1455
1456
1457
1458
1459
1460
1461
1462
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->winTable,
		(char *) winPtr->window));
	winPtr->window = None;
    }
    UnlinkWindow(winPtr);
    TkEventDeadWindow(winPtr);
#ifdef TK_USE_INPUT_METHODS
    if (winPtr->inputContext != NULL &&
	    winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) {
	XDestroyIC(winPtr->inputContext);

    }
    winPtr->inputContext = NULL;
#endif /* TK_USE_INPUT_METHODS */
    if (winPtr->tagPtr != NULL) {
	TkFreeBindingTags(winPtr);
    }
    TkOptionDeadWindow(winPtr);
    TkSelDeadWindow(winPtr);
    TkGrabDeadWindow(winPtr);

Changes to unix/tkUnixEvent.c.

34
35
36
37
38
39
40


41
42
43
44
45
46
47

static void		DisplayCheckProc(ClientData clientData, int flags);
static void		DisplayExitHandler(ClientData clientData);
static void		DisplayFileProc(ClientData clientData, int flags);
static void		DisplaySetupProc(ClientData clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS


static void		OpenIM(TkDisplay *dispPtr);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkCreateXEventSource --







>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

static void		DisplayCheckProc(ClientData clientData, int flags);
static void		DisplayExitHandler(ClientData clientData);
static void		DisplayFileProc(ClientData clientData, int flags);
static void		DisplaySetupProc(ClientData clientData, int flags);
static void		TransferXEventsToTcl(Display *display);
#ifdef TK_USE_INPUT_METHODS
static void		InstantiateIMCallback(Display *, XPointer client_data, XPointer call_data);
static void		DestroyIMCallback(XIM im, XPointer client_data, XPointer call_data);
static void		OpenIM(TkDisplay *dispPtr);
#endif

/*
 *----------------------------------------------------------------------
 *
 * TkCreateXEventSource --
175
176
177
178
179
180
181


182
183
184
185
186
187
188
    }
    dispPtr = ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
    dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
    OpenIM(dispPtr);


#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);
    return dispPtr;
}

/*







>
>







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
    }
    dispPtr = ckalloc(sizeof(TkDisplay));
    memset(dispPtr, 0, sizeof(TkDisplay));
    dispPtr->display = display;
    dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
    OpenIM(dispPtr);
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
#endif
    Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE,
	    DisplayFileProc, dispPtr);
    return dispPtr;
}

/*
659
660
661
662
663
664
665





























666
667
668
669
670
671
672
    /*
     * Transfer events from the X event queue to the Tk event queue.
     */

    TransferXEventsToTcl(display);
}
#ifdef TK_USE_INPUT_METHODS






























/*
 *--------------------------------------------------------------
 *
 * OpenIM --
 *
 *	Tries to open an X input method associated with the given display.







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







663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
    /*
     * Transfer events from the X event queue to the Tk event queue.
     */

    TransferXEventsToTcl(display);
}
#ifdef TK_USE_INPUT_METHODS

static void
InstantiateIMCallback(
    Display      *display,
    XPointer     client_data,
    XPointer     call_data)
{
    TkDisplay    *dispPtr;

    dispPtr = (TkDisplay *) client_data;
    OpenIM(dispPtr);
    XUnregisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
}

static void
DestroyIMCallback(
    XIM         im,
    XPointer    client_data,
    XPointer    call_data)
{
    TkDisplay   *dispPtr;

    dispPtr = (TkDisplay *) client_data;
    dispPtr->inputMethod = NULL;
    ++dispPtr->ximGeneration;
    XRegisterIMInstantiateCallback(dispPtr->display, NULL, NULL, NULL,
	    InstantiateIMCallback, (XPointer) dispPtr);
}

/*
 *--------------------------------------------------------------
 *
 * OpenIM --
 *
 *	Tries to open an X input method associated with the given display.
689
690
691
692
693
694
695

696
697
698
699











700
701
702
703
704
705
706
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;

    if (XSetLocaleModifiers("") == NULL) {
	return;
    }


    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }












    if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
	    NULL) != NULL) || (stylePtr == NULL)) {
	goto error;
    }

    /*







>




>
>
>
>
>
>
>
>
>
>
>







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
    XIMStyles *stylePtr;
    XIMStyle bestStyle = 0;

    if (XSetLocaleModifiers("") == NULL) {
	return;
    }

    ++dispPtr->ximGeneration;
    dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
    if (dispPtr->inputMethod == NULL) {
	return;
    }

    /* Require X11R6 */
    {
	XIMCallback destroy_cb;

	destroy_cb.callback = DestroyIMCallback;
	destroy_cb.client_data = (XPointer) dispPtr;
	if (XSetIMValues(dispPtr->inputMethod, XNDestroyCallback,
		&destroy_cb, NULL))
	    goto error;
    }

    if ((XGetIMValues(dispPtr->inputMethod, XNQueryInputStyle, &stylePtr,
	    NULL) != NULL) || (stylePtr == NULL)) {
	goto error;
    }

    /*
740
741
742
743
744
745
746

747
748
749
750
751
752
753

    return;

error:
    if (dispPtr->inputMethod) {
	XCloseIM(dispPtr->inputMethod);
	dispPtr->inputMethod = NULL;

    }
}
#endif /* TK_USE_INPUT_METHODS */

void
TkpWarpPointer(
    TkDisplay *dispPtr)







>







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799

    return;

error:
    if (dispPtr->inputMethod) {
	XCloseIM(dispPtr->inputMethod);
	dispPtr->inputMethod = NULL;
	++dispPtr->ximGeneration;
    }
}
#endif /* TK_USE_INPUT_METHODS */

void
TkpWarpPointer(
    TkDisplay *dispPtr)