summaryrefslogtreecommitdiff
path: root/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'test.c')
-rw-r--r--test.c200
1 files changed, 200 insertions, 0 deletions
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..bacd442
--- /dev/null
+++ b/test.c
@@ -0,0 +1,200 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <locale.h>
+#include <langinfo.h>
+#include <assert.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+
+static Atom atom_wm_protocols;
+static Atom atom_wm_delete;
+static Atom atom_wm_state;
+static Atom atom_wm_fullscreen;
+static Display *dpy;
+static Window win;
+static GC gc;
+static XIM im;
+static XIC ic;
+
+static void set_fullscreen()
+{
+ XEvent e = { 0 };
+ e.type = ClientMessage;
+ e.xclient.window = win;
+ e.xclient.message_type = atom_wm_state;
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = 1;
+ e.xclient.data.l[1] = atom_wm_fullscreen;
+ e.xclient.data.l[2] = 0;
+
+ XSendEvent(dpy, DefaultRootWindow(dpy), False, SubstructureNotifyMask, &e);
+}
+
+static int preedit_start_cb(XIC ic, XPointer client_data, XPointer p)
+{
+ printf("start preedit\n");
+ return -1;
+}
+
+static int preedit_stop_cb(XIC ic, XPointer client_data, XPointer p)
+{
+ printf("stop preedit\n");
+ return 0;
+}
+
+static int preedit_draw_cb(XIC ic, XPointer client_data, XIMPreeditDrawCallbackStruct *s)
+{
+ printf("draw preedit %d'%s'\n", s->text->length, s->text->string.multi_byte);
+ return 0;
+}
+
+int main(int argc, char ** argv)
+{
+ bool quit = false;
+ setlocale(LC_ALL, "");
+ XSetLocaleModifiers("@im=xmim");
+
+ char *nl = nl_langinfo(CODESET);
+ printf("codeset %s\n", nl);
+
+ dpy = XOpenDisplay(NULL);
+ assert(dpy);
+ int scr = DefaultScreen(dpy);
+
+ atom_wm_protocols = XInternAtom(dpy, "WM_PROTOCOLS", True);
+ atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
+ atom_wm_state = XInternAtom(dpy, "_NET_WM_STATE", True);
+ atom_wm_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", True);
+
+ win = XCreateSimpleWindow(dpy, RootWindow(dpy, scr), 0, 0, 400, 400, 0,
+ WhitePixel(dpy, scr), WhitePixel(dpy, scr));
+
+ im = XOpenIM(dpy, NULL, NULL, NULL);
+ assert(im);
+
+ XIMStyles *xim_styles = NULL;
+ if (XGetIMValues(im, XNQueryInputStyle, &xim_styles, NULL) == 0) {
+ printf("styles: (%u)\n", xim_styles->count_styles);
+ for (int i = 0; i < xim_styles->count_styles; i++) {
+ const XIMStyle style = xim_styles->supported_styles[i];
+ printf(" style %lu\n", style);
+ }
+ }
+
+ XIMCallback preedit_start = { NULL, (XIMProc) preedit_start_cb };
+ XIMCallback preedit_stop = { NULL, (XIMProc) preedit_stop_cb };
+ XIMCallback preedit_draw = { NULL, (XIMProc) preedit_draw_cb };
+
+ XVaNestedList preedit_list =
+ XVaCreateNestedList(0,
+ XNPreeditStartCallback, &preedit_start,
+ XNPreeditDoneCallback, &preedit_stop,
+ XNPreeditDrawCallback, &preedit_draw,
+ NULL);
+
+ ic = XCreateIC(im,
+ XNInputStyle, XIMPreeditCallbacks | XIMStatusNothing,
+ XNClientWindow, win, XNFocusWindow, win,
+ XNPreeditAttributes, preedit_list,
+ NULL);
+ assert(ic);
+
+ XGCValues gc_values;
+ gc = XCreateGC(dpy, win, 0, &gc_values);
+
+ unsigned long im_event_mask;
+ XGetICValues(ic, XNFilterEvents, &im_event_mask, NULL);
+ printf("im event mask 0x%lx\n", im_event_mask);
+
+ im_event_mask |= KeyPressMask | KeyReleaseMask | ButtonPressMask | FocusChangeMask | ClientMessage;
+ XSelectInput(dpy, win, im_event_mask);
+ XSetWMProtocols(dpy, win, &atom_wm_delete, 1);
+
+ set_fullscreen();
+
+ XMapWindow(dpy, win);
+
+ while (!quit) {
+ XEvent e;
+ XNextEvent(dpy, &e);
+ if (XFilterEvent(&e, None)) {
+ continue;
+ }
+ switch (e.type) {
+ case KeyPress: {
+ printf("key press\n");
+ KeySym keysym;
+ Status status;
+ int buflength;
+ static int bufsize = 16;
+ static char *buf;
+ if (buf == NULL) {
+ buf = malloc(bufsize + 1);
+ assert(buf);
+ }
+ buflength = Xutf8LookupString(ic, &e.xkey, buf, bufsize, &keysym, &status);
+ if (status == XBufferOverflow) {
+ bufsize = buflength;
+ buf = realloc(buf, bufsize + 1);
+ assert(buf);
+ buflength = Xutf8LookupString(ic, &e.xkey, buf, bufsize, &keysym, &status);
+ }
+ switch(status) {
+ case XLookupKeySym:
+ printf("keysim(0x%lx)\n", keysym);
+ break;
+ case XLookupBoth:
+ printf("keysim(0x%lx)+", keysym);
+ // Fallthrough
+ case XLookupChars:
+ buf[buflength] = '\0';
+ printf("string(%d'%s')\n", buflength, buf);
+ break;
+ case XLookupNone:
+ printf("none\n");
+ break;
+ default:
+ printf("weirdo\n");
+ break;
+ }
+ } break;
+ case KeyRelease:
+ printf("key release\n");
+ break;
+ case ButtonPress:
+ printf("button press\n");
+ break;
+ case FocusIn:
+ printf("focus in\n");
+ XSetICFocus(ic);
+ break;
+ case FocusOut:
+ printf("focus out\n");
+ XUnsetICFocus(ic);
+ break;
+ case ClientMessage:
+ printf("client message\n");
+ if (e.xclient.message_type == atom_wm_protocols) {
+ if (e.xclient.data.l[0] == atom_wm_delete) {
+ quit = true;
+ }
+ }
+ break;
+ default:
+ printf("unknown event\n");
+ break;
+ }
+ }
+
+ XFreeGC(dpy, gc);
+ XDestroyIC(ic);
+ XCloseIM(im);
+ XDestroyWindow(dpy, win);
+ XFlush(dpy);
+ XCloseDisplay(dpy);
+
+ return EXIT_SUCCESS;
+}