#include "dat.h" #include "fn.h" #include #include #include /* * One state per frontend, all made before the procs are: xkbcommon locks * nothing, and even its table refcount is a plain increment. cowner is * the context whose sequence a state holds. */ static struct xkb_compose_state *cstate[Ncompose]; static void *cowner[Ncompose]; /* Dead keys and Compose: no frontend's client does them for us. */ void composeinit(void) { struct xkb_context *ctx; struct xkb_compose_table *table; char *locale; int i; locale = setlocale(LC_CTYPE, ""); ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); if(ctx == nil) return; table = xkb_compose_table_new_from_locale(ctx, locale != nil ? locale : "C", XKB_COMPOSE_COMPILE_NO_FLAGS); if(table != nil) for(i = 0; i < Ncompose; i++) cstate[i] = xkb_compose_state_new(table, XKB_COMPOSE_STATE_NO_FLAGS); xkb_compose_table_unref(table); xkb_context_unref(ctx); } /* The context is going, and the sequence it left half typed with it. */ void composedrop(int who, void *owner) { if(cstate[who] == nil || owner != cowner[who]) return; xkb_compose_state_reset(cstate[who]); cowner[who] = nil; } /* * Feeds sym to the Compose table. Returns 1 while a sequence is * unfinished: the key belongs to the sequence, not to the engine. A * finished sequence leaves its text in buf, which the caller commits * after whatever the engine had pending. A sequence belongs to the * context that started it: a key from another one starts over. */ int composekey(int who, void *owner, u32int sym, char *buf, int n) { struct xkb_compose_state *cs; buf[0] = '\0'; cs = cstate[who]; if(cs == nil) return 0; if(owner != cowner[who]){ xkb_compose_state_reset(cs); cowner[who] = owner; } if(xkb_compose_state_feed(cs, sym) != XKB_COMPOSE_FEED_ACCEPTED) return 0; switch(xkb_compose_state_get_status(cs)){ case XKB_COMPOSE_COMPOSING: case XKB_COMPOSE_CANCELLED: return 1; case XKB_COMPOSE_COMPOSED: xkb_compose_state_get_utf8(cs, buf, n); break; default: break; } return 0; }