commit c6739137f261945b2ae071f96c4b9daf1270eea7
parent b25e55e4622d419f252570d15080cdd2628b9236
Author: Nihal Jere <nihal@nihaljere.xyz>
Date: Mon, 26 Apr 2021 20:30:22 -0500
port to wayland
stolen from oasis' dmenu wayland port
Diffstat:
11 files changed, 1047 insertions(+), 1054 deletions(-)
diff --git a/Makefile b/Makefile
@@ -8,7 +8,7 @@ VERSION = 0.3
include config.mk
BIN = ${NAME}-${LAYOUT}
-SRC = drw.c ${NAME}.c util.c
+SRC = drw.c ${NAME}.c util.c swc-protocol.c
OBJ = ${SRC:.c=.o}
MAN1 = ${NAME}.1
@@ -29,7 +29,15 @@ svkbd.o: config.h layout.${LAYOUT}.h
.c.o:
${CC} ${SVKBD_CFLAGS} ${SVKBD_CPPFLAGS} -c $<
-${OBJ}: config.h config.mk
+swc-protocol.c: $(SWCPROTO)
+ @echo GEN $@
+ wayland-scanner code < $< > $@
+
+swc-client-protocol.h: $(SWCPROTO)
+ @echo GEN $@
+ wayland-scanner client-header < $< > $@
+
+${OBJ}: config.h config.mk swc-client-protocol.h
${BIN}: ${OBJ}
${CC} -o ${BIN} ${OBJ} ${SVKBD_LDFLAGS}
diff --git a/config.def.h b/config.def.h
@@ -1,4 +1,4 @@
-static const Bool wmborder = True;
+static const Bool wmborder = true;
static int fontsize = 22;
static double overlay_delay = 1.0; //in seconds
static double repeat_delay = 0.75; //in seconds, will not work on keys with overlays
diff --git a/config.mk b/config.mk
@@ -9,19 +9,21 @@ X11LIB = /usr/X11R6/lib
PKG_CONFIG = pkg-config
-# Xinerama, comment if you don't want it
-XINERAMALIBS = -L${X11LIB} -lXinerama
-XINERAMAFLAGS = -DXINERAMA
+PIXMANINC = /usr/include/pixman-1
+SWCPROTO = /usr/share/swc/swc.xml
+VKPROTO = protocols/virtual-keyboard-unstable-v1.xml
# includes and libs
INCS = -I. -I./layouts -I${X11INC} \
`$(PKG_CONFIG) --cflags fontconfig` \
- `$(PKG_CONFIG) --cflags freetype2`
-LIBS = -L${X11LIB} -lX11 -lXtst -lXft ${XINERAMALIBS} \
+ `$(PKG_CONFIG) --cflags freetype2` \
+ `$(PKG_CONFIG) --cflags pixman-1`
+LIBS = -L${X11LIB} -lX11 -lwayland-client -lxkbcommon -lwld -lswc \
`$(PKG_CONFIG) --libs fontconfig` \
- `$(PKG_CONFIG) --libs freetype2`
+ `$(PKG_CONFIG) --libs freetype2` \
+ `$(PKG_CONFIG) --libs pixman-1`
# use system flags
SVKBD_CFLAGS = ${CFLAGS} ${INCS}
SVKBD_LDFLAGS = ${LDFLAGS} ${LIBS}
-SVKBD_CPPFLAGS = ${CPPFLAGS} -D_DEFAULT_SOURCE -DVERSION=\"VERSION\" ${XINERAMAFLAGS} -DLAYOUT=\"layout.${LAYOUT}.h\"
+SVKBD_CPPFLAGS = ${CPPFLAGS} -D_DEFAULT_SOURCE -DVERSION=\"VERSION\" -DLAYOUT=\"layout.${LAYOUT}.h\"
diff --git a/drw.c b/drw.c
@@ -2,8 +2,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xft/Xft.h>
+#include <wayland-client.h>
+#include <wld/wld.h>
+#include <wld/wayland.h>
#include "drw.h"
#include "util.h"
@@ -61,41 +62,34 @@ utf8decode(const char *c, long *u, size_t clen)
}
Drw *
-drw_create(Display *dpy, int screen, Window root, unsigned int w, unsigned int h)
+drw_create(struct wl_display *dpy)
{
Drw *drw = ecalloc(1, sizeof(Drw));
drw->dpy = dpy;
- drw->screen = screen;
- drw->root = root;
- drw->w = w;
- drw->h = h;
- drw->drawable = XCreatePixmap(dpy, root, w, h, DefaultDepth(dpy, screen));
- drw->gc = XCreateGC(dpy, root, 0, NULL);
- XSetLineAttributes(dpy, drw->gc, 1, LineSolid, CapButt, JoinMiter);
+ drw->ctx = wld_wayland_create_context(dpy, WLD_SHM);
+ drw->renderer = wld_create_renderer(drw->ctx);
+ drw->fontctx = wld_font_create_context();
return drw;
}
void
-drw_resize(Drw *drw, unsigned int w, unsigned int h)
+drw_resize(Drw *drw, struct wl_surface *surface, unsigned int w, unsigned int h)
{
- if (!drw)
- return;
-
- drw->w = w;
- drw->h = h;
- if (drw->drawable)
- XFreePixmap(drw->dpy, drw->drawable);
- drw->drawable = XCreatePixmap(drw->dpy, drw->root, w, h, DefaultDepth(drw->dpy, drw->screen));
+ if (drw->surface)
+ wld_destroy_surface(drw->surface);
+ drw->surface = wld_wayland_create_surface(drw->ctx, w, h, WLD_FORMAT_XRGB8888, 0, surface);
}
void
drw_free(Drw *drw)
{
- XFreePixmap(drw->dpy, drw->drawable);
- XFreeGC(drw->dpy, drw->gc);
+ wld_destroy_surface(drw->surface);
+ wld_destroy_renderer(drw->renderer);
+ wld_destroy_context(drw->ctx);
drw_fontset_free(drw->fonts);
+ wld_font_destroy_context(drw->fontctx);
free(drw);
}
@@ -103,11 +97,10 @@ drw_free(Drw *drw)
* drw_fontset_create instead.
*/
static Fnt *
-xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
+wldfont_create(Drw *drw, const char *fontname, FcPattern *pattern)
{
Fnt *font;
- XftFont *xfont = NULL;
- FcPattern *pattern = NULL;
+ struct wld_font *wld = NULL;
if (fontname) {
/* Using the pattern found at font->xfont->pattern does not yield the
@@ -115,17 +108,17 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
* FcNameParse; using the latter results in the desired fallback
* behaviour whereas the former just results in missing-character
* rectangles being drawn, at least with some fonts. */
- if (!(xfont = XftFontOpenName(drw->dpy, drw->screen, fontname))) {
+ if (!(wld = wld_font_open_name(drw->fontctx, fontname))) {
fprintf(stderr, "error, cannot load font from name: '%s'\n", fontname);
return NULL;
}
if (!(pattern = FcNameParse((FcChar8 *) fontname))) {
fprintf(stderr, "error, cannot parse font name to pattern: '%s'\n", fontname);
- XftFontClose(drw->dpy, xfont);
+ wld_font_close(wld);
return NULL;
}
- } else if (fontpattern) {
- if (!(xfont = XftFontOpenPattern(drw->dpy, fontpattern))) {
+ } else if (pattern) {
+ if (!(wld = wld_font_open_pattern(drw->fontctx, pattern))) {
fprintf(stderr, "error, cannot load font from pattern.\n");
return NULL;
}
@@ -141,28 +134,26 @@ xfont_create(Drw *drw, const char *fontname, FcPattern *fontpattern)
* and lots more all over the internet.
*/
FcBool iscol;
- if(FcPatternGetBool(xfont->pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
- XftFontClose(drw->dpy, xfont);
+ if(FcPatternGetBool(pattern, FC_COLOR, 0, &iscol) == FcResultMatch && iscol) {
+ wld_font_close(wld);
return NULL;
}
font = ecalloc(1, sizeof(Fnt));
- font->xfont = xfont;
+ font->wld = wld;
font->pattern = pattern;
- font->h = xfont->ascent + xfont->descent;
- font->dpy = drw->dpy;
return font;
}
static void
-xfont_free(Fnt *font)
+wldfont_free(Fnt *font)
{
if (!font)
return;
if (font->pattern)
FcPatternDestroy(font->pattern);
- XftFontClose(font->dpy, font->xfont);
+ wld_font_close(font->wld);
free(font);
}
@@ -176,7 +167,7 @@ drw_fontset_create(Drw* drw, const char *fonts[], size_t fontcount)
return NULL;
for (i = 1; i <= fontcount; i++) {
- if ((cur = xfont_create(drw, fonts[fontcount - i], NULL))) {
+ if ((cur = wldfont_create(drw, fonts[fontcount - i], NULL))) {
cur->next = ret;
ret = cur;
}
@@ -189,7 +180,7 @@ drw_fontset_free(Fnt *font)
{
if (font) {
drw_fontset_free(font->next);
- xfont_free(font);
+ wldfont_free(font);
}
}
@@ -199,9 +190,7 @@ drw_clr_create(Drw *drw, Clr *dest, const char *clrname)
if (!drw || !dest || !clrname)
return;
- if (!XftColorAllocName(drw->dpy, DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen),
- clrname, dest))
+ if (!(wld_lookup_named_color(clrname, dest)))
die("error, cannot allocate color '%s'", clrname);
}
@@ -214,7 +203,7 @@ drw_scm_create(Drw *drw, const char *clrnames[], size_t clrcount)
Clr *ret;
/* need at least two colors for a scheme */
- if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(XftColor))))
+ if (!drw || !clrnames || clrcount < 2 || !(ret = ecalloc(clrcount, sizeof(*ret))))
die("error, cannot create color scheme (drw=%d) (clrcount=%d)", drw, clrcount);
for (i = 0; i < clrcount; i++)
@@ -241,11 +230,15 @@ drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled, int
{
if (!drw || !drw->scheme)
return;
- XSetForeground(drw->dpy, drw->gc, invert ? drw->scheme[ColBg].pixel : drw->scheme[ColFg].pixel);
+ Clr color = invert ? drw->scheme[ColBg] : drw->scheme[ColFg];
if (filled)
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- else
- XDrawRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w - 1, h - 1);
+ wld_fill_rectangle(drw->renderer, color, x, y, w, h);
+ else {
+ wld_fill_rectangle(drw->renderer, color, x, y, w, 1);
+ wld_fill_rectangle(drw->renderer, color, x + w - 1, y + 1, 1, h - 2);
+ wld_fill_rectangle(drw->renderer, color, x, y + 1, 1, h - 2);
+ wld_fill_rectangle(drw->renderer, color, x, y - 1, w, 1);
+ }
}
int
@@ -254,7 +247,6 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
char buf[1024];
int ty;
unsigned int ew;
- XftDraw *d = NULL;
Fnt *usedfont, *curfont, *nextfont;
size_t i, len;
int utf8strlen, utf8charlen, render = x || y || w || h;
@@ -263,7 +255,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcCharSet *fccharset;
FcPattern *fcpattern;
FcPattern *match;
- XftResult result;
+ FcResult result;
int charexists = 0;
if (!drw || (render && !drw->scheme) || !text || !drw->fonts)
@@ -272,11 +264,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
if (!render) {
w = ~w;
} else {
- XSetForeground(drw->dpy, drw->gc, drw->scheme[invert ? ColFg : ColBg].pixel);
- XFillRectangle(drw->dpy, drw->drawable, drw->gc, x, y, w, h);
- d = XftDrawCreate(drw->dpy, drw->drawable,
- DefaultVisual(drw->dpy, drw->screen),
- DefaultColormap(drw->dpy, drw->screen));
+ wld_fill_rectangle(drw->renderer, drw->scheme[invert ? ColFg : ColBg], x, y, w, h);
x += lpad;
w -= lpad;
}
@@ -289,7 +277,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
while (*text) {
utf8charlen = utf8decode(text, &utf8codepoint, UTF_SIZ);
for (curfont = drw->fonts; curfont; curfont = curfont->next) {
- charexists = charexists || XftCharExists(drw->dpy, curfont->xfont, utf8codepoint);
+ charexists = charexists || wld_font_ensure_char(curfont->wld, utf8codepoint);
if (charexists) {
if (curfont == usedfont) {
utf8strlen += utf8charlen;
@@ -321,9 +309,9 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
; /* NOP */
if (render) {
- ty = y + (h - usedfont->h) / 2 + usedfont->xfont->ascent;
- XftDrawStringUtf8(d, &drw->scheme[invert ? ColBg : ColFg],
- usedfont->xfont, x, ty, (XftChar8 *)buf, len);
+ ty = y + (h - usedfont->wld->height) / 2 + usedfont->wld->ascent;
+ wld_draw_text(drw->renderer, usedfont->wld, drw->scheme[invert ? ColBg : ColFg],
+ x, ty, buf, len, NULL);
}
x += ew;
w -= ew;
@@ -344,7 +332,7 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcCharSetAddChar(fccharset, utf8codepoint);
if (!drw->fonts->pattern) {
- /* Refer to the comment in xfont_create for more information. */
+ /* Refer to the comment in wldfont_create for more information. */
die("the first font in the cache must be loaded from a font string.");
}
@@ -355,43 +343,44 @@ drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lp
FcConfigSubstitute(NULL, fcpattern, FcMatchPattern);
FcDefaultSubstitute(fcpattern);
- match = XftFontMatch(drw->dpy, drw->screen, fcpattern, &result);
+ match = FcFontMatch(NULL, fcpattern, &result);
FcCharSetDestroy(fccharset);
FcPatternDestroy(fcpattern);
if (match) {
- usedfont = xfont_create(drw, NULL, match);
- if (usedfont && XftCharExists(drw->dpy, usedfont->xfont, utf8codepoint)) {
+ usedfont = wldfont_create(drw, NULL, match);
+ if (usedfont && wld_font_ensure_char(usedfont->wld, utf8codepoint)) {
for (curfont = drw->fonts; curfont->next; curfont = curfont->next)
; /* NOP */
curfont->next = usedfont;
} else {
- xfont_free(usedfont);
+ wldfont_free(usedfont);
usedfont = drw->fonts;
}
}
}
}
- if (d)
- XftDrawDestroy(d);
return x + (render ? w : 0);
}
void
-drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h)
+drw_map(Drw *drw, struct wl_surface *surface, int x, int y, unsigned int w, unsigned int h)
{
if (!drw)
return;
- XCopyArea(drw->dpy, drw->drawable, win, drw->gc, x, y, w, h, x, y);
+ wl_surface_damage(surface, x, y, w, h);
+ wld_flush(drw->renderer);
+ wld_swap(drw->surface);
}
void
drw_sync(Drw *drw)
{
- XSync(drw->dpy, False);
+ wld_flush(drw->renderer);
+ wld_swap(drw->surface);
}
unsigned int
@@ -405,14 +394,14 @@ drw_fontset_getwidth(Drw *drw, const char *text)
void
drw_font_getexts(Fnt *font, const char *text, unsigned int len, unsigned int *w, unsigned int *h)
{
- XGlyphInfo ext;
+ struct wld_extents ext;
if (!font || !text)
return;
- XftTextExtentsUtf8(font->dpy, font->xfont, (XftChar8 *)text, len, &ext);
+ wld_font_text_extents_n(font->wld, text, len, &ext);
if (w)
- *w = ext.xOff;
+ *w = ext.advance;
if (h)
- *h = font->h;
+ *h = font->wld->height;
}
diff --git a/drw.h b/drw.h
@@ -1,30 +1,28 @@
/* See LICENSE file for copyright and license details. */
typedef struct Fnt {
- Display *dpy;
- unsigned int h;
- XftFont *xfont;
+ struct wld_font *wld;
FcPattern *pattern;
struct Fnt *next;
} Fnt;
enum { ColFg, ColBg }; /* Clr scheme index */
-typedef XftColor Clr;
+typedef uint32_t Clr;
typedef struct {
unsigned int w, h;
- Display *dpy;
- int screen;
- Window root;
- Drawable drawable;
- GC gc;
+ struct wl_display *dpy;
+ struct wld_context *ctx;
+ struct wld_renderer *renderer;
+ struct wld_surface *surface;
+ struct wld_font_context *fontctx;
Clr *scheme;
Fnt *fonts;
} Drw;
/* Drawable abstraction */
-Drw *drw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h);
-void drw_resize(Drw *drw, unsigned int w, unsigned int h);
+Drw *drw_create(struct wl_display *dpy);
+void drw_resize(Drw *drw, struct wl_surface *surface, unsigned int w, unsigned int h);
void drw_free(Drw *drw);
/* Fnt abstraction */
@@ -46,5 +44,5 @@ void drw_rect(Drw *drw, int x, int y, unsigned int w, unsigned int h, int filled
int drw_text(Drw *drw, int x, int y, unsigned int w, unsigned int h, unsigned int lpad, const char *text, int invert);
/* Map functions */
-void drw_map(Drw *drw, Window win, int x, int y, unsigned int w, unsigned int h);
+void drw_map(Drw *drw, struct wl_surface *surface, int x, int y, unsigned int w, unsigned int h);
void drw_sync(Drw *drw);
diff --git a/layout.mobile-intl.h b/layout.mobile-intl.h
@@ -1,261 +1,261 @@
#define KEYS 55
static Key keys_en[KEYS] = {
- { "Esc", "", XK_Escape, 1 },
- { "1", "!", XK_1, 1 },
- { "2", "@", XK_2, 1 },
- { "3", "#", XK_3, 1 },
- { "4", "$", XK_4, 1 },
- { "5", "%", XK_5, 1 },
- { "6", "^", XK_6, 1 },
- { "7", "&", XK_7, 1 },
- { "8", "*", XK_8, 1 },
- { "9", "(", XK_9, 1 },
- { "0", ")", XK_0, 1 },
+ { "Esc", "", XKB_KEY_Escape, 1 },
+ { "1", "!", XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
{ 0 }, /* New row */
- { 0, 0, XK_q, 1 },
- { 0, 0, XK_w, 1 },
- { 0, 0, XK_e, 1 },
- { 0, 0, XK_r, 1 },
- { 0, 0, XK_t, 1 },
- { 0, 0, XK_y, 1 },
- { 0, 0, XK_u, 1 },
- { 0, 0, XK_i, 1 },
- { 0, 0, XK_o, 1 },
- { 0, 0, XK_p, 1 },
- { "'", "\"", XK_apostrophe, 1 },
+ { "q", 0, XKB_KEY_q, 1 },
+ { "w", 0, XKB_KEY_w, 1 },
+ { "e", 0, XKB_KEY_e, 1 },
+ { "r", 0, XKB_KEY_r, 1 },
+ { "t", 0, XKB_KEY_t, 1 },
+ { "y", 0, XKB_KEY_y, 1 },
+ { "u", 0, XKB_KEY_u, 1 },
+ { "i", 0, XKB_KEY_i, 1 },
+ { "o", 0, XKB_KEY_o, 1 },
+ { "p", 0, XKB_KEY_p, 1 },
+ { "'", "\"", XKB_KEY_apostrophe, 1 },
{ 0 }, /* New row */
- { 0, 0, XK_a, 1 },
- { 0, 0, XK_s, 1 },
- { 0, 0, XK_d, 1 },
- { 0, 0, XK_f, 1 },
- { 0, 0, XK_g, 1 },
- { 0, 0, XK_h, 1 },
- { 0, 0, XK_j, 1 },
- { 0, 0, XK_k, 1 },
- { 0, 0, XK_l, 1 },
- { "/", "?", XK_slash, 1 },
- { "Tab", 0, XK_Tab, 1 },
+ { "a", 0, XKB_KEY_a, 1 },
+ { "s", 0, XKB_KEY_s, 1 },
+ { "d", 0, XKB_KEY_d, 1 },
+ { "f", 0, XKB_KEY_f, 1 },
+ { "g", 0, XKB_KEY_g, 1 },
+ { "h", 0, XKB_KEY_h, 1 },
+ { "j", 0, XKB_KEY_j, 1 },
+ { "k", 0, XKB_KEY_k, 1 },
+ { "l", 0, XKB_KEY_l, 1 },
+ { "/", "?", XKB_KEY_slash, 1 },
+ { "Tab", 0, XKB_KEY_Tab, 1 },
{ 0 }, /* New row */
- { 0, 0, XK_z, 1 },
- { 0, 0, XK_x, 1 },
- { 0, 0, XK_c, 1 },
- { 0, 0, XK_v, 1 },
- { 0, 0, XK_b, 1 },
- { 0, 0, XK_n, 1 },
- { 0, 0, XK_m, 1 },
- { ",", "<", XK_comma, 1 },
- { ".", ">", XK_period, 1 },
- { "⌫Bksp", 0, XK_BackSpace, 2 },
+ { "z", 0, XKB_KEY_z, 1 },
+ { "x", 0, XKB_KEY_x, 1 },
+ { "c", 0, XKB_KEY_c, 1 },
+ { "v", 0, XKB_KEY_v, 1 },
+ { "b", 0, XKB_KEY_b, 1 },
+ { "n", 0, XKB_KEY_n, 1 },
+ { "m", 0, XKB_KEY_m, 1 },
+ { ",", "<", XKB_KEY_comma, 1 },
+ { ".", ">", XKB_KEY_period, 1 },
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 2 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "Shift", 0, XK_Shift_L, 2 },
- { "Ctrl", 0, XK_Control_L, 1 },
- { "Alt", 0, XK_Alt_L, 1 },
- { "", 0, XK_space, 2 },
- { "↓", 0, XK_Down, 1 },
- { "↑", 0, XK_Up, 1 },
- { "↲ Enter", 0, XK_Return, 2 },
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "Shift", 0, XKB_KEY_Shift_L, 2 },
+ { "Ctrl", 0, XKB_KEY_Control_L, 1 },
+ { "Alt", 0, XKB_KEY_Alt_L, 1 },
+ { "", 0, XKB_KEY_space, 2 },
+ { "↓", 0, XKB_KEY_Down, 1 },
+ { "↑", 0, XKB_KEY_Up, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
};
#define OVERLAYS 197
static Key overlay[OVERLAYS] = {
- { 0, 0, XK_a }, //Overlay for a
- //---
- { "à", 0, XK_agrave },
- { "á", 0, XK_aacute },
- { "â", 0, XK_acircumflex },
- { "ä", 0, XK_adiaeresis },
- { "ą", 0, XK_aogonek },
- { "ã", 0, XK_atilde },
- { "ā", 0, XK_amacron },
- { "ă", 0, XK_abreve },
- { "å", 0, XK_aring },
- { "æ", 0, XK_ae },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { 0, 0, XKB_KEY_a }, //Overlay for a
+ //---
+ { "à", 0, XKB_KEY_agrave },
+ { "á", 0, XKB_KEY_aacute },
+ { "â", 0, XKB_KEY_acircumflex },
+ { "ä", 0, XKB_KEY_adiaeresis },
+ { "ą", 0, XKB_KEY_aogonek },
+ { "ã", 0, XKB_KEY_atilde },
+ { "ā", 0, XKB_KEY_amacron },
+ { "ă", 0, XKB_KEY_abreve },
+ { "å", 0, XKB_KEY_aring },
+ { "æ", 0, XKB_KEY_ae },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_e }, //Overlay for e (first item after boundary defines the trigger)
- //---
- { "è", 0, XK_egrave },
- { "é", 0, XK_eacute },
- { "ê", 0, XK_ecircumflex },
- { "ë", 0, XK_ediaeresis },
- { "ę", 0, XK_eogonek },
- { "ē", 0, XK_emacron },
- { "ė", 0, XK_eabovedot },
- { 0, 0, XK_Cancel },
+ { 0, 0, XKB_KEY_e }, //Overlay for e (first item after boundary defines the trigger)
+ //---
+ { "è", 0, XKB_KEY_egrave },
+ { "é", 0, XKB_KEY_eacute },
+ { "ê", 0, XKB_KEY_ecircumflex },
+ { "ë", 0, XKB_KEY_ediaeresis },
+ { "ę", 0, XKB_KEY_eogonek },
+ { "ē", 0, XKB_KEY_emacron },
+ { "ė", 0, XKB_KEY_eabovedot },
+ { 0, 0, XKB_KEY_Cancel },
//--
- { 0, 0, XK_y }, //New overlay
+ { 0, 0, XKB_KEY_y }, //New overlay
//---
- { "ỳ", 0, XK_ygrave },
- { "ý", 0, XK_yacute },
- { "ŷ", 0, XK_ycircumflex },
- { "ÿ", 0, XK_ydiaeresis },
- { 0, 0, XK_Cancel },
+ { "ỳ", 0, XKB_KEY_ygrave },
+ { "ý", 0, XKB_KEY_yacute },
+ { "ŷ", 0, XKB_KEY_ycircumflex },
+ { "ÿ", 0, XKB_KEY_ydiaeresis },
+ { 0, 0, XKB_KEY_Cancel },
//--
- { 0, 0, XK_u }, //New overlay
- //---
- { "ù", 0, XK_ugrave },
- { "ú", 0, XK_uacute },
- { "û", 0, XK_ucircumflex },
- { "ü", 0, XK_udiaeresis },
- { "ų", 0, XK_uogonek },
- { "ū", 0, XK_umacron },
- { "ů", 0, XK_uring},
- { "ŭ", 0, XK_ubreve},
- { "ű", 0, XK_udoubleacute },
- { 0, 0, XK_Cancel },
+ { 0, 0, XKB_KEY_u }, //New overlay
+ //---
+ { "ù", 0, XKB_KEY_ugrave },
+ { "ú", 0, XKB_KEY_uacute },
+ { "û", 0, XKB_KEY_ucircumflex },
+ { "ü", 0, XKB_KEY_udiaeresis },
+ { "ų", 0, XKB_KEY_uogonek },
+ { "ū", 0, XKB_KEY_umacron },
+ { "ů", 0, XKB_KEY_uring},
+ { "ŭ", 0, XKB_KEY_ubreve},
+ { "ű", 0, XKB_KEY_udoubleacute },
+ { 0, 0, XKB_KEY_Cancel },
//--
- { 0, 0, XK_i }, //New overlay
- //---
- { "ì", 0, XK_igrave },
- { "í", 0, XK_iacute },
- { "î", 0, XK_icircumflex },
- { "ï", 0, XK_idiaeresis },
- { "į", 0, XK_iogonek },
- { "ī", 0, XK_imacron },
- { "ı", 0, XK_idotless },
- { 0, 0, XK_Cancel },
+ { 0, 0, XKB_KEY_i }, //New overlay
+ //---
+ { "ì", 0, XKB_KEY_igrave },
+ { "í", 0, XKB_KEY_iacute },
+ { "î", 0, XKB_KEY_icircumflex },
+ { "ï", 0, XKB_KEY_idiaeresis },
+ { "į", 0, XKB_KEY_iogonek },
+ { "ī", 0, XKB_KEY_imacron },
+ { "ı", 0, XKB_KEY_idotless },
+ { 0, 0, XKB_KEY_Cancel },
//--
- { 0, 0, XK_o }, //New overlay
- //---
- { "ò", 0, XK_ograve },
- { "ó", 0, XK_oacute },
- { "ô", 0, XK_ocircumflex },
- { "ö", 0, XK_odiaeresis },
- { "ǫ", 0, XK_ogonek },
- { "õ", 0, XK_otilde },
- { "ō", 0, XK_omacron },
- { "ø", 0, XK_oslash },
- { "ő", 0, XK_odoubleacute },
- { "œ", 0, XK_oe },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { 0, 0, XKB_KEY_o }, //New overlay
+ //---
+ { "ò", 0, XKB_KEY_ograve },
+ { "ó", 0, XKB_KEY_oacute },
+ { "ô", 0, XKB_KEY_ocircumflex },
+ { "ö", 0, XKB_KEY_odiaeresis },
+ { "ǫ", 0, XKB_KEY_ogonek },
+ { "õ", 0, XKB_KEY_otilde },
+ { "ō", 0, XKB_KEY_omacron },
+ { "ø", 0, XKB_KEY_oslash },
+ { "ő", 0, XKB_KEY_odoubleacute },
+ { "œ", 0, XKB_KEY_oe },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_d }, //New overlay
+ { 0, 0, XKB_KEY_d }, //New overlay
//---
- { "ď", 0, XK_dcaron },
- { "ð", 0, XK_eth },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ď", 0, XKB_KEY_dcaron },
+ { "ð", 0, XKB_KEY_eth },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_c }, //New overlay
+ { 0, 0, XKB_KEY_c }, //New overlay
//---
- { "ç", 0, XK_ccedilla },
- { "ĉ", 0, XK_ccircumflex },
- { "č", 0, XK_ccaron },
- { "ć", 0, XK_cacute },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ç", 0, XKB_KEY_ccedilla },
+ { "ĉ", 0, XKB_KEY_ccircumflex },
+ { "č", 0, XKB_KEY_ccaron },
+ { "ć", 0, XKB_KEY_cacute },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_s }, //New overlay
+ { 0, 0, XKB_KEY_s }, //New overlay
//---
- { "ş", 0, XK_scedilla },
- { "ŝ", 0, XK_scircumflex },
- { "š", 0, XK_scaron },
- { "ś", 0, XK_sacute },
- { "ß", 0, XK_ssharp },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ş", 0, XKB_KEY_scedilla },
+ { "ŝ", 0, XKB_KEY_scircumflex },
+ { "š", 0, XKB_KEY_scaron },
+ { "ś", 0, XKB_KEY_sacute },
+ { "ß", 0, XKB_KEY_ssharp },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_z }, //New overlay
+ { 0, 0, XKB_KEY_z }, //New overlay
//---
- { "ž", 0, XK_zcaron },
- { "ż", 0, XK_zabovedot },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ž", 0, XKB_KEY_zcaron },
+ { "ż", 0, XKB_KEY_zabovedot },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_n }, //New overlay
+ { 0, 0, XKB_KEY_n }, //New overlay
//---
- { "ñ", 0, XK_ntilde },
- { "ń", 0, XK_nacute },
- { "ň", 0, XK_ncaron },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ñ", 0, XKB_KEY_ntilde },
+ { "ń", 0, XKB_KEY_nacute },
+ { "ň", 0, XKB_KEY_ncaron },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//
- { 0, 0, XK_t }, //New overlay
+ { 0, 0, XKB_KEY_t }, //New overlay
//---
- { "ț", 0, XK_tcedilla },
- { "ť", 0, XK_tcaron },
- { "þ", 0, XK_thorn },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ț", 0, XKB_KEY_tcedilla },
+ { "ť", 0, XKB_KEY_tcaron },
+ { "þ", 0, XKB_KEY_thorn },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//----
- { 0, 0, XK_g }, //New overlay
+ { 0, 0, XKB_KEY_g }, //New overlay
//---
- { "ĝ", 0, XK_gcircumflex },
- { "ğ", 0, XK_gbreve },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ĝ", 0, XKB_KEY_gcircumflex },
+ { "ğ", 0, XKB_KEY_gbreve },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//
- { 0, 0, XK_h }, //New overlay
+ { 0, 0, XKB_KEY_h }, //New overlay
//---
- { "ĥ", 0, XK_hcircumflex },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ĥ", 0, XKB_KEY_hcircumflex },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//
- { 0, 0, XK_j }, //New overlay
+ { 0, 0, XKB_KEY_j }, //New overlay
//---
- { "ĵ", 0, XK_jcircumflex },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ĵ", 0, XKB_KEY_jcircumflex },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_l }, //New overlay
+ { 0, 0, XKB_KEY_l }, //New overlay
//---
- { "ł", 0, XK_lstroke },
- { "ľ", 0, XK_lcaron },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ł", 0, XKB_KEY_lstroke },
+ { "ľ", 0, XKB_KEY_lcaron },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { 0, 0, XK_r }, //New overlay
+ { 0, 0, XKB_KEY_r }, //New overlay
//---
- { "ř", 0, XK_rcaron },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ř", 0, XKB_KEY_rcaron },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_softsign }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_softsign }, //New overlay
//---
- { "ъ", 0, XK_Cyrillic_hardsign },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ъ", 0, XKB_KEY_Cyrillic_hardsign },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_ie }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_ie }, //New overlay
//---
- { "ё", 0, XK_Cyrillic_io },
- { "э", 0, XK_Cyrillic_e },
- { "Є", 0, XK_Ukrainian_ie },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ё", 0, XKB_KEY_Cyrillic_io },
+ { "э", 0, XKB_KEY_Cyrillic_e },
+ { "Є", 0, XKB_KEY_Ukrainian_ie },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_i }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_i }, //New overlay
//---
- { "і", 0, XK_Ukrainian_i },
- { "ї", 0, XK_Ukrainian_yi },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "і", 0, XKB_KEY_Ukrainian_i },
+ { "ї", 0, XKB_KEY_Ukrainian_yi },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_u }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_u }, //New overlay
//---
- { "ў", 0, XK_Byelorussian_shortu },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ў", 0, XKB_KEY_Byelorussian_shortu },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_shorti }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_shorti }, //New overlay
//---
- { "ј", 0, XK_Cyrillic_je },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ј", 0, XKB_KEY_Cyrillic_je },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_el }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_el }, //New overlay
//---
- { "љ", 0, XK_Cyrillic_lje },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "љ", 0, XKB_KEY_Cyrillic_lje },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_en }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_en }, //New overlay
//---
- { "њ", 0, XK_Cyrillic_nje },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "њ", 0, XKB_KEY_Cyrillic_nje },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_tse }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_tse }, //New overlay
//---
- { "џ", 0, XK_Cyrillic_dzhe },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "џ", 0, XKB_KEY_Cyrillic_dzhe },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
- { 0, 0, XK_Cyrillic_che }, //New overlay
+ { 0, 0, XKB_KEY_Cyrillic_che }, //New overlay
//---
- { "ћ", 0, XK_Serbian_tshe },
- { "ђ", 0, XK_Serbian_dje },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "ћ", 0, XKB_KEY_Serbian_tshe },
+ { "ђ", 0, XKB_KEY_Serbian_dje },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//---
{ "🙂", 0, 0x101f642 }, //emoji overlay
//---
@@ -286,264 +286,264 @@ static Key overlay[OVERLAYS] = {
{ "😭", 0, 0x101f62d },
{ "😳", 0, 0x101f633 },
{ "😴", 0, 0x101f634 },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
//--
- { "/?", 0, XK_slash }, //punctuation overlay
+ { "/?", 0, XKB_KEY_slash }, //punctuation overlay
//--
- { "1", "!", XK_1, 1 },
- { "2", "@", XK_2, 1 },
- { "3", "#", XK_3, 1 },
- { "4", "$", XK_4, 1 },
- { "5", "%", XK_5, 1 },
- { "6", "^", XK_6, 1 },
- { "7", "&", XK_7, 1 },
- { "8", "*", XK_8, 1 },
- { "9", "(", XK_9, 1 },
- { "0", ")", XK_0, 1 },
- { "'", "\"", XK_apostrophe, 1 },
- { "`", "~", XK_grave, 1 },
- { "-", "_", XK_minus, 1 },
- { "=", "+", XK_plus, 1 },
- { "[", "{", XK_bracketleft, 1 },
- { "]", "}", XK_bracketright, 1 },
- { ",", "<", XK_comma, 1 },
- { ".", ">", XK_period, 1 },
- { "/", "?", XK_slash, 1 },
- { "\\", "|", XK_backslash, 1 },
- { "¡", 0, XK_exclamdown, 1 },
- { "?", 0, XK_questiondown, 1 },
- { "°", 0, XK_degree, 1 },
- { "£", 0, XK_sterling, 1 },
- { "€", 0, XK_EuroSign, 1 },
- { "¥", 0, XK_yen, 1 },
- { ";", ":", XK_colon, 1 },
- { 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
+ { "1", "!", XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
+ { "'", "\"", XKB_KEY_apostrophe, 1 },
+ { "`", "~", XKB_KEY_grave, 1 },
+ { "-", "_", XKB_KEY_minus, 1 },
+ { "=", "+", XKB_KEY_plus, 1 },
+ { "[", "{", XKB_KEY_bracketleft, 1 },
+ { "]", "}", XKB_KEY_bracketright, 1 },
+ { ",", "<", XKB_KEY_comma, 1 },
+ { ".", ">", XKB_KEY_period, 1 },
+ { "/", "?", XKB_KEY_slash, 1 },
+ { "\\", "|", XKB_KEY_backslash, 1 },
+ { "¡", 0, XKB_KEY_exclamdown, 1 },
+ { "?", 0, XKB_KEY_questiondown, 1 },
+ { "°", 0, XKB_KEY_degree, 1 },
+ { "£", 0, XKB_KEY_sterling, 1 },
+ { "€", 0, XKB_KEY_EuroSign, 1 },
+ { "¥", 0, XKB_KEY_yen, 1 },
+ { ";", ":", XKB_KEY_colon, 1 },
+ { 0, 0, XKB_KEY_Cancel }, /* XKB_KEY_Cancel signifies overlay boundary */
};
static Key keys_symbols[KEYS] = {
- { "Esc", 0, XK_Escape, 1 },
- { "F1", 0, XK_F1, 1 },
- { "F2", 0, XK_F2, 1 },
- { "F3", 0, XK_F3, 1 },
- { "F4", 0, XK_F4, 1 },
- { "F5", 0, XK_F5, 1 },
- { "F6", 0, XK_F6, 1 },
- { "F7", 0, XK_F7, 1 },
- { "F8", 0, XK_F8, 1 },
- { "F9", 0, XK_F9, 1 },
- { "F10", 0, XK_F10, 1 },
+ { "Esc", 0, XKB_KEY_Escape, 1 },
+ { "F1", 0, XKB_KEY_F1, 1 },
+ { "F2", 0, XKB_KEY_F2, 1 },
+ { "F3", 0, XKB_KEY_F3, 1 },
+ { "F4", 0, XKB_KEY_F4, 1 },
+ { "F5", 0, XKB_KEY_F5, 1 },
+ { "F6", 0, XKB_KEY_F6, 1 },
+ { "F7", 0, XKB_KEY_F7, 1 },
+ { "F8", 0, XKB_KEY_F8, 1 },
+ { "F9", 0, XKB_KEY_F9, 1 },
+ { "F10", 0, XKB_KEY_F10, 1 },
{ 0 }, /* New row */
- { "'\"", 0, XK_apostrophe, 1 },
- { "1", "!", XK_1, 1 },
- { "2", "@", XK_2, 1 },
- { "3", "#", XK_3, 1 },
- { "4", "$", XK_4, 1 },
- { "5", "%", XK_5, 1 },
- { "6", "^", XK_6, 1 },
- { "7", "&", XK_7, 1 },
- { "8", "*", XK_8, 1 },
- { "9", "(", XK_9, 1 },
- { "0", ")", XK_0, 1 },
+ { "'\"", 0, XKB_KEY_apostrophe, 1 },
+ { "1", "!", XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
{ 0 }, /* New row */
- { ".", ">", XK_period, 1 },
- { ",", "<", XK_comma, 1 },
- { "`", "~", XK_grave, 1 },
- { "-", "_", XK_minus, 1 },
- { "=", "+", XK_plus, 1 },
- { "\\", "|", XK_backslash, 1 },
- { ";", ":", XK_colon, 1 },
- { "/", "?", XK_slash, 1 },
- { "[", "{", XK_bracketleft, 1 },
- { "]", "}", XK_bracketright, 1 },
- { "Del", 0, XK_Delete, 1 },
+ { ".", ">", XKB_KEY_period, 1 },
+ { ",", "<", XKB_KEY_comma, 1 },
+ { "`", "~", XKB_KEY_grave, 1 },
+ { "-", "_", XKB_KEY_minus, 1 },
+ { "=", "+", XKB_KEY_plus, 1 },
+ { "\\", "|", XKB_KEY_backslash, 1 },
+ { ";", ":", XKB_KEY_colon, 1 },
+ { "/", "?", XKB_KEY_slash, 1 },
+ { "[", "{", XKB_KEY_bracketleft, 1 },
+ { "]", "}", XKB_KEY_bracketright, 1 },
+ { "Del", 0, XKB_KEY_Delete, 1 },
{ 0 }, /* New row */
- { "abc", 0, XK_Mode_switch, 1 },
+ { "abc", 0, XKB_KEY_Mode_switch, 1 },
{ "☺", 0, 0x101f642, 1 },
- { "⇤", 0, XK_Home, 1 },
- { "←", 0, XK_Left, 1 },
- { "→", 0, XK_Right, 1 },
- { "⇥", 0, XK_End, 1 },
- { "⇊", 0, XK_Next, 1 },
- { "⇈", 0, XK_Prior, 1 },
- { "Tab", 0, XK_Tab, 1 },
- { "⌫Bksp", 0, XK_BackSpace, 2 },
+ { "⇤", 0, XKB_KEY_Home, 1 },
+ { "←", 0, XKB_KEY_Left, 1 },
+ { "→", 0, XKB_KEY_Right, 1 },
+ { "⇥", 0, XKB_KEY_End, 1 },
+ { "⇊", 0, XKB_KEY_Next, 1 },
+ { "⇈", 0, XKB_KEY_Prior, 1 },
+ { "Tab", 0, XKB_KEY_Tab, 1 },
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 2 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "Shift", 0, XK_Shift_L, 2 },
- { "Ctrl", 0, XK_Control_L, 1 },
- { "Alt", 0, XK_Alt_L, 1 },
- { "", 0, XK_space, 2 },
- { "↓", 0, XK_Down, 1 },
- { "↑", 0, XK_Up, 1 },
- { "↲ Enter", 0, XK_Return, 2 },
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "Shift", 0, XKB_KEY_Shift_L, 2 },
+ { "Ctrl", 0, XKB_KEY_Control_L, 1 },
+ { "Alt", 0, XKB_KEY_Alt_L, 1 },
+ { "", 0, XKB_KEY_space, 2 },
+ { "↓", 0, XKB_KEY_Down, 1 },
+ { "↑", 0, XKB_KEY_Up, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
};
static Key keys_functions[KEYS] = {
- { "Esc", 0, XK_Escape, 1 },
- { "▶", 0, XF86XK_AudioPlay, 1 },
- { "●", 0, XF86XK_AudioRecord, 1 },
- { "■", 0, XF86XK_AudioStop, 1 },
- { "◂◂", 0, XF86XK_AudioPrev, 1 },
- { "▸▸", 0, XF86XK_AudioNext, 1 },
- { "♫M", 0, XF86XK_AudioMute, 1 },
- { "♫-", 0, XF86XK_AudioLowerVolume, 1 },
- { "♫+", 0, XF86XK_AudioRaiseVolume, 1 },
- { "☀-", 0, XF86XK_MonBrightnessDown, 1 },
- { "☀+", 0, XF86XK_MonBrightnessUp, 1 },
+ { "Esc", 0, XKB_KEY_Escape, 1 },
+ { "▶", 0, XKB_KEY_XF86AudioPlay, 1 },
+ { "●", 0, XKB_KEY_XF86AudioRecord, 1 },
+ { "■", 0, XKB_KEY_XF86AudioStop, 1 },
+ { "◂◂", 0, XKB_KEY_XF86AudioPrev, 1 },
+ { "▸▸", 0, XKB_KEY_XF86AudioNext, 1 },
+ { "♫M", 0, XKB_KEY_XF86AudioMute, 1 },
+ { "♫-", 0, XKB_KEY_XF86AudioLowerVolume, 1 },
+ { "♫+", 0, XKB_KEY_XF86AudioRaiseVolume, 1 },
+ { "☀-", 0, XKB_KEY_XF86MonBrightnessDown, 1 },
+ { "☀+", 0, XKB_KEY_XF86MonBrightnessUp, 1 },
{ 0 }, /* New row */
- { "≅", 0, XK_KP_Insert, 1 },
- { "Del", 0, XK_Delete, 1 },
- { "⇤", 0, XK_Home, 1 },
- { "←", 0, XK_Left, 1 },
- { "→", 0, XK_Right, 1 },
- { "⇥", 0, XK_End, 1 },
- { "⇊", 0, XK_Next, 1 },
- { "⇈", 0, XK_Prior, 1 },
- { "Tab", 0, XK_Tab, 1 },
- { "⌫Bksp", 0, XK_BackSpace, 2 },
+ { "≅", 0, XKB_KEY_KP_Insert, 1 },
+ { "Del", 0, XKB_KEY_Delete, 1 },
+ { "⇤", 0, XKB_KEY_Home, 1 },
+ { "←", 0, XKB_KEY_Left, 1 },
+ { "→", 0, XKB_KEY_Right, 1 },
+ { "⇥", 0, XKB_KEY_End, 1 },
+ { "⇊", 0, XKB_KEY_Next, 1 },
+ { "⇈", 0, XKB_KEY_Prior, 1 },
+ { "Tab", 0, XKB_KEY_Tab, 1 },
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 2 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "Shift", 0, XK_Shift_L, 2 },
- { "Ctrl", 0, XK_Control_L, 1 },
- { "Alt", 0, XK_Alt_L, 1 },
- { "", 0, XK_space, 2 },
- { "↓", 0, XK_Down, 1 },
- { "↑", 0, XK_Up, 1 },
- { "↲ Enter", 0, XK_Return, 2 },
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "Shift", 0, XKB_KEY_Shift_L, 2 },
+ { "Ctrl", 0, XKB_KEY_Control_L, 1 },
+ { "Alt", 0, XKB_KEY_Alt_L, 1 },
+ { "", 0, XKB_KEY_space, 2 },
+ { "↓", 0, XKB_KEY_Down, 1 },
+ { "↑", 0, XKB_KEY_Up, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
{ 0 }, /* Last item (double 0) */
{ 0 }, /* Last item (double 0) */
};
static Key keys_navigation[KEYS] = {
- { "Esc", 0, XK_Escape, 1 },
- { "⇤", 0, XK_Home, 1 },
- { "↑", 0, XK_Up, 1 },
- { "⇥", 0, XK_End, 1 },
- { "⇈", 0, XK_Prior, 1 },
+ { "Esc", 0, XKB_KEY_Escape, 1 },
+ { "⇤", 0, XKB_KEY_Home, 1 },
+ { "↑", 0, XKB_KEY_Up, 1 },
+ { "⇥", 0, XKB_KEY_End, 1 },
+ { "⇈", 0, XKB_KEY_Prior, 1 },
{ 0 }, /* New row */
- { "Shift", 0, XK_Shift_L, 1 },
- { "←", 0, XK_Left, 1 },
- { "", 0, XK_space, 1 },
- { "→", 0, XK_Right, 1 },
- { "⇊", 0, XK_Next, 1 },
+ { "Shift", 0, XKB_KEY_Shift_L, 1 },
+ { "←", 0, XKB_KEY_Left, 1 },
+ { "", 0, XKB_KEY_space, 1 },
+ { "→", 0, XKB_KEY_Right, 1 },
+ { "⇊", 0, XKB_KEY_Next, 1 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "⌫Bksp", 0, XK_BackSpace, 1 },
- { "↓", 0, XK_Down, 1 },
- { "Tab", 0, XK_Tab, 1 },
- { "↲ Enter", 0, XK_Return, 1},
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 1 },
+ { "↓", 0, XKB_KEY_Down, 1 },
+ { "Tab", 0, XKB_KEY_Tab, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 1},
{ 0 }, /* Last item (double 0) */
{ 0 }, /* Last item (double 0) */
};
static Key keys_ru[KEYS] = {
- { "Esc", 0, XK_Escape, 1 },
- { "1", "!", XK_1, 1 },
- { "2", "@", XK_2, 1 },
- { "3", "#", XK_3, 1 },
- { "4", "$", XK_4, 1 },
- { "5", "%", XK_5, 1 },
- { "6", "^", XK_6, 1 },
- { "7", "&", XK_7, 1 },
- { "8", "*", XK_8, 1 },
- { "9", "(", XK_9, 1 },
- { "0", ")", XK_0, 1 },
+ { "Esc", 0, XKB_KEY_Escape, 1 },
+ { "1", "!", XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
{ 0 }, /* New row */
- { "й", 0, XK_Cyrillic_shorti, 1 },
- { "ц", 0, XK_Cyrillic_tse, 1 },
- { "у", 0, XK_Cyrillic_u, 1 },
- { "к", 0, XK_Cyrillic_ka, 1 },
- { "е", 0, XK_Cyrillic_ie, 1 },
- { "н", 0, XK_Cyrillic_en, 1 },
- { "г", 0, XK_Cyrillic_ghe, 1 },
- { "ш", 0, XK_Cyrillic_sha, 1 },
- { "щ", 0, XK_Cyrillic_shcha, 1 },
- { "з", 0, XK_Cyrillic_ze, 1 },
- { "х", 0, XK_Cyrillic_ha, 1 },
+ { "й", 0, XKB_KEY_Cyrillic_shorti, 1 },
+ { "ц", 0, XKB_KEY_Cyrillic_tse, 1 },
+ { "у", 0, XKB_KEY_Cyrillic_u, 1 },
+ { "к", 0, XKB_KEY_Cyrillic_ka, 1 },
+ { "е", 0, XKB_KEY_Cyrillic_ie, 1 },
+ { "н", 0, XKB_KEY_Cyrillic_en, 1 },
+ { "г", 0, XKB_KEY_Cyrillic_ghe, 1 },
+ { "ш", 0, XKB_KEY_Cyrillic_sha, 1 },
+ { "щ", 0, XKB_KEY_Cyrillic_shcha, 1 },
+ { "з", 0, XKB_KEY_Cyrillic_ze, 1 },
+ { "х", 0, XKB_KEY_Cyrillic_ha, 1 },
{ 0 }, /* New row */
- { "ф", 0, XK_Cyrillic_ef, 1 },
- { "ы", 0, XK_Cyrillic_yeru, 1 },
- { "в", 0, XK_Cyrillic_ve, 1 },
- { "а", 0, XK_Cyrillic_a, 1 },
- { "п", 0, XK_Cyrillic_pe, 1 },
- { "р", 0, XK_Cyrillic_er, 1 },
- { "о", 0, XK_Cyrillic_o, 1 },
- { "л", 0, XK_Cyrillic_el, 1 },
- { "д", 0, XK_Cyrillic_de, 1 },
- { "ж", 0, XK_Cyrillic_zhe, 1 },
- { "ю", 0, XK_Cyrillic_yu, 1 },
+ { "ф", 0, XKB_KEY_Cyrillic_ef, 1 },
+ { "ы", 0, XKB_KEY_Cyrillic_yeru, 1 },
+ { "в", 0, XKB_KEY_Cyrillic_ve, 1 },
+ { "а", 0, XKB_KEY_Cyrillic_a, 1 },
+ { "п", 0, XKB_KEY_Cyrillic_pe, 1 },
+ { "р", 0, XKB_KEY_Cyrillic_er, 1 },
+ { "о", 0, XKB_KEY_Cyrillic_o, 1 },
+ { "л", 0, XKB_KEY_Cyrillic_el, 1 },
+ { "д", 0, XKB_KEY_Cyrillic_de, 1 },
+ { "ж", 0, XKB_KEY_Cyrillic_zhe, 1 },
+ { "ю", 0, XKB_KEY_Cyrillic_yu, 1 },
{ 0 }, /* New row */
- { "123", 0, XK_Mode_switch, 1 },
- { "я", 0, XK_Cyrillic_ya, 1 },
- { "ч", 0, XK_Cyrillic_che, 1 },
- { "с", 0, XK_Cyrillic_es, 1 },
- { "м", 0, XK_Cyrillic_em, 1 },
- { "и", 0, XK_Cyrillic_i, 1 },
- { "т", 0, XK_Cyrillic_te, 1 },
- { "ь", 0, XK_Cyrillic_softsign, 1 },
- { "б", 0, XK_Cyrillic_be, 1 },
- { "⌫Bksp", 0, XK_BackSpace, 2 },
+ { "123", 0, XKB_KEY_Mode_switch, 1 },
+ { "я", 0, XKB_KEY_Cyrillic_ya, 1 },
+ { "ч", 0, XKB_KEY_Cyrillic_che, 1 },
+ { "с", 0, XKB_KEY_Cyrillic_es, 1 },
+ { "м", 0, XKB_KEY_Cyrillic_em, 1 },
+ { "и", 0, XKB_KEY_Cyrillic_i, 1 },
+ { "т", 0, XKB_KEY_Cyrillic_te, 1 },
+ { "ь", 0, XKB_KEY_Cyrillic_softsign, 1 },
+ { "б", 0, XKB_KEY_Cyrillic_be, 1 },
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 2 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "Shift", 0, XK_Shift_L, 2 },
- { "Ctrl", 0, XK_Control_L, 1 },
- { "Alt", 0, XK_Alt_L, 1 },
- { "", 0, XK_space, 2 },
- { "↓", 0, XK_Down, 1 },
- { "↑", 0, XK_Up, 1 },
- { "↲ Enter", 0, XK_Return, 2 },
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "Shift", 0, XKB_KEY_Shift_L, 2 },
+ { "Ctrl", 0, XKB_KEY_Control_L, 1 },
+ { "Alt", 0, XKB_KEY_Alt_L, 1 },
+ { "", 0, XKB_KEY_space, 2 },
+ { "↓", 0, XKB_KEY_Down, 1 },
+ { "↑", 0, XKB_KEY_Up, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
};
static Key keys_dialer[KEYS] = {
- { "Esc", 0, XK_Escape, 1 },
- { "1", "!" , XK_1, 1 },
- { "2", "@", XK_2, 1 },
- { "3", "#", XK_3, 1 },
- { "⌫Bksp", 0, XK_BackSpace, 2 },
+ { "Esc", 0, XKB_KEY_Escape, 1 },
+ { "1", "!" , XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "⌫Bksp", 0, XKB_KEY_BackSpace, 2 },
{ 0 }, /* New row */
- { "Shift", 0, XK_Shift_L, 1 },
- { "4", "$", XK_4, 1 },
- { "5", "%", XK_5, 1 },
- { "6", "^", XK_6, 1 },
- { "-", "_", XK_minus, 1 },
- { ",", "<", XK_comma, 1 },
+ { "Shift", 0, XKB_KEY_Shift_L, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "-", "_", XKB_KEY_minus, 1 },
+ { ",", "<", XKB_KEY_comma, 1 },
{ 0 }, /* New row */
- { "abc", 0, XK_Mode_switch, 1 },
- { "7", "&", XK_7, 1 },
- { "8", "*", XK_8, 1 },
- { "9", "(", XK_9, 1 },
- { "=", "+", XK_equal, 1 },
- { "/", "?", XK_slash, 1 },
+ { "abc", 0, XKB_KEY_Mode_switch, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "=", "+", XKB_KEY_equal, 1 },
+ { "/", "?", XKB_KEY_slash, 1 },
{ 0 }, /* New row */
- { "↺", 0, XK_Cancel, 1},
- { "", 0, XK_space, 1 },
- { "0", ")", XK_0, 1 },
- { ".", ">", XK_period, 1 },
- { "↲ Enter", 0, XK_Return, 2},
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "", 0, XKB_KEY_space, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
+ { ".", ">", XKB_KEY_period, 1 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2},
{ 0 }, /* New row */
{ 0 }, /* Last item (double 0) */
};
@@ -567,6 +567,6 @@ static Key* available_layers[LAYERS] = {
Buttonmod buttonmods[] = {
- { XK_Shift_L, Button2 },
- { XK_Alt_L, Button3 },
+ { XKB_KEY_Shift_L, BTN_RIGHT },
+ { XKB_KEY_Alt_L, BTN_MIDDLE },
};
diff --git a/layout.mobile-minimal.h b/layout.mobile-minimal.h
@@ -0,0 +1,98 @@
+#define KEYS 44
+static Key keys_en[KEYS] = {
+ { "q", 0, XKB_KEY_q, 1 },
+ { "w", 0, XKB_KEY_w, 1 },
+ { "e", 0, XKB_KEY_e, 1 },
+ { "r", 0, XKB_KEY_r, 1 },
+ { "t", 0, XKB_KEY_t, 1 },
+ { "y", 0, XKB_KEY_y, 1 },
+ { "u", 0, XKB_KEY_u, 1 },
+ { "i", 0, XKB_KEY_i, 1 },
+ { "o", 0, XKB_KEY_o, 1 },
+ { "p", 0, XKB_KEY_p, 1 },
+
+ { 0 }, /* New row */
+
+ { "a", 0, XKB_KEY_a, 1 },
+ { "s", 0, XKB_KEY_s, 1 },
+ { "d", 0, XKB_KEY_d, 1 },
+ { "f", 0, XKB_KEY_f, 1 },
+ { "g", 0, XKB_KEY_g, 1 },
+ { "h", 0, XKB_KEY_h, 1 },
+ { "j", 0, XKB_KEY_j, 1 },
+ { "k", 0, XKB_KEY_k, 1 },
+ { "l", 0, XKB_KEY_l, 1 },
+ { ";",":", XKB_KEY_colon, 1 },
+ /*{ "'", XKB_KEY_apostrophe, 2 },*/
+
+ { 0 }, /* New row */
+
+ { "Shft", 0, XKB_KEY_Shift_L, 1 },
+ { "z", 0, XKB_KEY_z, 1 },
+ { "x", 0, XKB_KEY_x, 1 },
+ { "c", 0, XKB_KEY_c, 1 },
+ { "v", 0, XKB_KEY_v, 1 },
+ { "b", 0, XKB_KEY_b, 1 },
+ { "n", 0, XKB_KEY_n, 1 },
+ { "m", 0, XKB_KEY_m, 1 },
+ /*{ "/?", XKB_KEY_slash, 1 },*/
+
+ { 0 }, /* New row */
+ { "⇍ Bksp", 0, XKB_KEY_BackSpace, 2 },
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "", 0, XKB_KEY_space, 2 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
+};
+
+static Key keys_symbols[KEYS] = {
+ { "1", "!", XKB_KEY_1, 1 },
+ { "2", "@", XKB_KEY_2, 1 },
+ { "3", "#", XKB_KEY_3, 1 },
+ { "4", "$", XKB_KEY_4, 1 },
+ { "5", "%", XKB_KEY_5, 1 },
+ { "6", "^", XKB_KEY_6, 1 },
+ { "7", "&", XKB_KEY_7, 1 },
+ { "8", "*", XKB_KEY_8, 1 },
+ { "9", "(", XKB_KEY_9, 1 },
+ { "0", ")", XKB_KEY_0, 1 },
+
+ { 0 }, /* New row */
+
+ { "'", "\"", XKB_KEY_apostrophe, 1 },
+ { "`", "~", XKB_KEY_grave, 1 },
+ { "-", "_", XKB_KEY_minus, 1 },
+ { "=", "+", XKB_KEY_plus, 1 },
+ { "[", "{", XKB_KEY_bracketleft, 1 },
+ { "]", "}", XKB_KEY_bracketright, 1 },
+ { ",", "<", XKB_KEY_comma, 1 },
+ { ".", ">", XKB_KEY_period, 1 },
+ { "/", "?", XKB_KEY_slash, 1 },
+ { "\\", "|", XKB_KEY_backslash, 1 },
+
+ { 0 }, /* New row */
+
+ { "", 0, XKB_KEY_Shift_L|XKB_KEY_bar, 1 },
+ { "⇍ Bksp", 0, XKB_KEY_BackSpace, 2 },
+
+ { 0 }, /* New row */
+ { "↺", 0, XKB_KEY_Cancel, 1},
+ { "Shft", 0, XKB_KEY_Shift_L, 1 },
+ { "", 0, XKB_KEY_space, 2 },
+ { "↲ Enter", 0, XKB_KEY_Return, 2 },
+};
+
+#define OVERLAYS 1
+static Key overlay[OVERLAYS] = {
+ { 0, 0, XKB_KEY_Cancel },
+};
+
+#define LAYERS 2
+static char* layer_names[LAYERS] = {
+ "en",
+ "symbols",
+};
+
+static Key* available_layers[LAYERS] = {
+ keys_en,
+ keys_symbols,
+};
diff --git a/protocol/virtual-keyboard-unstable-v1.xml b/protocol/virtual-keyboard-unstable-v1.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<protocol name="virtual_keyboard_unstable_v1">
+ <copyright>
+ 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.
+ </copyright>
+
+ <interface name="zwp_virtual_keyboard_v1" version="1">
+ <description summary="virtual keyboard">
+ 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.
+ </description>
+
+ <request name="keymap">
+ <description summary="keyboard mapping">
+ 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.
+ </description>
+ <arg name="format" type="uint" summary="keymap format"/>
+ <arg name="fd" type="fd" summary="keymap file descriptor"/>
+ <arg name="size" type="uint" summary="keymap size, in bytes"/>
+ </request>
+
+ <enum name="error">
+ <entry name="no_keymap" value="0" summary="No keymap was set"/>
+ </enum>
+
+ <request name="key">
+ <description summary="key event">
+ 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.
+ </description>
+ <arg name="time" type="uint" summary="timestamp with millisecond granularity"/>
+ <arg name="key" type="uint" summary="key that produced the event"/>
+ <arg name="state" type="uint" summary="physical state of the key"/>
+ </request>
+
+ <request name="modifiers">
+ <description summary="modifier and group state">
+ 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.
+ </description>
+ <arg name="mods_depressed" type="uint" summary="depressed modifiers"/>
+ <arg name="mods_latched" type="uint" summary="latched modifiers"/>
+ <arg name="mods_locked" type="uint" summary="locked modifiers"/>
+ <arg name="group" type="uint" summary="keyboard layout"/>
+ </request>
+
+ <request name="destroy" type="destructor" since="1">
+ <description summary="destroy the virtual keyboard keyboard object"/>
+ </request>
+ </interface>
+
+ <interface name="zwp_virtual_keyboard_manager_v1" version="1">
+ <description summary="virtual keyboard manager">
+ A virtual keyboard manager allows an application to provide keyboard
+ input events as if they came from a physical keyboard.
+ </description>
+
+ <enum name="error">
+ <entry name="unauthorized" value="0" summary="client not authorized to use the interface"/>
+ </enum>
+
+ <request name="create_virtual_keyboard">
+ <description summary="Create a new virtual keyboard">
+ 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.
+ </description>
+ <arg name="seat" type="object" interface="wl_seat"/>
+ <arg name="id" type="new_id" interface="zwp_virtual_keyboard_v1"/>
+ </request>
+ </interface>
+</protocol>
diff --git a/svkbd.c b/svkbd.c
@@ -1,8 +1,9 @@
/* See LICENSE file for copyright and license details. */
-#include <sys/select.h>
+#include <poll.h>
#include <sys/time.h>
#include <ctype.h>
+#include <float.h>
#include <locale.h>
#include <signal.h>
#include <stdarg.h>
@@ -12,27 +13,21 @@
#include <time.h>
#include <unistd.h>
-#include <X11/keysym.h>
-#include <X11/keysymdef.h>
-#include <X11/XF86keysym.h>
-#include <X11/Xatom.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xproto.h>
-#include <X11/extensions/XTest.h>
-#include <X11/Xft/Xft.h>
-#include <X11/Xresource.h>
-#ifdef XINERAMA
-#include <X11/extensions/Xinerama.h>
-#endif
+#include <wayland-client.h>
+#include <wld/wayland.h>
+#include <wld/wld.h>
+#include <swc.h>
+#include <xkbcommon/xkbcommon.h>
+#include <linux/input-event-codes.h>
#include "drw.h"
#include "util.h"
+#include "swc-client-protocol.h"
/* macros */
-#define LENGTH(x) (sizeof x / sizeof x[0])
-#define STRINGTOKEYSYM(X) (XStringToKeySym(X))
-#define TEXTW(X) (drw_fontset_getwidth(drw, (X)))
+#define LENGTH(x) (sizeof x / sizeof x[0])
+#define STRINGTOKEYSYM(X) (XStringToxkb_keysym_t(X))
+#define TEXTW(X) (drw_fontset_getwidth(drw, (X)))
/* enums */
enum {
@@ -40,77 +35,59 @@ enum {
SchemePressShift, SchemeHighlight, SchemeHighlightShift, SchemeOverlay,
SchemeOverlayShift, SchemeLast
};
-enum { NetWMWindowType, NetLast };
/* typedefs */
typedef struct {
char *label;
char *label2;
- KeySym keysym;
+ xkb_keysym_t keysym;
unsigned int width;
- KeySym modifier;
+ char *str;
+ xkb_keysym_t modifier;
int x, y, w, h;
- Bool pressed;
- Bool highlighted;
- Bool isoverlay;
+ bool pressed;
+ bool highlighted;
+ bool isoverlay;
} Key;
typedef struct {
- KeySym mod;
+ xkb_keysym_t mod;
unsigned int button;
} Buttonmod;
/* function declarations */
static void printdbg(const char *fmt, ...);
-static void motionnotify(XEvent *e);
-static void buttonpress(XEvent *e);
-static void buttonrelease(XEvent *e);
static void cleanup(void);
-static void configurenotify(XEvent *e);
static void countrows();
static int countkeys(Key *layer);
static void drawkeyboard(void);
static void drawkey(Key *k);
-static void expose(XEvent *e);
static Key *findkey(int x, int y);
-static void leavenotify(XEvent *e);
-static void press(Key *k, KeySym mod);
+static void press(Key *k);
static double get_press_duration();
static void run(void);
static void setup(void);
-static void simulate_keypress(KeySym keysym);
-static void simulate_keyrelease(KeySym keysym);
+static void simulate_keypress(xkb_keysym_t keysym);
+static void simulate_keyrelease(xkb_keysym_t keysym);
static void showoverlay(int idx);
static void hideoverlay();
static void cyclelayer();
static void setlayer();
static void togglelayer();
-static void unpress(Key *k, KeySym mod);
+static void unpress(Key *k);
static void updatekeys();
-static void printkey(Key *k, KeySym mod);
+static void printkey(Key *k, xkb_keysym_t mod);
/* variables */
-static int screen;
-static void (*handler[LASTEvent]) (XEvent *) = {
- [ButtonPress] = buttonpress,
- [ButtonRelease] = buttonrelease,
- [ConfigureNotify] = configurenotify,
- [Expose] = expose,
- [LeaveNotify] = leavenotify,
- [MotionNotify] = motionnotify
-};
-static Atom netatom[NetLast];
-static Display *dpy;
static Drw *drw;
-static Window root, win;
static Clr* scheme[SchemeLast];
-static Bool running = True, isdock = False;
+static bool running = true, isdock = false;
static struct timeval pressbegin;
static int currentlayer = 0;
static int enableoverlays = 1;
static int currentoverlay = -1; /* -1 = no overlay */
static int pressonrelease = 1;
-static KeySym overlaykeysym = 0; /* keysym for which the overlay is presented */
+static xkb_keysym_t overlaykeysym = 0; /* keysym for which the overlay is presented */
static int releaseprotect = 0; /* set to 1 after overlay is shown, protecting against immediate release */
static int tmp_keycode = 1;
static int rows = 0, ww = 0, wh = 0, wx = 0, wy = 0;
@@ -124,10 +101,31 @@ static int numkeys = 0;
static char *colors[10][2]; /* 10 schemes, 2 colors each */
static char *fonts[] = { 0 };
-static KeySym ispressingkeysym;
+static xkb_keysym_t ispressingkeysym;
+
+bool ispressing = false;
+bool sigtermd = false;
+
+static struct {
+ int x, y;
+} ptrstate;
-Bool ispressing = False;
-Bool sigtermd = False;
+/* we assume that the slot id is at maximum the number of fingers on the screen */
+static struct {
+ int x, y;
+ Key *k;
+} touchstate[32];
+
+static int mon = -1;
+static struct wl_display *dpy;
+static struct wl_compositor *compositor;
+static struct wl_pointer *pointer;
+static struct wl_touch *touch;
+static struct wl_seat *seat;
+static struct wl_surface *surface;
+static struct wl_registry *reg;
+static struct swc_panel_manager *panelman;
+static struct swc_panel *panel;
/* configuration, allows nested code to access above variables */
#include "config.h"
@@ -140,105 +138,6 @@ static Key keys[KEYS] = { NULL };
static Key* layers[LAYERS];
void
-motionnotify(XEvent *e)
-{
- XPointerMovedEvent *ev = &e->xmotion;
- int i;
- int lostfocus = -1;
- int gainedfocus = -1;
-
- for (i = 0; i < numkeys; i++) {
- if (keys[i].keysym && ev->x > keys[i].x
- && ev->x < keys[i].x + keys[i].w
- && ev->y > keys[i].y
- && ev->y < keys[i].y + keys[i].h) {
- if (keys[i].highlighted != True) {
- if (ispressing) {
- gainedfocus = i;
- } else {
- keys[i].highlighted = True;
- }
- drawkey(&keys[i]);
- }
- continue;
- } else if (keys[i].highlighted == True) {
- keys[i].highlighted = False;
- drawkey(&keys[i]);
- }
- }
-
- for (i = 0; i < numkeys; i++) {
- if (!IsModifierKey(keys[i].keysym) && keys[i].pressed == True && lostfocus != gainedfocus) {
- printdbg("Pressed key lost focus: %ld\n", keys[i].keysym);
- lostfocus = i;
- ispressingkeysym = 0;
- keys[i].pressed = 0;
- drawkey(&keys[i]);
- }
- }
-
- if ((lostfocus != -1) && (gainedfocus != -1) && (lostfocus != gainedfocus)) {
- printdbg("Clicking new key that gained focus\n");
- press(&keys[gainedfocus], 0);
- keys[gainedfocus].pressed = True;
- keys[gainedfocus].highlighted = True;
- }
-}
-
-void
-buttonpress(XEvent *e)
-{
- XButtonPressedEvent *ev = &e->xbutton;
- Key *k;
- KeySym mod = 0;
- int i;
-
- ispressing = True;
-
- if (!(k = findkey(ev->x, ev->y)))
- return;
-
- if (k->modifier) {
- mod = k->modifier;
- } else {
- for (i = 0; i < LENGTH(buttonmods); i++) {
- if (ev->button == buttonmods[i].button) {
- mod = buttonmods[i].mod;
- break;
- }
- }
- }
- press(k, mod);
-}
-
-void
-buttonrelease(XEvent *e)
-{
- XButtonPressedEvent *ev = &e->xbutton;
- Key *k;
- KeySym mod = 0;
- int i;
-
- ispressing = False;
-
- for (i = 0; i < LENGTH(buttonmods); i++) {
- if (ev->button == buttonmods[i].button) {
- mod = buttonmods[i].mod;
- break;
- }
- }
-
- if (ev->x < 0 || ev->y < 0) {
- unpress(NULL, mod);
- } else if ((k = findkey(ev->x, ev->y))) {
- if (k->modifier)
- unpress(k, k->modifier);
- else
- unpress(k, mod);
- }
-}
-
-void
cleanup(void)
{
int i;
@@ -247,23 +146,6 @@ cleanup(void)
free(scheme[i]);
drw_sync(drw);
drw_free(drw);
- XSync(dpy, False);
- XDestroyWindow(dpy, win);
- XSync(dpy, False);
- XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
-}
-
-void
-configurenotify(XEvent *e)
-{
- XConfigureEvent *ev = &e->xconfigure;
-
- if (ev->window == win && (ev->width != ww || ev->height != wh)) {
- ww = ev->width;
- wh = ev->height;
- drw_resize(drw, ww, wh);
- updatekeys();
- }
}
void
@@ -302,11 +184,14 @@ void
drawkeyboard(void)
{
int i;
+ warn("drawing keyboard...");
+ wld_set_target_surface(drw->renderer, drw->surface);
for (i = 0; i < numkeys; i++) {
if (keys[i].keysym != 0)
drawkey(&keys[i]);
}
+ drw_map(drw, surface, 0, 0, ww, wh);
}
void
@@ -315,6 +200,7 @@ drawkey(Key *k)
int x, y, w, h;
const char *l;
+ wld_set_target_surface(drw->renderer, drw->surface);
int use_scheme = SchemeNorm;
if (k->pressed)
@@ -323,9 +209,9 @@ drawkey(Key *k)
use_scheme = SchemeHighlight;
else if (k->isoverlay)
use_scheme = SchemeOverlay;
- else if ((k->keysym == XK_Return) ||
- ((k->keysym >= XK_a) && (k->keysym <= XK_z)) ||
- ((k->keysym >= XK_Cyrillic_io) && (k->keysym <= XK_Cyrillic_hardsign)))
+ else if ((k->keysym == XKB_KEY_Return) ||
+ ((k->keysym >= XKB_KEY_a) && (k->keysym <= XKB_KEY_z)) ||
+ ((k->keysym >= XKB_KEY_Cyrillic_io) && (k->keysym <= XKB_KEY_Cyrillic_hardsign)))
use_scheme = SchemeNormABC;
else
use_scheme = SchemeNorm;
@@ -333,7 +219,7 @@ drawkey(Key *k)
drw_setscheme(drw, scheme[use_scheme]);
drw_rect(drw, k->x, k->y, k->w, k->h, 1, 1);
- if (k->keysym == XK_KP_Insert) {
+ if (k->keysym == XKB_KEY_KP_Insert) {
if (enableoverlays) {
l = "≅";
} else {
@@ -342,9 +228,9 @@ drawkey(Key *k)
} else if (k->label) {
l = k->label;
} else {
- l = XKeysymToString(k->keysym);
+ warn("key missing label");
}
- h = fontsize * 2;
+ h = drw->fonts[0].wld->height + 10;
y = k->y + (k->h / 2) - (h / 2);
w = TEXTW(l);
x = k->x + (k->w / 2) - (w / 2);
@@ -362,21 +248,11 @@ drawkey(Key *k)
use_scheme = SchemeOverlayShift;
drw_setscheme(drw, scheme[use_scheme]);
x += w;
- y -= 15;
+ //y -= 15;
l = k->label2;
w = TEXTW(l);
drw_text(drw, x, y, w, h, 0, l, 0);
}
- drw_map(drw, win, k->x, k->y, k->w, k->h);
-}
-
-void
-expose(XEvent *e)
-{
- XExposeEvent *ev = &e->xexpose;
-
- if (ev->count == 0 && (ev->window == win))
- drawkeyboard();
}
Key *
@@ -394,13 +270,13 @@ findkey(int x, int y) {
}
int
-hasoverlay(KeySym keysym)
+hasoverlay(xkb_keysym_t keysym)
{
int begin, i;
begin = 0;
for (i = 0; i < OVERLAYS; i++) {
- if (overlay[i].keysym == XK_Cancel) {
+ if (overlay[i].keysym == XKB_KEY_Cancel) {
begin = i + 1;
} else if (overlay[i].keysym == keysym) {
return begin + 1;
@@ -410,142 +286,65 @@ hasoverlay(KeySym keysym)
}
void
-leavenotify(XEvent *e)
-{
- if (currentoverlay != -1)
- hideoverlay();
- ispressingkeysym = 0;
- unpress(NULL, 0);
-}
-
-void
-record_press_begin(KeySym ks)
+record_press_begin(xkb_keysym_t ks)
{
/* record the begin of the press, don't simulate the actual keypress yet */
gettimeofday(&pressbegin, NULL);
ispressingkeysym = ks;
}
-void
-press(Key *k, KeySym buttonmod)
-{
- int i;
- int overlayidx = -1;
-
- k->pressed = !k->pressed;
- printdbg("Begin click: %ld\n", k->keysym);
- pressbegin.tv_sec = 0;
- pressbegin.tv_usec = 0;
- ispressingkeysym = 0;
-
- if (!IsModifierKey(k->keysym)) {
- if (enableoverlays && currentoverlay == -1)
- overlayidx = hasoverlay(k->keysym);
- if ((pressonrelease) || (enableoverlays && overlayidx != -1)) {
- /*record the begin of the press, don't simulate the actual keypress yet */
- record_press_begin(k->keysym);
- } else {
- printdbg("Simulating press: %ld (mod %ld)\n", k->keysym, buttonmod);
- for (i = 0; i < numkeys; i++) {
- if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
- simulate_keypress(keys[i].keysym);
- }
- }
- if (buttonmod)
- simulate_keypress(buttonmod);
- simulate_keypress(k->keysym);
- if (printoutput)
- printkey(k, buttonmod);
-
- for (i = 0; i < numkeys; i++) {
- if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
- simulate_keyrelease(keys[i].keysym);
- }
- }
- }
- }
- drawkey(k);
+/* TODO replace with something saner */
+bool
+IsModifierKey(int ks)
+{
+ return (ks >= XKB_KEY_Shift_L && ks <= XKB_KEY_Hyper_R);
}
-int
-tmp_remap(KeySym keysym)
+void
+press(Key *k)
{
- XChangeKeyboardMapping(dpy, tmp_keycode, 1, &keysym, 1);
- XSync(dpy, False);
-
- return tmp_keycode;
+ fprintf(stderr, "pressed key %s\n", k->label);
+ k->pressed = true;
}
void
-printkey(Key *k, KeySym mod)
+printkey(Key *k, xkb_keysym_t mod)
{
int i, shift;
- shift = (mod == XK_Shift_L) || (mod == XK_Shift_R) || (mod == XK_Shift_Lock);
+ shift = (mod == XKB_KEY_Shift_L) || (mod == XKB_KEY_Shift_R) || (mod == XKB_KEY_Shift_Lock);
if (!shift) {
for (i = 0; i < numkeys; i++) {
- if ((keys[i].pressed) && ((keys[i].keysym == XK_Shift_L) ||
- (keys[i].keysym == XK_Shift_R) || (keys[i].keysym == XK_Shift_Lock))) {
- shift = True;
+ if ((keys[i].pressed) && ((keys[i].keysym == XKB_KEY_Shift_L) ||
+ (keys[i].keysym == XKB_KEY_Shift_R) || (keys[i].keysym == XKB_KEY_Shift_Lock))) {
+ shift = true;
break;
}
}
}
printdbg("Printing key %ld (shift=%d)\n", k->keysym, shift);
- if (k->keysym == XK_Cancel)
+ if (k->keysym == XKB_KEY_Cancel)
return;
- KeySym *keysym = &(k->keysym);
- XIM xim = XOpenIM(dpy, 0, 0, 0);
- XIC xic = XCreateIC(xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, NULL);
-
- XKeyPressedEvent event;
- event.type = KeyPress;
- event.display = dpy;
- event.state = shift ? ShiftMask : 0;
- event.keycode = XKeysymToKeycode(dpy, *keysym);
- if (event.keycode == 0)
- event.keycode = tmp_remap(*keysym);
+ xkb_keysym_t *keysym = &(k->keysym);
char buffer[32];
- KeySym ignore;
- Status return_status;
- int l = Xutf8LookupString(xic, &event, buffer, sizeof(buffer), &ignore, &return_status);
+ xkb_keysym_t ignore;
+ int l = xkb_keysym_get_name(*keysym, buffer, sizeof(buffer));
buffer[l] = '\0';
printdbg("Print buffer: [%s] (length=%d)\n", &buffer, l);
printf("%s", buffer);
-
- XDestroyIC(xic);
- XCloseIM(xim);
}
void
-simulate_keypress(KeySym keysym)
+simulate_keypress(xkb_keysym_t keysym)
{
- KeyCode code;
-
- if (!simulateoutput)
- return;
-
- code = XKeysymToKeycode(dpy, keysym);
- if (code == 0)
- code = tmp_remap(keysym);
- XTestFakeKeyEvent(dpy, code, True, 0);
}
void
-simulate_keyrelease(KeySym keysym)
+simulate_keyrelease(xkb_keysym_t keysym)
{
- KeyCode code;
-
- if (!simulateoutput)
- return;
-
- code = XKeysymToKeycode(dpy, keysym);
- if (code == 0)
- code = tmp_remap(keysym);
- XTestFakeKeyEvent(dpy, code, False, 0);
}
double
@@ -561,113 +360,251 @@ get_press_duration(void)
}
void
-unpress(Key *k, KeySym buttonmod)
+unpress(Key *k)
{
+ warn("sending...\n");
int i;
if (k != NULL) {
switch(k->keysym) {
- case XK_Cancel:
+ case XKB_KEY_Cancel:
cyclelayer();
break;
- case XK_script_switch:
+ case XKB_KEY_script_switch:
togglelayer();
break;
- case XK_KP_Insert:
+ case XKB_KEY_KP_Insert:
enableoverlays = !enableoverlays;
break;
- case XK_Break:
- running = False;
+ case XKB_KEY_Break:
+ running = false;
break;
default:
break;
}
+ k->pressed = false;
}
- if ((pressbegin.tv_sec || pressbegin.tv_usec) && (enableoverlays || pressonrelease) && k && k->keysym == ispressingkeysym) {
- printdbg("Delayed simulation of press after release: %ld\n", k->keysym);
- /* simulate the press event, as we postponed it earlier in press() */
- for (i = 0; i < numkeys; i++) {
- if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
- simulate_keypress(keys[i].keysym);
+ fprintf(stderr, "unpress of %s\n", k->label);
+}
+
+static void
+regglobal(void *d, struct wl_registry *r, uint32_t name, const char *interface, uint32_t version)
+{
+ if (strcmp(interface, "wl_compositor") == 0)
+ compositor = wl_registry_bind(r, name, &wl_compositor_interface, 1);
+ else if (strcmp(interface, "wl_seat") == 0)
+ seat = wl_registry_bind(r, name, &wl_seat_interface, 1);
+ else if (strcmp(interface, "swc_panel_manager") == 0)
+ panelman = wl_registry_bind(r, name, &swc_panel_manager_interface, 1);
+}
+
+static void
+regglobalremove(void *d, struct wl_registry *reg, uint32_t name)
+{
+}
+
+static const struct wl_registry_listener reglistener = { regglobal, regglobalremove };
+
+static void
+pointerenter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t sx, wl_fixed_t sy)
+{
+ ptrstate.x = wl_fixed_to_int(sx);
+ ptrstate.y = wl_fixed_to_int(sy);
+}
+
+static void
+pointerleave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface)
+{
+ if (currentoverlay != -1)
+ hideoverlay();
+ ispressingkeysym = 0;
+ unpress(NULL);
+}
+
+static void
+pointermotion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t sx, wl_fixed_t sy)
+{
+ ptrstate.x = wl_fixed_to_int(sx);
+ ptrstate.y = wl_fixed_to_int(sy);
+ int i;
+ int lostfocus = -1;
+ int gainedfocus = -1;
+
+ for (i = 0; i < numkeys; i++) {
+ if (keys[i].keysym && ptrstate.x > keys[i].x
+ && ptrstate.x < keys[i].x + keys[i].w
+ && ptrstate.y > keys[i].y
+ && ptrstate.y < keys[i].y + keys[i].h) {
+ if (!keys[i].highlighted) {
+ if (ispressing) {
+ gainedfocus = i;
+ } else {
+ keys[i].highlighted = true;
+ drawkeyboard();
+ }
}
+ continue;
+ } else if (keys[i].highlighted) {
+ keys[i].highlighted = false;
+ drawkeyboard();
}
- if (buttonmod) {
- simulate_keypress(buttonmod);
- }
- simulate_keypress(k->keysym);
- pressbegin.tv_sec = 0;
- pressbegin.tv_usec = 0;
}
- if (k)
- printdbg("Simulation of release: %ld\n", k->keysym);
- else
- printdbg("Simulation of release (all keys)\n");
-
for (i = 0; i < numkeys; i++) {
- if (keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
- simulate_keyrelease(keys[i].keysym);
- if (printoutput)
- printkey(&keys[i], buttonmod);
- keys[i].pressed = 0;
- drawkey(&keys[i]);
+ if (!IsModifierKey(keys[i].keysym) && keys[i].pressed && lostfocus != gainedfocus) {
+ printdbg("Pressed key lost focus: %ld\n", keys[i].keysym);
+ lostfocus = i;
+ ispressingkeysym = 0;
+ keys[i].pressed = false;
}
}
- if (buttonmod) {
- simulate_keyrelease(buttonmod);
+ if ((lostfocus != -1) && (gainedfocus != -1) && (lostfocus != gainedfocus)) {
+ printdbg("Clicking new key that gained focus\n");
+ press(&keys[gainedfocus]);
+ keys[gainedfocus].pressed = true;
+ keys[gainedfocus].highlighted = true;
}
+}
- if ((k == NULL) || (!IsModifierKey(k->keysym))) {
- for (i = 0; i < numkeys; i++) {
- if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
- simulate_keyrelease(keys[i].keysym);
- keys[i].pressed = 0;
- drawkey(&keys[i]);
- }
- }
+void
+pointerbutton(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t state)
+{
+ Key *k;
+ int i;
+
+ ispressing = true;
+
+ switch (state) {
+ case WL_POINTER_BUTTON_STATE_PRESSED:
+ if ((k = findkey(ptrstate.x, ptrstate.y)))
+ press(k);
+
+ break;
+
+ case WL_POINTER_BUTTON_STATE_RELEASED:
+ if ((k = findkey(ptrstate.x, ptrstate.y)))
+ unpress(k);
+ break;
}
+}
- if (enableoverlays && currentoverlay != -1 && !IsModifierKey(k->keysym)) {
- if (releaseprotect) {
- releaseprotect = 0;
- } else {
- hideoverlay();
- }
+
+static const struct wl_pointer_listener pointerlistener = { pointerenter, pointerleave, pointermotion, pointerbutton };
+
+void
+touchdown(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, wl_fixed_t x, wl_fixed_t y)
+{
+ Key *k;
+
+ ispressing = true;
+ touchstate[id].x = wl_fixed_to_double(x);
+ touchstate[id].y = wl_fixed_to_double(y);
+
+ if ((k = findkey(touchstate[id].x, touchstate[id].y)))
+ press(k);
+
+ touchstate[id].k = k;
+}
+
+void
+touchup(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, int32_t id)
+{
+ /*
+ Key *k;
+ if ((k = findkey(touchstate[id].x, touchstate[id].y)))
+ unpress(k);
+ touchstate[id].x = DBL_MIN;
+ touchstate[id].y = DBL_MIN;
+ touchstate[id].k = NULL;
+ */
+ unpress(touchstate[id].k);
+ touchstate[id].x = DBL_MIN;
+ touchstate[id].y = DBL_MIN;
+ touchstate[id].k = NULL;
+}
+
+void
+touchmotion(void *data, struct wl_touch *wl_touch, uint32_t time, int32_t id, wl_fixed_t x, wl_fixed_t y)
+{
+ Key *k;
+ touchstate[id].x = wl_fixed_to_double(x);
+ touchstate[id].y = wl_fixed_to_double(y);
+
+ int i;
+ int lostfocus = -1;
+ int gainedfocus = -1;
+
+ if ((k = findkey(touchstate[id].x, touchstate[id].y))) {
+ if (k == touchstate[id].k)
+ return;
+
+ if (touchstate[id].k)
+ touchstate[id].k->pressed = false;
+
+ press(k);
+ touchstate[id].k = k;
+ } else if (touchstate[id].k) {
+ touchstate[id].k->pressed = false;
+ touchstate[id].k = NULL;
}
}
void
+touchframe(void *data, struct wl_touch *wl_touch)
+{
+ drawkeyboard();
+}
+
+void
+touchcancel(void *data, struct wl_touch *wl_touch)
+{
+ fprintf(stderr, "cancel!\n");
+}
+
+static const struct wl_touch_listener touchlistener = { touchdown, touchup, touchmotion, touchframe , touchcancel};
+
+static void
+panel_docked(void *data, struct swc_panel *panel, uint32_t length)
+{
+ ww = length;
+}
+
+static const struct swc_panel_listener panellistener = { .docked = &panel_docked };
+
+void
run(void)
{
- XEvent ev;
- int xfd;
- fd_set fds;
+ struct pollfd fds[2];
struct timeval tv;
double duration = 0.0;
int overlayidx = -1;
int i, r;
- xfd = ConnectionNumber(dpy);
+ fds[0].fd = wl_display_get_fd(dpy);
+ fds[0].events = POLLIN;
+
+ /* TODO use timer_create to create timer for long presses */
+ fds[1].fd = -1;
+ fds[1].events = POLLIN;
tv.tv_sec = 0;
tv.tv_usec = scan_rate;
- XFlush(dpy);
-
while (running) {
- usleep(100000L); /* 100ms */
- FD_ZERO(&fds);
- FD_SET(xfd, &fds);
- r = select(xfd + 1, &fds, NULL, NULL, &tv);
- if (r) {
- while (XPending(dpy)) {
- XNextEvent(dpy, &ev);
- if (handler[ev.type]) {
- (handler[ev.type])(&ev); /* call handler */
- }
+ if (poll(fds, sizeof(fds) / sizeof(fds[0]), -1) == -1) {
+ fprintf(stderr, "poll failed\n");
+ break;
+ }
+
+ if (fds[0].revents & POLLIN) {
+ if (wl_display_dispatch(dpy) == -1) {
+ warn("failed to dispatch display:");
+ break;
}
- } else {
+ }
+
+ if (0) {
/* time-out expired without anything interesting happening, check for long-presses */
if (ispressing && ispressingkeysym) {
duration = get_press_duration();
@@ -685,7 +622,6 @@ run(void)
printdbg("press duration %f, activating repeat\n", duration);
simulate_keyrelease(ispressingkeysym);
simulate_keypress(ispressingkeysym);
- XSync(dpy, False);
}
}
}
@@ -698,118 +634,31 @@ run(void)
process will be dead before finger lifts - in that case we
just trigger out fake up presses for all keys */
printdbg("signal received, releasing all keys");
- for (i = 0; i < numkeys; i++) {
- XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, keys[i].keysym), False, 0);
- }
- running = False;
+ running = false;
}
}
}
void
-readxresources(void)
-{
- XrmDatabase xdb;
- XrmValue xval;
- char *type, *xrm;
-
- XrmInitialize();
-
- if ((xrm = XResourceManagerString(drw->dpy))) {
- xdb = XrmGetStringDatabase(xrm);
-
- if (XrmGetResource(xdb, "svkbd.font", "*", &type, &xval) && !fonts[0])
- fonts[0] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.background", "*", &type, &xval) && !colors[SchemeNorm][ColBg])
- colors[SchemeNorm][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.foreground", "*", &type, &xval) && !colors[SchemeNorm][ColFg])
- colors[SchemeNorm][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.shiftforeground", "*", &type, &xval) && !colors[SchemeNormShift][ColFg])
- colors[SchemeNormShift][ColFg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.shiftbackground", "*", &type, &xval) && !colors[SchemeNormShift][ColBg])
- colors[SchemeNormShift][ColBg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.ABCforeground", "*", &type, &xval) && !colors[SchemeNormABC][ColFg])
- colors[SchemeNormABC][ColFg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.ABCbackground", "*", &type, &xval) && !colors[SchemeNormABC][ColBg])
- colors[SchemeNormABC][ColBg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.ABCshiftforeground", "*", &type, &xval) && !colors[SchemeNormShift][ColFg])
- colors[SchemeNormShift][ColFg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.ABCshiftbackground", "*", &type, &xval) && !colors[SchemeNormShift][ColBg])
- colors[SchemeNormShift][ColBg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.pressbackground", "*", &type, &xval) && !colors[SchemePress][ColBg])
- colors[SchemePress][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.pressforeground", "*", &type, &xval) && !colors[SchemePress][ColFg])
- colors[SchemePress][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.pressshiftbackground", "*", &type, &xval) && !colors[SchemePressShift][ColBg])
- colors[SchemePressShift][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.pressshiftforeground", "*", &type, &xval) && !colors[SchemePressShift][ColFg])
- colors[SchemePressShift][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.highlightbackground", "*", &type, &xval) && !colors[SchemeHighlight][ColBg])
- colors[SchemeHighlight][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.highlightforeground", "*", &type, &xval) && !colors[SchemeHighlight][ColFg])
- colors[SchemeHighlight][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.highlightshiftbackground", "*", &type, &xval) && !colors[SchemeHighlightShift][ColBg])
- colors[SchemeHighlightShift][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.highlightshiftforeground", "*", &type, &xval) && !colors[SchemeHighlightShift][ColFg])
- colors[SchemeHighlightShift][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.overlaybackground", "*", &type, &xval) && !colors[SchemeOverlay][ColBg])
- colors[SchemeOverlay][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.overlayforeground", "*", &type, &xval) && !colors[SchemeOverlay][ColFg])
- colors[SchemeOverlay][ColFg] = estrdup(xval.addr);
-
- if (XrmGetResource(xdb, "svkbd.overlayshiftbackground", "*", &type, &xval) && !colors[SchemeOverlayShift][ColBg])
- colors[SchemeOverlayShift][ColBg] = estrdup(xval.addr);
- if (XrmGetResource(xdb, "svkbd.overlayshiftforeground", "*", &type, &xval) && !colors[SchemeOverlayShift][ColFg])
- colors[SchemeOverlayShift][ColFg] = estrdup(xval.addr);
-
- XrmDestroyDatabase(xdb);
- }
-}
-
-void
setup(void)
{
- XSetWindowAttributes wa;
- XTextProperty str;
- XSizeHints *sizeh = NULL;
- XClassHint *ch;
- XWMHints *wmh;
- Atom atype = -1;
- int i, j, sh, sw;
-
-#ifdef XINERAMA
- XineramaScreenInfo *info = NULL;
-#endif
+ int i, j, rh;
- /* init screen */
- screen = DefaultScreen(dpy);
- root = RootWindow(dpy, screen);
-#ifdef XINERAMA
- if (XineramaIsActive(dpy)) {
- info = XineramaQueryScreens(dpy, &i);
- sw = info[0].width;
- sh = info[0].height;
- XFree(info);
- } else
-#endif
- {
- sw = DisplayWidth(dpy, screen);
- sh = DisplayHeight(dpy, screen);
- }
- drw = drw_create(dpy, screen, root, sw, sh);
+ drw = drw_create(dpy);
+
+ if (!compositor || !seat || !panelman)
+ exit(1);
- readxresources();
+ pointer = wl_seat_get_pointer(seat);
+ wl_pointer_add_listener(pointer, &pointerlistener, NULL);
- /* Apply defaults to font and colors*/
+ touch = wl_seat_get_touch(seat);
+ wl_touch_add_listener(touch, &touchlistener, NULL);
+
+ if (!pointer)
+ exit(1);
+
+ /* Apply defaults to font and colors */
if (!fonts[0])
fonts[0] = estrdup(defaultfonts[0]);
for (i = 0; i < SchemeLast; ++i) {
@@ -823,34 +672,6 @@ setup(void)
die("no fonts could be loaded");
free(fonts[0]);
- drw_setscheme(drw, scheme[SchemeNorm]);
-
- /* find an unused keycode to use as a temporary keycode (derived from source:
- https://stackoverflow.com/questions/44313966/c-xtest-emitting-key-presses-for-every-unicode-character) */
- KeySym *keysyms;
- int keysyms_per_keycode = 0;
- int keycode_low, keycode_high;
- Bool key_is_empty;
- int symindex;
-
- XDisplayKeycodes(dpy, &keycode_low, &keycode_high);
- keysyms = XGetKeyboardMapping(dpy, keycode_low, keycode_high - keycode_low, &keysyms_per_keycode);
- for (i = keycode_low; i <= keycode_high; i++) {
- key_is_empty = True;
- for (j = 0; j < keysyms_per_keycode; j++) {
- symindex = (i - keycode_low) * keysyms_per_keycode + j;
- if (keysyms[symindex] != 0) {
- key_is_empty = False;
- } else {
- break;
- }
- }
- if (key_is_empty) {
- tmp_keycode = i;
- break;
- }
- }
-
/* init appearance */
for (j = 0; j < SchemeLast; j++)
scheme[j] = drw_scm_create(drw, (const char **) colors[j], 2);
@@ -860,76 +681,32 @@ setup(void)
free(colors[j][ColBg]);
}
- /* init atoms */
- if (isdock) {
- netatom[NetWMWindowType] = XInternAtom(dpy,
- "_NET_WM_WINDOW_TYPE", False);
- atype = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DOCK", False);
- }
+ drw_setscheme(drw, scheme[SchemeNorm]);
+
+ surface = wl_compositor_create_surface(compositor);
+ panel = swc_panel_manager_create_panel(panelman, surface);
+ swc_panel_add_listener(panel, &panellistener, NULL);
+ swc_panel_dock(panel, SWC_PANEL_EDGE_BOTTOM, NULL, 0);
+ wl_display_roundtrip(dpy);
/* init appearance */
countrows();
+ /* TODO calculate row height properly */
+ rh = drw->fonts[0].wld->height + 15;
if (!ww)
- ww = sw;
+ exit(1);
if (!wh)
- wh = sh * rows / heightfactor;
+ wh = rh * rows;
- if (!wx)
- wx = 0;
- if (wx < 0)
- wx = sw + wx - ww;
- if (!wy)
- wy = sh - wh;
- if (wy < 0)
- wy = sh + wy - wh;
for (i = 0; i < numkeys; i++)
keys[i].pressed = 0;
- wa.override_redirect = !wmborder;
- wa.border_pixel = scheme[SchemeNorm][ColFg].pixel;
- wa.background_pixel = scheme[SchemeNorm][ColBg].pixel;
- win = XCreateWindow(dpy, root, wx, wy, ww, wh, 0,
- CopyFromParent, CopyFromParent, CopyFromParent,
- CWOverrideRedirect | CWBorderPixel |
- CWBackingPixel, &wa);
- XSelectInput(dpy, win, StructureNotifyMask|ButtonReleaseMask|
- ButtonPressMask|ExposureMask|LeaveWindowMask|
- PointerMotionMask);
-
- wmh = XAllocWMHints();
- wmh->input = False;
- wmh->flags = InputHint;
- if (!isdock) {
- sizeh = XAllocSizeHints();
- sizeh->flags = PMaxSize | PMinSize;
- sizeh->min_width = sizeh->max_width = ww;
- sizeh->min_height = sizeh->max_height = wh;
- }
- XStringListToTextProperty(&name, 1, &str);
- ch = XAllocClassHint();
- ch->res_class = name;
- ch->res_name = name;
-
- XSetWMProperties(dpy, win, &str, &str, NULL, 0, sizeh, wmh, ch);
-
- XFree(keysyms);
- XFree(ch);
- XFree(wmh);
- XFree(str.value);
- if (sizeh != NULL)
- XFree(sizeh);
-
- if (isdock) {
- XChangeProperty(dpy, win, netatom[NetWMWindowType], XA_ATOM,
- 32, PropModeReplace,
- (unsigned char *)&atype, 1);
- }
-
- XMapRaised(dpy, win);
- drw_resize(drw, ww, wh);
+ drw_resize(drw, surface, ww, wh);
+ swc_panel_set_strut(panel, wh, 0, ww);
updatekeys();
drawkeyboard();
+ wl_display_roundtrip(dpy);
}
void
@@ -960,17 +737,17 @@ usage(char *argv0)
{
fprintf(stderr, "usage: %s [-hdnovDOR] [-g geometry] [-fn font] [-l layers] [-s initial_layer]\n", argv0);
fprintf(stderr, "Options:\n");
- fprintf(stderr, " -d - Set Dock Window Type\n");
- fprintf(stderr, " -D - Enable debug\n");
- fprintf(stderr, " -O - Disable overlays\n");
- fprintf(stderr, " -R - Disable press-on-release\n");
- fprintf(stderr, " -n - Do not simulate key presses for X\n");
- fprintf(stderr, " -o - Print to standard output\n");
- fprintf(stderr, " -l - Comma separated list of layers to enable\n");
- fprintf(stderr, " -s - Layer to select on program start\n");
+ fprintf(stderr, " -d - Set Dock Window Type\n");
+ fprintf(stderr, " -D - Enable debug\n");
+ fprintf(stderr, " -O - Disable overlays\n");
+ fprintf(stderr, " -R - Disable press-on-release\n");
+ fprintf(stderr, " -n - Do not simulate key presses for X\n");
+ fprintf(stderr, " -o - Print to standard output\n");
+ fprintf(stderr, " -l - Comma separated list of layers to enable\n");
+ fprintf(stderr, " -s - Layer to select on program start\n");
fprintf(stderr, " -H [int] - Height fraction, one key row takes 1/x of the screen height\n");
fprintf(stderr, " -fn [font] - Set font (Xft, e.g: DejaVu Sans:bold:size=20)\n");
- fprintf(stderr, " -g - Set the window position or size using the X geometry format\n");
+ fprintf(stderr, " -g - Set the window position or size using the X geometry format\n");
exit(1);
}
@@ -1019,13 +796,12 @@ showoverlay(int idx)
for (i = 0; i < numkeys; i++) {
if (keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
keys[i].pressed = 0;
- drawkey(&keys[i]);
break;
}
}
for (i = idx, j=0; i < OVERLAYS; i++, j++) {
- if (overlay[i].keysym == XK_Cancel) {
+ if (overlay[i].keysym == XKB_KEY_Cancel) {
break;
}
while (keys[j].keysym == 0)
@@ -1036,14 +812,13 @@ showoverlay(int idx)
keys[j].label2 = overlay[i].label2;
keys[j].keysym = overlay[i].keysym;
keys[j].modifier = overlay[i].modifier;
- keys[j].isoverlay = True;
+ keys[j].isoverlay = true;
}
currentoverlay = idx;
overlaykeysym = ispressingkeysym;
releaseprotect = 1;
updatekeys();
drawkeyboard();
- XSync(dpy, False);
}
void
@@ -1059,8 +834,8 @@ hideoverlay(void)
void
sigterm(int signo)
{
- running = False;
- sigtermd = True;
+ running = false;
+ sigtermd = true;
printdbg("SIGTERM received\n");
}
@@ -1103,7 +878,7 @@ init_layers(char *layer_names_list, const char *initial_layer_name)
exit(3);
}
numlayers++;
- s = strtok(NULL,",");
+ s = strtok(NULL, ",");
}
}
setlayer();
@@ -1153,24 +928,12 @@ main(int argc, char *argv[])
if (!strcmp(argv[i], "-v")) {
die("svkbd-"VERSION);
} else if (!strcmp(argv[i], "-d")) {
- isdock = True;
+ isdock = true;
} else if (!strncmp(argv[i], "-g", 2)) {
if (i >= argc - 1)
usage(argv[0]);
- bitm = XParseGeometry(argv[++i], &xr, &yr, &wr, &hr);
- if (bitm & XValue)
- wx = xr;
- if (bitm & YValue)
- wy = yr;
- if (bitm & WidthValue)
- ww = (int)wr;
- if (bitm & HeightValue)
- wh = (int)hr;
- if (bitm & XNegative && wx == 0)
- wx = -1;
- if (bitm & YNegative && wy == 0)
- wy = -1;
+ /* TODO implement */
} else if (!strcmp(argv[i], "-fn")) { /* font or font set */
if (i >= argc - 1)
usage(argv[0]);
@@ -1214,14 +977,18 @@ main(int argc, char *argv[])
init_layers(layer_names_list, initial_layer_name);
- if (!setlocale(LC_CTYPE, "") || !XSupportsLocale())
+ if (!setlocale(LC_CTYPE, ""))
fprintf(stderr, "warning: no locale support");
- if (!(dpy = XOpenDisplay(0)))
+ if (!(dpy = wl_display_connect(NULL)))
die("cannot open display");
+ if (!(reg = wl_display_get_registry(dpy)))
+ die("cannot get registry");
+ wl_registry_add_listener(reg, ®listener, NULL);
+ wl_display_roundtrip(dpy);
setup();
run();
cleanup();
- XCloseDisplay(dpy);
+ wl_display_disconnect(dpy);
free(layer_names_list);
return 0;
diff --git a/util.c b/util.c
@@ -44,3 +44,20 @@ die(const char *fmt, ...)
exit(1);
}
+
+void
+warn(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+
+ if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
+ fputc(' ', stderr);
+ perror(NULL);
+ } else {
+ fputc('\n', stderr);
+ }
+}
diff --git a/util.h b/util.h
@@ -5,5 +5,6 @@
#define BETWEEN(X, A, B) ((A) <= (X) && (X) <= (B))
void die(const char *fmt, ...);
+void warn(const char *fmt, ...);
void *ecalloc(size_t nmemb, size_t size);
char *estrdup(const char *s);