diff options
Diffstat (limited to 'tk/unix/tkUnixEvent.c')
-rw-r--r-- | tk/unix/tkUnixEvent.c | 128 |
1 files changed, 113 insertions, 15 deletions
diff --git a/tk/unix/tkUnixEvent.c b/tk/unix/tkUnixEvent.c index f90963be892..a4debe3f7f6 100644 --- a/tk/unix/tkUnixEvent.c +++ b/tk/unix/tkUnixEvent.c @@ -39,6 +39,9 @@ static void DisplayFileProc _ANSI_ARGS_((ClientData clientData, static void DisplaySetupProc _ANSI_ARGS_((ClientData clientData, int flags)); static void TransferXEventsToTcl _ANSI_ARGS_((Display *display)); +#ifdef TK_USE_INPUT_METHODS +static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr)); +#endif /* @@ -118,7 +121,7 @@ DisplayExitHandler(clientData) TkDisplay * TkpOpenDisplay(display_name) - char *display_name; + CONST char *display_name; { TkDisplay *dispPtr; Display *display = XOpenDisplay(display_name); @@ -127,7 +130,11 @@ TkpOpenDisplay(display_name) return NULL; } dispPtr = (TkDisplay *) ckalloc(sizeof(TkDisplay)); + memset(dispPtr, 0, sizeof(TkDisplay)); dispPtr->display = display; +#ifdef TK_USE_INPUT_METHODS + OpenIM(dispPtr); +#endif Tcl_CreateFileHandler(ConnectionNumber(display), TCL_READABLE, DisplayFileProc, (ClientData) dispPtr); return dispPtr; @@ -144,25 +151,44 @@ TkpOpenDisplay(display_name) * None. * * Side effects: - * Deallocates the displayPtr. + * Deallocates the displayPtr and unix-specific resources. * *---------------------------------------------------------------------- */ void -TkpCloseDisplay(displayPtr) - TkDisplay *displayPtr; +TkpCloseDisplay(dispPtr) + TkDisplay *dispPtr; { - TkDisplay *dispPtr = (TkDisplay *) displayPtr; + TkSendCleanup(dispPtr); + + TkFreeXId(dispPtr); + + TkWmCleanup(dispPtr); + +#ifdef TK_USE_INPUT_METHODS +#if TK_XIM_SPOT + if (dispPtr->inputXfs) { + XFreeFontSet(dispPtr->display, dispPtr->inputXfs); + } +#endif + if (dispPtr->inputMethod) { + /* + * This caused core dumps on some systems (Solaris 2.3 1/6/95). + * The most likely cause of this is a bug in X that accesses + * memory that was already deallocated inside XCloseIM(). + * One can work around this issue by making sure a XDestroyIC() + * gets invoked for each XCreateIC(). + */ + XCloseIM(dispPtr->inputMethod); + } +#endif if (dispPtr->display != 0) { - Tcl_DeleteFileHandler(ConnectionNumber(dispPtr->display)); - - (void) XSync(dispPtr->display, False); - (void) XCloseDisplay(dispPtr->display); + Tcl_DeleteFileHandler(ConnectionNumber(dispPtr->display)); + (void) XSync(dispPtr->display, False); + (void) XCloseDisplay(dispPtr->display); } - - ckfree((char *) dispPtr); } /* @@ -230,7 +256,6 @@ DisplaySetupProc(clientData, flags) *---------------------------------------------------------------------- */ - static void TransferXEventsToTcl(display) Display *display; @@ -285,8 +310,6 @@ DisplayCheckProc(clientData, flags) TransferXEventsToTcl(dispPtr->display); } } - - /* *---------------------------------------------------------------------- @@ -516,6 +539,81 @@ TkpSync(display) * 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. Right now we can only deal with a bare-bones + * input style: no preedit, and no status. + * + * Results: + * Stores the input method in dispPtr->inputMethod; if there isn't + * a suitable input method, then NULL is stored in dispPtr->inputMethod. + * + * Side effects: + * An input method gets opened. + * + *-------------------------------------------------------------- + */ + +static void +OpenIM(dispPtr) + TkDisplay *dispPtr; /* Tk's structure for the display. */ +{ + unsigned short i; + XIMStyles *stylePtr; + char *modifier_list; + + if ((modifier_list = XSetLocaleModifiers("")) == NULL) { + goto error; + } + + 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; + } +#if TK_XIM_SPOT + /* + * If we want to do over-the-spot XIM, we have to check that this + * mode is supported. If not we will fall-through to the check below. + */ + for (i = 0; i < stylePtr->count_styles; i++) { + if (stylePtr->supported_styles[i] + == (XIMPreeditPosition | XIMStatusNothing)) { + dispPtr->flags |= TK_DISPLAY_XIM_SPOT; + XFree(stylePtr); + return; + } + } +#endif + for (i = 0; i < stylePtr->count_styles; i++) { + if (stylePtr->supported_styles[i] + == (XIMPreeditNothing | XIMStatusNothing)) { + XFree(stylePtr); + return; + } + } + XFree(stylePtr); + error: + + if (dispPtr->inputMethod) { + /* + * This call should not suffer from any core dumping problems + * since we have not allocated any input contexts. + */ + XCloseIM(dispPtr->inputMethod); + dispPtr->inputMethod = NULL; + } +} +#endif /* TK_USE_INPUT_METHODS */ |