ibus preedit
This commit is contained in:
78
ibus.c
78
ibus.c
@@ -200,47 +200,54 @@ mget(u32int state)
|
|||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
sendkey(u32int ks, u32int mod, char *out, int sz, int *eaten)
|
sendkey(u32int ks, u32int mod, char *com, int csz, char *pre, int psz,
|
||||||
|
int *eaten)
|
||||||
{
|
{
|
||||||
Keyreq kr;
|
Keyreq kr;
|
||||||
int p[2];
|
int p[2];
|
||||||
uchar hdr[2];
|
uchar hdr[2];
|
||||||
|
uchar pl;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
*eaten = 0;
|
*eaten = 0;
|
||||||
out[0] = '\0';
|
com[0] = '\0';
|
||||||
|
pre[0] = '\0';
|
||||||
if(pipe(p) < 0)
|
if(pipe(p) < 0)
|
||||||
return 0;
|
return;
|
||||||
kr.fd = p[1];
|
kr.fd = p[1];
|
||||||
kr.ks = ks;
|
kr.ks = ks;
|
||||||
kr.mod = mod;
|
kr.mod = mod;
|
||||||
|
kr.want = 1;
|
||||||
chansend(keyc, &kr);
|
chansend(keyc, &kr);
|
||||||
if(read(p[0], hdr, 2) != 2){
|
if(read(p[0], hdr, 2) != 2)
|
||||||
close(p[0]);
|
goto out;
|
||||||
close(p[1]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*eaten = hdr[0];
|
*eaten = hdr[0];
|
||||||
n = hdr[1];
|
n = hdr[1];
|
||||||
if(n > 0 && n < sz){
|
if(n > 0 && n < csz){
|
||||||
if(read(p[0], out, n) != n)
|
if(read(p[0], com, n) != n)
|
||||||
n = 0;
|
goto out;
|
||||||
}else
|
com[n] = '\0';
|
||||||
n = 0;
|
}
|
||||||
out[n] = '\0';
|
if(read(p[0], &pl, 1) != 1)
|
||||||
|
goto out;
|
||||||
|
if(pl > 0 && pl < psz){
|
||||||
|
if(read(p[0], pre, pl) != pl)
|
||||||
|
goto out;
|
||||||
|
pre[pl] = '\0';
|
||||||
|
}
|
||||||
|
out:
|
||||||
close(p[0]);
|
close(p[0]);
|
||||||
close(p[1]);
|
close(p[1]);
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendreset(void)
|
sendreset(void)
|
||||||
{
|
{
|
||||||
char buf[64];
|
char com[64], pre[256];
|
||||||
int eaten;
|
int eaten;
|
||||||
|
|
||||||
sendkey(Kesc, 0, buf, sizeof(buf), &eaten);
|
sendkey(Kesc, 0, com, sizeof(com), pre, sizeof(pre), &eaten);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -284,6 +291,28 @@ emitcommit(DBusConnection *c, const char *path, const char *text)
|
|||||||
dbus_message_unref(sig);
|
dbus_message_unref(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emitpreedit(DBusConnection *c, const char *path, const char *text)
|
||||||
|
{
|
||||||
|
DBusMessage *sig;
|
||||||
|
DBusMessageIter it;
|
||||||
|
dbus_uint32_t cursor;
|
||||||
|
dbus_bool_t visible;
|
||||||
|
|
||||||
|
sig = dbus_message_new_signal(path,
|
||||||
|
"org.freedesktop.IBus.InputContext", "UpdatePreeditText");
|
||||||
|
if(sig == nil)
|
||||||
|
return;
|
||||||
|
dbus_message_iter_init_append(sig, &it);
|
||||||
|
appendibustext(&it, text);
|
||||||
|
cursor = utflen(text);
|
||||||
|
visible = text[0] != '\0' ? TRUE : FALSE;
|
||||||
|
dbus_message_iter_append_basic(&it, DBUS_TYPE_UINT32, &cursor);
|
||||||
|
dbus_message_iter_append_basic(&it, DBUS_TYPE_BOOLEAN, &visible);
|
||||||
|
dbus_connection_send(c, sig, nil);
|
||||||
|
dbus_message_unref(sig);
|
||||||
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
handlehello(DBusConnection *c, DBusMessage *m)
|
handlehello(DBusConnection *c, DBusMessage *m)
|
||||||
{
|
{
|
||||||
@@ -324,8 +353,8 @@ handlekey(DBusConnection *c, DBusMessage *m)
|
|||||||
DBusMessage *r;
|
DBusMessage *r;
|
||||||
DBusError err;
|
DBusError err;
|
||||||
dbus_uint32_t sym, code, state;
|
dbus_uint32_t sym, code, state;
|
||||||
char commit[256];
|
char commit[256], preedit[256];
|
||||||
int eaten, n;
|
int eaten;
|
||||||
dbus_bool_t b;
|
dbus_bool_t b;
|
||||||
u32int ks, mod;
|
u32int ks, mod;
|
||||||
|
|
||||||
@@ -349,9 +378,11 @@ handlekey(DBusConnection *c, DBusMessage *m)
|
|||||||
}
|
}
|
||||||
ks = kget(sym);
|
ks = kget(sym);
|
||||||
mod = mget(state);
|
mod = mget(state);
|
||||||
n = sendkey(ks, mod, commit, sizeof(commit), &eaten);
|
sendkey(ks, mod, commit, sizeof(commit), preedit, sizeof(preedit),
|
||||||
if(n > 0)
|
&eaten);
|
||||||
|
if(commit[0] != '\0')
|
||||||
emitcommit(c, dbus_message_get_path(m), commit);
|
emitcommit(c, dbus_message_get_path(m), commit);
|
||||||
|
emitpreedit(c, dbus_message_get_path(m), preedit);
|
||||||
r = dbus_message_new_method_return(m);
|
r = dbus_message_new_method_return(m);
|
||||||
b = eaten ? TRUE : FALSE;
|
b = eaten ? TRUE : FALSE;
|
||||||
dbus_message_append_args(r, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
|
dbus_message_append_args(r, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
|
||||||
@@ -375,6 +406,7 @@ static DBusHandlerResult
|
|||||||
handlereset(DBusConnection *c, DBusMessage *m)
|
handlereset(DBusConnection *c, DBusMessage *m)
|
||||||
{
|
{
|
||||||
sendreset();
|
sendreset();
|
||||||
|
emitpreedit(c, dbus_message_get_path(m), "");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,6 +437,8 @@ static const char introspectxml[] =
|
|||||||
"<arg direction=\"in\" type=\"i\"/><arg direction=\"in\" type=\"i\"/></method>\n"
|
"<arg direction=\"in\" type=\"i\"/><arg direction=\"in\" type=\"i\"/></method>\n"
|
||||||
" <method name=\"SetEngine\"><arg direction=\"in\" type=\"s\"/></method>\n"
|
" <method name=\"SetEngine\"><arg direction=\"in\" type=\"s\"/></method>\n"
|
||||||
" <signal name=\"CommitText\"><arg type=\"v\"/></signal>\n"
|
" <signal name=\"CommitText\"><arg type=\"v\"/></signal>\n"
|
||||||
|
" <signal name=\"UpdatePreeditText\">"
|
||||||
|
"<arg type=\"v\"/><arg type=\"u\"/><arg type=\"b\"/></signal>\n"
|
||||||
" </interface>\n"
|
" </interface>\n"
|
||||||
"</node>\n";
|
"</node>\n";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user