ipc: negotiate preedit capability and caret messages
This commit is contained in:
71
srv.c
71
srv.c
@@ -8,20 +8,46 @@ static char adir[256];
|
||||
static Channel *clientc;
|
||||
|
||||
static int
|
||||
srvreadkey(int fd, Keyreq *kr)
|
||||
srvreadreq(int fd, Keyreq *kr, int *want)
|
||||
{
|
||||
uchar req[Ipcreqsz];
|
||||
uchar req[Ipccaretsz];
|
||||
int type, valid;
|
||||
int32_t x, y, h;
|
||||
u32int ks, mod;
|
||||
int want;
|
||||
|
||||
if(ipcreadn(fd, req, sizeof req) < 0)
|
||||
if(ipcreadn(fd, req, Ipcreqsz) < 0)
|
||||
return -1;
|
||||
ipcunpackreq(req, &want, &mod, &ks);
|
||||
kr->op = ipcreqreset(req) ? Keyreset : Keypress;
|
||||
kr->ks = ks;
|
||||
kr->mod = mod;
|
||||
memset(&kr->caret, 0, sizeof kr->caret);
|
||||
return want;
|
||||
type = ipcreqtype(req);
|
||||
switch(type){
|
||||
case Ipclegacy:
|
||||
ipcunpackreq(req, want, &mod, &ks);
|
||||
kr->op = ipcreqreset(req) ? Keyreset : Keypress;
|
||||
kr->ks = ks;
|
||||
kr->mod = mod;
|
||||
break;
|
||||
case Ipccap:
|
||||
*want = (req[0] & Ipcreqwant) != 0;
|
||||
kr->op = Keycap;
|
||||
kr->ks = 0;
|
||||
kr->mod = 0;
|
||||
break;
|
||||
case Ipccaret:
|
||||
if(ipcreadn(fd, req + Ipcreqsz, Ipccaretsz - Ipcreqsz) < 0 ||
|
||||
ipcunpackcaret(req, &valid, &x, &y, &h) < 0)
|
||||
return -1;
|
||||
*want = 0;
|
||||
kr->op = Keycaret;
|
||||
kr->ks = 0;
|
||||
kr->mod = 0;
|
||||
kr->caret.valid = valid;
|
||||
kr->caret.x = x;
|
||||
kr->caret.y = y;
|
||||
kr->caret.h = h;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -31,9 +57,10 @@ clientthread(void *arg)
|
||||
int fd;
|
||||
Keyreq kr;
|
||||
Keyres res;
|
||||
Caret caret;
|
||||
uchar out[Ipcmaxresp];
|
||||
char commit[Maxutf], preedit[Maxutf];
|
||||
int n, ncommit, npreedit, want;
|
||||
int cap, n, ncommit, npreedit, type, want;
|
||||
uchar token;
|
||||
|
||||
fd = (int)(uintptr)arg;
|
||||
@@ -41,18 +68,34 @@ clientthread(void *arg)
|
||||
reply = chancreate(sizeof(Keyres), 0);
|
||||
kr.reply = reply;
|
||||
kr.owner = &fd;
|
||||
kr.cap = Cclientpreedit;
|
||||
while((want = srvreadkey(fd, &kr)) >= 0){
|
||||
cap = Cclientpreedit;
|
||||
memset(&caret, 0, sizeof caret);
|
||||
kr.cap = cap;
|
||||
kr.caret = caret;
|
||||
while((type = srvreadreq(fd, &kr, &want)) >= 0){
|
||||
if(type == Ipccap)
|
||||
cap = want ? Cclientpreedit : 0;
|
||||
else if(type == Ipccaret)
|
||||
caret = kr.caret;
|
||||
kr.cap = cap;
|
||||
kr.caret = caret;
|
||||
chansend(keyc, &kr);
|
||||
chanrecv(reply, &res);
|
||||
if(type == Ipccaret)
|
||||
continue;
|
||||
ncommit = stoutf(&res.commit, commit, sizeof commit);
|
||||
npreedit = stoutf(&res.preedit, preedit, sizeof preedit);
|
||||
n = ipcpackresp(out, sizeof out, res.eaten,
|
||||
n = ipcpackresp(out, sizeof out,
|
||||
type == Ipccap ? 1 : res.eaten,
|
||||
commit, ncommit, preedit, npreedit, want);
|
||||
if(n < 0 || ipcsend(fd, out, n) < 0)
|
||||
break;
|
||||
}
|
||||
kr.op = Keyrelease;
|
||||
kr.cap = cap;
|
||||
kr.caret = caret;
|
||||
kr.ks = 0;
|
||||
kr.mod = 0;
|
||||
chansend(keyc, &kr);
|
||||
chanrecv(reply, &res);
|
||||
chanfree(reply);
|
||||
|
||||
Reference in New Issue
Block a user