Compare commits
6 Commits
403f5d52f1
...
795353609b
| Author | SHA1 | Date | |
|---|---|---|---|
| 795353609b | |||
| 28b48d997c | |||
| f4347b70cc | |||
| 69e92de010 | |||
| 293313652f | |||
| b842c724e2 |
@@ -51,6 +51,7 @@ Switch input modes with Ctrl + key:
|
|||||||
T English
|
T English
|
||||||
V Vietnamese (Telex)
|
V Vietnamese (Telex)
|
||||||
E Emoji
|
E Emoji
|
||||||
|
P Toggle preedit/candidate popup window
|
||||||
|
|
||||||
Type romanized input. Select candidates with 1-9 or arrow keys.
|
Type romanized input. Select candidates with 1-9 or arrow keys.
|
||||||
Tab or Enter to commit.
|
Tab or Enter to commit.
|
||||||
|
|||||||
45
gtk/main.c
45
gtk/main.c
@@ -12,6 +12,8 @@ struct Im
|
|||||||
{
|
{
|
||||||
GtkIMContext parent;
|
GtkIMContext parent;
|
||||||
int fd;
|
int fd;
|
||||||
|
char pre[256];
|
||||||
|
int prelen;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ImClass ImClass;
|
typedef struct ImClass ImClass;
|
||||||
@@ -44,8 +46,8 @@ srvconnect(Im *im)
|
|||||||
static int
|
static int
|
||||||
readresp(Im *im, char *buf, int bufsz)
|
readresp(Im *im, char *buf, int bufsz)
|
||||||
{
|
{
|
||||||
unsigned char hdr[2];
|
unsigned char hdr[2], pl;
|
||||||
int n;
|
int n, was;
|
||||||
|
|
||||||
if(read(im->fd, hdr, 2) != 2)
|
if(read(im->fd, hdr, 2) != 2)
|
||||||
return -1;
|
return -1;
|
||||||
@@ -56,6 +58,21 @@ readresp(Im *im, char *buf, int bufsz)
|
|||||||
return -1;
|
return -1;
|
||||||
buf[n] = '\0';
|
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];
|
return hdr[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,7 +109,7 @@ sendreset(Im *im)
|
|||||||
|
|
||||||
if(im->fd < 0)
|
if(im->fd < 0)
|
||||||
return;
|
return;
|
||||||
buf[0] = 0;
|
buf[0] = 1;
|
||||||
buf[1] = 0;
|
buf[1] = 0;
|
||||||
buf[2] = Kesc & 0xff;
|
buf[2] = Kesc & 0xff;
|
||||||
buf[3] = Kesc >> 8;
|
buf[3] = Kesc >> 8;
|
||||||
@@ -119,7 +136,7 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
|
|||||||
if(key == 0)
|
if(key == 0)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
mod = mget(ev->state);
|
mod = mget(ev->state);
|
||||||
buf[0] = 0;
|
buf[0] = 1;
|
||||||
buf[1] = mod;
|
buf[1] = mod;
|
||||||
buf[2] = key & 0xff;
|
buf[2] = key & 0xff;
|
||||||
buf[3] = key >> 8;
|
buf[3] = key >> 8;
|
||||||
@@ -133,6 +150,25 @@ kpress(GtkIMContext *ctx, GdkEventKey *ev)
|
|||||||
return r != 0;
|
return r != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
getpreedit(GtkIMContext *ctx, gchar **str, PangoAttrList **attrs,
|
||||||
|
gint *cursor_pos)
|
||||||
|
{
|
||||||
|
Im *im;
|
||||||
|
PangoAttribute *u;
|
||||||
|
|
||||||
|
im = (Im*)ctx;
|
||||||
|
*str = g_strdup(im->pre);
|
||||||
|
*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);
|
||||||
|
}
|
||||||
|
*cursor_pos = g_utf8_strlen(im->pre, -1);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reset(GtkIMContext *ctx)
|
reset(GtkIMContext *ctx)
|
||||||
{
|
{
|
||||||
@@ -171,6 +207,7 @@ classinit(ImClass *klass)
|
|||||||
ic = GTK_IM_CONTEXT_CLASS(klass);
|
ic = GTK_IM_CONTEXT_CLASS(klass);
|
||||||
oc = G_OBJECT_CLASS(klass);
|
oc = G_OBJECT_CLASS(klass);
|
||||||
ic->filter_keypress = kpress;
|
ic->filter_keypress = kpress;
|
||||||
|
ic->get_preedit_string = getpreedit;
|
||||||
ic->reset = reset;
|
ic->reset = reset;
|
||||||
ic->focus_out = focusout;
|
ic->focus_out = focusout;
|
||||||
oc->finalize = finalize;
|
oc->finalize = finalize;
|
||||||
|
|||||||
6
srv.c
6
srv.c
@@ -4,14 +4,14 @@
|
|||||||
static char adir[40];
|
static char adir[40];
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendkey(int fd, u32int ks, u32int mod)
|
sendkey(int fd, u32int ks, u32int mod, int want)
|
||||||
{
|
{
|
||||||
Keyreq kr;
|
Keyreq kr;
|
||||||
|
|
||||||
kr.fd = fd;
|
kr.fd = fd;
|
||||||
kr.ks = ks;
|
kr.ks = ks;
|
||||||
kr.mod = mod;
|
kr.mod = mod;
|
||||||
kr.want = 0;
|
kr.want = want;
|
||||||
chansend(keyc, &kr);
|
chansend(keyc, &kr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ clientthread(void *arg)
|
|||||||
fd = (int)(uintptr)arg;
|
fd = (int)(uintptr)arg;
|
||||||
threadsetname("client %d", fd);
|
threadsetname("client %d", fd);
|
||||||
while(read(fd, req, 4) == 4)
|
while(read(fd, req, 4) == 4)
|
||||||
sendkey(fd, req[2] | (req[3] << 8), req[1]);
|
sendkey(fd, req[2] | (req[3] << 8), req[1], req[0]);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
7
strans.c
7
strans.c
@@ -2,6 +2,7 @@
|
|||||||
#include "fn.h"
|
#include "fn.h"
|
||||||
|
|
||||||
static Im im;
|
static Im im;
|
||||||
|
static int popup = 0;
|
||||||
static void dictqmap(Im*);
|
static void dictqmap(Im*);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -45,6 +46,8 @@ show(void)
|
|||||||
Drawcmd dc;
|
Drawcmd dc;
|
||||||
int i, first, n;
|
int i, first, n;
|
||||||
|
|
||||||
|
if(!popup)
|
||||||
|
return;
|
||||||
sclear(&dc.pre);
|
sclear(&dc.pre);
|
||||||
if(!mapget(im.l->map, &im.pre, &dc.pre))
|
if(!mapget(im.l->map, &im.pre, &dc.pre))
|
||||||
dc.pre = im.pre;
|
dc.pre = im.pre;
|
||||||
@@ -256,6 +259,10 @@ keystroke(u32int ks, u32int mod, Str *com)
|
|||||||
reset();
|
reset();
|
||||||
if(ks >= 'a' && ks <= 'z')
|
if(ks >= 'a' && ks <= 'z')
|
||||||
ks -= 'a' - 1;
|
ks -= 'a' - 1;
|
||||||
|
if(ks == 0x10){
|
||||||
|
popup = !popup;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if(setlang(ks))
|
if(setlang(ks))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
12
wayland.c
12
wayland.c
@@ -5,6 +5,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <poll.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
@@ -118,8 +119,10 @@ kpress(uint32_t time, uint32_t keycode, uint32_t state)
|
|||||||
}
|
}
|
||||||
mod = mget();
|
mod = mget();
|
||||||
sendkey(k, mod, com, sizeof(com), pre, sizeof(pre), &eaten);
|
sendkey(k, mod, com, sizeof(com), pre, sizeof(pre), &eaten);
|
||||||
if(com[0] != '\0')
|
if(com[0] != '\0'){
|
||||||
zwp_input_method_v2_commit_string(im, com);
|
zwp_input_method_v2_commit_string(im, com);
|
||||||
|
zwp_input_method_v2_commit(im, imserial);
|
||||||
|
}
|
||||||
plen = strlen(pre);
|
plen = strlen(pre);
|
||||||
zwp_input_method_v2_set_preedit_string(im, pre, plen, plen);
|
zwp_input_method_v2_set_preedit_string(im, pre, plen, plen);
|
||||||
zwp_input_method_v2_commit(im, imserial);
|
zwp_input_method_v2_commit(im, imserial);
|
||||||
@@ -321,11 +324,8 @@ waylandthread(void *_)
|
|||||||
|
|
||||||
(void)_;
|
(void)_;
|
||||||
threadsetname("wayland");
|
threadsetname("wayland");
|
||||||
dpy = wl_display_connect(nil);
|
while((dpy = wl_display_connect(nil)) == nil)
|
||||||
if(dpy == nil){
|
poll(nil, 0, 1000);
|
||||||
fprint(2, "strans: wayland: cannot connect to display\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
xkb = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
if(xkb == nil){
|
if(xkb == nil){
|
||||||
wl_display_disconnect(dpy);
|
wl_display_disconnect(dpy);
|
||||||
|
|||||||
14
win.c
14
win.c
@@ -31,6 +31,8 @@ wininit(void)
|
|||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
u32int mask, vals[4];
|
u32int mask, vals[4];
|
||||||
|
xcb_intern_atom_cookie_t c1, c2;
|
||||||
|
xcb_intern_atom_reply_t *r1, *r2;
|
||||||
|
|
||||||
conn = xcb_connect(nil, &n);
|
conn = xcb_connect(nil, &n);
|
||||||
if(conn == nil || xcb_connection_has_error(conn))
|
if(conn == nil || xcb_connection_has_error(conn))
|
||||||
@@ -49,6 +51,18 @@ wininit(void)
|
|||||||
xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, scr->root,
|
xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, scr->root,
|
||||||
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
|
||||||
scr->root_visual, mask, vals);
|
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);
|
gc = xcb_generate_id(conn);
|
||||||
xcb_create_gc(conn, gc, win, 0, nil);
|
xcb_create_gc(conn, gc, win, 0, nil);
|
||||||
img = emalloc(Imgw * Imgh * sizeof(img[0]));
|
img = emalloc(Imgw * Imgh * sizeof(img[0]));
|
||||||
|
|||||||
Reference in New Issue
Block a user