From 88ad5f7630141ecd8eb98e856b21aa04c6a8fbde Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Mon, 17 Aug 2026 10:57:15 +0900 Subject: [PATCH] engine: the one capability is a flag Cclientpreedit was a one-bit mask that every producer set as "want ? Cclientpreedit : 0" and every consumer masked out again; nothing else was ever going to join it. Keyreq carries clientpre, an int that says whether the client draws the preedit, and the engine and the XIM context keep it under that name. --- dat.h | 8 ++------ ibus.c | 2 +- srv.c | 6 +++--- strans.c | 14 +++++++------- tests/engine_test.c | 28 ++++++++++++++-------------- tests/ibus_test.c | 8 ++++---- tests/ipc_test.c | 4 ++-- tests/server_test.c | 8 ++++---- tests/xim_adapter_test.c | 22 +++++++++++----------- xim.c | 10 +++++----- 10 files changed, 53 insertions(+), 57 deletions(-) diff --git a/dat.h b/dat.h index 936f6da..19fe5bf 100644 --- a/dat.h +++ b/dat.h @@ -173,10 +173,6 @@ struct Popup typedef struct Keyreq Keyreq; typedef struct Keyres Keyres; enum -{ - Cclientpreedit = 1<<0, -}; -enum { Keypress, Keyreset, @@ -186,7 +182,7 @@ enum }; struct Keyres { - int eaten; /* Keycap: caller is active and capability was applied. */ + int eaten; /* Keycap: the caller is the owner and clientpre took. */ Str commit; Str preedit; }; @@ -194,7 +190,7 @@ struct Keyres struct Keyreq { void *owner; /* stable until the context's release is acknowledged */ - int cap; + int clientpre; /* the client draws the preedit; the popup does not */ int op; u32int ks; u32int mod; diff --git a/ibus.c b/ibus.c index 9dd1324..1181cbf 100644 --- a/ibus.c +++ b/ibus.c @@ -291,7 +291,7 @@ sendrequest(Ictx *ctx, int op, u32int ks, u32int mod, Keyres *res) memset(&kr, 0, sizeof kr); kr.owner = ctx; - kr.cap = clientpreedit(ctx) ? Cclientpreedit : 0; + kr.clientpre = clientpreedit(ctx); kr.op = op; kr.ks = ks; kr.mod = mod; diff --git a/srv.c b/srv.c index 063e886..79f822f 100644 --- a/srv.c +++ b/srv.c @@ -67,7 +67,7 @@ srvreadreq(int fd, Keyreq *kr, int *want) } /* - * One Keyreq persists for the connection: the negotiated capability and + * One Keyreq persists for the connection: the negotiated preedit and * the last caret ride along with every request, and the socket closing * releases the engine. */ @@ -85,10 +85,10 @@ clientthread(void *arg) memset(&kr, 0, sizeof kr); kr.reply = chancreate(sizeof(Keyres), 0); kr.owner = &fd; - kr.cap = Cclientpreedit; + kr.clientpre = 1; while(srvreadreq(fd, &kr, &want) >= 0){ if(kr.op != Keycaret) - kr.cap = want ? Cclientpreedit : 0; + kr.clientpre = want; chansend(keyc, &kr); chanrecv(kr.reply, &res); if(kr.op == Keycaret) diff --git a/strans.c b/strans.c index 602d776..909fd4d 100644 --- a/strans.c +++ b/strans.c @@ -3,7 +3,7 @@ static Im im; static void *activeowner; -static int activecap; +static int clientpre; /* the owner draws its own preedit */ static Caret caret; static Drawcmd lastdraw; static Emit transjp(Im*, Rune); @@ -191,7 +191,7 @@ snapshot(Drawcmd *dc) pre = search.text; else impre(&im, &pre); - if(!(activecap & Cclientpreedit)) + if(!clientpre) dc->pre = pre; if(search.lang && pre.n == 0) /* a search just begun shows itself */ sputr(&dc->pre, search.lang == LangEMOJI ? L'☺' : L'漢'); @@ -881,7 +881,7 @@ init(void) memset(&search, 0, sizeof search); memset(&caret, 0, sizeof caret); activeowner = nil; - activecap = 0; + clientpre = 0; memset(&lastdraw, 0, sizeof lastdraw); } @@ -905,7 +905,7 @@ imhandlekey(Keyreq *kr) if(kr->owner == activeowner){ flush(&res.commit); activeowner = nil; - activecap = 0; + clientpre = 0; } break; case Keyreset: @@ -919,17 +919,17 @@ imhandlekey(Keyreq *kr) case Keycap: res.eaten = kr->owner == activeowner; if(res.eaten) - activecap = kr->cap & Cclientpreedit; + clientpre = kr->clientpre; break; case Keypress: res.eaten = 0; if(kr->owner == activeowner) - activecap = kr->cap & Cclientpreedit; + clientpre = kr->clientpre; if(keymeaningful(kr->ks)){ if(kr->owner != activeowner){ reset(); activeowner = kr->owner; - activecap = kr->cap & Cclientpreedit; + clientpre = kr->clientpre; } caret = kr->caret; res.eaten = transition(kr->ks, kr->mod, &res.commit); diff --git a/tests/engine_test.c b/tests/engine_test.c index e398d50..f153e59 100644 --- a/tests/engine_test.c +++ b/tests/engine_test.c @@ -184,7 +184,7 @@ ownerrequestatcap(void *owner, int cap, int op, Rune key, u32int mod, reply = chancreate(sizeof(Keyres), 1); memset(&req, 0, sizeof req); req.owner = owner; - req.cap = cap; + req.clientpre = cap; req.op = op; req.ks = key; req.mod = mod; @@ -360,7 +360,7 @@ engine_vietnamese_client_preedit(struct ct *t) draindraw(nil); sclear(&com); for(k = cases[i].keys; *k != '\0'; k++){ - res = ownerrequestcap(&owner, Cclientpreedit, + res = ownerrequestcap(&owner, 1, Keypress, *k, 0); sappend(&com, &res.commit); if(!res.eaten) @@ -371,7 +371,7 @@ engine_vietnamese_client_preedit(struct ct *t) shown = com; sappend(&shown, &res.preedit); checkstr(t, "client preedit", cases[i].shown, &shown); - activecap = 0; + clientpre = 0; redraw(); if(CT_CHECK(t, draindraw(&dc) > 0)) CT_EQ_INT(t, 0, scmp(&dc.pre, &res.preedit)); @@ -403,7 +403,7 @@ engine_commit_contract(struct ct *t) im.l = getlang(LangKO); sclear(&all); for(i = 0; i < 3; i++){ - res = ownerrequestcap(&owner, Cclientpreedit, + res = ownerrequestcap(&owner, 1, Keypress, cases[j].key, 0); CT_CHECK(t, res.eaten); checkstr(t, "repeated jamo commit", @@ -692,7 +692,7 @@ struct Searchfix Search search; Lang *dictlang; Trie *dict; - int activecap; + int clientpre; Drawcmd lastdraw; }; @@ -919,7 +919,7 @@ searchsave(Searchfix *f, int lang) f->search = search; f->dictlang = getlang(lang); f->dict = f->dictlang->dict; - f->activecap = activecap; + f->clientpre = clientpre; f->lastdraw = lastdraw; draindraw(nil); } @@ -947,7 +947,7 @@ emojibegin(Searchfix *f, int showpre) "c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12"); init(); im.l = getlang(LangKO); - activecap = showpre ? 0 : Cclientpreedit; + clientpre = showpre ? 0 : 1; } static void @@ -961,7 +961,7 @@ searchend(Searchfix *f) draindraw(nil); im = f->im; search = f->search; - activecap = f->activecap; + clientpre = f->clientpre; lastdraw = f->lastdraw; } @@ -981,8 +981,8 @@ engine_popup_preedit_capability(struct ct *t) init(); im.l = jp; draindraw(nil); - ownerrequestcap(&client, Cclientpreedit, Keypress, 'k', 0); - ownerrequestcap(&client, Cclientpreedit, Keypress, 'a', 0); + ownerrequestcap(&client, 1, Keypress, 'k', 0); + ownerrequestcap(&client, 1, Keypress, 'a', 0); CT_EQ_INT(t, 1, im.nkouho); redraw(); if(CT_CHECK(t, draindraw(&dc) > 0)){ @@ -1009,14 +1009,14 @@ engine_popup_preedit_capability(struct ct *t) CT_CHECK(t, kres.eaten); CT_EQ_INT(t, 0, draindraw(nil)); - kres = ownerrequestcap(&inactive, Cclientpreedit, Keycap, 0, 0); + kres = ownerrequestcap(&inactive, 1, Keycap, 0, 0); CT_CHECK(t, !kres.eaten); CT_EQ_INT(t, 0, kres.preedit.n); CT_EQ_PTR(t, &client, activeowner); - CT_EQ_INT(t, 0, activecap & Cclientpreedit); + CT_EQ_INT(t, 0, clientpre); CT_EQ_INT(t, 0, draindraw(nil)); - kres = ownerrequestcap(&client, Cclientpreedit, Keycap, 0, 0); + kres = ownerrequestcap(&client, 1, Keycap, 0, 0); CT_CHECK(t, kres.eaten); checkstr(t, "restored client preedit", "か", &kres.preedit); if(CT_CHECK(t, draindraw(&dc) > 0)){ @@ -1028,7 +1028,7 @@ engine_popup_preedit_capability(struct ct *t) CT_EQ_INT(t, 1, im.nkouho); CT_EQ_INT(t, -1, im.sel); checkstr(t, "retained client candidate", "家", &im.kouho[0]); - kres = ownerrequestcap(&client, Cclientpreedit, Keycap, 0, 0); + kres = ownerrequestcap(&client, 1, Keycap, 0, 0); CT_CHECK(t, kres.eaten); CT_EQ_INT(t, 0, draindraw(nil)); diff --git a/tests/ibus_test.c b/tests/ibus_test.c index c29df87..ae64ae0 100644 --- a/tests/ibus_test.c +++ b/tests/ibus_test.c @@ -133,7 +133,7 @@ nexttrace(struct ct *t, Ibusfix *f, int op, Ictx *ctx) CT_EQ_INT(t, op, req.op); CT_EQ_PTR(t, ctx, req.owner); if(ctx != nil) - CT_EQ_INT(t, ctx->cap & 1 ? Cclientpreedit : 0, req.cap); + CT_EQ_INT(t, clientpreedit(ctx), req.clientpre); CT_EQ_PTR(t, replyc, req.reply); return req; } @@ -178,7 +178,7 @@ ibus_capability_policy(struct ct *t) checkstr(t, "preedit", "k", &res.preedit); CT_EQ_PTR(t, a, testengineowner()); - a->cap = Cclientpreedit; + a->cap = Ibuscappreedit; memset(&res, 0, sizeof res); sendrequest(a, Keycap, 0, 0, &res); nexttrace(t, &f, Keycap, a); @@ -186,7 +186,7 @@ ibus_capability_policy(struct ct *t) checkstr(t, "preedit", "k", &res.preedit); b->focused = 1; - b->cap = Cclientpreedit; + b->cap = Ibuscappreedit; memset(&res, 0, sizeof res); sendrequest(b, Keycap, 0, 0, &res); nexttrace(t, &f, Keycap, b); @@ -229,7 +229,7 @@ ibus_private_input_policy(struct ct *t) } ctx->focused = 1; - ctx->cap = Cclientpreedit; + ctx->cap = 1; ctx->purpose = 0; contextkey(t, &f, ctx, 'n', Testctrlmask); res = contextkey(t, &f, ctx, 'k', 0); diff --git a/tests/ipc_test.c b/tests/ipc_test.c index 26f6a23..b81a95f 100644 --- a/tests/ipc_test.c +++ b/tests/ipc_test.c @@ -70,7 +70,7 @@ void ipc_control_and_caret_frames(struct ct *t) { static const uchar capon[Ipcreqsz] = { - Ipcext|Cclientpreedit, Ipcversion, Ipcopcap, 0, 0, 0, + Ipcext|Ipcreqwant, Ipcversion, Ipcopcap, 0, 0, 0, }; static const uchar capoff[Ipcreqsz] = { Ipcext, Ipcversion, Ipcopcap, 0, 0, 0, @@ -89,7 +89,7 @@ ipc_control_and_caret_frames(struct ct *t) int valid, want; int32_t x, y, h; - ipcpackcap(buf, Cclientpreedit); + ipcpackcap(buf, 1); CT_EQ_MEM(t, capon, buf, sizeof capon); CT_EQ_INT(t, Ipccap, ipcreqtype(buf)); /* The probe remains a harmless key-zero request to an old daemon. */ diff --git a/tests/server_test.c b/tests/server_test.c index da70a31..66571f3 100644 --- a/tests/server_test.c +++ b/tests/server_test.c @@ -143,14 +143,14 @@ nextrequestcap(struct ct *t, Pump *p, int op, int cap) memset(&req, 0, sizeof req); chanrecv(p->trace, &req); CT_EQ_INT(t, op, req.op); - CT_EQ_INT(t, cap, req.cap); + CT_EQ_INT(t, cap, req.clientpre); return req; } static Keyreq nextrequest(struct ct *t, Pump *p, int op) { - return nextrequestcap(t, p, op, Cclientpreedit); + return nextrequestcap(t, p, op, 1); } static void @@ -387,7 +387,7 @@ server_extension_stream(struct ct *t) goto cleanup; /* Capability and caret frames may be split at any byte boundary. */ - ipcpackcap(frame, Cclientpreedit); + ipcpackcap(frame, 1); if(!sendframe(t, &a, frame, Ipcreqsz, 1)) goto cleanup; req = nextrequest(t, &f.pump, Keycap); @@ -446,7 +446,7 @@ server_extension_stream(struct ct *t) allowrequest(&f.pump); CT_EQ_INT(t, 1, readreply(t, &a, 0, "k", preedit)); - ipcpackcap(frame, Cclientpreedit); + ipcpackcap(frame, 1); if(!sendframe(t, &a, frame, Ipcreqsz, 0)) goto cleanup; req = nextrequest(t, &f.pump, Keycap); diff --git a/tests/xim_adapter_test.c b/tests/xim_adapter_test.c index 275b101..b4864bc 100644 --- a/tests/xim_adapter_test.c +++ b/tests/xim_adapter_test.c @@ -437,7 +437,7 @@ nexttracecap(struct ct *t, Ximfix *f, int op, Ic *owner, int cap) return req; CT_EQ_INT(t, op, req.op); CT_EQ_PTR(t, owner, req.owner); - CT_EQ_INT(t, cap, req.cap); + CT_EQ_INT(t, cap, req.clientpre); CT_EQ_PTR(t, replyc, req.reply); return req; } @@ -445,7 +445,7 @@ nexttracecap(struct ct *t, Ximfix *f, int op, Ic *owner, int cap) static Keyreq nexttrace(struct ct *t, Ximfix *f, int op, Ic *state) { - return nexttracecap(t, f, op, state, state->cap); + return nexttracecap(t, f, op, state, state->clientpre); } static void @@ -539,7 +539,7 @@ xim_adapter_release_lifecycle(struct ct *t) keypress(dead, 'n', 0, &res); nexttrace(t, &f, Keypress, dead); CT_EQ_PTR(t, dead, testengineowner()); - deadcap = dead->cap; + deadcap = dead->clientpre; icfree(dead); nexttracecap(t, &f, Keyrelease, dead, deadcap); dead = nil; @@ -654,8 +654,8 @@ xim_adapter_styles(struct ct *t) state = icbindings[0].data; if(!CT_CHECK(t, state != nil && state == ics)) continue; - CT_EQ_INT(t, want[i] & XCB_IM_PreeditCallbacks ? Cclientpreedit : 0, - state->cap); + CT_EQ_INT(t, want[i] & XCB_IM_PreeditCallbacks ? 1 : 0, + state->clientpre); CT_EQ_PTR(t, ic, state->xic); icunlink(state); free(state); @@ -799,7 +799,7 @@ xim_adapter_callback_replacement(struct ct *t) ic = (xcb_im_input_context_t*)(uintptr)3; memset(&state, 0, sizeof state); state.xic = ic; - state.cap = Cclientpreedit; + state.clientpre = 1; wireclear(); sinit(&pre, "k", strlen("k")); updatepreedit(&state, &pre); @@ -848,7 +848,7 @@ xim_adapter_callback_unicode(struct ct *t) for(i = 0; i < nelem(text); i++){ memset(&state, 0, sizeof state); state.xic = (xcb_im_input_context_t*)(uintptr)(10+i); - state.cap = Cclientpreedit; + state.clientpre = 1; sinit(&pre, text[i], strlen(text[i])); wireclear(); updatepreedit(&state, &pre); @@ -868,7 +868,7 @@ startstate(Ic *state, xcb_im_input_context_t *ic) memset(state, 0, sizeof *state); state->xic = ic; - state->cap = Cclientpreedit; + state->clientpre = 1; sinit(&pre, "あ", strlen("あ")); updatepreedit(state, &pre); } @@ -896,7 +896,7 @@ xim_adapter_callback_cleanup(struct ct *t) wireclear(); wirebind(0, ic, &state); state.xic = ic; - state.cap = Cclientpreedit; + state.clientpre = 1; keypress(&state, 'k', 0, &res); nexttrace(t, &f, Keypress, &state); keypress(&state, 'a', 0, &res); @@ -984,7 +984,7 @@ xim_adapter_callback_transfer(struct ct *t) goto cleanup; wireclear(); a.xic = aic; - a.cap = Cclientpreedit; + a.clientpre = 1; sinit(&pre, "あ", strlen("あ")); updatepreedit(&a, &pre); keypress(&b, 'x', 0, &res); @@ -1021,7 +1021,7 @@ xim_adapter_callback_owner_loss(struct ct *t) wireclear(); wirebind(0, ic, &state); state.xic = ic; - state.cap = Cclientpreedit; + state.clientpre = 1; keypress(&state, 'k', 0, &res); nexttrace(t, &f, Keypress, &state); updatepreedit(&state, &res.preedit); diff --git a/xim.c b/xim.c index 88b8db7..3228b1c 100644 --- a/xim.c +++ b/xim.c @@ -16,7 +16,7 @@ /* * One XIM input context. Only PreeditCallbacks clients draw the preedit - * themselves (cap); the popup shows it for the others. engaged means the + * themselves (clientpre); the popup shows it for the others. engaged means the * engine has seen a real key from this context and owes it a release. */ typedef struct Ic Ic; @@ -26,7 +26,7 @@ struct Ic xcb_im_input_context_t *xic; xcb_im_client_t *client; int engaged; - int cap; + int clientpre; int prestarted; int nprerune; Caret caret; @@ -255,7 +255,7 @@ updatepreedit(Ic *state, Str *pre) size_t nwire; int i, nbyte; - if(!(state->cap & Cclientpreedit)) + if(!state->clientpre) return; if(pre->n == 0){ clearpreedit(state); @@ -291,7 +291,7 @@ sendrequest(Ic *state, int op, u32int key, u32int mod, Keyres *res) memset(&kr, 0, sizeof kr); kr.owner = state; - kr.cap = state->cap; + kr.clientpre = state->clientpre; kr.op = op; kr.ks = key; kr.mod = ipcmod(mod); @@ -471,7 +471,7 @@ iccreate(xcb_im_client_t *client, xcb_im_input_context_t *ic) state->xic = ic; state->client = client; if(xcb_im_input_context_get_input_style(ic) & XCB_IM_PreeditCallbacks) - state->cap = Cclientpreedit; + state->clientpre = 1; state->next = ics; ics = state; xcb_im_input_context_set_data(ic, state, icfree);