Next | Prev | Up | Top | Contents | Index

Events Under IM Control

Processing events under input method control is almost the same in X11R6 as it was under R4 and before. There are two essential differences: the XFilterEvent() and X*LookupString() routines.


Using XFilterEvent()

Every event received by your application should be fed to the IM via XFilterEvent(), which returns a value telling you whether or not to disregard the event. IMs asks you to disregard the event if they have extracted the data and plan on giving it to you later, possibly in some other form. All events (not just KeyPress and KeyRelease events) go to XFilterEvent().

If you compacted the event processing into a single routine, a typical event loop would look something like the code in Example 6-12.

Example 6-12 : Event Loop

Xevent event;
while (TRUE) {
    XNextEvent(dpy, &event);
    if (XFilterEvent(&event, None))
        continue;
    DealWithEvent(&event);
}

Using XLookupString(), XwcLookupString(), and XmbLookupString()

When using an input method, you should replace calls to XLookupString() with calls to XwcLookupString() or XmbLookupString(). The MB and WC versions have very similar interfaces. The examples below arbitrarily use XmbLookupString(), but apply to both versions.

There are two new situations to deal with:

  1. The string returned may be long.

  2. There may be an interesting keysym returned, an interesting set of characters returned, both, or neither.
Dealing with the former is a matter of maintaining an arena, as in Example 6-13.

To tell the application what to pay attention to for a given event, XmbLookupString() returns a status value in a passed parameter, equal to one of the following:

XLookupKeysymIndicates that the keysym should be checked.
XLookupCharsIndicates that a string has been typed or composed.
XLookupBothMeans both of the above.
XLookupNoneMeans neither is ready for processing.
XBufferOverflowMeans the supplied buffer is too small--call XmbLookupString() again with a bigger buffer

XmbLookupString() also returns the length of the string in question. Note that XmbLookupString() returns the length of the string in bytes, while XwcLookupString() returns the length of the string in characters.

The example below should help show how these functions work. Most event processors perform a switch on the event type; assume you have done that and have received a KeyPress event.

Example 6-13 : KeyPress Event

case KeyPress:
{
    Keysym keysym;
    Status status;
    int buflength;
    static int bufsize = 16;
    static char *buf = NULL;
    if (buf == NULL) {
        buf = malloc(bufsize);
        if (buf < 0) StopSequence();
    }
    buflength = XmbLookupString(ic, &event, buf, bufsize,
                             &keysym, &status);
    /* first, check to see if that worked */
    if (status == XBufferOverflow) {
        buf = realloc(buf, (bufsize = buflength));
        buflength = XmbLookupString(ic, &event, buf, bufsize,
                                 &keysym, &status);
    }
    /* We have a valid status. Check that */
    switch(status) {
    case XLookupKeysym:
        DealWithKeysym(keysym);
        break;
    case XLookupBoth:
        DealWithKeysym(keysym);
        /* **FALL INTO** charcter case */
    case XLookupChars:
        DealWithString(buf, buflength);
    case XLookupNone:
        break;
    } /* end switch(status) */
} /* end case KeyPress segment */
break; /* we are in a switch(event.type) statement */ 

Next | Prev | Up | Top | Contents | Index