#include #include /* * Key request: [flags, modifiers, key byte 0, ..., key byte 3]. * The want flag asks for the preedit text: the client then draws it and * the popup does not. The reset flag is a lifecycle reset, not Escape. * The server identifies the connection as the engine owner; that identity is * not sent on the wire. * Only Mmask modifier bits are retained. * Response: [eaten, commit-length-low, commit-length-high, commit...], * followed, when requested, by * [preedit-length-low, preedit-length-high, preedit...]. * Lengths are little-endian byte counts; fields are at most Ipcfieldmax bytes, * so callers read them into char[Ipcfieldmax+1]. * * Capability control is six bytes: [0x80|want, version, 0, 0, 0, 0]; the * server always answers it eaten, which tells the client that extension * frames are understood. * Caret control is sixteen bytes: [0x80, version, 1, valid, x, y, h], * with the signed coordinates and height encoded as little-endian 32-bit words. */ enum { Ipcreqwant = 1<<0, Ipcreqreset = 1<<1, Ipcext = 1<<7, Ipcversion = 1, Ipcopcap = 0, Ipcopcaret = 1, Kspec = 0x110000, Kback = Kspec|0x08, Ktab = Kspec|0x09, Kret = Kspec|0x0d, Kesc = Kspec|0x1b, Kup = Kspec|0x52, Kdown = Kspec|0x54, Kpgup = Kspec|0x55, Kpgdown = Kspec|0x56, Khangul = Kspec|0x31, Khanja = Kspec|0x34, Kmodfirst = Kspec|0xe1, Kmodlast = Kspec|0xee, /* X core modifier bits; GDK and IBus also flag Super at bit 26. */ Mshift = 1<<0, Mctrl = 1<<2, Malt = 1<<3, Msuper = 1<<6, Mmask = Mshift|Mctrl|Malt|Msuper, Msupervirt = 1<<26, Ipcreqsz = 6, Ipccaretsz = 16, Ipclensz = 2, Ipcresphdrsz = 1 + Ipclensz, Ipcfieldmax = 256, Ipcmaxresp = Ipcresphdrsz + Ipcfieldmax + Ipclensz + Ipcfieldmax, Ipcwaitms = 250, }; enum { Ipcunknown = -1, Ipckey, Ipccap, Ipccaret, }; typedef struct Ipcresp Ipcresp; struct Ipcresp { int eaten; /* Bytes copied to each caller buffer, excluding its trailing NUL. */ size_t commitlen; size_t preeditlen; }; uint32_t ipckeysym(uint32_t, uint32_t); uint32_t ipcmod(uint32_t); void ipcpackreq(unsigned char[Ipcreqsz], int, uint32_t, uint32_t); void ipcpackreset(unsigned char[Ipcreqsz], int); void ipcpackcap(unsigned char[Ipcreqsz], int); void ipcpackcaret(unsigned char[Ipccaretsz], int, int32_t, int32_t, int32_t); void ipcunpackreq(const unsigned char[Ipcreqsz], int*, uint32_t*, uint32_t*); int ipcunpackcaret(const unsigned char[Ipccaretsz], int*, int32_t*, int32_t*, int32_t*); int ipcreqtype(const unsigned char[Ipcreqsz]); int ipcreqreset(const unsigned char[Ipcreqsz]); int ipcpackresp(unsigned char*, size_t, int, const char*, size_t, const char*, size_t, int); int ipcreadn(int, void*, size_t); int ipcsend(int, const void*, size_t); int ipcreadresp(int, int, char*, char*, Ipcresp*); int ipcpath(char*, size_t); int ipcconnect(void);