summaryrefslogtreecommitdiffstats
path: root/unix/tkUnixEvent.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tkUnixEvent.c')
-rw-r--r--unix/tkUnixEvent.c452
1 files changed, 237 insertions, 215 deletions
diff --git a/unix/tkUnixEvent.c b/unix/tkUnixEvent.c
index 60800d2..0cc3731 100644
--- a/unix/tkUnixEvent.c
+++ b/unix/tkUnixEvent.c
@@ -1,22 +1,26 @@
-/*
+/*
* tkUnixEvent.c --
*
- * This file implements an event source for X displays for the
- * UNIX version of Tk.
+ * This file implements an event source for X displays for the UNIX
+ * version of Tk.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * 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.
*/
-#include "tkInt.h"
#include "tkUnixInt.h"
#include <signal.h>
+#ifdef HAVE_XKBKEYCODETOKEYSYM
+# include <X11/XKBlib.h>
+#else
+# define XkbOpenDisplay(D,V,E,M,m,R) (V),(E),(M),(m),(R),(NULL)
+#endif
/*
- * The following static indicates whether this module has been initialized
- * in the current thread.
+ * The following static indicates whether this module has been initialized in
+ * the current thread.
*/
typedef struct ThreadSpecificData {
@@ -24,42 +28,26 @@ typedef struct ThreadSpecificData {
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
-#if defined(TK_USE_INPUT_METHODS) && defined(PEEK_XCLOSEIM)
-/*
- * Structure used to peek into internal XIM data structure.
- * This is only known to work with XFree86.
- */
-struct XIMPeek {
- void *junk1, *junk2;
- XIC ic_chain;
-};
-#endif
-
/*
- * Prototypes for procedures that are referenced only in this file:
+ * Prototypes for functions that are referenced only in this file:
*/
-static void DisplayCheckProc _ANSI_ARGS_((ClientData clientData,
- int flags));
-static void DisplayExitHandler _ANSI_ARGS_((
- ClientData clientData));
-static void DisplayFileProc _ANSI_ARGS_((ClientData clientData,
- int flags));
-static void DisplaySetupProc _ANSI_ARGS_((ClientData clientData,
- int flags));
-static void TransferXEventsToTcl _ANSI_ARGS_((Display *display));
+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 _ANSI_ARGS_((TkDisplay *dispPtr));
+static void OpenIM(TkDisplay *dispPtr);
#endif
-
/*
*----------------------------------------------------------------------
*
* TkCreateXEventSource --
*
- * This procedure is called during Tk initialization to create
- * the event source for X Window events.
+ * This function is called during Tk initialization to create the event
+ * source for X Window events.
*
* Results:
* None.
@@ -71,10 +59,10 @@ static void OpenIM _ANSI_ARGS_((TkDisplay *dispPtr));
*/
void
-TkCreateXEventSource()
+TkCreateXEventSource(void)
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
if (!tsdPtr->initialized) {
tsdPtr->initialized = 1;
@@ -88,8 +76,8 @@ TkCreateXEventSource()
*
* DisplayExitHandler --
*
- * This function is called during finalization to clean up the
- * display module.
+ * This function is called during finalization to clean up the display
+ * module.
*
* Results:
* None.
@@ -101,11 +89,11 @@ TkCreateXEventSource()
*/
static void
-DisplayExitHandler(clientData)
- ClientData clientData; /* Not used. */
+DisplayExitHandler(
+ ClientData clientData) /* Not used. */
{
- ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
- Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
+ ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
+ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
Tcl_DeleteEventSource(DisplaySetupProc, DisplayCheckProc, NULL);
tsdPtr->initialized = 0;
@@ -116,8 +104,8 @@ DisplayExitHandler(clientData)
*
* TkpOpenDisplay --
*
- * Allocates a new TkDisplay, opens the X display, and establishes
- * the file handler for the connection.
+ * Allocates a new TkDisplay, opens the X display, and establishes the
+ * file handler for the connection.
*
* Results:
* A pointer to a Tk display structure.
@@ -129,11 +117,37 @@ DisplayExitHandler(clientData)
*/
TkDisplay *
-TkpOpenDisplay(display_name)
- CONST char *display_name;
+TkpOpenDisplay(
+ CONST char *displayNameStr)
{
TkDisplay *dispPtr;
- Display *display = XOpenDisplay(display_name);
+ Display *display;
+ int event = 0;
+ int error = 0;
+ int major = 1;
+ int minor = 0;
+ int reason = 0;
+ unsigned int use_xkb = 0;
+
+ /*
+ ** Bug [3607830]: Before using Xkb, it must be initialized and confirmed
+ ** that the serve supports it. The XkbOpenDisplay call
+ ** will perform this check and return NULL if the extension
+ ** is not supported.
+ **
+ ** Work around un-const-ified Xkb headers using (char *) cast.
+ */
+ display = XkbOpenDisplay((char *)displayNameStr, &event, &error, &major,
+ &minor, &reason);
+
+ if (display == NULL) {
+ /*fprintf(stderr,"event=%d error=%d major=%d minor=%d reason=%d\nDisabling xkb\n",
+ event, error, major, minor, reason);*/
+ display = XOpenDisplay(displayNameStr);
+ } else {
+ use_xkb = TK_DISPLAY_USE_XKB;
+ /*fprintf(stderr, "Using xkb %d.%d\n", major, minor);*/
+ }
if (display == NULL) {
return NULL;
@@ -141,6 +155,7 @@ TkpOpenDisplay(display_name)
dispPtr = (TkDisplay *) ckalloc(sizeof(TkDisplay));
memset(dispPtr, 0, sizeof(TkDisplay));
dispPtr->display = display;
+ dispPtr->flags |= use_xkb;
#ifdef TK_USE_INPUT_METHODS
OpenIM(dispPtr);
#endif
@@ -154,7 +169,7 @@ TkpOpenDisplay(display_name)
*
* TkpCloseDisplay --
*
- * Cancels notifier callbacks and closes a display.
+ * Cancels notifier callbacks and closes a display.
*
* Results:
* None.
@@ -166,8 +181,8 @@ TkpOpenDisplay(display_name)
*/
void
-TkpCloseDisplay(dispPtr)
- TkDisplay *dispPtr;
+TkpCloseDisplay(
+ TkDisplay *dispPtr)
{
TkSendCleanup(dispPtr);
@@ -176,55 +191,10 @@ TkpCloseDisplay(dispPtr)
TkWmCleanup(dispPtr);
#ifdef TK_USE_INPUT_METHODS
-#if TK_XIM_SPOT
if (dispPtr->inputXfs) {
XFreeFontSet(dispPtr->display, dispPtr->inputXfs);
}
-#endif
if (dispPtr->inputMethod) {
- /*
- * Calling XCloseIM with an input context that has not
- * been freed can cause a crash. This crash has been
- * reproduced under Linux systems with XFree86 3.3
- * and may have also been seen under Solaris 2.3.
- * The crash is caused by a double free of memory
- * inside the X library. Memory that was already
- * deallocated may be accessed again inside XCloseIM.
- * This bug can be avoided by making sure that a
- * call to XDestroyIC is made for each XCreateIC call.
- * This bug has been fixed in XFree86 4.2.99.2.
- * The internal layout of the XIM structure changed
- * in the XFree86 4.2 release so the test should
- * not be run for with these new releases.
- */
-
-#if defined(TK_USE_INPUT_METHODS) && defined(PEEK_XCLOSEIM)
- int do_peek = 0;
- struct XIMPeek *peek;
-
- if (strstr(ServerVendor(dispPtr->display), "XFree86")) {
- int vendrel = VendorRelease(dispPtr->display);
- if (vendrel < 336) {
- /* 3.3.4 and 3.3.5 */
- do_peek = 1;
- } else if (vendrel < 3900) {
- /* Other 3.3.x versions */
- do_peek = 1;
- } else if (vendrel < 40000000) {
- /* 4.0.x versions */
- do_peek = 1;
- } else {
- /* Newer than 4.0 */
- do_peek = 0;
- }
- }
-
- if (do_peek) {
- peek = (struct XIMPeek *) dispPtr->inputMethod;
- if (peek->ic_chain != NULL)
- panic("input contexts not freed before XCloseIM");
- }
-#endif
XCloseIM(dispPtr->inputMethod);
}
#endif
@@ -241,11 +211,10 @@ TkpCloseDisplay(dispPtr)
*
* TkClipCleanup --
*
- * This procedure is called to cleanup resources associated with
- * claiming clipboard ownership and for receiving selection get
- * results. This function is called in tkWindow.c. This has to be
- * called by the display cleanup function because we still need the
- * access display elements.
+ * This function is called to cleanup resources associated with claiming
+ * clipboard ownership and for receiving selection get results. This
+ * function is called in tkWindow.c. This has to be called by the display
+ * cleanup function because we still need the access display elements.
*
* Results:
* None.
@@ -257,8 +226,8 @@ TkpCloseDisplay(dispPtr)
*/
void
-TkClipCleanup(dispPtr)
- TkDisplay *dispPtr; /* display associated with clipboard */
+TkClipCleanup(
+ TkDisplay *dispPtr) /* Display associated with clipboard */
{
if (dispPtr->clipWindow != NULL) {
Tk_DeleteSelHandler(dispPtr->clipWindow, dispPtr->clipboardAtom,
@@ -277,25 +246,25 @@ TkClipCleanup(dispPtr)
*
* DisplaySetupProc --
*
- * This procedure implements the setup part of the UNIX X display
- * event source. It is invoked by Tcl_DoOneEvent before entering
- * the notifier to check for events on all displays.
+ * This function implements the setup part of the UNIX X display event
+ * source. It is invoked by Tcl_DoOneEvent before entering the notifier
+ * to check for events on all displays.
*
* Results:
* None.
*
* Side effects:
- * If data is queued on a display inside Xlib, then the maximum
- * block time will be set to 0 to ensure that the notifier returns
- * control to Tcl even if there is no more data on the X connection.
+ * If data is queued on a display inside Xlib, then the maximum block
+ * time will be set to 0 to ensure that the notifier returns control to
+ * Tcl even if there is no more data on the X connection.
*
*----------------------------------------------------------------------
*/
static void
-DisplaySetupProc(clientData, flags)
- ClientData clientData; /* Not used. */
- int flags;
+DisplaySetupProc(
+ ClientData clientData, /* Not used. */
+ int flags)
{
TkDisplay *dispPtr;
static Tcl_Time blockTime = { 0, 0 };
@@ -305,13 +274,11 @@ DisplaySetupProc(clientData, flags)
}
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
- dispPtr = dispPtr->nextPtr) {
-
+ dispPtr = dispPtr->nextPtr) {
/*
- * Flush the display. If data is pending on the X queue, set
- * the block time to zero. This ensures that we won't block
- * in the notifier if there is data in the X queue, but not on
- * the server socket.
+ * Flush the display. If data is pending on the X queue, set the block
+ * time to zero. This ensures that we won't block in the notifier if
+ * there is data in the X queue, but not on the server socket.
*/
XFlush(dispPtr->display);
@@ -324,9 +291,9 @@ DisplaySetupProc(clientData, flags)
/*
*----------------------------------------------------------------------
*
- * TransferXEventsToTcl
+ * TransferXEventsToTcl --
*
- * Transfer events from the X event queue to the Tk event queue.
+ * Transfer events from the X event queue to the Tk event queue.
*
* Results:
* None.
@@ -338,25 +305,72 @@ DisplaySetupProc(clientData, flags)
*/
static void
-TransferXEventsToTcl(display)
- Display *display;
+TransferXEventsToTcl(
+ Display *display)
{
- XEvent event;
+ union {
+ int type;
+ XEvent x;
+ TkKeyEvent k;
+ } event;
+ Window w;
+ TkDisplay *dispPtr = NULL;
/*
- * Transfer events from the X event queue to the Tk event queue
- * after XIM event filtering. KeyPress and KeyRelease events
- * are filtered in Tk_HandleEvent instead of here, so that Tk's
- * focus management code can redirect them.
+ * Transfer events from the X event queue to the Tk event queue after XIM
+ * event filtering. KeyPress and KeyRelease events need special treatment
+ * so that they get directed according to Tk's focus rules during XIM
+ * handling. Theoretically they can go to the wrong place still (if
+ * there's a focus change in the queue) but if we push the handling off
+ * until Tk_HandleEvent then many input methods actually cease to work
+ * correctly. Most of the time, Tk processes its event queue fast enough
+ * for this to not be an issue anyway. [Bug 1924761]
*/
+
while (QLength(display) > 0) {
- XNextEvent(display, &event);
- if (event.type != KeyPress && event.type != KeyRelease) {
- if (XFilterEvent(&event, None)) {
- continue;
+ XNextEvent(display, &event.x);
+ w = None;
+ if (event.type == KeyPress || event.type == KeyRelease) {
+ for (dispPtr = TkGetDisplayList(); ; dispPtr = dispPtr->nextPtr) {
+ if (dispPtr == NULL) {
+ break;
+ } else if (dispPtr->display == event.x.xany.display) {
+ if (dispPtr->focusPtr != NULL) {
+ w = dispPtr->focusPtr->window;
+ }
+ break;
+ }
}
}
- Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
+ 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]
+ */
+
+#ifdef TK_USE_INPUT_METHODS
+ if (event.type == KeyPress && dispPtr &&
+ (dispPtr->flags & TK_DISPLAY_USE_IM)) {
+ if (dispPtr->focusPtr && dispPtr->focusPtr->inputContext) {
+ Tcl_DString ds;
+
+ Tcl_DStringInit(&ds);
+ (void) TkpGetString(dispPtr->focusPtr, &event.x, &ds);
+ Tcl_DStringFree(&ds);
+ }
+ }
+#endif
+ }
+ Tk_QueueWindowEvent(&event.x, TCL_QUEUE_TAIL);
}
}
@@ -365,8 +379,7 @@ TransferXEventsToTcl(display)
*
* DisplayCheckProc --
*
- * This procedure checks for events sitting in the X event
- * queue.
+ * This function checks for events sitting in the X event queue.
*
* Results:
* None.
@@ -378,9 +391,9 @@ TransferXEventsToTcl(display)
*/
static void
-DisplayCheckProc(clientData, flags)
- ClientData clientData; /* Not used. */
- int flags;
+DisplayCheckProc(
+ ClientData clientData, /* Not used. */
+ int flags)
{
TkDisplay *dispPtr;
@@ -389,7 +402,7 @@ DisplayCheckProc(clientData, flags)
}
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
- dispPtr = dispPtr->nextPtr) {
+ dispPtr = dispPtr->nextPtr) {
XFlush(dispPtr->display);
TransferXEventsToTcl(dispPtr->display);
}
@@ -400,22 +413,22 @@ DisplayCheckProc(clientData, flags)
*
* DisplayFileProc --
*
- * This procedure implements the file handler for the X connection.
+ * This function implements the file handler for the X connection.
*
* Results:
* None.
*
* Side effects:
- * Makes entries on the Tcl event queue for all the events available
- * from all the displays.
+ * Makes entries on the Tcl event queue for all the events available from
+ * all the displays.
*
*----------------------------------------------------------------------
*/
static void
-DisplayFileProc(clientData, flags)
- ClientData clientData; /* The display pointer. */
- int flags; /* Should be TCL_READABLE. */
+DisplayFileProc(
+ ClientData clientData, /* The display pointer. */
+ int flags) /* Should be TCL_READABLE. */
{
TkDisplay *dispPtr = (TkDisplay *) clientData;
Display *display = dispPtr->display;
@@ -424,38 +437,34 @@ DisplayFileProc(clientData, flags)
XFlush(display);
numFound = XEventsQueued(display, QueuedAfterReading);
if (numFound == 0) {
-
/*
- * Things are very tricky if there aren't any events readable
- * at this point (after all, there was supposedly data
- * available on the connection). A couple of things could
- * have occurred:
- *
- * One possibility is that there were only error events in the
- * input from the server. If this happens, we should return
- * (we don't want to go to sleep in XNextEvent below, since
- * this would block out other sources of input to the
- * process).
+ * Things are very tricky if there aren't any events readable at this
+ * point (after all, there was supposedly data available on the
+ * connection). A couple of things could have occurred:
+ *
+ * One possibility is that there were only error events in the input
+ * from the server. If this happens, we should return (we don't want
+ * to go to sleep in XNextEvent below, since this would block out
+ * other sources of input to the process).
*
- * Another possibility is that our connection to the server
- * has been closed. This will not necessarily be detected in
- * XEventsQueued (!!), so if we just return then there will be
- * an infinite loop. To detect such an error, generate a NoOp
- * protocol request to exercise the connection to the server,
- * then return. However, must disable SIGPIPE while sending
- * the request, or else the process will die from the signal
- * and won't invoke the X error function to print a nice (?!)
- * message.
+ * Another possibility is that our connection to the server has been
+ * closed. This will not necessarily be detected in XEventsQueued (!!)
+ * so if we just return then there will be an infinite loop. To detect
+ * such an error, generate a NoOp protocol request to exercise the
+ * connection to the server, then return. However, must disable
+ * SIGPIPE while sending the request, or else the process will die
+ * from the signal and won't invoke the X error function to print a
+ * nice (?!) message.
*/
-
+
void (*oldHandler)();
-
+
oldHandler = (void (*)()) signal(SIGPIPE, SIG_IGN);
XNoOp(display);
XFlush(display);
(void) signal(SIGPIPE, oldHandler);
}
-
+
TransferXEventsToTcl(display);
}
@@ -481,8 +490,8 @@ DisplayFileProc(clientData, flags)
*/
int
-TkUnixDoOneXEvent(timePtr)
- Tcl_Time *timePtr; /* Specifies the absolute time when the call
+TkUnixDoOneXEvent(
+ Tcl_Time *timePtr) /* Specifies the absolute time when the call
* should time out. */
{
TkDisplay *dispPtr;
@@ -490,10 +499,10 @@ TkUnixDoOneXEvent(timePtr)
struct timeval blockTime, *timeoutPtr;
Tcl_Time now;
int fd, index, numFound, numFdBits = 0;
- fd_mask bit;
+ fd_mask bit, *readMaskPtr = readMask;
/*
- * Look for queued events first.
+ * Look for queued events first.
*/
if (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {
@@ -507,7 +516,7 @@ TkUnixDoOneXEvent(timePtr)
*/
if (timePtr) {
- TclpGetTime(&now);
+ Tcl_GetTime(&now);
blockTime.tv_sec = timePtr->sec;
blockTime.tv_usec = timePtr->usec - now.usec;
if (blockTime.tv_usec < 0) {
@@ -530,7 +539,7 @@ TkUnixDoOneXEvent(timePtr)
* pending, then we want to poll instead of blocking.
*/
- memset((VOID *) readMask, 0, MASK_SIZE*sizeof(fd_mask));
+ memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
dispPtr = dispPtr->nextPtr) {
XFlush(dispPtr->display);
@@ -539,11 +548,6 @@ TkUnixDoOneXEvent(timePtr)
blockTime.tv_usec = 0;
}
fd = ConnectionNumber(dispPtr->display);
-
- /*
- * Assume there are always at least 'fd' bits in the 'readMask' array.
- */
-
index = fd/(NBBY*sizeof(fd_mask));
bit = ((fd_mask)1) << (fd%(NBBY*sizeof(fd_mask)));
readMask[index] |= bit;
@@ -552,7 +556,7 @@ TkUnixDoOneXEvent(timePtr)
}
}
- numFound = select(numFdBits, (SELECT_MASK *) &readMask[0], NULL, NULL,
+ numFound = select(numFdBits, (SELECT_MASK *) readMaskPtr, NULL, NULL,
timeoutPtr);
if (numFound <= 0) {
/*
@@ -560,7 +564,7 @@ TkUnixDoOneXEvent(timePtr)
* it here.
*/
- memset((VOID *) readMask, 0, MASK_SIZE*sizeof(fd_mask));
+ memset(readMask, 0, MASK_SIZE*sizeof(fd_mask));
}
/*
@@ -585,7 +589,7 @@ TkUnixDoOneXEvent(timePtr)
*/
if (timePtr) {
- TclpGetTime(&now);
+ Tcl_GetTime(&now);
if ((now.sec > timePtr->sec) || ((now.sec == timePtr->sec)
&& (now.usec > timePtr->usec))) {
return 0;
@@ -605,9 +609,9 @@ TkUnixDoOneXEvent(timePtr)
*
* TkpSync --
*
- * This routine ensures that all pending X requests have been
- * seen by the server, and that any pending X events have been
- * moved onto the Tk event queue.
+ * This routine ensures that all pending X requests have been seen by the
+ * server, and that any pending X events have been moved onto the Tk
+ * event queue.
*
* Results:
* None.
@@ -619,30 +623,29 @@ TkUnixDoOneXEvent(timePtr)
*/
void
-TkpSync(display)
- Display *display; /* Display to sync. */
+TkpSync(
+ Display *display) /* Display to sync. */
{
XSync(display, False);
/*
* 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.
+ * Tries to open an X input method associated with the given display.
*
* Results:
- * Stores the input method in dispPtr->inputMethod; if there isn't
- * a suitable input method, then NULL is stored in dispPtr->inputMethod.
+ * 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.
@@ -651,14 +654,15 @@ TkpSync(display)
*/
static void
-OpenIM(dispPtr)
- TkDisplay *dispPtr; /* Tk's structure for the display. */
+OpenIM(
+ TkDisplay *dispPtr) /* Tk's structure for the display. */
{
- unsigned short i;
+ int i;
XIMStyles *stylePtr;
+ XIMStyle bestStyle = 0;
if (XSetLocaleModifiers("") == NULL) {
- goto error;
+ return;
}
dispPtr->inputMethod = XOpenIM(dispPtr->display, NULL, NULL, NULL);
@@ -670,38 +674,56 @@ OpenIM(dispPtr)
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.
+ * Select the best input style supported by both the IM and Tk.
*/
for (i = 0; i < stylePtr->count_styles; i++) {
- if (stylePtr->supported_styles[i]
- == (XIMPreeditPosition | XIMStatusNothing)) {
- dispPtr->flags |= TK_DISPLAY_XIM_SPOT;
- XFree(stylePtr);
- return;
+ XIMStyle thisStyle = stylePtr->supported_styles[i];
+ if (thisStyle == (XIMPreeditPosition | XIMStatusNothing)) {
+ bestStyle = thisStyle;
+ break;
+ } else if (thisStyle == (XIMPreeditNothing | XIMStatusNothing)) {
+ bestStyle = thisStyle;
}
}
-#endif
- for (i = 0; i < stylePtr->count_styles; i++) {
- if (stylePtr->supported_styles[i]
- == (XIMPreeditNothing | XIMStatusNothing)) {
- XFree(stylePtr);
- return;
+ XFree(stylePtr);
+ if (bestStyle == 0) {
+ goto error;
+ }
+
+ dispPtr->inputStyle = bestStyle;
+
+ /*
+ * Create an XFontSet for preedit area.
+ */
+ if (dispPtr->inputStyle & XIMPreeditPosition) {
+ char **missing_list;
+ int missing_count;
+ char *def_string;
+
+ dispPtr->inputXfs = XCreateFontSet(dispPtr->display,
+ "-*-*-*-R-Normal--14-130-75-75-*-*",
+ &missing_list, &missing_count, &def_string);
+ if (missing_count > 0) {
+ XFreeStringList(missing_list);
}
}
- XFree(stylePtr);
- error:
+ return;
+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 */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */