這個程式示範如何用最少的程式碼在 X window 程式中接收 XIM 輸入法的輸入字串。Input style 為 Over the spot。
#include <stdio.h>
#include <string.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <X11/Xlocale.h>
#define TITLE_STRING "XIM test"
int main(int argc, char **argv)
{
int quit = False;
Display* display = NULL;
Window window;
XTextProperty title;
XEvent event;
Atom wm_delete_window;
XIM xim;
XIC xic;
int xim_status;
KeySym keysym;
int count = 0;
unsigned long fevent;
char buffer[256]= {};
/* Call XSetLocaleModifiers before initialize XIM */
setlocale(LC_ALL, "");
XSetLocaleModifiers("");
display = XOpenDisplay(NULL);
window = XCreateWindow(display, RootWindow(display, 0), 0, 0, 512, 512, 0, CopyFromParent, CopyFromParent, CopyFromParent, 0, NULL);
XSetWindowBackground(display, window, BlackPixel(display, 0));
title.value = (unsigned char*)TITLE_STRING;
title.encoding = XA_STRING;
title.format = 8;
title.nitems = strlen(TITLE_STRING);
XSetWMProperties(display, window, &title, &title, NULL, 0, NULL, NULL, NULL);
wm_delete_window = XInternAtom(display, "WM_DELETE_WINDOW", False);
XSetWMProtocols(display, window, &wm_delete_window, 1);
XMapWindow(display, window);
/* XIM initialization */
xim = XOpenIM(display, NULL, NULL, NULL);
xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing ,XNClientWindow, window, NULL);
/* We need IC event to switch IME */
XGetICValues(xic, XNFilterEvents, &fevent, NULL);
XSelectInput(display, window, ExposureMask | KeyPressMask | FocusChangeMask | StructureNotifyMask | fevent);
XSetICFocus(xic);
while(!quit)
{
XNextEvent(display, &event);
if(XFilterEvent(&event, None))
continue;
switch(event.type)
{
case KeyPress:
count = XmbLookupString(xic, &event.xkey, buffer, 256, &keysym, &xim_status);
/* Cut redundant chars */
buffer[count] = 0;
if(xim_status == XLookupChars || xim_status == XLookupBoth)
fprintf(stderr, "%s\n", buffer);
break;
case ClientMessage:
if(event.xclient.data.l[0] == wm_delete_window)
{
XDestroyWindow(display, window);
quit = True;
}
break;
case FocusIn:
XSetICFocus(xic);
break;
case FocusOut:
XUnsetICFocus(xic);
break;
}
}
XCloseDisplay(display);
return 0;
}