fix: repair IBus context lifecycle
This commit is contained in:
304
ibus.c
304
ibus.c
@@ -14,7 +14,9 @@ enum
|
|||||||
{
|
{
|
||||||
Maxwatches = 32,
|
Maxwatches = 32,
|
||||||
Maxconns = 16,
|
Maxconns = 16,
|
||||||
|
Maxcontexts = 64,
|
||||||
Relmask = 1<<30,
|
Relmask = 1<<30,
|
||||||
|
Ibussupermask = 1<<26,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Watch Watch;
|
typedef struct Watch Watch;
|
||||||
@@ -23,24 +25,41 @@ struct Watch
|
|||||||
DBusWatch *w;
|
DBusWatch *w;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct Ictx Ictx;
|
||||||
|
struct Ictx
|
||||||
|
{
|
||||||
|
DBusConnection *conn;
|
||||||
|
char path[64];
|
||||||
|
uvlong owner;
|
||||||
|
int focused;
|
||||||
|
Caret caret;
|
||||||
|
};
|
||||||
|
|
||||||
static Watch watches[Maxwatches];
|
static Watch watches[Maxwatches];
|
||||||
static int nwatches;
|
static int nwatches;
|
||||||
static DBusConnection *conns[Maxconns];
|
static DBusConnection *conns[Maxconns];
|
||||||
static int nconns;
|
static int nconns;
|
||||||
static DBusServer *srv;
|
static DBusServer *srv;
|
||||||
static char addrfile[256];
|
static Ictx contexts[Maxcontexts];
|
||||||
|
static char addrfile[512];
|
||||||
|
static dev_t addrdev;
|
||||||
|
static ino_t addrino;
|
||||||
|
static int addrowned;
|
||||||
static int icctr;
|
static int icctr;
|
||||||
static int busctr;
|
static int busctr;
|
||||||
static Channel *replyc;
|
static Channel *replyc;
|
||||||
static uvlong owner;
|
|
||||||
|
|
||||||
static DBusHandlerResult onmsg(DBusConnection*, DBusMessage*, void*);
|
static DBusHandlerResult onmsg(DBusConnection*, DBusMessage*, void*);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
unlinkaddr(void)
|
unlinkaddr(void)
|
||||||
{
|
{
|
||||||
if(addrfile[0] != '\0')
|
struct stat st;
|
||||||
|
|
||||||
|
if(addrowned && lstat(addrfile, &st) == 0 &&
|
||||||
|
st.st_dev == addrdev && st.st_ino == addrino)
|
||||||
unlink(addrfile);
|
unlink(addrfile);
|
||||||
|
addrowned = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -98,7 +117,8 @@ buildaddrpath(char *buf, int sz)
|
|||||||
{
|
{
|
||||||
char mid[64], host[64], num[8], *cfg, *home;
|
char mid[64], host[64], num[8], *cfg, *home;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
char dir[256];
|
char dir[512];
|
||||||
|
int n;
|
||||||
|
|
||||||
machineid(mid, sizeof(mid));
|
machineid(mid, sizeof(mid));
|
||||||
if(mid[0] == '\0')
|
if(mid[0] == '\0')
|
||||||
@@ -106,15 +126,17 @@ buildaddrpath(char *buf, int sz)
|
|||||||
xdisplay(host, sizeof(host), num, sizeof(num));
|
xdisplay(host, sizeof(host), num, sizeof(num));
|
||||||
cfg = getenv("XDG_CONFIG_HOME");
|
cfg = getenv("XDG_CONFIG_HOME");
|
||||||
if(cfg != nil && cfg[0] != '\0')
|
if(cfg != nil && cfg[0] != '\0')
|
||||||
snprintf(dir, sizeof(dir), "%s/ibus/bus", cfg);
|
n = snprintf(dir, sizeof(dir), "%s/ibus/bus", cfg);
|
||||||
else{
|
else{
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
if(home == nil)
|
if(home == nil)
|
||||||
return -1;
|
return -1;
|
||||||
snprintf(dir, sizeof(dir), "%s/.config/ibus/bus", home);
|
n = snprintf(dir, sizeof(dir), "%s/.config/ibus/bus", home);
|
||||||
}
|
}
|
||||||
|
if(n < 0 || n >= (int)sizeof dir)
|
||||||
|
return -1;
|
||||||
if(stat(dir, &st) < 0){
|
if(stat(dir, &st) < 0){
|
||||||
char tmp[256];
|
char tmp[512];
|
||||||
char *p;
|
char *p;
|
||||||
strncpy(tmp, dir, sizeof(tmp));
|
strncpy(tmp, dir, sizeof(tmp));
|
||||||
tmp[sizeof(tmp)-1] = '\0';
|
tmp[sizeof(tmp)-1] = '\0';
|
||||||
@@ -126,23 +148,55 @@ buildaddrpath(char *buf, int sz)
|
|||||||
}
|
}
|
||||||
mkdir(tmp, 0700);
|
mkdir(tmp, 0700);
|
||||||
}
|
}
|
||||||
snprintf(buf, sz, "%s/%s-%s-%s", dir, mid, host, num);
|
n = snprintf(buf, sz, "%s/%s-%s-%s", dir, mid, host, num);
|
||||||
return 0;
|
return n < 0 || n >= sz ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
writeaddr(char *path, char *addr)
|
writeaddr(char *path, char *addr)
|
||||||
{
|
{
|
||||||
|
char tmp[576];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
struct stat st;
|
||||||
|
int fd, n, ok;
|
||||||
|
|
||||||
fp = fopen(path, "w");
|
n = snprintf(tmp, sizeof tmp, "%s.tmp.XXXXXX", path);
|
||||||
if(fp == nil)
|
if(n < 0 || n >= (int)sizeof tmp)
|
||||||
return -1;
|
return -1;
|
||||||
fprintf(fp, "IBUS_ADDRESS=%s\n", addr);
|
fd = mkstemp(tmp);
|
||||||
fprintf(fp, "IBUS_DAEMON_PID=%d\n", (int)getpid());
|
if(fd < 0)
|
||||||
fclose(fp);
|
return -1;
|
||||||
chmod(path, 0600);
|
ok = 0;
|
||||||
return 0;
|
fp = nil;
|
||||||
|
if(fchmod(fd, 0600) < 0)
|
||||||
|
goto out;
|
||||||
|
fp = fdopen(fd, "w");
|
||||||
|
if(fp == nil)
|
||||||
|
goto out;
|
||||||
|
fd = -1;
|
||||||
|
if(fprintf(fp, "IBUS_ADDRESS=%s\n", addr) < 0 ||
|
||||||
|
fprintf(fp, "IBUS_DAEMON_PID=%d\n", (int)getpid()) < 0 ||
|
||||||
|
fflush(fp) < 0 || fsync(fileno(fp)) < 0)
|
||||||
|
goto out;
|
||||||
|
if(fclose(fp) < 0){
|
||||||
|
fp = nil;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
fp = nil;
|
||||||
|
if(rename(tmp, path) < 0 || lstat(path, &st) < 0)
|
||||||
|
goto out;
|
||||||
|
addrdev = st.st_dev;
|
||||||
|
addrino = st.st_ino;
|
||||||
|
addrowned = 1;
|
||||||
|
ok = 1;
|
||||||
|
out:
|
||||||
|
if(fp != nil)
|
||||||
|
fclose(fp);
|
||||||
|
if(fd >= 0)
|
||||||
|
close(fd);
|
||||||
|
if(!ok)
|
||||||
|
unlink(tmp);
|
||||||
|
return ok ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static dbus_bool_t
|
static dbus_bool_t
|
||||||
@@ -204,38 +258,72 @@ mget(u32int state)
|
|||||||
if(state & (1<<0)) m |= Mshift;
|
if(state & (1<<0)) m |= Mshift;
|
||||||
if(state & (1<<2)) m |= Mctrl;
|
if(state & (1<<2)) m |= Mctrl;
|
||||||
if(state & (1<<3)) m |= Malt;
|
if(state & (1<<3)) m |= Malt;
|
||||||
if(state & (1<<6)) m |= Msuper;
|
if(state & ((1<<6)|Ibussupermask)) m |= Msuper;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Ictx*
|
||||||
|
findcontext(DBusConnection *conn, const char *path)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < nelem(contexts); i++)
|
||||||
|
if(contexts[i].conn == conn && strcmp(contexts[i].path, path) == 0)
|
||||||
|
return &contexts[i];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Ictx*
|
||||||
|
newcontext(DBusConnection *conn, const char *path)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < nelem(contexts); i++)
|
||||||
|
if(contexts[i].conn == nil){
|
||||||
|
memset(&contexts[i], 0, sizeof contexts[i]);
|
||||||
|
contexts[i].conn = conn;
|
||||||
|
contexts[i].owner = ownernew();
|
||||||
|
strncpy(contexts[i].path, path, sizeof contexts[i].path);
|
||||||
|
contexts[i].path[sizeof contexts[i].path-1] = '\0';
|
||||||
|
return &contexts[i];
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendkey(u32int ks, u32int mod, Keyres *res)
|
sendrequest(Ictx *ctx, int op, u32int ks, u32int mod, Keyres *res)
|
||||||
{
|
{
|
||||||
Keyreq kr;
|
Keyreq kr;
|
||||||
|
|
||||||
memset(&kr, 0, sizeof kr);
|
memset(&kr, 0, sizeof kr);
|
||||||
kr.owner = owner;
|
kr.owner = ctx->owner;
|
||||||
kr.op = Keypress;
|
kr.op = op;
|
||||||
kr.ks = ks;
|
kr.ks = ks;
|
||||||
kr.mod = mod;
|
kr.mod = mod;
|
||||||
kr.want = 1;
|
kr.caret = ctx->caret;
|
||||||
|
kr.want = op == Keypress;
|
||||||
kr.reply = replyc;
|
kr.reply = replyc;
|
||||||
chansend(keyc, &kr);
|
chansend(keyc, &kr);
|
||||||
chanrecv(replyc, res);
|
chanrecv(replyc, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendreset(void)
|
releasecontext(Ictx *ctx)
|
||||||
{
|
{
|
||||||
Keyreq kr;
|
|
||||||
Keyres res;
|
Keyres res;
|
||||||
|
|
||||||
memset(&kr, 0, sizeof kr);
|
if(replyc != nil)
|
||||||
kr.owner = owner;
|
sendrequest(ctx, Keyrelease, 0, 0, &res);
|
||||||
kr.op = Keyreset;
|
ctx->focused = 0;
|
||||||
kr.reply = replyc;
|
memset(&ctx->caret, 0, sizeof ctx->caret);
|
||||||
chansend(keyc, &kr);
|
|
||||||
chanrecv(replyc, &res);
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dropcontext(Ictx *ctx)
|
||||||
|
{
|
||||||
|
releasecontext(ctx);
|
||||||
|
memset(ctx, 0, sizeof *ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -318,15 +406,53 @@ handlehello(DBusConnection *c, DBusMessage *m)
|
|||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handleerror(DBusConnection *c, DBusMessage *m, const char *name,
|
||||||
|
const char *text)
|
||||||
|
{
|
||||||
|
DBusMessage *r;
|
||||||
|
|
||||||
|
r = dbus_message_new_error(m, name, text);
|
||||||
|
if(r != nil){
|
||||||
|
dbus_connection_send(c, r, nil);
|
||||||
|
dbus_message_unref(r);
|
||||||
|
}
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handlebool(DBusConnection *c, DBusMessage *m, int value)
|
||||||
|
{
|
||||||
|
DBusMessage *r;
|
||||||
|
dbus_bool_t b;
|
||||||
|
|
||||||
|
r = dbus_message_new_method_return(m);
|
||||||
|
b = value ? TRUE : FALSE;
|
||||||
|
dbus_message_append_args(r, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
|
||||||
|
dbus_connection_send(c, r, nil);
|
||||||
|
dbus_message_unref(r);
|
||||||
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
handlecreate(DBusConnection *c, DBusMessage *m)
|
handlecreate(DBusConnection *c, DBusMessage *m)
|
||||||
{
|
{
|
||||||
DBusMessage *r;
|
DBusMessage *r;
|
||||||
char path[64];
|
char path[64];
|
||||||
const char *pp;
|
const char *pp;
|
||||||
|
Ictx *ctx;
|
||||||
|
int n;
|
||||||
|
|
||||||
icctr++;
|
icctr++;
|
||||||
snprintf(path, sizeof(path), "/org/freedesktop/IBus/InputContext_%d", icctr);
|
n = snprintf(path, sizeof(path),
|
||||||
|
"/org/freedesktop/IBus/InputContext_%d", icctr);
|
||||||
|
if(n < 0 || n >= (int)sizeof path)
|
||||||
|
return handleerror(c, m, DBUS_ERROR_LIMITS_EXCEEDED,
|
||||||
|
"input context path exhausted");
|
||||||
|
ctx = newcontext(c, path);
|
||||||
|
if(ctx == nil)
|
||||||
|
return handleerror(c, m, DBUS_ERROR_LIMITS_EXCEEDED,
|
||||||
|
"too many input contexts");
|
||||||
pp = path;
|
pp = path;
|
||||||
r = dbus_message_new_method_return(m);
|
r = dbus_message_new_method_return(m);
|
||||||
dbus_message_append_args(r, DBUS_TYPE_OBJECT_PATH, &pp, DBUS_TYPE_INVALID);
|
dbus_message_append_args(r, DBUS_TYPE_OBJECT_PATH, &pp, DBUS_TYPE_INVALID);
|
||||||
@@ -336,14 +462,12 @@ handlecreate(DBusConnection *c, DBusMessage *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
handlekey(DBusConnection *c, DBusMessage *m)
|
handlekey(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
{
|
{
|
||||||
DBusMessage *r;
|
|
||||||
DBusError err;
|
DBusError err;
|
||||||
dbus_uint32_t sym, code, state;
|
dbus_uint32_t sym, code, state;
|
||||||
Keyres res;
|
Keyres res;
|
||||||
char commit[Maxutf], preedit[Maxutf];
|
char commit[Maxutf], preedit[Maxutf];
|
||||||
dbus_bool_t b;
|
|
||||||
u32int ks, mod;
|
u32int ks, mod;
|
||||||
|
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
@@ -356,28 +480,17 @@ handlekey(DBusConnection *c, DBusMessage *m)
|
|||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
}
|
}
|
||||||
USED(code);
|
USED(code);
|
||||||
if(state & Relmask){
|
if(state & Relmask || !ctx->focused)
|
||||||
r = dbus_message_new_method_return(m);
|
return handlebool(c, m, 0);
|
||||||
b = FALSE;
|
|
||||||
dbus_message_append_args(r, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
|
|
||||||
dbus_connection_send(c, r, nil);
|
|
||||||
dbus_message_unref(r);
|
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
|
||||||
}
|
|
||||||
ks = kget(sym);
|
ks = kget(sym);
|
||||||
mod = mget(state);
|
mod = mget(state);
|
||||||
sendkey(ks, mod, &res);
|
sendrequest(ctx, Keypress, ks, mod, &res);
|
||||||
stoutf(&res.commit, commit, sizeof commit);
|
stoutf(&res.commit, commit, sizeof commit);
|
||||||
stoutf(&res.preedit, preedit, sizeof preedit);
|
stoutf(&res.preedit, preedit, sizeof preedit);
|
||||||
if(commit[0] != '\0')
|
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);
|
emitpreedit(c, dbus_message_get_path(m), preedit);
|
||||||
r = dbus_message_new_method_return(m);
|
return handlebool(c, m, res.eaten);
|
||||||
b = res.eaten ? TRUE : FALSE;
|
|
||||||
dbus_message_append_args(r, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
|
|
||||||
dbus_connection_send(c, r, nil);
|
|
||||||
dbus_message_unref(r);
|
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
@@ -392,13 +505,66 @@ handlenoop(DBusConnection *c, DBusMessage *m)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult
|
static DBusHandlerResult
|
||||||
handlereset(DBusConnection *c, DBusMessage *m)
|
handlereset(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
{
|
{
|
||||||
sendreset();
|
Keyres res;
|
||||||
|
|
||||||
|
sendrequest(ctx, Keyreset, 0, 0, &res);
|
||||||
emitpreedit(c, dbus_message_get_path(m), "");
|
emitpreedit(c, dbus_message_get_path(m), "");
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handlefocusin(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
|
{
|
||||||
|
ctx->focused = 1;
|
||||||
|
return handlenoop(c, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handlefocusout(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
|
{
|
||||||
|
releasecontext(ctx);
|
||||||
|
emitpreedit(c, dbus_message_get_path(m), "");
|
||||||
|
return handlenoop(c, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handledestroy(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
|
{
|
||||||
|
dropcontext(ctx);
|
||||||
|
return handlenoop(c, m);
|
||||||
|
}
|
||||||
|
|
||||||
|
static DBusHandlerResult
|
||||||
|
handlecursor(DBusConnection *c, DBusMessage *m, Ictx *ctx)
|
||||||
|
{
|
||||||
|
DBusError err;
|
||||||
|
dbus_int32_t x, y, w, h;
|
||||||
|
Keyres res;
|
||||||
|
|
||||||
|
dbus_error_init(&err);
|
||||||
|
if(!dbus_message_get_args(m, &err,
|
||||||
|
DBUS_TYPE_INT32, &x, DBUS_TYPE_INT32, &y,
|
||||||
|
DBUS_TYPE_INT32, &w, DBUS_TYPE_INT32, &h,
|
||||||
|
DBUS_TYPE_INVALID)){
|
||||||
|
dbus_error_free(&err);
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"SetCursorLocation expects four integers");
|
||||||
|
}
|
||||||
|
if(w < 0 || h < 0)
|
||||||
|
return handleerror(c, m, DBUS_ERROR_INVALID_ARGS,
|
||||||
|
"cursor dimensions must not be negative");
|
||||||
|
ctx->caret.valid = 1;
|
||||||
|
ctx->caret.x = x;
|
||||||
|
ctx->caret.y = y;
|
||||||
|
ctx->caret.w = w;
|
||||||
|
ctx->caret.h = h;
|
||||||
|
if(ctx->focused)
|
||||||
|
sendrequest(ctx, Keycaret, 0, 0, &res);
|
||||||
|
return handlenoop(c, m);
|
||||||
|
}
|
||||||
|
|
||||||
static const char introspectxml[] =
|
static const char introspectxml[] =
|
||||||
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
|
||||||
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
|
||||||
@@ -448,6 +614,7 @@ static DBusHandlerResult
|
|||||||
onmsg(DBusConnection *c, DBusMessage *m, void *_)
|
onmsg(DBusConnection *c, DBusMessage *m, void *_)
|
||||||
{
|
{
|
||||||
const char *iface, *member, *path;
|
const char *iface, *member, *path;
|
||||||
|
Ictx *ctx;
|
||||||
|
|
||||||
USED(_);
|
USED(_);
|
||||||
if(dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_CALL)
|
if(dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_CALL)
|
||||||
@@ -472,15 +639,23 @@ onmsg(DBusConnection *c, DBusMessage *m, void *_)
|
|||||||
return handlecreate(c, m);
|
return handlecreate(c, m);
|
||||||
}
|
}
|
||||||
if(strcmp(iface, "org.freedesktop.IBus.InputContext") == 0){
|
if(strcmp(iface, "org.freedesktop.IBus.InputContext") == 0){
|
||||||
|
ctx = findcontext(c, path);
|
||||||
|
if(ctx == nil)
|
||||||
|
return handleerror(c, m, DBUS_ERROR_UNKNOWN_OBJECT,
|
||||||
|
"unknown input context");
|
||||||
if(strcmp(member, "ProcessKeyEvent") == 0)
|
if(strcmp(member, "ProcessKeyEvent") == 0)
|
||||||
return handlekey(c, m);
|
return handlekey(c, m, ctx);
|
||||||
if(strcmp(member, "FocusOut") == 0
|
if(strcmp(member, "FocusIn") == 0)
|
||||||
|| strcmp(member, "Reset") == 0)
|
return handlefocusin(c, m, ctx);
|
||||||
return handlereset(c, m);
|
if(strcmp(member, "FocusOut") == 0)
|
||||||
if(strcmp(member, "FocusIn") == 0
|
return handlefocusout(c, m, ctx);
|
||||||
|| strcmp(member, "Destroy") == 0
|
if(strcmp(member, "Reset") == 0)
|
||||||
|| strcmp(member, "SetCapabilities") == 0
|
return handlereset(c, m, ctx);
|
||||||
|| strcmp(member, "SetCursorLocation") == 0
|
if(strcmp(member, "Destroy") == 0)
|
||||||
|
return handledestroy(c, m, ctx);
|
||||||
|
if(strcmp(member, "SetCursorLocation") == 0)
|
||||||
|
return handlecursor(c, m, ctx);
|
||||||
|
if(strcmp(member, "SetCapabilities") == 0
|
||||||
|| strcmp(member, "SetEngine") == 0)
|
|| strcmp(member, "SetEngine") == 0)
|
||||||
return handlenoop(c, m);
|
return handlenoop(c, m);
|
||||||
}
|
}
|
||||||
@@ -507,7 +682,7 @@ newconn(DBusServer *s, DBusConnection *c, void *_)
|
|||||||
static void
|
static void
|
||||||
pruneconns(void)
|
pruneconns(void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j, k;
|
||||||
|
|
||||||
j = 0;
|
j = 0;
|
||||||
for(i = 0; i < nconns; i++){
|
for(i = 0; i < nconns; i++){
|
||||||
@@ -515,6 +690,9 @@ pruneconns(void)
|
|||||||
conns[j++] = conns[i];
|
conns[j++] = conns[i];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
for(k = 0; k < nelem(contexts); k++)
|
||||||
|
if(contexts[k].conn == conns[i])
|
||||||
|
dropcontext(&contexts[k]);
|
||||||
dbus_connection_unref(conns[i]);
|
dbus_connection_unref(conns[i]);
|
||||||
}
|
}
|
||||||
nconns = j;
|
nconns = j;
|
||||||
@@ -531,8 +709,11 @@ ibusinit(void)
|
|||||||
fprintf(stderr, "strans: ibus: cannot build address path\n");
|
fprintf(stderr, "strans: ibus: cannot build address path\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
unlink(addrfile);
|
if(snprintf(addr, sizeof(addr), "unix:abstract=strans-%d",
|
||||||
snprintf(addr, sizeof(addr), "unix:abstract=strans-%d", (int)getpid());
|
(int)getpid()) >= (int)sizeof addr){
|
||||||
|
fprintf(stderr, "strans: ibus: address is too long\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
dbus_error_init(&err);
|
dbus_error_init(&err);
|
||||||
srv = dbus_server_listen(addr, &err);
|
srv = dbus_server_listen(addr, &err);
|
||||||
if(srv == nil){
|
if(srv == nil){
|
||||||
@@ -571,7 +752,6 @@ ibusthread(void *_)
|
|||||||
if(ibusinit() < 0)
|
if(ibusinit() < 0)
|
||||||
return;
|
return;
|
||||||
replyc = chancreate(sizeof(Keyres), 0);
|
replyc = chancreate(sizeof(Keyres), 0);
|
||||||
owner = ownernew();
|
|
||||||
for(;;){
|
for(;;){
|
||||||
n = 0;
|
n = 0;
|
||||||
for(i = 0; i < nwatches && n < Maxwatches; i++){
|
for(i = 0; i < nwatches && n < Maxwatches; i++){
|
||||||
|
|||||||
Reference in New Issue
Block a user