Skip to content

Instantly share code, notes, and snippets.

@Determinant
Last active October 9, 2023 13:54
Show Gist options
  • Save Determinant/19bbecb6db35312861f6cf9f54fdd3a5 to your computer and use it in GitHub Desktop.
Save Determinant/19bbecb6db35312861f6cf9f54fdd3a5 to your computer and use it in GitHub Desktop.
A minimal example for X Input Method.
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <stdlib.h>
#include <stdio.h>
#include <locale.h>
#include <assert.h>
Display *dpy;
Window win;
int scr;
void send_spot(XIC ic, XPoint nspot) {
XVaNestedList preedit_attr;
preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &nspot, NULL);
XSetICValues(ic, XNPreeditAttributes, preedit_attr, NULL);
XFree(preedit_attr);
}
int main() {
/* fallback to LC_CTYPE in env */
setlocale(LC_CTYPE, "");
/* implementation-dependent behavior, on my machine it defaults to
* XMODIFIERS in env */
XSetLocaleModifiers("");
/* setting up a simple window */
dpy = XOpenDisplay(NULL);
scr = DefaultScreen(dpy);
win = XCreateSimpleWindow(dpy,
XDefaultRootWindow(dpy),
0, 0, 100, 100, 5,
BlackPixel(dpy, scr),
BlackPixel(dpy, scr));
XMapWindow(dpy, win);
/* initialize IM and IC */
XIM xim = XOpenIM(dpy, NULL, NULL, NULL);
XIC ic = XCreateIC(xim,
/* the following are in attr, val format, terminated by NULL */
XNInputStyle, XIMPreeditNothing | XIMStatusNothing,
XNClientWindow, win,
NULL);
/* focus on the only IC */
XSetICFocus(ic);
/* capture the input */
XSelectInput(dpy, win, KeyPressMask);
XPoint spot;
spot.x = 0;
spot.y = 0;
send_spot(ic, spot);
static char *buff;
size_t buff_size = 16;
buff = (char *)malloc(buff_size);
for (;;)
{
KeySym ksym;
Status status;
XEvent ev;
XNextEvent(dpy, &ev);
if (XFilterEvent(&ev, None))
continue;
if (ev.type == KeyPress)
{
size_t c = Xutf8LookupString(ic, &ev.xkey,
buff, buff_size - 1,
&ksym, &status);
if (status == XBufferOverflow)
{
printf("reallocate to the size of: %lu\n", c + 1);
buff = realloc(buff, c + 1);
c = Xutf8LookupString(ic, &ev.xkey,
buff, c,
&ksym, &status);
}
if (c)
{
spot.x += 20;
spot.y += 20;
send_spot(ic, spot);
buff[c] = 0;
printf("delievered string: %s\n", buff);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment