Compare commits

..

4 Commits

Author SHA1 Message Date
129b842487 optimize rendering 2026-02-09 09:10:51 +09:00
b41cf78862 add bench 2026-02-09 09:10:51 +09:00
2cfee1d36c fix kouho selection. 2026-02-09 09:10:51 +09:00
b35b81ad3d vietnamese telex input 2026-02-09 09:10:44 +09:00
23 changed files with 262 additions and 3562 deletions

View File

@@ -1,19 +1,15 @@
CC = 9c
LD = 9l
DBUS_CFLAGS := $(shell pkg-config --cflags dbus-1)
DBUS_LIBS := $(shell pkg-config --libs dbus-1)
WL_CFLAGS := $(shell pkg-config --cflags wayland-client xkbcommon)
WL_LIBS := $(shell pkg-config --libs wayland-client xkbcommon)
CFLAGS = -Wall -Wextra -O2 -g $(DBUS_CFLAGS) $(WL_CFLAGS)
CFLAGS = -Wall -Wextra -O2 -g
PROG = strans
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
all: $(PROG) xim bench
all: $(PROG) xim bench
$(PROG): $(OBJS)
$(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm $(DBUS_LIBS) $(WL_LIBS)
$(LD) -o $@ $(OBJS) -lthread -lString -lbio -lxcb -lm
$(OBJS): dat.h fn.h ipc.h

View File

@@ -1,14 +1,12 @@
# strans
An input method daemon for CJK text entry on X11 and Wayland.
An input method daemon for CJK text entry on X11.
Inspired by 9front's ktrans. Threads communicate via CSP channels.
## Dependencies
- plan9port
- dbus-1
- wayland-client, libxkbcommon (for Wayland support)
- gtk+-3.0 (optional, for GTK IM module)
## Build
@@ -30,17 +28,6 @@ For GTK apps:
GTK_IM_MODULE=strans gedit
For IBus apps (kitty, foot, etc.):
GLFW_IM_MODULE=ibus kitty
For Wayland apps (text-input-v3 clients on wlroots compositors):
# nothing to set; the compositor relays text-input-v3 to strans
Strans itself is the IBus endpoint and the Wayland input-method-v2 client;
no ibus-daemon or fcitx5 needed. Start strans after the compositor.
## Usage
Switch input modes with Ctrl + key:
@@ -51,21 +38,18 @@ Switch input modes with Ctrl + key:
T English
V Vietnamese (Telex)
E Emoji
P Toggle preedit/candidate popup window
Type romanized input. Select candidates with 1-9 or arrow keys.
Tab or Enter to commit.
## Architecture
Threads communicate via CSP channels:
Four threads communicate via CSP channels:
- [imthread](strans.c#L271): keystroke processing, transliteration
- [dictthread](dict.c#L38): dictionary lookup
- [drawthread](win.c#L133): preedit window rendering
- [srvthread](srv.c#L42): IPC via unix socket
- [ibusthread](ibus.c): IBus D-Bus endpoint for GLFW/kitty
- [waylandthread](wayland.c): Wayland input-method-v2 + virtual-keyboard-v1
Adapters (strans-xim, im-strans.so) bridge X11/GTK events.
@@ -75,18 +59,9 @@ Adapters (strans-xim, im-strans.so) bridge X11/GTK events.
dict.c dictionary queries
win.c xcb window management
font.c truetype rendering (stb_truetype)
wayland.c wayland input-method-v2 adapter
map/ transliteration tables
font/ bundled CJK fonts
input-method-unstable-v2-*.{c,h} wayland-scanner output, vendored
virtual-keyboard-unstable-v1-*.{c,h}
The two Wayland protocols (input-method-v2, virtual-keyboard-v1) are
wlroots-only and not in the upstream wayland-protocols package, so the
generated client code is vendored. Regenerate with wayland-scanner if
the XML upstream ever changes (it hasn't in years).
## References
- https://git.9front.org/plan9front/plan9front/HEAD/info.html

1
dat.h
View File

@@ -128,7 +128,6 @@ struct Keyreq
int fd;
u32int ks;
u32int mod;
int want; /* nonzero: append preedit after commit */
};
typedef struct Dictreq Dictreq;

2
fn.h
View File

@@ -33,8 +33,6 @@ void backko(Im*);
void dictsend(Im*, Str*);
void srvthread(void*);
void ibusthread(void*);
void waylandthread(void*);
void* emalloc(ulong);
void* erealloc(void*, ulong);

View File

@@ -12,8 +12,6 @@ struct Im
{
GtkIMContext parent;
int fd;
char pre[256];
int prelen;
};
typedef struct ImClass ImClass;
@@ -46,8 +44,8 @@ srvconnect(Im *im)
static int
readresp(Im *im, char *buf, int bufsz)
{
unsigned char hdr[2], pl;
int n, was;
unsigned char hdr[2];
int n;
if(read(im->fd, hdr, 2) != 2)
return -1;
@@ -58,21 +56,6 @@ readresp(Im *im, char *buf, int bufsz)
return -1;
buf[n] = '\0';
}
if(read(im->fd, &pl, 1) != 1)
return -1;
if(pl >= sizeof(im->pre))
return -1;
was = im->prelen;
if(pl > 0 && read(im->fd, im->pre, pl) != pl)
return -1;
im->pre[pl] = '\0';
im->prelen = pl;
if(was == 0 && pl > 0)
g_signal_emit_by_name(im, "preedit-start");
if(was != 0 || pl != 0)
g_signal_emit_by_name(im, "preedit-changed");
if(was > 0 && pl == 0)
g_signal_emit_by_name(im, "preedit-end");
return hdr[0];
}
@@ -109,7 +92,7 @@ sendreset(Im *im)
if(im->fd < 0)
return;
buf[0] = 1;
buf[0] = 0;
buf[1] = 0;
buf[2] = Kesc & 0xff;
buf[3] = Kesc >> 8;
@@ -136,7 +119,7 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
if(key == 0)
return FALSE;
mod = mget(ev->state);
buf[0] = 1;
buf[0] = 0;
buf[1] = mod;
buf[2] = key & 0xff;
buf[3] = key >> 8;
@@ -145,34 +128,11 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
r = readresp(im, resp, sizeof(resp));
if(r < 0)
return FALSE;
if(resp[0] != '\0')
if(r != 0 && resp[0] != '\0')
g_signal_emit_by_name(ctx, "commit", resp);
return r != 0;
}
static void
getpreedit(GtkIMContext *ctx, gchar **str, PangoAttrList **attrs,
gint *cursor_pos)
{
Im *im;
PangoAttribute *u;
im = (Im*)ctx;
if(str)
*str = g_strdup(im->pre);
if(attrs){
*attrs = pango_attr_list_new();
if(im->prelen > 0){
u = pango_attr_underline_new(PANGO_UNDERLINE_SINGLE);
u->start_index = 0;
u->end_index = im->prelen;
pango_attr_list_insert(*attrs, u);
}
}
if(cursor_pos)
*cursor_pos = g_utf8_strlen(im->pre, -1);
}
static void
reset(GtkIMContext *ctx)
{
@@ -211,7 +171,6 @@ classinit(ImClass *klass)
ic = GTK_IM_CONTEXT_CLASS(klass);
oc = G_OBJECT_CLASS(klass);
ic->filter_keypress = kpress;
ic->get_preedit_string = getpreedit;
ic->reset = reset;
ic->focus_out = focusout;
oc->finalize = finalize;

619
ibus.c
View File

@@ -1,619 +0,0 @@
#include "dat.h"
#include "fn.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <poll.h>
#include <dbus/dbus.h>
enum
{
Maxwatches = 32,
Maxconns = 16,
Relmask = 1<<30,
};
typedef struct Watch Watch;
struct Watch
{
DBusWatch *w;
};
static Watch watches[Maxwatches];
static int nwatches;
static DBusConnection *conns[Maxconns];
static int nconns;
static DBusServer *srv;
static char addrfile[256];
static int icctr;
static int busctr;
static DBusHandlerResult onmsg(DBusConnection*, DBusMessage*, void*);
static void
unlinkaddr(void)
{
if(addrfile[0] != '\0')
unlink(addrfile);
}
static void
machineid(char *buf, int sz)
{
int fd, n;
fd = open("/etc/machine-id", 0);
if(fd < 0)
fd = open("/var/lib/dbus/machine-id", 0);
if(fd < 0){
buf[0] = '\0';
return;
}
n = read(fd, buf, sz - 1);
close(fd);
if(n < 0) n = 0;
buf[n] = '\0';
while(n > 0 && (buf[n-1] == '\n' || buf[n-1] == '\r'))
buf[--n] = '\0';
}
static void
xdisplay(char *host, int hsz, char *num, int nsz)
{
char *d, *colon, *dot, *p;
int n;
strncpy(host, "unix", hsz);
host[hsz-1] = '\0';
strncpy(num, "0", nsz);
num[nsz-1] = '\0';
d = getenv("DISPLAY");
if(d == nil || d[0] == '\0')
return;
colon = strchr(d, ':');
if(colon == nil)
return;
if(colon > d){
n = colon - d;
if(n >= hsz) n = hsz - 1;
memcpy(host, d, n);
host[n] = '\0';
}
p = colon + 1;
dot = strchr(p, '.');
n = dot ? dot - p : (int)strlen(p);
if(n >= nsz) n = nsz - 1;
memcpy(num, p, n);
num[n] = '\0';
}
static int
buildaddrpath(char *buf, int sz)
{
char mid[64], host[64], num[8], *cfg, *home;
struct stat st;
char dir[256];
machineid(mid, sizeof(mid));
if(mid[0] == '\0')
return -1;
xdisplay(host, sizeof(host), num, sizeof(num));
cfg = getenv("XDG_CONFIG_HOME");
if(cfg != nil && cfg[0] != '\0')
snprintf(dir, sizeof(dir), "%s/ibus/bus", cfg);
else{
home = getenv("HOME");
if(home == nil)
return -1;
snprintf(dir, sizeof(dir), "%s/.config/ibus/bus", home);
}
if(stat(dir, &st) < 0){
char tmp[256];
char *p;
strncpy(tmp, dir, sizeof(tmp));
tmp[sizeof(tmp)-1] = '\0';
for(p = tmp+1; *p; p++)
if(*p == '/'){
*p = '\0';
mkdir(tmp, 0700);
*p = '/';
}
mkdir(tmp, 0700);
}
snprintf(buf, sz, "%s/%s-%s-%s", dir, mid, host, num);
return 0;
}
static int
writeaddr(char *path, char *addr)
{
FILE *fp;
fp = fopen(path, "w");
if(fp == nil)
return -1;
fprintf(fp, "IBUS_ADDRESS=%s\n", addr);
fprintf(fp, "IBUS_DAEMON_PID=%d\n", (int)getpid());
fclose(fp);
chmod(path, 0600);
return 0;
}
static dbus_bool_t
addwatch(DBusWatch *w, void *_)
{
int i;
USED(_);
for(i = 0; i < nwatches; i++)
if(watches[i].w == nil){
watches[i].w = w;
return TRUE;
}
if(nwatches >= Maxwatches)
return FALSE;
watches[nwatches++].w = w;
return TRUE;
}
static void
removewatch(DBusWatch *w, void *_)
{
int i;
USED(_);
for(i = 0; i < nwatches; i++)
if(watches[i].w == w){
watches[i].w = nil;
return;
}
}
static void
togglewatch(DBusWatch *w, void *_)
{
USED(w);
USED(_);
}
static u32int
kget(u32int sym)
{
if(sym >= 0xff00 && sym <= 0xffff)
return Kspec + (sym - 0xff00);
return sym;
}
static u32int
mget(u32int state)
{
u32int m;
m = 0;
if(state & (1<<0)) m |= Mshift;
if(state & (1<<2)) m |= Mctrl;
if(state & (1<<3)) m |= Malt;
if(state & (1<<6)) m |= Msuper;
return m;
}
static void
sendkey(u32int ks, u32int mod, char *com, int csz, char *pre, int psz,
int *eaten)
{
Keyreq kr;
int p[2];
uchar hdr[2];
uchar pl;
int n;
*eaten = 0;
com[0] = '\0';
pre[0] = '\0';
if(pipe(p) < 0)
return;
kr.fd = p[1];
kr.ks = ks;
kr.mod = mod;
kr.want = 1;
chansend(keyc, &kr);
if(read(p[0], hdr, 2) != 2)
goto out;
*eaten = hdr[0];
n = hdr[1];
if(n > 0 && n < csz){
if(read(p[0], com, n) != n)
goto out;
com[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[1]);
}
static void
sendreset(void)
{
char com[64], pre[256];
int eaten;
sendkey(Kesc, 0, com, sizeof(com), pre, sizeof(pre), &eaten);
}
static void
appendibustext(DBusMessageIter *it, const char *s)
{
DBusMessageIter v, st, attach, alv, ali, attr, alist;
const char *name = "IBusText";
const char *aname = "IBusAttrList";
dbus_message_iter_open_container(it, DBUS_TYPE_VARIANT, "(sa{sv}sv)", &v);
dbus_message_iter_open_container(&v, DBUS_TYPE_STRUCT, nil, &st);
dbus_message_iter_append_basic(&st, DBUS_TYPE_STRING, &name);
dbus_message_iter_open_container(&st, DBUS_TYPE_ARRAY, "{sv}", &attach);
dbus_message_iter_close_container(&st, &attach);
dbus_message_iter_append_basic(&st, DBUS_TYPE_STRING, &s);
dbus_message_iter_open_container(&st, DBUS_TYPE_VARIANT, "(sa{sv}av)", &alv);
dbus_message_iter_open_container(&alv, DBUS_TYPE_STRUCT, nil, &ali);
dbus_message_iter_append_basic(&ali, DBUS_TYPE_STRING, &aname);
dbus_message_iter_open_container(&ali, DBUS_TYPE_ARRAY, "{sv}", &attr);
dbus_message_iter_close_container(&ali, &attr);
dbus_message_iter_open_container(&ali, DBUS_TYPE_ARRAY, "v", &alist);
dbus_message_iter_close_container(&ali, &alist);
dbus_message_iter_close_container(&alv, &ali);
dbus_message_iter_close_container(&st, &alv);
dbus_message_iter_close_container(&v, &st);
dbus_message_iter_close_container(it, &v);
}
static void
emitcommit(DBusConnection *c, const char *path, const char *text)
{
DBusMessage *sig;
DBusMessageIter it;
sig = dbus_message_new_signal(path, "org.freedesktop.IBus.InputContext", "CommitText");
if(sig == nil)
return;
dbus_message_iter_init_append(sig, &it);
appendibustext(&it, text);
dbus_connection_send(c, sig, nil);
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
handlehello(DBusConnection *c, DBusMessage *m)
{
DBusMessage *r;
char name[32];
const char *np;
busctr++;
snprintf(name, sizeof(name), ":1.%d", busctr);
np = name;
r = dbus_message_new_method_return(m);
dbus_message_append_args(r, DBUS_TYPE_STRING, &np, DBUS_TYPE_INVALID);
dbus_connection_send(c, r, nil);
dbus_message_unref(r);
return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult
handlecreate(DBusConnection *c, DBusMessage *m)
{
DBusMessage *r;
char path[64];
const char *pp;
icctr++;
snprintf(path, sizeof(path), "/org/freedesktop/IBus/InputContext_%d", icctr);
pp = path;
r = dbus_message_new_method_return(m);
dbus_message_append_args(r, DBUS_TYPE_OBJECT_PATH, &pp, DBUS_TYPE_INVALID);
dbus_connection_send(c, r, nil);
dbus_message_unref(r);
return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult
handlekey(DBusConnection *c, DBusMessage *m)
{
DBusMessage *r;
DBusError err;
dbus_uint32_t sym, code, state;
char commit[256], preedit[256];
int eaten;
dbus_bool_t b;
u32int ks, mod;
dbus_error_init(&err);
if(!dbus_message_get_args(m, &err,
DBUS_TYPE_UINT32, &sym,
DBUS_TYPE_UINT32, &code,
DBUS_TYPE_UINT32, &state,
DBUS_TYPE_INVALID)){
dbus_error_free(&err);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
USED(code);
if(state & Relmask){
r = dbus_message_new_method_return(m);
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);
mod = mget(state);
sendkey(ks, mod, commit, sizeof(commit), preedit, sizeof(preedit),
&eaten);
if(commit[0] != '\0')
emitcommit(c, dbus_message_get_path(m), commit);
emitpreedit(c, dbus_message_get_path(m), preedit);
r = dbus_message_new_method_return(m);
b = 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
handlenoop(DBusConnection *c, DBusMessage *m)
{
DBusMessage *r;
r = dbus_message_new_method_return(m);
dbus_connection_send(c, r, nil);
dbus_message_unref(r);
return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult
handlereset(DBusConnection *c, DBusMessage *m)
{
sendreset();
emitpreedit(c, dbus_message_get_path(m), "");
return handlenoop(c, m);
}
static const char introspectxml[] =
"<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n"
" \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n"
"<node>\n"
" <interface name=\"org.freedesktop.IBus\">\n"
" <method name=\"CreateInputContext\">\n"
" <arg direction=\"in\" type=\"s\"/>\n"
" <arg direction=\"out\" type=\"o\"/>\n"
" </method>\n"
" </interface>\n"
" <interface name=\"org.freedesktop.IBus.InputContext\">\n"
" <method name=\"ProcessKeyEvent\">\n"
" <arg direction=\"in\" type=\"u\"/>\n"
" <arg direction=\"in\" type=\"u\"/>\n"
" <arg direction=\"in\" type=\"u\"/>\n"
" <arg direction=\"out\" type=\"b\"/>\n"
" </method>\n"
" <method name=\"FocusIn\"/>\n"
" <method name=\"FocusOut\"/>\n"
" <method name=\"Reset\"/>\n"
" <method name=\"Destroy\"/>\n"
" <method name=\"SetCapabilities\"><arg direction=\"in\" type=\"u\"/></method>\n"
" <method name=\"SetCursorLocation\">"
"<arg direction=\"in\" type=\"i\"/><arg direction=\"in\" type=\"i\"/>"
"<arg direction=\"in\" type=\"i\"/><arg direction=\"in\" type=\"i\"/></method>\n"
" <method name=\"SetEngine\"><arg direction=\"in\" type=\"s\"/></method>\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"
"</node>\n";
static DBusHandlerResult
handleintrospect(DBusConnection *c, DBusMessage *m)
{
DBusMessage *r;
const char *xml = introspectxml;
r = dbus_message_new_method_return(m);
dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID);
dbus_connection_send(c, r, nil);
dbus_message_unref(r);
return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult
onmsg(DBusConnection *c, DBusMessage *m, void *_)
{
const char *iface, *member, *path;
USED(_);
if(dbus_message_get_type(m) != DBUS_MESSAGE_TYPE_METHOD_CALL)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
iface = dbus_message_get_interface(m);
member = dbus_message_get_member(m);
path = dbus_message_get_path(m);
if(iface == nil || member == nil || path == nil)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if(strcmp(iface, "org.freedesktop.DBus.Introspectable") == 0
&& strcmp(member, "Introspect") == 0)
return handleintrospect(c, m);
if(strcmp(iface, "org.freedesktop.DBus") == 0){
if(strcmp(member, "Hello") == 0)
return handlehello(c, m);
if(strcmp(member, "AddMatch") == 0
|| strcmp(member, "RemoveMatch") == 0)
return handlenoop(c, m);
}
if(strcmp(iface, "org.freedesktop.IBus") == 0){
if(strcmp(member, "CreateInputContext") == 0)
return handlecreate(c, m);
}
if(strcmp(iface, "org.freedesktop.IBus.InputContext") == 0){
if(strcmp(member, "ProcessKeyEvent") == 0)
return handlekey(c, m);
if(strcmp(member, "FocusOut") == 0
|| strcmp(member, "Reset") == 0)
return handlereset(c, m);
if(strcmp(member, "FocusIn") == 0
|| strcmp(member, "Destroy") == 0
|| strcmp(member, "SetCapabilities") == 0
|| strcmp(member, "SetCursorLocation") == 0
|| strcmp(member, "SetEngine") == 0)
return handlenoop(c, m);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static void
newconn(DBusServer *s, DBusConnection *c, void *_)
{
DBusObjectPathVTable vt;
USED(s);
USED(_);
if(nconns >= Maxconns)
return;
dbus_connection_ref(c);
dbus_connection_set_watch_functions(c, addwatch, removewatch, togglewatch, nil, nil);
memset(&vt, 0, sizeof(vt));
vt.message_function = onmsg;
dbus_connection_register_fallback(c, "/", &vt, nil);
conns[nconns++] = c;
}
static void
pruneconns(void)
{
int i, j;
j = 0;
for(i = 0; i < nconns; i++){
if(dbus_connection_get_is_connected(conns[i])){
conns[j++] = conns[i];
continue;
}
dbus_connection_unref(conns[i]);
}
nconns = j;
}
static int
ibusinit(void)
{
DBusError err;
char addr[128];
char *full;
if(buildaddrpath(addrfile, sizeof(addrfile)) < 0){
fprintf(stderr, "strans: ibus: cannot build address path\n");
return -1;
}
unlink(addrfile);
snprintf(addr, sizeof(addr), "unix:abstract=strans-%d", (int)getpid());
dbus_error_init(&err);
srv = dbus_server_listen(addr, &err);
if(srv == nil){
fprintf(stderr, "strans: ibus: listen: %s\n", err.message);
dbus_error_free(&err);
addrfile[0] = '\0';
return -1;
}
dbus_server_set_new_connection_function(srv, newconn, nil, nil);
dbus_server_set_watch_functions(srv, addwatch, removewatch, togglewatch, nil, nil);
full = dbus_server_get_address(srv);
if(writeaddr(addrfile, full) < 0){
fprintf(stderr, "strans: ibus: cannot write %s\n", addrfile);
dbus_free(full);
dbus_server_disconnect(srv);
dbus_server_unref(srv);
srv = nil;
addrfile[0] = '\0';
return -1;
}
dbus_free(full);
atexit(unlinkaddr);
return 0;
}
void
ibusthread(void *_)
{
struct pollfd pfds[Maxwatches];
int wi[Maxwatches];
int i, n, rv;
unsigned int f;
USED(_);
threadsetname("ibus");
if(ibusinit() < 0)
return;
for(;;){
n = 0;
for(i = 0; i < nwatches && n < Maxwatches; i++){
if(watches[i].w == nil)
continue;
if(!dbus_watch_get_enabled(watches[i].w))
continue;
pfds[n].fd = dbus_watch_get_unix_fd(watches[i].w);
pfds[n].events = 0;
f = dbus_watch_get_flags(watches[i].w);
if(f & DBUS_WATCH_READABLE) pfds[n].events |= POLLIN;
if(f & DBUS_WATCH_WRITABLE) pfds[n].events |= POLLOUT;
wi[n] = i;
n++;
}
rv = poll(pfds, n, 200);
if(rv < 0)
continue;
for(i = 0; i < n; i++){
if(pfds[i].revents == 0)
continue;
if(watches[wi[i]].w == nil)
continue;
f = 0;
if(pfds[i].revents & POLLIN) f |= DBUS_WATCH_READABLE;
if(pfds[i].revents & POLLOUT) f |= DBUS_WATCH_WRITABLE;
if(pfds[i].revents & POLLHUP) f |= DBUS_WATCH_HANGUP;
if(pfds[i].revents & POLLERR) f |= DBUS_WATCH_ERROR;
dbus_watch_handle(watches[wi[i]].w, f);
}
for(i = 0; i < nconns; i++)
while(dbus_connection_dispatch(conns[i]) == DBUS_DISPATCH_DATA_REMAINS)
;
pruneconns();
}
}

View File

@@ -1,955 +0,0 @@
/* Generated by wayland-scanner 1.21.0 */
#ifndef INPUT_METHOD_UNSTABLE_V2_CLIENT_PROTOCOL_H
#define INPUT_METHOD_UNSTABLE_V2_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_input_method_unstable_v2 The input_method_unstable_v2 protocol
* Protocol for creating input methods
*
* @section page_desc_input_method_unstable_v2 Description
*
* This protocol allows applications to act as input methods for compositors.
*
* An input method context is used to manage the state of the input method.
*
* Text strings are UTF-8 encoded, their indices and lengths are in bytes.
*
* This document adheres to the RFC 2119 when using words like "must",
* "should", "may", etc.
*
* Warning! The protocol described in this file is experimental and
* backward incompatible changes may be made. Backward compatible changes
* may be added together with the corresponding interface version bump.
* Backward incompatible changes are done by bumping the version number in
* the protocol and interface names and resetting the interface version.
* Once the protocol is to be declared stable, the 'z' prefix and the
* version number in the protocol and interface names are removed and the
* interface version number is reset.
*
* @section page_ifaces_input_method_unstable_v2 Interfaces
* - @subpage page_iface_zwp_input_method_v2 - input method
* - @subpage page_iface_zwp_input_popup_surface_v2 - popup surface
* - @subpage page_iface_zwp_input_method_keyboard_grab_v2 - keyboard grab
* - @subpage page_iface_zwp_input_method_manager_v2 - input method manager
* @section page_copyright_input_method_unstable_v2 Copyright
* <pre>
*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2011 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
* Copyright © 2012, 2013 Intel Corporation
* Copyright © 2015, 2016 Jan Arne Petersen
* Copyright © 2017, 2018 Red Hat, Inc.
* Copyright © 2018 Purism SPC
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </pre>
*/
struct wl_seat;
struct wl_surface;
struct zwp_input_method_keyboard_grab_v2;
struct zwp_input_method_manager_v2;
struct zwp_input_method_v2;
struct zwp_input_popup_surface_v2;
#ifndef ZWP_INPUT_METHOD_V2_INTERFACE
#define ZWP_INPUT_METHOD_V2_INTERFACE
/**
* @page page_iface_zwp_input_method_v2 zwp_input_method_v2
* @section page_iface_zwp_input_method_v2_desc Description
*
* An input method object allows for clients to compose text.
*
* The objects connects the client to a text input in an application, and
* lets the client to serve as an input method for a seat.
*
* The zwp_input_method_v2 object can occupy two distinct states: active and
* inactive. In the active state, the object is associated to and
* communicates with a text input. In the inactive state, there is no
* associated text input, and the only communication is with the compositor.
* Initially, the input method is in the inactive state.
*
* Requests issued in the inactive state must be accepted by the compositor.
* Because of the serial mechanism, and the state reset on activate event,
* they will not have any effect on the state of the next text input.
*
* There must be no more than one input method object per seat.
* @section page_iface_zwp_input_method_v2_api API
* See @ref iface_zwp_input_method_v2.
*/
/**
* @defgroup iface_zwp_input_method_v2 The zwp_input_method_v2 interface
*
* An input method object allows for clients to compose text.
*
* The objects connects the client to a text input in an application, and
* lets the client to serve as an input method for a seat.
*
* The zwp_input_method_v2 object can occupy two distinct states: active and
* inactive. In the active state, the object is associated to and
* communicates with a text input. In the inactive state, there is no
* associated text input, and the only communication is with the compositor.
* Initially, the input method is in the inactive state.
*
* Requests issued in the inactive state must be accepted by the compositor.
* Because of the serial mechanism, and the state reset on activate event,
* they will not have any effect on the state of the next text input.
*
* There must be no more than one input method object per seat.
*/
extern const struct wl_interface zwp_input_method_v2_interface;
#endif
#ifndef ZWP_INPUT_POPUP_SURFACE_V2_INTERFACE
#define ZWP_INPUT_POPUP_SURFACE_V2_INTERFACE
/**
* @page page_iface_zwp_input_popup_surface_v2 zwp_input_popup_surface_v2
* @section page_iface_zwp_input_popup_surface_v2_desc Description
*
* This interface marks a surface as a popup for interacting with an input
* method.
*
* The compositor should place it near the active text input area. It must
* be visible if and only if the input method is in the active state.
*
* The client must not destroy the underlying wl_surface while the
* zwp_input_popup_surface_v2 object exists.
* @section page_iface_zwp_input_popup_surface_v2_api API
* See @ref iface_zwp_input_popup_surface_v2.
*/
/**
* @defgroup iface_zwp_input_popup_surface_v2 The zwp_input_popup_surface_v2 interface
*
* This interface marks a surface as a popup for interacting with an input
* method.
*
* The compositor should place it near the active text input area. It must
* be visible if and only if the input method is in the active state.
*
* The client must not destroy the underlying wl_surface while the
* zwp_input_popup_surface_v2 object exists.
*/
extern const struct wl_interface zwp_input_popup_surface_v2_interface;
#endif
#ifndef ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_INTERFACE
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_INTERFACE
/**
* @page page_iface_zwp_input_method_keyboard_grab_v2 zwp_input_method_keyboard_grab_v2
* @section page_iface_zwp_input_method_keyboard_grab_v2_desc Description
*
* The zwp_input_method_keyboard_grab_v2 interface represents an exclusive
* grab of the wl_keyboard interface associated with the seat.
* @section page_iface_zwp_input_method_keyboard_grab_v2_api API
* See @ref iface_zwp_input_method_keyboard_grab_v2.
*/
/**
* @defgroup iface_zwp_input_method_keyboard_grab_v2 The zwp_input_method_keyboard_grab_v2 interface
*
* The zwp_input_method_keyboard_grab_v2 interface represents an exclusive
* grab of the wl_keyboard interface associated with the seat.
*/
extern const struct wl_interface zwp_input_method_keyboard_grab_v2_interface;
#endif
#ifndef ZWP_INPUT_METHOD_MANAGER_V2_INTERFACE
#define ZWP_INPUT_METHOD_MANAGER_V2_INTERFACE
/**
* @page page_iface_zwp_input_method_manager_v2 zwp_input_method_manager_v2
* @section page_iface_zwp_input_method_manager_v2_desc Description
*
* The input method manager allows the client to become the input method on
* a chosen seat.
*
* No more than one input method must be associated with any seat at any
* given time.
* @section page_iface_zwp_input_method_manager_v2_api API
* See @ref iface_zwp_input_method_manager_v2.
*/
/**
* @defgroup iface_zwp_input_method_manager_v2 The zwp_input_method_manager_v2 interface
*
* The input method manager allows the client to become the input method on
* a chosen seat.
*
* No more than one input method must be associated with any seat at any
* given time.
*/
extern const struct wl_interface zwp_input_method_manager_v2_interface;
#endif
#ifndef ZWP_INPUT_METHOD_V2_ERROR_ENUM
#define ZWP_INPUT_METHOD_V2_ERROR_ENUM
enum zwp_input_method_v2_error {
/**
* wl_surface has another role
*/
ZWP_INPUT_METHOD_V2_ERROR_ROLE = 0,
};
#endif /* ZWP_INPUT_METHOD_V2_ERROR_ENUM */
/**
* @ingroup iface_zwp_input_method_v2
* @struct zwp_input_method_v2_listener
*/
struct zwp_input_method_v2_listener {
/**
* input method has been requested
*
* Notification that a text input focused on this seat requested
* the input method to be activated.
*
* This event serves the purpose of providing the compositor with
* an active input method.
*
* This event resets all state associated with previous
* surrounding_text, text_change_cause, and content_type events, as
* well as the state associated with set_preedit_string,
* commit_string, and delete_surrounding_text requests. In
* addition, it marks the zwp_input_method_v2 object as active, and
* makes any existing zwp_input_popup_surface_v2 objects visible.
*
* The surrounding_text, and content_type events must follow before
* the next done event if the text input supports the respective
* functionality.
*
* State set with this event is double-buffered. It will get
* applied on the next zwp_input_method_v2.done event, and stay
* valid until changed.
*/
void (*activate)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2);
/**
* deactivate event
*
* Notification that no focused text input currently needs an
* active input method on this seat.
*
* This event marks the zwp_input_method_v2 object as inactive. The
* compositor must make all existing zwp_input_popup_surface_v2
* objects invisible until the next activate event.
*
* State set with this event is double-buffered. It will get
* applied on the next zwp_input_method_v2.done event, and stay
* valid until changed.
*/
void (*deactivate)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2);
/**
* surrounding text event
*
* Updates the surrounding plain text around the cursor,
* excluding the preedit text.
*
* If any preedit text is present, it is replaced with the cursor
* for the purpose of this event.
*
* The argument text is a buffer containing the surrounding text,
* and must include the cursor position, and the complete
* selection. It should contain additional characters before and
* after these. There is a maximum length of wayland messages, so
* text can not be longer than 4000 bytes.
*
* cursor is the byte offset of the cursor within the text buffer.
*
* anchor is the byte offset of the selection anchor within the
* text buffer. If there is no selected text, anchor must be the
* same as cursor.
*
* If this event does not arrive before the first done event, the
* input method may assume that the text input does not support
* this functionality and ignore following surrounding_text events.
*
* Values set with this event are double-buffered. They will get
* applied and set to initial values on the next
* zwp_input_method_v2.done event.
*
* The initial state for affected fields is empty, meaning that the
* text input does not support sending surrounding text. If the
* empty values get applied, subsequent attempts to change them may
* have no effect.
*/
void (*surrounding_text)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2,
const char *text,
uint32_t cursor,
uint32_t anchor);
/**
* indicates the cause of surrounding text change
*
* Tells the input method why the text surrounding the cursor
* changed.
*
* Whenever the client detects an external change in text, cursor,
* or anchor position, it must issue this request to the
* compositor. This request is intended to give the input method a
* chance to update the preedit text in an appropriate way, e.g. by
* removing it when the user starts typing with a keyboard.
*
* cause describes the source of the change.
*
* The value set with this event is double-buffered. It will get
* applied and set to its initial value on the next
* zwp_input_method_v2.done event.
*
* The initial value of cause is input_method.
*/
void (*text_change_cause)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2,
uint32_t cause);
/**
* content purpose and hint
*
* Indicates the content type and hint for the current
* zwp_input_method_v2 instance.
*
* Values set with this event are double-buffered. They will get
* applied on the next zwp_input_method_v2.done event.
*
* The initial value for hint is none, and the initial value for
* purpose is normal.
*/
void (*content_type)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2,
uint32_t hint,
uint32_t purpose);
/**
* apply state
*
* Atomically applies state changes recently sent to the client.
*
* The done event establishes and updates the state of the client,
* and must be issued after any changes to apply them.
*
* Text input state (content purpose, content hint, surrounding
* text, and change cause) is conceptually double-buffered within
* an input method context.
*
* Events modify the pending state, as opposed to the current state
* in use by the input method. A done event atomically applies all
* pending state, replacing the current state. After done, the new
* pending state is as documented for each related request.
*
* Events must be applied in the order of arrival.
*
* Neither current nor pending state are modified unless noted
* otherwise.
*/
void (*done)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2);
/**
* input method unavailable
*
* The input method ceased to be available.
*
* The compositor must issue this event as the only event on the
* object if there was another input_method object associated with
* the same seat at the time of its creation.
*
* The compositor must issue this request when the object is no
* longer usable, e.g. due to seat removal.
*
* The input method context becomes inert and should be destroyed
* after deactivation is handled. Any further requests and events
* except for the destroy request must be ignored.
*/
void (*unavailable)(void *data,
struct zwp_input_method_v2 *zwp_input_method_v2);
};
/**
* @ingroup iface_zwp_input_method_v2
*/
static inline int
zwp_input_method_v2_add_listener(struct zwp_input_method_v2 *zwp_input_method_v2,
const struct zwp_input_method_v2_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_input_method_v2,
(void (**)(void)) listener, data);
}
#define ZWP_INPUT_METHOD_V2_COMMIT_STRING 0
#define ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING 1
#define ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT 2
#define ZWP_INPUT_METHOD_V2_COMMIT 3
#define ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE 4
#define ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD 5
#define ZWP_INPUT_METHOD_V2_DESTROY 6
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_ACTIVATE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_DEACTIVATE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_SURROUNDING_TEXT_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_TEXT_CHANGE_CAUSE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_CONTENT_TYPE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_DONE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_UNAVAILABLE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_COMMIT_STRING_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_COMMIT_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_v2
*/
#define ZWP_INPUT_METHOD_V2_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_input_method_v2 */
static inline void
zwp_input_method_v2_set_user_data(struct zwp_input_method_v2 *zwp_input_method_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_v2, user_data);
}
/** @ingroup iface_zwp_input_method_v2 */
static inline void *
zwp_input_method_v2_get_user_data(struct zwp_input_method_v2 *zwp_input_method_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_v2);
}
static inline uint32_t
zwp_input_method_v2_get_version(struct zwp_input_method_v2 *zwp_input_method_v2)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2);
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Send the commit string text for insertion to the application.
*
* Inserts a string at current cursor position (see commit event
* sequence). The string to commit could be either just a single character
* after a key press or the result of some composing.
*
* The argument text is a buffer containing the string to insert. There is
* a maximum length of wayland messages, so text can not be longer than
* 4000 bytes.
*
* Values set with this event are double-buffered. They must be applied
* and reset to initial on the next zwp_text_input_v3.commit request.
*
* The initial value of text is an empty string.
*/
static inline void
zwp_input_method_v2_commit_string(struct zwp_input_method_v2 *zwp_input_method_v2, const char *text)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_COMMIT_STRING, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, text);
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Send the pre-edit string text to the application text input.
*
* Place a new composing text (pre-edit) at the current cursor position.
* Any previously set composing text must be removed. Any previously
* existing selected text must be removed. The cursor is moved to a new
* position within the preedit string.
*
* The argument text is a buffer containing the preedit string. There is
* a maximum length of wayland messages, so text can not be longer than
* 4000 bytes.
*
* The arguments cursor_begin and cursor_end are counted in bytes relative
* to the beginning of the submitted string buffer. Cursor should be
* hidden by the text input when both are equal to -1.
*
* cursor_begin indicates the beginning of the cursor. cursor_end
* indicates the end of the cursor. It may be equal or different than
* cursor_begin.
*
* Values set with this event are double-buffered. They must be applied on
* the next zwp_input_method_v2.commit event.
*
* The initial value of text is an empty string. The initial value of
* cursor_begin, and cursor_end are both 0.
*/
static inline void
zwp_input_method_v2_set_preedit_string(struct zwp_input_method_v2 *zwp_input_method_v2, const char *text, int32_t cursor_begin, int32_t cursor_end)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_SET_PREEDIT_STRING, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, text, cursor_begin, cursor_end);
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Remove the surrounding text.
*
* before_length and after_length are the number of bytes before and after
* the current cursor index (excluding the preedit text) to delete.
*
* If any preedit text is present, it is replaced with the cursor for the
* purpose of this event. In effect before_length is counted from the
* beginning of preedit text, and after_length from its end (see commit
* event sequence).
*
* Values set with this event are double-buffered. They must be applied
* and reset to initial on the next zwp_input_method_v2.commit request.
*
* The initial values of both before_length and after_length are 0.
*/
static inline void
zwp_input_method_v2_delete_surrounding_text(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t before_length, uint32_t after_length)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_DELETE_SURROUNDING_TEXT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, before_length, after_length);
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Apply state changes from commit_string, set_preedit_string and
* delete_surrounding_text requests.
*
* The state relating to these events is double-buffered, and each one
* modifies the pending state. This request replaces the current state
* with the pending state.
*
* The connected text input is expected to proceed by evaluating the
* changes in the following order:
*
* 1. Replace existing preedit string with the cursor.
* 2. Delete requested surrounding text.
* 3. Insert commit string with the cursor at its end.
* 4. Calculate surrounding text to send.
* 5. Insert new preedit text in cursor position.
* 6. Place cursor inside preedit text.
*
* The serial number reflects the last state of the zwp_input_method_v2
* object known to the client. The value of the serial argument must be
* equal to the number of done events already issued by that object. When
* the compositor receives a commit request with a serial different than
* the number of past done events, it must proceed as normal, except it
* should not change the current state of the zwp_input_method_v2 object.
*/
static inline void
zwp_input_method_v2_commit(struct zwp_input_method_v2 *zwp_input_method_v2, uint32_t serial)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_COMMIT, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, serial);
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Creates a new zwp_input_popup_surface_v2 object wrapping a given
* surface.
*
* The surface gets assigned the "input_popup" role. If the surface
* already has an assigned role, the compositor must issue a protocol
* error.
*/
static inline struct zwp_input_popup_surface_v2 *
zwp_input_method_v2_get_input_popup_surface(struct zwp_input_method_v2 *zwp_input_method_v2, struct wl_surface *surface)
{
struct wl_proxy *id;
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_GET_INPUT_POPUP_SURFACE, &zwp_input_popup_surface_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, NULL, surface);
return (struct zwp_input_popup_surface_v2 *) id;
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Allow an input method to receive hardware keyboard input and process
* key events to generate text events (with pre-edit) over the wire. This
* allows input methods which compose multiple key events for inputting
* text like it is done for CJK languages.
*
* The compositor should send all keyboard events on the seat to the grab
* holder via the returned wl_keyboard object. Nevertheless, the
* compositor may decide not to forward any particular event. The
* compositor must not further process any event after it has been
* forwarded to the grab holder.
*
* Releasing the resulting wl_keyboard object releases the grab.
*/
static inline struct zwp_input_method_keyboard_grab_v2 *
zwp_input_method_v2_grab_keyboard(struct zwp_input_method_v2 *zwp_input_method_v2)
{
struct wl_proxy *keyboard;
keyboard = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_GRAB_KEYBOARD, &zwp_input_method_keyboard_grab_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), 0, NULL);
return (struct zwp_input_method_keyboard_grab_v2 *) keyboard;
}
/**
* @ingroup iface_zwp_input_method_v2
*
* Destroys the zwp_text_input_v2 object and any associated child
* objects, i.e. zwp_input_popup_surface_v2 and
* zwp_input_method_keyboard_grab_v2.
*/
static inline void
zwp_input_method_v2_destroy(struct zwp_input_method_v2 *zwp_input_method_v2)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_v2,
ZWP_INPUT_METHOD_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_v2), WL_MARSHAL_FLAG_DESTROY);
}
/**
* @ingroup iface_zwp_input_popup_surface_v2
* @struct zwp_input_popup_surface_v2_listener
*/
struct zwp_input_popup_surface_v2_listener {
/**
* set text input area position
*
* Notify about the position of the area of the text input
* expressed as a rectangle in surface local coordinates.
*
* This is a hint to the input method telling it the relative
* position of the text being entered.
*/
void (*text_input_rectangle)(void *data,
struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2,
int32_t x,
int32_t y,
int32_t width,
int32_t height);
};
/**
* @ingroup iface_zwp_input_popup_surface_v2
*/
static inline int
zwp_input_popup_surface_v2_add_listener(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2,
const struct zwp_input_popup_surface_v2_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_input_popup_surface_v2,
(void (**)(void)) listener, data);
}
#define ZWP_INPUT_POPUP_SURFACE_V2_DESTROY 0
/**
* @ingroup iface_zwp_input_popup_surface_v2
*/
#define ZWP_INPUT_POPUP_SURFACE_V2_TEXT_INPUT_RECTANGLE_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_popup_surface_v2
*/
#define ZWP_INPUT_POPUP_SURFACE_V2_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_input_popup_surface_v2 */
static inline void
zwp_input_popup_surface_v2_set_user_data(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_input_popup_surface_v2, user_data);
}
/** @ingroup iface_zwp_input_popup_surface_v2 */
static inline void *
zwp_input_popup_surface_v2_get_user_data(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_popup_surface_v2);
}
static inline uint32_t
zwp_input_popup_surface_v2_get_version(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_input_popup_surface_v2);
}
/**
* @ingroup iface_zwp_input_popup_surface_v2
*/
static inline void
zwp_input_popup_surface_v2_destroy(struct zwp_input_popup_surface_v2 *zwp_input_popup_surface_v2)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_popup_surface_v2,
ZWP_INPUT_POPUP_SURFACE_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_popup_surface_v2), WL_MARSHAL_FLAG_DESTROY);
}
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
* @struct zwp_input_method_keyboard_grab_v2_listener
*/
struct zwp_input_method_keyboard_grab_v2_listener {
/**
* keyboard mapping
*
* This event provides a file descriptor to the client which can
* be memory-mapped to provide a keyboard mapping description.
* @param format keymap format
* @param fd keymap file descriptor
* @param size keymap size, in bytes
*/
void (*keymap)(void *data,
struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2,
uint32_t format,
int32_t fd,
uint32_t size);
/**
* key event
*
* A key was pressed or released. The time argument is a
* timestamp with millisecond granularity, with an undefined base.
* @param serial serial number of the key event
* @param time timestamp with millisecond granularity
* @param key key that produced the event
* @param state physical state of the key
*/
void (*key)(void *data,
struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2,
uint32_t serial,
uint32_t time,
uint32_t key,
uint32_t state);
/**
* modifier and group state
*
* Notifies clients that the modifier and/or group state has
* changed, and it should update its local state.
* @param serial serial number of the modifiers event
* @param mods_depressed depressed modifiers
* @param mods_latched latched modifiers
* @param mods_locked locked modifiers
* @param group keyboard layout
*/
void (*modifiers)(void *data,
struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2,
uint32_t serial,
uint32_t mods_depressed,
uint32_t mods_latched,
uint32_t mods_locked,
uint32_t group);
/**
* repeat rate and delay
*
* Informs the client about the keyboard's repeat rate and delay.
*
* This event is sent as soon as the
* zwp_input_method_keyboard_grab_v2 object has been created, and
* is guaranteed to be received by the client before any key press
* event.
*
* Negative values for either rate or delay are illegal. A rate of
* zero will disable any repeating (regardless of the value of
* delay).
*
* This event can be sent later on as well with a new value if
* necessary, so clients should continue listening for the event
* past the creation of zwp_input_method_keyboard_grab_v2.
* @param rate the rate of repeating keys in characters per second
* @param delay delay in milliseconds since key down until repeating starts
*/
void (*repeat_info)(void *data,
struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2,
int32_t rate,
int32_t delay);
};
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
static inline int
zwp_input_method_keyboard_grab_v2_add_listener(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2,
const struct zwp_input_method_keyboard_grab_v2_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) zwp_input_method_keyboard_grab_v2,
(void (**)(void)) listener, data);
}
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE 0
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_KEYMAP_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_KEY_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_MODIFIERS_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_REPEAT_INFO_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
#define ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE_SINCE_VERSION 1
/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */
static inline void
zwp_input_method_keyboard_grab_v2_set_user_data(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_keyboard_grab_v2, user_data);
}
/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */
static inline void *
zwp_input_method_keyboard_grab_v2_get_user_data(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_keyboard_grab_v2);
}
static inline uint32_t
zwp_input_method_keyboard_grab_v2_get_version(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_keyboard_grab_v2);
}
/** @ingroup iface_zwp_input_method_keyboard_grab_v2 */
static inline void
zwp_input_method_keyboard_grab_v2_destroy(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2)
{
wl_proxy_destroy((struct wl_proxy *) zwp_input_method_keyboard_grab_v2);
}
/**
* @ingroup iface_zwp_input_method_keyboard_grab_v2
*/
static inline void
zwp_input_method_keyboard_grab_v2_release(struct zwp_input_method_keyboard_grab_v2 *zwp_input_method_keyboard_grab_v2)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_keyboard_grab_v2,
ZWP_INPUT_METHOD_KEYBOARD_GRAB_V2_RELEASE, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_keyboard_grab_v2), WL_MARSHAL_FLAG_DESTROY);
}
#define ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD 0
#define ZWP_INPUT_METHOD_MANAGER_V2_DESTROY 1
/**
* @ingroup iface_zwp_input_method_manager_v2
*/
#define ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD_SINCE_VERSION 1
/**
* @ingroup iface_zwp_input_method_manager_v2
*/
#define ZWP_INPUT_METHOD_MANAGER_V2_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_input_method_manager_v2 */
static inline void
zwp_input_method_manager_v2_set_user_data(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_input_method_manager_v2, user_data);
}
/** @ingroup iface_zwp_input_method_manager_v2 */
static inline void *
zwp_input_method_manager_v2_get_user_data(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_input_method_manager_v2);
}
static inline uint32_t
zwp_input_method_manager_v2_get_version(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2);
}
/**
* @ingroup iface_zwp_input_method_manager_v2
*
* Request a new input zwp_input_method_v2 object associated with a given
* seat.
*/
static inline struct zwp_input_method_v2 *
zwp_input_method_manager_v2_get_input_method(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2, struct wl_seat *seat)
{
struct wl_proxy *input_method;
input_method = wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_manager_v2,
ZWP_INPUT_METHOD_MANAGER_V2_GET_INPUT_METHOD, &zwp_input_method_v2_interface, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2), 0, seat, NULL);
return (struct zwp_input_method_v2 *) input_method;
}
/**
* @ingroup iface_zwp_input_method_manager_v2
*
* Destroys the zwp_input_method_manager_v2 object.
*
* The zwp_input_method_v2 objects originating from it remain valid.
*/
static inline void
zwp_input_method_manager_v2_destroy(struct zwp_input_method_manager_v2 *zwp_input_method_manager_v2)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_input_method_manager_v2,
ZWP_INPUT_METHOD_MANAGER_V2_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_input_method_manager_v2), WL_MARSHAL_FLAG_DESTROY);
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,132 +0,0 @@
/* Generated by wayland-scanner 1.21.0 */
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2011 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
* Copyright © 2012, 2013 Intel Corporation
* Copyright © 2015, 2016 Jan Arne Petersen
* Copyright © 2017, 2018 Red Hat, Inc.
* Copyright © 2018 Purism SPC
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface zwp_input_method_keyboard_grab_v2_interface;
extern const struct wl_interface zwp_input_method_v2_interface;
extern const struct wl_interface zwp_input_popup_surface_v2_interface;
static const struct wl_interface *input_method_unstable_v2_types[] = {
NULL,
NULL,
NULL,
NULL,
NULL,
&zwp_input_popup_surface_v2_interface,
&wl_surface_interface,
&zwp_input_method_keyboard_grab_v2_interface,
&wl_seat_interface,
&zwp_input_method_v2_interface,
};
static const struct wl_message zwp_input_method_v2_requests[] = {
{ "commit_string", "s", input_method_unstable_v2_types + 0 },
{ "set_preedit_string", "sii", input_method_unstable_v2_types + 0 },
{ "delete_surrounding_text", "uu", input_method_unstable_v2_types + 0 },
{ "commit", "u", input_method_unstable_v2_types + 0 },
{ "get_input_popup_surface", "no", input_method_unstable_v2_types + 5 },
{ "grab_keyboard", "n", input_method_unstable_v2_types + 7 },
{ "destroy", "", input_method_unstable_v2_types + 0 },
};
static const struct wl_message zwp_input_method_v2_events[] = {
{ "activate", "", input_method_unstable_v2_types + 0 },
{ "deactivate", "", input_method_unstable_v2_types + 0 },
{ "surrounding_text", "suu", input_method_unstable_v2_types + 0 },
{ "text_change_cause", "u", input_method_unstable_v2_types + 0 },
{ "content_type", "uu", input_method_unstable_v2_types + 0 },
{ "done", "", input_method_unstable_v2_types + 0 },
{ "unavailable", "", input_method_unstable_v2_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_input_method_v2_interface = {
"zwp_input_method_v2", 1,
7, zwp_input_method_v2_requests,
7, zwp_input_method_v2_events,
};
static const struct wl_message zwp_input_popup_surface_v2_requests[] = {
{ "destroy", "", input_method_unstable_v2_types + 0 },
};
static const struct wl_message zwp_input_popup_surface_v2_events[] = {
{ "text_input_rectangle", "iiii", input_method_unstable_v2_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_input_popup_surface_v2_interface = {
"zwp_input_popup_surface_v2", 1,
1, zwp_input_popup_surface_v2_requests,
1, zwp_input_popup_surface_v2_events,
};
static const struct wl_message zwp_input_method_keyboard_grab_v2_requests[] = {
{ "release", "", input_method_unstable_v2_types + 0 },
};
static const struct wl_message zwp_input_method_keyboard_grab_v2_events[] = {
{ "keymap", "uhu", input_method_unstable_v2_types + 0 },
{ "key", "uuuu", input_method_unstable_v2_types + 0 },
{ "modifiers", "uuuuu", input_method_unstable_v2_types + 0 },
{ "repeat_info", "ii", input_method_unstable_v2_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_input_method_keyboard_grab_v2_interface = {
"zwp_input_method_keyboard_grab_v2", 1,
1, zwp_input_method_keyboard_grab_v2_requests,
4, zwp_input_method_keyboard_grab_v2_events,
};
static const struct wl_message zwp_input_method_manager_v2_requests[] = {
{ "get_input_method", "on", input_method_unstable_v2_types + 8 },
{ "destroy", "", input_method_unstable_v2_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_input_method_manager_v2_interface = {
"zwp_input_method_manager_v2", 1,
2, zwp_input_method_manager_v2_requests,
0, NULL,
};

1
ko.c
View File

@@ -203,6 +203,7 @@ transko(Im *im, Rune c)
e.s = im->pre;
sclear(&im->pre);
}
sputr(&e.s, c);
return e;
}

2
main.c
View File

@@ -69,8 +69,6 @@ threadmain(int argc, char **argv)
dictinit(argv[1]);
proccreate(drawthread, nil, 16384);
proccreate(srvthread, nil, 16384);
proccreate(ibusthread, nil, 32768);
proccreate(waylandthread, nil, 32768);
threadcreate(dictthread, nil, 16384);
threadcreate(imthread, nil, 16384);

View File

@@ -0,0 +1,179 @@
! ⚠ ≠
!! ⚠
!= ≠
* ★
** ★
+ ±
+- ±
- →
-> →
. · … ÷
.. · …
... …
./ ÷
: ☹ ☺
:( ☹
:) ☺
< ← ≤ ≠ ♥
<- ←
<= ≤
<> ≠
= ≡ ⇒
== ≡
=> ⇒
> ≥
>= ≥
^ ⁽ ⁾ ⁺ ⁻ ⁼ ⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹ ⁱ ⁿ
^( ⁽
^) ⁾
^+ ⁺
^- ⁻
^= ⁼
_ ₍ ₎ ₊ ₋ ₌ ₀ ₁ ₂ ₃ ₄ ₅ ₆ ₇ ₈ ₉ ₐ ₑ ₒ ₓ
_( ₍
_) ₎
_+ ₊
_- ₋
_= ₌
~ ≈
~= ≈
^0 ⁰
_0 ₀
^1 ¹
_1 ₁
^2 ²
_2 ₂
<3 ♥
^3 ³
_3 ₃
^4 ⁴
_4 ₄
^5 ⁵
_5 ₅
^6 ⁶
_6 ₆
^7 ⁷
_7 ₇
^8 ⁸
_8 ₈
^9 ⁹
_9 ₉
_a ₐ
a α
al α
alp α
alph α
alpha α
b β
be β
bet β
beta β
c χ
ch χ
chi χ
d ° δ ↓
D Δ
de ° δ
De Δ
deg °
del δ
delt δ
delta δ
dn ↓
_e ₑ
e ε η
ep ε
eps ε
et η
eta η
g γ
G Γ
ga γ
Ga Γ
gam γ
gamm γ
gamma γ
^i ⁱ
i ∞ ι
I ∫
II ∫
in ∞
inf ∞
io ι
iot ι
iota ι
k κ
ka κ
kap κ
kapp κ
kappa κ
l λ
L Λ
la λ
La Λ
lam λ
lamb λ
lambd λ
lambda λ
m × μ
mu × μ
mul ×
^n ⁿ
n ν
nu ν
_o ₒ
o ω ●
O Ω
om ω
Om Ω
ome ω
omeg ω
omega ω
oo ●
p φ π ψ
P Φ Π ∏ Ψ
ph φ
Ph Φ
phi φ
pi π
Pi Π
PP ∏
ps ψ
Ps Ψ
psi ψ
r ρ
rh ρ
rho ρ
s σ
S Σ ∑
si σ
Si Σ
sig σ
sigm σ
sigma σ
sq √
SS ∑
t τ θ
T Θ
ta τ
tau τ
th θ
Th Θ
the θ
thet θ
theta θ
u ↑ υ
up ↑ υ
ups υ
v ✓
vv ✓
_x ₓ
x ξ ✗
X Ξ
xi ξ
Xi Ξ
xx ✗
z ζ
ze ζ
zet ζ
zeta ζ

View File

@@ -16,7 +16,6 @@
:) ☺
< <
<- ←
<3 ♥
<= ≤
<> ≠
= =
@@ -24,66 +23,42 @@
=> ⇒
> >
>= ≥
D D
De Δ
G G
Ga Γ
I I
II ∫
L L
La Λ
O O
Om Ω
P P
PP ∏
Ph Φ
Pi Π
Ps Ψ
S S
SS ∑
Si Σ
T T
Th Θ
X X
Xi Ξ
^ ^
^( ⁽
^) ⁾
^+ ⁺
^- ⁻
^0 ⁰
^1 ¹
^2 ²
^3 ³
^4 ⁴
^5 ⁵
^6 ⁶
^7 ⁷
^8 ⁸
^9 ⁹
^= ⁼
^i ⁱ
^n ⁿ
_ _
_( ₍
_) ₎
_+ ₊
_- ₋
_0 ₀
_1 ₁
_2 ₂
_3 ₃
_4 ₄
_5 ₅
_6 ₆
_7 ₇
_8 ₈
_9 ₉
_= ₌
~ ~
~= ≈
^0 ⁰
_0 ₀
^1 ¹
_1 ₁
^2 ²
_2 ₂
<3 ♥
^3 ³
_3 ₃
^4 ⁴
_4 ₄
^5 ⁵
_5 ₅
^6 ⁶
_6 ₆
^7 ⁷
_7 ₇
^8 ⁸
_8 ₈
^9 ⁹
_9 ₉
_a ₐ
_e ₑ
_o ₒ
_x ₓ
a a
al al
alp alp
@@ -97,27 +72,31 @@ c c
ch ch
chi χ
d d
D D
de de
De Δ
deg °
del del
delt delt
delta δ
dn ↓
_e ₑ
e e
ep ep
eps ε
et et
eta η
f f
fu fu
fuc fuc
fuck 凸
g g
G G
ga ga
Ga Γ
gam gam
gamm gamm
gamma γ
^i ⁱ
i i
I I
II ∫
in in
inf ∞
io io
@@ -129,7 +108,9 @@ kap kap
kapp kapp
kappa κ
l l
L L
la la
La Λ
lam lam
lamb lamb
lambd lambd
@@ -137,33 +118,47 @@ lambda λ
m m
mu μ
mul ×
^n ⁿ
n n
nu ν
_o ₒ
o o
O O
om om
Om Ω
ome ome
omeg omeg
omega ω
oo ●
p p
P P
ph ph
Ph Φ
phi φ
pi π
Pi Π
PP ∏
ps ps
Ps Ψ
psi ψ
r r
rh rh
rho ρ
s s
S S
si si
Si Σ
sig sig
sigm sigm
sigma σ
sq √
SS ∑
t t
T T
ta ta
tau τ
th th
Th Θ
the the
thet thet
theta θ
@@ -172,12 +167,13 @@ up ↑
ups υ
v v
vv ✓
_x ₓ
x x
X X
xi ξ
Xi Ξ
xx ✗
z z
ze ze
zet zet
zeta ζ
~ ~
~= ≈

View File

@@ -57,7 +57,6 @@ dn ↓
_e ₑ
eps ε
eta η
fuck 凸
gamma γ
Ga Γ
^i ⁱ

View File

@@ -31,10 +31,7 @@ upper = str.maketrans(
def addtone(v, t):
return v.translate(tone[t])
entries = []
def emit(input, output):
entries.append((input, output))
print(f"{input}\t{output}")
def up(s):
c = s[0].translate(upper)
@@ -150,24 +147,6 @@ def final():
for t in tone:
emit(i+c+t, o.replace(v, addtone(v, t), 1)+c)
def onsets():
# Keep the qu-/gi- onset in the preedit so the tone lands on the rime
# nucleus, not on the onset glide (qua->quá not qúa, gia->giá not gía).
# transvi (onsetglide) knows to skip the glide; here we only need the
# composed clusters to exist so the preedit accumulates them.
vowels = set("aeiouy")
tones = set("sfrxj")
base = [(i, o) for (i, o) in list(entries)
if i and i[0] in vowels and not (set(i) & tones)]
for i, o in base:
if i[0] != 'u': # no qu+u syllable; u is the glide
emit("qu" + i, "qu" + o)
emit("gi" + i, "gi" + o)
# gi- with the i as nucleus (no following vowel): gì, gìn, gìm, ...
for c in ["", "c", "m", "n", "p", "t", "ch", "ng", "nh"]:
if c:
emit("gi" + c, "gi" + c)
vowel1()
vowel2()
vowel3()
@@ -178,4 +157,3 @@ tone1mod()
tone2mod()
escape()
final()
onsets()

View File

@@ -587,903 +587,3 @@ Yt Yt
y y
Y Y
\ \
qua qua
Qua Qua
gia gia
Gia Gia
quaa quâ
Quaa Quâ
giaa giâ
Giaa Giâ
quaaa quaa
Quaaa Quaa
giaaa giaa
Giaaa Giaa
quaac quâc
Quaac Quâc
giaac giâc
Giaac Giâc
quaach quâch
Quaach Quâch
giaach giâch
Giaach Giâch
quaam quâm
Quaam Quâm
giaam giâm
Giaam Giâm
quaan quân
Quaan Quân
giaan giân
Giaan Giân
quaang quâng
Quaang Quâng
giaang giâng
Giaang Giâng
quaanh quânh
Quaanh Quânh
giaanh giânh
Giaanh Giânh
quaap quâp
Quaap Quâp
giaap giâp
Giaap Giâp
quaat quât
Quaat Quât
giaat giât
Giaat Giât
quac quac
Quac Quac
giac giac
Giac Giac
quach quach
Quach Quach
giach giach
Giach Giach
quai quai
Quai Quai
giai giai
Giai Giai
quaic quaic
Quaic Quaic
giaic giaic
Giaic Giaic
quaich quaich
Quaich Quaich
giaich giaich
Giaich Giaich
quaim quaim
Quaim Quaim
giaim giaim
Giaim Giaim
quain quain
Quain Quain
giain giain
Giain Giain
quaing quaing
Quaing Quaing
giaing giaing
Giaing Giaing
quainh quainh
Quainh Quainh
giainh giainh
Giainh Giainh
quaip quaip
Quaip Quaip
giaip giaip
Giaip Giaip
quait quait
Quait Quait
giait giait
Giait Giait
quam quam
Quam Quam
giam giam
Giam Giam
quan quan
Quan Quan
gian gian
Gian Gian
quang quang
Quang Quang
giang giang
Giang Giang
quanh quanh
Quanh Quanh
gianh gianh
Gianh Gianh
quao quao
Quao Quao
giao giao
Giao Giao
quaoc quaoc
Quaoc Quaoc
giaoc giaoc
Giaoc Giaoc
quaoch quaoch
Quaoch Quaoch
giaoch giaoch
Giaoch Giaoch
quaom quaom
Quaom Quaom
giaom giaom
Giaom Giaom
quaon quaon
Quaon Quaon
giaon giaon
Giaon Giaon
quaong quaong
Quaong Quaong
giaong giaong
Giaong Giaong
quaonh quaonh
Quaonh Quaonh
giaonh giaonh
Giaonh Giaonh
quaop quaop
Quaop Quaop
giaop giaop
Giaop Giaop
quaot quaot
Quaot Quaot
giaot giaot
Giaot Giaot
quap quap
Quap Quap
giap giap
Giap Giap
quat quat
Quat Quat
giat giat
Giat Giat
quau quau
Quau Quau
giau giau
Giau Giau
quauc quauc
Quauc Quauc
giauc giauc
Giauc Giauc
quauch quauch
Quauch Quauch
giauch giauch
Giauch Giauch
quaum quaum
Quaum Quaum
giaum giaum
Giaum Giaum
quaun quaun
Quaun Quaun
giaun giaun
Giaun Giaun
quaung quaung
Quaung Quaung
giaung giaung
Giaung Giaung
quaunh quaunh
Quaunh Quaunh
giaunh giaunh
Giaunh Giaunh
quaup quaup
Quaup Quaup
giaup giaup
Giaup Giaup
quaut quaut
Quaut Quaut
giaut giaut
Giaut Giaut
quaw quă
Quaw Quă
giaw giă
Giaw Giă
quawc quăc
Quawc Quăc
giawc giăc
Giawc Giăc
quawch quăch
Quawch Quăch
giawch giăch
Giawch Giăch
quawm quăm
Quawm Quăm
giawm giăm
Giawm Giăm
quawn quăn
Quawn Quăn
giawn giăn
Giawn Giăn
quawng quăng
Quawng Quăng
giawng giăng
Giawng Giăng
quawnh quănh
Quawnh Quănh
giawnh giănh
Giawnh Giănh
quawp quăp
Quawp Quăp
giawp giăp
Giawp Giăp
quawt quăt
Quawt Quăt
giawt giăt
Giawt Giăt
quaww quaw
Quaww Quaw
giaww giaw
Giaww Giaw
quay quay
Quay Quay
giay giay
Giay Giay
quayc quayc
Quayc Quayc
giayc giayc
Giayc Giayc
quaych quaych
Quaych Quaych
giaych giaych
Giaych Giaych
quaym quaym
Quaym Quaym
giaym giaym
Giaym Giaym
quayn quayn
Quayn Quayn
giayn giayn
Giayn Giayn
quayng quayng
Quayng Quayng
giayng giayng
Giayng Giayng
quaynh quaynh
Quaynh Quaynh
giaynh giaynh
Giaynh Giaynh
quayp quayp
Quayp Quayp
giayp giayp
Giayp Giayp
quayt quayt
Quayt Quayt
giayt giayt
Giayt Giayt
quec quec
Quec Quec
giec giec
Giec Giec
quech quech
Quech Quech
giech giech
Giech Giech
que que
Que Que
gie gie
Gie Gie
queec quêc
Queec Quêc
gieec giêc
Gieec Giêc
queech quêch
Queech Quêch
gieech giêch
Gieech Giêch
quee quê
Quee Quê
giee giê
Giee Giê
queee quee
Queee Quee
gieee giee
Gieee Giee
queem quêm
Queem Quêm
gieem giêm
Gieem Giêm
queen quên
Queen Quên
gieen giên
Gieen Giên
queeng quêng
Queeng Quêng
gieeng giêng
Gieeng Giêng
queenh quênh
Queenh Quênh
gieenh giênh
Gieenh Giênh
queep quêp
Queep Quêp
gieep giêp
Gieep Giêp
queet quêt
Queet Quêt
gieet giêt
Gieet Giêt
quem quem
Quem Quem
giem giem
Giem Giem
quen quen
Quen Quen
gien gien
Gien Gien
queng queng
Queng Queng
gieng gieng
Gieng Gieng
quenh quenh
Quenh Quenh
gienh gienh
Gienh Gienh
quep quep
Quep Quep
giep giep
Giep Giep
quet quet
Quet Quet
giet giet
Giet Giet
queu queu
Queu Queu
gieu gieu
Gieu Gieu
quich quich
Quich Quich
giich giich
Giich Giich
quic quic
Quic Quic
giic giic
Giic Giic
quieech quiêch
Quieech Quiêch
giieech giiêch
Giieech Giiêch
quieec quiêc
Quieec Quiêc
giieec giiêc
Giieec Giiêc
quiee quiê
Quiee Quiê
giiee giiê
Giiee Giiê
quieem quiêm
Quieem Quiêm
giieem giiêm
Giieem Giiêm
quieeng quiêng
Quieeng Quiêng
giieeng giiêng
Giieeng Giiêng
quieenh quiênh
Quieenh Quiênh
giieenh giiênh
Giieenh Giiênh
quieen quiên
Quieen Quiên
giieen giiên
Giieen Giiên
quieep quiêp
Quieep Quiêp
giieep giiêp
Giieep Giiêp
quieet quiêt
Quieet Quiêt
giieet giiêt
Giieet Giiêt
quieeu quiêu
Quieeu Quiêu
giieeu giiêu
Giieeu Giiêu
quie quie
Quie Quie
giie giie
Giie Giie
qui qui
Qui Qui
gii gii
Gii Gii
quim quim
Quim Quim
giim giim
Giim Giim
quing quing
Quing Quing
giing giing
Giing Giing
quinh quinh
Quinh Quinh
giinh giinh
Giinh Giinh
quin quin
Quin Quin
giin giin
Giin Giin
quip quip
Quip Quip
giip giip
Giip Giip
quit quit
Quit Quit
giit giit
Giit Giit
quiu quiu
Quiu Quiu
giiu giiu
Giiu Giiu
quoach quoach
Quoach Quoach
gioach gioach
Gioach Gioach
quoac quoac
Quoac Quoac
gioac gioac
Gioac Gioac
quoai quoai
Quoai Quoai
gioai gioai
Gioai Gioai
quoam quoam
Quoam Quoam
gioam gioam
Gioam Gioam
quoang quoang
Quoang Quoang
gioang gioang
Gioang Gioang
quoanh quoanh
Quoanh Quoanh
gioanh gioanh
Gioanh Gioanh
quoan quoan
Quoan Quoan
gioan gioan
Gioan Gioan
quoa quoa
Quoa Quoa
gioa gioa
Gioa Gioa
quoap quoap
Quoap Quoap
gioap gioap
Gioap Gioap
quoat quoat
Quoat Quoat
gioat gioat
Gioat Gioat
quoawch quoăch
Quoawch Quoăch
gioawch gioăch
Gioawch Gioăch
quoawc quoăc
Quoawc Quoăc
gioawc gioăc
Gioawc Gioăc
quoawm quoăm
Quoawm Quoăm
gioawm gioăm
Gioawm Gioăm
quoawng quoăng
Quoawng Quoăng
gioawng gioăng
Gioawng Gioăng
quoawnh quoănh
Quoawnh Quoănh
gioawnh gioănh
Gioawnh Gioănh
quoawn quoăn
Quoawn Quoăn
gioawn gioăn
Gioawn Gioăn
quoaw quoă
Quoaw Quoă
gioaw gioă
Gioaw Gioă
quoawp quoăp
Quoawp Quoăp
gioawp gioăp
Gioawp Gioăp
quoawt quoăt
Quoawt Quoăt
gioawt gioăt
Gioawt Gioăt
quoay quoay
Quoay Quoay
gioay gioay
Gioay Gioay
quoch quoch
Quoch Quoch
gioch gioch
Gioch Gioch
quoc quoc
Quoc Quoc
gioc gioc
Gioc Gioc
quoe quoe
Quoe Quoe
gioe gioe
Gioe Gioe
quoich quoich
Quoich Quoich
gioich gioich
Gioich Gioich
quoic quoic
Quoic Quoic
gioic gioic
Gioic Gioic
quoim quoim
Quoim Quoim
gioim gioim
Gioim Gioim
quoing quoing
Quoing Quoing
gioing gioing
Gioing Gioing
quoinh quoinh
Quoinh Quoinh
gioinh gioinh
Gioinh Gioinh
quoin quoin
Quoin Quoin
gioin gioin
Gioin Gioin
quoi quoi
Quoi Quoi
gioi gioi
Gioi Gioi
quoip quoip
Quoip Quoip
gioip gioip
Gioip Gioip
quoit quoit
Quoit Quoit
gioit gioit
Gioit Gioit
quom quom
Quom Quom
giom giom
Giom Giom
quong quong
Quong Quong
giong giong
Giong Giong
quonh quonh
Quonh Quonh
gionh gionh
Gionh Gionh
quon quon
Quon Quon
gion gion
Gion Gion
quo quo
Quo Quo
gio gio
Gio Gio
quooch quôch
Quooch Quôch
giooch giôch
Giooch Giôch
quooc quôc
Quooc Quôc
giooc giôc
Giooc Giôc
quoom quôm
Quoom Quôm
gioom giôm
Gioom Giôm
quoong quông
Quoong Quông
gioong giông
Gioong Giông
quoonh quônh
Quoonh Quônh
gioonh giônh
Gioonh Giônh
quoon quôn
Quoon Quôn
gioon giôn
Gioon Giôn
quoo quô
Quoo Quô
gioo giô
Gioo Giô
quooo quoo
Quooo Quoo
giooo gioo
Giooo Gioo
quoop quôp
Quoop Quôp
gioop giôp
Gioop Giôp
quoot quôt
Quoot Quôt
gioot giôt
Gioot Giôt
quop quop
Quop Quop
giop giop
Giop Giop
quot quot
Quot Quot
giot giot
Giot Giot
quowch quơch
Quowch Quơch
giowch giơch
Giowch Giơch
quowc quơc
Quowc Quơc
giowc giơc
Giowc Giơc
quowm quơm
Quowm Quơm
giowm giơm
Giowm Giơm
quowng quơng
Quowng Quơng
giowng giơng
Giowng Giơng
quownh quơnh
Quownh Quơnh
giownh giơnh
Giownh Giơnh
quown quơn
Quown Quơn
giown giơn
Giown Giơn
quow quơ
Quow Quơ
giow giơ
Giow Giơ
quowp quơp
Quowp Quơp
giowp giơp
Giowp Giơp
quowt quơt
Quowt Quơt
giowt giơt
Giowt Giơt
quoww quow
Quoww Quow
gioww giow
Gioww Giow
giuaach giuâch
Giuaach Giuâch
giuaac giuâc
Giuaac Giuâc
giuaam giuâm
Giuaam Giuâm
giuaang giuâng
Giuaang Giuâng
giuaanh giuânh
Giuaanh Giuânh
giuaan giuân
Giuaan Giuân
giuaap giuâp
Giuaap Giuâp
giuaat giuât
Giuaat Giuât
giuaa giuâ
Giuaa Giuâ
giua giua
Giua Giua
giuch giuch
Giuch Giuch
giuc giuc
Giuc Giuc
giuich giuich
Giuich Giuich
giuic giuic
Giuic Giuic
giuim giuim
Giuim Giuim
giuing giuing
Giuing Giuing
giuinh giuinh
Giuinh Giuinh
giuin giuin
Giuin Giuin
giuip giuip
Giuip Giuip
giuit giuit
Giuit Giuit
giui giui
Giui Giui
gium gium
Gium Gium
giung giung
Giung Giung
giunh giunh
Giunh Giunh
giun giun
Giun Giun
giuooch giuôch
Giuooch Giuôch
giuooc giuôc
Giuooc Giuôc
giuooi giuôi
Giuooi Giuôi
giuoom giuôm
Giuoom Giuôm
giuoong giuông
Giuoong Giuông
giuoonh giuônh
Giuoonh Giuônh
giuoon giuôn
Giuoon Giuôn
giuoop giuôp
Giuoop Giuôp
giuoot giuôt
Giuoot Giuôt
giuoo giuô
Giuoo Giuô
giuo giuo
Giuo Giuo
giuowch giươch
Giuowch Giươch
giuowc giươc
Giuowc Giươc
giuowi giươi
Giuowi Giươi
giuowm giươm
Giuowm Giươm
giuowng giương
Giuowng Giương
giuownh giươnh
Giuownh Giươnh
giuown giươn
Giuown Giươn
giuowp giươp
Giuowp Giươp
giuowt giươt
Giuowt Giươt
giuow giươ
Giuow Giươ
giup giup
Giup Giup
giut giut
Giut Giut
giu giu
Giu Giu
giuwa giưa
Giuwa Giưa
giuwch giưch
Giuwch Giưch
giuwc giưc
Giuwc Giưc
giuwm giưm
Giuwm Giưm
giuwng giưng
Giuwng Giưng
giuwnh giưnh
Giuwnh Giưnh
giuwn giưn
Giuwn Giưn
giuwow giươ
Giuwow Giươ
giuwp giưp
Giuwp Giưp
giuwt giưt
Giuwt Giưt
giuw giư
Giuw Giư
giuww giuw
Giuww Giuw
giuya giuya
Giuya Giuya
giuych giuych
Giuych Giuych
giuyc giuyc
Giuyc Giuyc
giuyee giuyê
Giuyee Giuyê
giuym giuym
Giuym Giuym
giuyng giuyng
Giuyng Giuyng
giuynh giuynh
Giuynh Giuynh
giuyn giuyn
Giuyn Giuyn
giuyp giuyp
Giuyp Giuyp
giuyt giuyt
Giuyt Giuyt
giuy giuy
Giuy Giuy
quych quych
Quych Quych
giych giych
Giych Giych
quyc quyc
Quyc Quyc
giyc giyc
Giyc Giyc
quyeech quyêch
Quyeech Quyêch
giyeech giyêch
Giyeech Giyêch
quyeec quyêc
Quyeec Quyêc
giyeec giyêc
Giyeec Giyêc
quyeem quyêm
Quyeem Quyêm
giyeem giyêm
Giyeem Giyêm
quyeeng quyêng
Quyeeng Quyêng
giyeeng giyêng
Giyeeng Giyêng
quyeenh quyênh
Quyeenh Quyênh
giyeenh giyênh
Giyeenh Giyênh
quyeen quyên
Quyeen Quyên
giyeen giyên
Giyeen Giyên
quyeep quyêp
Quyeep Quyêp
giyeep giyêp
Giyeep Giyêp
quyeet quyêt
Quyeet Quyêt
giyeet giyêt
Giyeet Giyêt
quyeeu quyêu
Quyeeu Quyêu
giyeeu giyêu
Giyeeu Giyêu
quyee quyê
Quyee Quyê
giyee giyê
Giyee Giyê
quye quye
Quye Quye
giye giye
Giye Giye
quym quym
Quym Quym
giym giym
Giym Giym
quyng quyng
Quyng Quyng
giyng giyng
Giyng Giyng
quynh quynh
Quynh Quynh
giynh giynh
Giynh Giynh
quyn quyn
Quyn Quyn
giyn giyn
Giyn Giyn
quyp quyp
Quyp Quyp
giyp giyp
Giyp Giyp
quyt quyt
Quyt Quyt
giyt giyt
Giyt Giyt
quy quy
Quy Quy
giy giy
Giy Giy
gic gic
Gic Gic
gim gim
Gim Gim
gin gin
Gin Gin
gip gip
Gip Gip
git git
Git Git
gich gich
Gich Gich
ging ging
Ging Ging
ginh ginh
Ginh Ginh

3
run.sh
View File

@@ -1,7 +1,8 @@
#!/bin/sh
cd "$(dirname "$0")"
pkill strans
pkill strans-xim
sleep 1
./strans map font &
sleep 1

5
srv.c
View File

@@ -4,14 +4,13 @@
static char adir[40];
static void
sendkey(int fd, u32int ks, u32int mod, int want)
sendkey(int fd, u32int ks, u32int mod)
{
Keyreq kr;
kr.fd = fd;
kr.ks = ks;
kr.mod = mod;
kr.want = want;
chansend(keyc, &kr);
}
@@ -24,7 +23,7 @@ clientthread(void *arg)
fd = (int)(uintptr)arg;
threadsetname("client %d", fd);
while(read(fd, req, 4) == 4)
sendkey(fd, req[2] | (req[3] << 8), req[1], req[0]);
sendkey(fd, req[2] | (req[3] << 8), req[1]);
close(fd);
}

View File

@@ -2,7 +2,6 @@
#include "fn.h"
static Im im;
static int popup = 0;
static void dictqmap(Im*);
static void
@@ -46,8 +45,6 @@ show(void)
Drawcmd dc;
int i, first, n;
if(!popup)
return;
sclear(&dc.pre);
if(!mapget(im.l->map, &im.pre, &dc.pre))
dc.pre = im.pre;
@@ -185,8 +182,10 @@ transmap(Im *im, Rune c)
e.s = im->pre;
sclear(&key);
sputr(&key, c);
if(!maplookup(t, &key, &e.dict))
if(!maplookup(t, &key, &e.dict)){
sputr(&e.s, c);
return e;
}
e.eat = 1;
sputr(&e.next, c);
return e;
@@ -257,10 +256,6 @@ keystroke(u32int ks, u32int mod, Str *com)
reset();
if(ks >= 'a' && ks <= 'z')
ks -= 'a' - 1;
if(ks == 0x10){
popup = !popup;
return 1;
}
if(setlang(ks))
return 1;
return 0;
@@ -271,16 +266,14 @@ keystroke(u32int ks, u32int mod, Str *com)
return 1;
}
if(ks > 0x7f || ks == ' '){
if(im.pre.n == 0)
return 0;
commit(com);
sputr(com, ks);
reset();
return 1;
}
n = dotrans(ks, com);
dotrans(ks, com);
show();
return n;
return 1;
}
static void
@@ -319,13 +312,6 @@ imthread(void*)
out[1] = len;
n += len;
}
if(kr.want){
len = im.pre.n > 0 ?
stoutf(&im.pre, (char*)(out+n+1),
sizeof(out)-n-1) : 0;
out[n] = len;
n += 1 + len;
}
write(kr.fd, out, n);
break;
case 1:

62
vi.c
View File

@@ -31,24 +31,12 @@ static struct {
{L'Y', {L'Ý', L'', L'', L'', L''}},
};
static int
istone(Rune c)
{
return c == 's' || c == 'f' || c == 'r' || c == 'x' || c == 'j';
}
static int tonetab[128] = {
['s'] = 1, ['f'] = 2, ['r'] = 3, ['x'] = 4, ['j'] = 5,
};
static int
toneidx(Rune c)
{
switch(c){
case 's': return 0;
case 'f': return 1;
case 'r': return 2;
case 'x': return 3;
case 'j': return 4;
}
return -1;
}
#define Istone(c) ((c) < 128 && tonetab[(c)] > 0)
#define Toneidx(c) (tonetab[(c)] - 1)
static int
isvowel(Rune c)
@@ -89,45 +77,22 @@ applytone(Rune c, int tidx)
return c;
}
/*
* In qu- and gi- onsets the u/i is a glide that belongs to the onset,
* not the rime, so it must not bear the tone (qua -> quá, gia -> giá).
* The i of gi- is only a glide when another vowel follows; otherwise it
* is the nucleus itself (gì, gìn). Returns the rune index to skip, or -1.
*/
static int
onsetglide(Str *m)
{
Rune a, b;
int i;
if(m->n < 2)
return -1;
a = m->r[0];
b = removetone(m->r[1]);
if((a == 'q' || a == 'Q') && (b == 'u' || b == 'U'))
return 1;
if((a == 'g' || a == 'G') && (b == 'i' || b == 'I'))
for(i = 2; i < m->n; i++)
if(isvowel(removetone(m->r[i])))
return 1;
return -1;
}
Emit
transvi(Im *im, Rune c)
{
Emit e;
Str mapped, pre;
int i, tidx, vi, last, penult, glide;
int i, tidx, vi, last, penult;
Rune v, b1, b2;
if(!istone(c) && c != 'z')
if(!Istone(c) && c != 'z')
return transmap(im, c);
memset(&e, 0, sizeof e);
if(im->pre.n == 0)
if(im->pre.n == 0){
sputr(&e.s, c);
return e;
}
if(im->pre.r[im->pre.n - 1] == '\\'){
pre = im->pre;
pre.n--;
@@ -140,12 +105,9 @@ transvi(Im *im, Rune c)
}
if(!mapget(im->l->map, &im->pre, &mapped))
mapped = im->pre;
glide = onsetglide(&mapped);
last = -1;
penult = -1;
for(i = 0; i < mapped.n; i++){
if(i == glide)
continue;
v = removetone(mapped.r[i]);
if(isvowel(v)){
penult = last;
@@ -168,14 +130,16 @@ transvi(Im *im, Rune c)
}
}
if(vi < 0){
e.eat = 1;
e.s = mapped;
sputr(&e.s, c);
return e;
}
if(c == 'z')
mapped.r[vi] = removetone(mapped.r[vi]);
else{
tidx = toneidx(c);
tidx = Toneidx(c);
mapped.r[vi] = applytone(mapped.r[vi], tidx);
}
e.eat = 1;

View File

@@ -1,280 +0,0 @@
/* Generated by wayland-scanner 1.23.1 */
#ifndef VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H
#define VIRTUAL_KEYBOARD_UNSTABLE_V1_CLIENT_PROTOCOL_H
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @page page_virtual_keyboard_unstable_v1 The virtual_keyboard_unstable_v1 protocol
* @section page_ifaces_virtual_keyboard_unstable_v1 Interfaces
* - @subpage page_iface_zwp_virtual_keyboard_v1 - virtual keyboard
* - @subpage page_iface_zwp_virtual_keyboard_manager_v1 - virtual keyboard manager
* @section page_copyright_virtual_keyboard_unstable_v1 Copyright
* <pre>
*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
* Copyright © 2018 Purism SPC
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
* </pre>
*/
struct wl_seat;
struct zwp_virtual_keyboard_manager_v1;
struct zwp_virtual_keyboard_v1;
#ifndef ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE
#define ZWP_VIRTUAL_KEYBOARD_V1_INTERFACE
/**
* @page page_iface_zwp_virtual_keyboard_v1 zwp_virtual_keyboard_v1
* @section page_iface_zwp_virtual_keyboard_v1_desc Description
*
* The virtual keyboard provides an application with requests which emulate
* the behaviour of a physical keyboard.
*
* This interface can be used by clients on its own to provide raw input
* events, or it can accompany the input method protocol.
* @section page_iface_zwp_virtual_keyboard_v1_api API
* See @ref iface_zwp_virtual_keyboard_v1.
*/
/**
* @defgroup iface_zwp_virtual_keyboard_v1 The zwp_virtual_keyboard_v1 interface
*
* The virtual keyboard provides an application with requests which emulate
* the behaviour of a physical keyboard.
*
* This interface can be used by clients on its own to provide raw input
* events, or it can accompany the input method protocol.
*/
extern const struct wl_interface zwp_virtual_keyboard_v1_interface;
#endif
#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE
#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_INTERFACE
/**
* @page page_iface_zwp_virtual_keyboard_manager_v1 zwp_virtual_keyboard_manager_v1
* @section page_iface_zwp_virtual_keyboard_manager_v1_desc Description
*
* A virtual keyboard manager allows an application to provide keyboard
* input events as if they came from a physical keyboard.
* @section page_iface_zwp_virtual_keyboard_manager_v1_api API
* See @ref iface_zwp_virtual_keyboard_manager_v1.
*/
/**
* @defgroup iface_zwp_virtual_keyboard_manager_v1 The zwp_virtual_keyboard_manager_v1 interface
*
* A virtual keyboard manager allows an application to provide keyboard
* input events as if they came from a physical keyboard.
*/
extern const struct wl_interface zwp_virtual_keyboard_manager_v1_interface;
#endif
#ifndef ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM
#define ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM
enum zwp_virtual_keyboard_v1_error {
/**
* No keymap was set
*/
ZWP_VIRTUAL_KEYBOARD_V1_ERROR_NO_KEYMAP = 0,
};
#endif /* ZWP_VIRTUAL_KEYBOARD_V1_ERROR_ENUM */
#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP 0
#define ZWP_VIRTUAL_KEYBOARD_V1_KEY 1
#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS 2
#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY 3
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*/
#define ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP_SINCE_VERSION 1
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*/
#define ZWP_VIRTUAL_KEYBOARD_V1_KEY_SINCE_VERSION 1
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*/
#define ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS_SINCE_VERSION 1
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*/
#define ZWP_VIRTUAL_KEYBOARD_V1_DESTROY_SINCE_VERSION 1
/** @ingroup iface_zwp_virtual_keyboard_v1 */
static inline void
zwp_virtual_keyboard_v1_set_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1, user_data);
}
/** @ingroup iface_zwp_virtual_keyboard_v1 */
static inline void *
zwp_virtual_keyboard_v1_get_user_data(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_v1);
}
static inline uint32_t
zwp_virtual_keyboard_v1_get_version(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1);
}
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*
* Provide a file descriptor to the compositor which can be
* memory-mapped to provide a keyboard mapping description.
*
* Format carries a value from the keymap_format enumeration.
*/
static inline void
zwp_virtual_keyboard_v1_keymap(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t format, int32_t fd, uint32_t size)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
ZWP_VIRTUAL_KEYBOARD_V1_KEYMAP, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, format, fd, size);
}
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*
* A key was pressed or released.
* The time argument is a timestamp with millisecond granularity, with an
* undefined base. All requests regarding a single object must share the
* same clock.
*
* Keymap must be set before issuing this request.
*
* State carries a value from the key_state enumeration.
*/
static inline void
zwp_virtual_keyboard_v1_key(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t time, uint32_t key, uint32_t state)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
ZWP_VIRTUAL_KEYBOARD_V1_KEY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, time, key, state);
}
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*
* Notifies the compositor that the modifier and/or group state has
* changed, and it should update state.
*
* The client should use wl_keyboard.modifiers event to synchronize its
* internal state with seat state.
*
* Keymap must be set before issuing this request.
*/
static inline void
zwp_virtual_keyboard_v1_modifiers(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
ZWP_VIRTUAL_KEYBOARD_V1_MODIFIERS, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), 0, mods_depressed, mods_latched, mods_locked, group);
}
/**
* @ingroup iface_zwp_virtual_keyboard_v1
*/
static inline void
zwp_virtual_keyboard_v1_destroy(struct zwp_virtual_keyboard_v1 *zwp_virtual_keyboard_v1)
{
wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_v1,
ZWP_VIRTUAL_KEYBOARD_V1_DESTROY, NULL, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_v1), WL_MARSHAL_FLAG_DESTROY);
}
#ifndef ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM
#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM
enum zwp_virtual_keyboard_manager_v1_error {
/**
* client not authorized to use the interface
*/
ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_UNAUTHORIZED = 0,
};
#endif /* ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_ERROR_ENUM */
#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD 0
/**
* @ingroup iface_zwp_virtual_keyboard_manager_v1
*/
#define ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD_SINCE_VERSION 1
/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
static inline void
zwp_virtual_keyboard_manager_v1_set_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1, user_data);
}
/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
static inline void *
zwp_virtual_keyboard_manager_v1_get_user_data(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
{
return wl_proxy_get_user_data((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
}
static inline uint32_t
zwp_virtual_keyboard_manager_v1_get_version(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
{
return wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
}
/** @ingroup iface_zwp_virtual_keyboard_manager_v1 */
static inline void
zwp_virtual_keyboard_manager_v1_destroy(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1)
{
wl_proxy_destroy((struct wl_proxy *) zwp_virtual_keyboard_manager_v1);
}
/**
* @ingroup iface_zwp_virtual_keyboard_manager_v1
*
* Creates a new virtual keyboard associated to a seat.
*
* If the compositor enables a keyboard to perform arbitrary actions, it
* should present an error when an untrusted client requests a new
* keyboard.
*/
static inline struct zwp_virtual_keyboard_v1 *
zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(struct zwp_virtual_keyboard_manager_v1 *zwp_virtual_keyboard_manager_v1, struct wl_seat *seat)
{
struct wl_proxy *id;
id = wl_proxy_marshal_flags((struct wl_proxy *) zwp_virtual_keyboard_manager_v1,
ZWP_VIRTUAL_KEYBOARD_MANAGER_V1_CREATE_VIRTUAL_KEYBOARD, &zwp_virtual_keyboard_v1_interface, wl_proxy_get_version((struct wl_proxy *) zwp_virtual_keyboard_manager_v1), 0, seat, NULL);
return (struct zwp_virtual_keyboard_v1 *) id;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,78 +0,0 @@
/* Generated by wayland-scanner 1.23.1 */
/*
* Copyright © 2008-2011 Kristian Høgsberg
* Copyright © 2010-2013 Intel Corporation
* Copyright © 2012-2013 Collabora, Ltd.
* Copyright © 2018 Purism SPC
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
#ifndef __has_attribute
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
#endif
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
#else
#define WL_PRIVATE
#endif
extern const struct wl_interface wl_seat_interface;
extern const struct wl_interface zwp_virtual_keyboard_v1_interface;
static const struct wl_interface *virtual_keyboard_unstable_v1_types[] = {
NULL,
NULL,
NULL,
NULL,
&wl_seat_interface,
&zwp_virtual_keyboard_v1_interface,
};
static const struct wl_message zwp_virtual_keyboard_v1_requests[] = {
{ "keymap", "uhu", virtual_keyboard_unstable_v1_types + 0 },
{ "key", "uuu", virtual_keyboard_unstable_v1_types + 0 },
{ "modifiers", "uuuu", virtual_keyboard_unstable_v1_types + 0 },
{ "destroy", "", virtual_keyboard_unstable_v1_types + 0 },
};
WL_PRIVATE const struct wl_interface zwp_virtual_keyboard_v1_interface = {
"zwp_virtual_keyboard_v1", 1,
4, zwp_virtual_keyboard_v1_requests,
0, NULL,
};
static const struct wl_message zwp_virtual_keyboard_manager_v1_requests[] = {
{ "create_virtual_keyboard", "on", virtual_keyboard_unstable_v1_types + 4 },
};
WL_PRIVATE const struct wl_interface zwp_virtual_keyboard_manager_v1_interface = {
"zwp_virtual_keyboard_manager_v1", 1,
1, zwp_virtual_keyboard_manager_v1_requests,
0, NULL,
};

350
wayland.c
View File

@@ -1,350 +0,0 @@
#include "dat.h"
#include "fn.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <poll.h>
#include <sys/mman.h>
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#include "input-method-unstable-v2-client-protocol.h"
#include "virtual-keyboard-unstable-v1-client-protocol.h"
static struct wl_display *dpy;
static struct wl_seat *seat;
static struct zwp_input_method_manager_v2 *immgr;
static struct zwp_virtual_keyboard_manager_v1 *vkmgr;
static struct zwp_input_method_v2 *im;
static struct zwp_input_method_keyboard_grab_v2 *grab;
static struct zwp_virtual_keyboard_v1 *vk;
static struct xkb_context *xkb;
static struct xkb_keymap *keymap;
static struct xkb_state *xkbst;
static int active;
static int pending;
static u32int imserial;
static void
sendkey(u32int ks, u32int mod, char *com, int csz, char *pre, int psz,
int *eaten)
{
Keyreq kr;
int p[2];
uchar hdr[2];
uchar pl;
int n;
*eaten = 0;
com[0] = '\0';
pre[0] = '\0';
if(pipe(p) < 0)
return;
kr.fd = p[1];
kr.ks = ks;
kr.mod = mod;
kr.want = 1;
chansend(keyc, &kr);
if(read(p[0], hdr, 2) != 2)
goto out;
*eaten = hdr[0];
n = hdr[1];
if(n > 0 && n < csz){
if(read(p[0], com, n) != n)
goto out;
com[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[1]);
}
static void
sendreset(void)
{
char com[64], pre[256];
int eaten;
sendkey(Kesc, 0, com, sizeof(com), pre, sizeof(pre), &eaten);
}
static u32int
mget(void)
{
u32int m;
m = 0;
if(xkbst == nil)
return 0;
if(xkb_state_mod_name_is_active(xkbst,
XKB_MOD_NAME_SHIFT, XKB_STATE_MODS_EFFECTIVE) > 0)
m |= Mshift;
if(xkb_state_mod_name_is_active(xkbst,
XKB_MOD_NAME_CTRL, XKB_STATE_MODS_EFFECTIVE) > 0)
m |= Mctrl;
if(xkb_state_mod_name_is_active(xkbst,
XKB_MOD_NAME_ALT, XKB_STATE_MODS_EFFECTIVE) > 0)
m |= Malt;
if(xkb_state_mod_name_is_active(xkbst,
XKB_MOD_NAME_LOGO, XKB_STATE_MODS_EFFECTIVE) > 0)
m |= Msuper;
return m;
}
static void
kpress(uint32_t time, uint32_t keycode, uint32_t state)
{
xkb_keysym_t ks;
u32int k, mod;
char com[64], pre[256];
int eaten, plen;
if(state != WL_KEYBOARD_KEY_STATE_PRESSED || xkbst == nil){
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
return;
}
ks = xkb_state_key_get_one_sym(xkbst, keycode + 8);
k = ks >= 0xff00 ? Kspec + (ks - 0xff00) : xkb_keysym_to_utf32(ks);
if(k == 0){
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
return;
}
mod = mget();
sendkey(k, mod, com, sizeof(com), pre, sizeof(pre), &eaten);
if(com[0] != '\0'){
zwp_input_method_v2_commit_string(im, com);
zwp_input_method_v2_commit(im, imserial);
}
plen = strlen(pre);
zwp_input_method_v2_set_preedit_string(im, pre, plen, plen);
zwp_input_method_v2_commit(im, imserial);
if(!eaten)
zwp_virtual_keyboard_v1_key(vk, time, keycode, state);
}
static void
kg_keymap(void *data, struct zwp_input_method_keyboard_grab_v2 *g,
uint32_t format, int32_t fd, uint32_t size)
{
char *s;
(void)data;
(void)g;
if(format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1){
close(fd);
return;
}
s = mmap(nil, size, PROT_READ, MAP_PRIVATE, fd, 0);
if(s != MAP_FAILED){
if(xkbst != nil){
xkb_state_unref(xkbst);
xkbst = nil;
}
if(keymap != nil)
xkb_keymap_unref(keymap);
keymap = xkb_keymap_new_from_string(xkb, s,
XKB_KEYMAP_FORMAT_TEXT_V1,
XKB_KEYMAP_COMPILE_NO_FLAGS);
if(keymap != nil)
xkbst = xkb_state_new(keymap);
munmap(s, size);
}
zwp_virtual_keyboard_v1_keymap(vk, format, fd, size);
}
static void
kg_key(void *data, struct zwp_input_method_keyboard_grab_v2 *g,
uint32_t serial, uint32_t time, uint32_t key, uint32_t state)
{
(void)data;
(void)g;
(void)serial;
kpress(time, key, state);
}
static void
kg_mods(void *data, struct zwp_input_method_keyboard_grab_v2 *g,
uint32_t serial, uint32_t dep, uint32_t lat, uint32_t lck,
uint32_t group)
{
(void)data;
(void)g;
(void)serial;
if(xkbst != nil)
xkb_state_update_mask(xkbst, dep, lat, lck, 0, 0, group);
zwp_virtual_keyboard_v1_modifiers(vk, dep, lat, lck, group);
}
static void
kg_repeat(void *data, struct zwp_input_method_keyboard_grab_v2 *g,
int32_t rate, int32_t delay)
{
(void)data;
(void)g;
(void)rate;
(void)delay;
}
static const struct zwp_input_method_keyboard_grab_v2_listener
grab_listener = {
.keymap = kg_keymap,
.key = kg_key,
.modifiers = kg_mods,
.repeat_info = kg_repeat,
};
static void
im_activate(void *data, struct zwp_input_method_v2 *m)
{
(void)data;
(void)m;
pending = 1;
}
static void
im_deactivate(void *data, struct zwp_input_method_v2 *m)
{
(void)data;
(void)m;
pending = 0;
if(active){
active = 0;
sendreset();
if(grab != nil){
zwp_input_method_keyboard_grab_v2_release(grab);
grab = nil;
}
}
}
static void
im_surrounding(void *data, struct zwp_input_method_v2 *m,
const char *text, uint32_t cursor, uint32_t anchor)
{
(void)data;
(void)m;
(void)text;
(void)cursor;
(void)anchor;
}
static void
im_textchange(void *data, struct zwp_input_method_v2 *m, uint32_t cause)
{
(void)data;
(void)m;
(void)cause;
}
static void
im_content(void *data, struct zwp_input_method_v2 *m,
uint32_t hint, uint32_t purpose)
{
(void)data;
(void)m;
(void)hint;
(void)purpose;
}
static void
im_done(void *data, struct zwp_input_method_v2 *m)
{
(void)data;
(void)m;
imserial++;
if(pending && !active){
active = 1;
grab = zwp_input_method_v2_grab_keyboard(im);
if(grab != nil)
zwp_input_method_keyboard_grab_v2_add_listener(grab,
&grab_listener, nil);
}
}
static void
im_unavail(void *data, struct zwp_input_method_v2 *m)
{
(void)data;
(void)m;
fprint(2, "strans: wayland: input-method unavailable\n");
}
static const struct zwp_input_method_v2_listener im_listener = {
.activate = im_activate,
.deactivate = im_deactivate,
.surrounding_text = im_surrounding,
.text_change_cause = im_textchange,
.content_type = im_content,
.done = im_done,
.unavailable = im_unavail,
};
static void
reg_global(void *data, struct wl_registry *r, uint32_t name,
const char *iface, uint32_t version)
{
(void)data;
(void)version;
if(strcmp(iface, wl_seat_interface.name) == 0)
seat = wl_registry_bind(r, name, &wl_seat_interface, 5);
else if(strcmp(iface, zwp_input_method_manager_v2_interface.name) == 0)
immgr = wl_registry_bind(r, name,
&zwp_input_method_manager_v2_interface, 1);
else if(strcmp(iface,
zwp_virtual_keyboard_manager_v1_interface.name) == 0)
vkmgr = wl_registry_bind(r, name,
&zwp_virtual_keyboard_manager_v1_interface, 1);
}
static void
reg_remove(void *data, struct wl_registry *r, uint32_t name)
{
(void)data;
(void)r;
(void)name;
}
static const struct wl_registry_listener reg_listener = {
.global = reg_global,
.global_remove = reg_remove,
};
void
waylandthread(void *_)
{
struct wl_registry *reg;
(void)_;
threadsetname("wayland");
while((dpy = wl_display_connect(nil)) == nil)
poll(nil, 0, 1000);
xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if(xkb == nil){
wl_display_disconnect(dpy);
dpy = nil;
return;
}
reg = wl_display_get_registry(dpy);
wl_registry_add_listener(reg, &reg_listener, nil);
wl_display_roundtrip(dpy);
if(seat == nil || immgr == nil || vkmgr == nil){
fprint(2,
"strans: wayland: compositor missing input-method-v2\n");
wl_display_disconnect(dpy);
dpy = nil;
return;
}
im = zwp_input_method_manager_v2_get_input_method(immgr, seat);
zwp_input_method_v2_add_listener(im, &im_listener, nil);
vk = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkmgr, seat);
while(wl_display_dispatch(dpy) != -1)
;
}

14
win.c
View File

@@ -31,8 +31,6 @@ wininit(void)
{
int n;
u32int mask, vals[4];
xcb_intern_atom_cookie_t c1, c2;
xcb_intern_atom_reply_t *r1, *r2;
conn = xcb_connect(nil, &n);
if(conn == nil || xcb_connection_has_error(conn))
@@ -51,18 +49,6 @@ wininit(void)
xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, scr->root,
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
scr->root_visual, mask, vals);
c1 = xcb_intern_atom(conn, 0,
strlen("_NET_WM_WINDOW_TYPE"), "_NET_WM_WINDOW_TYPE");
c2 = xcb_intern_atom(conn, 0,
strlen("_NET_WM_WINDOW_TYPE_TOOLTIP"),
"_NET_WM_WINDOW_TYPE_TOOLTIP");
r1 = xcb_intern_atom_reply(conn, c1, nil);
r2 = xcb_intern_atom_reply(conn, c2, nil);
if(r1 != nil && r2 != nil)
xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
win, r1->atom, XCB_ATOM_ATOM, 32, 1, &r2->atom);
free(r1);
free(r2);
gc = xcb_generate_id(conn);
xcb_create_gc(conn, gc, win, 0, nil);
img = emalloc(Imgw * Imgh * sizeof(img[0]));