ipc: negotiate preedit capability and caret messages
This commit is contained in:
103
ipc.c
103
ipc.c
@@ -20,6 +20,32 @@ getlen(const unsigned char p[Ipclensz])
|
||||
return p[0] | (p[1] << 8);
|
||||
}
|
||||
|
||||
static void
|
||||
put32(unsigned char *p, int32_t v)
|
||||
{
|
||||
uint32_t u;
|
||||
|
||||
u = v;
|
||||
p[0] = u;
|
||||
p[1] = u >> 8;
|
||||
p[2] = u >> 16;
|
||||
p[3] = u >> 24;
|
||||
}
|
||||
|
||||
static int32_t
|
||||
get32(const unsigned char *p)
|
||||
{
|
||||
uint32_t u;
|
||||
|
||||
u = (uint32_t)p[0] |
|
||||
((uint32_t)p[1] << 8) |
|
||||
((uint32_t)p[2] << 16) |
|
||||
((uint32_t)p[3] << 24);
|
||||
if(u <= INT32_MAX)
|
||||
return u;
|
||||
return -(int32_t)(~u) - 1;
|
||||
}
|
||||
|
||||
int
|
||||
ipcpath(char *dst, size_t cap)
|
||||
{
|
||||
@@ -82,6 +108,37 @@ ipcpackreset(unsigned char req[Ipcreqsz], int want)
|
||||
req[0] = Ipcreqreset | (want ? Ipcreqwant : 0);
|
||||
}
|
||||
|
||||
/* An old server sees this reserved frame as a key-zero request. */
|
||||
void
|
||||
ipcpackcap(unsigned char req[Ipcreqsz], int want)
|
||||
{
|
||||
memset(req, 0, Ipcreqsz);
|
||||
req[0] = Ipcext | (want ? Ipcreqwant : 0);
|
||||
req[1] = Ipcversion;
|
||||
req[2] = Ipcopcap;
|
||||
}
|
||||
|
||||
int
|
||||
ipcpackcaret(unsigned char req[Ipccaretsz], int valid, int32_t x,
|
||||
int32_t y, int32_t h)
|
||||
{
|
||||
if(valid != 0 && valid != 1)
|
||||
return -1;
|
||||
if(valid && h < 0)
|
||||
return -1;
|
||||
memset(req, 0, Ipccaretsz);
|
||||
req[0] = Ipcext;
|
||||
req[1] = Ipcversion;
|
||||
req[2] = Ipcopcaret;
|
||||
req[3] = valid;
|
||||
if(!valid)
|
||||
return 0;
|
||||
put32(req + 4, x);
|
||||
put32(req + 8, y);
|
||||
put32(req + 12, h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ipcunpackreq(const unsigned char req[Ipcreqsz], int *want, uint32_t *mod,
|
||||
uint32_t *key)
|
||||
@@ -94,6 +151,52 @@ ipcunpackreq(const unsigned char req[Ipcreqsz], int *want, uint32_t *mod,
|
||||
((uint32_t)req[5] << 24);
|
||||
}
|
||||
|
||||
int
|
||||
ipcreqtype(const unsigned char req[Ipcreqsz])
|
||||
{
|
||||
if((req[0] & Ipcext) == 0)
|
||||
return Ipclegacy;
|
||||
if(req[1] != Ipcversion)
|
||||
return Ipcunknown;
|
||||
switch(req[2]){
|
||||
case Ipcopcap:
|
||||
if((req[0] & ~(Ipcext|Ipcreqwant)) != 0 ||
|
||||
req[3] != 0 || req[4] != 0 || req[5] != 0)
|
||||
return Ipcunknown;
|
||||
return Ipccap;
|
||||
case Ipcopcaret:
|
||||
if(req[0] != Ipcext || req[3] > 1)
|
||||
return Ipcunknown;
|
||||
return Ipccaret;
|
||||
}
|
||||
return Ipcunknown;
|
||||
}
|
||||
|
||||
int
|
||||
ipcunpackcaret(const unsigned char req[Ipccaretsz], int *valid,
|
||||
int32_t *x, int32_t *y, int32_t *h)
|
||||
{
|
||||
int32_t wireh;
|
||||
|
||||
if(valid == NULL || x == NULL || y == NULL || h == NULL ||
|
||||
ipcreqtype(req) != Ipccaret)
|
||||
return -1;
|
||||
wireh = get32(req + 12);
|
||||
if(wireh < 0)
|
||||
return -1;
|
||||
*valid = req[3];
|
||||
if(!*valid){
|
||||
*x = 0;
|
||||
*y = 0;
|
||||
*h = 0;
|
||||
return 0;
|
||||
}
|
||||
*x = get32(req + 4);
|
||||
*y = get32(req + 8);
|
||||
*h = wireh;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ipcreqreset(const unsigned char req[Ipcreqsz])
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user