mirror of git://git.suckless.org/svkbd
Compare commits
81 Commits
Author | SHA1 | Date |
---|---|---|
norayr chilingarian | 92795b2a0a | |
Hiltjo Posthuma | ff704d5d1e | |
Norayr Chilingarian | 7fc78a0b44 | |
Hiltjo Posthuma | 3dfb00ccf8 | |
Norayr Chilingarian | c247720ae4 | |
Hiltjo Posthuma | 38faf1cc8a | |
Justin Torres | 5dd14703ed | |
Max Schillinger | 4061bacc1d | |
Страхиња Радић | 0f07238b53 | |
Hiltjo Posthuma | 6ffe71a5f6 | |
Hiltjo Posthuma | d9dcf0d113 | |
Maarten van Gompel | 4a511a6cfb | |
Hiltjo Posthuma | 6a14319331 | |
Maarten van Gompel | 378a1c8b30 | |
Maarten van Gompel | 3cff4547c5 | |
Maarten van Gompel | b053404199 | |
Maarten van Gompel | b5775349f6 | |
Maarten van Gompel | 2164466746 | |
Maarten van Gompel | b70948b74c | |
Maarten van Gompel | e2828d4f7a | |
Hiltjo Posthuma | 4c9182636c | |
Hiltjo Posthuma | 2a2acdacaa | |
Hiltjo Posthuma | 81c96cec89 | |
Hiltjo Posthuma | fd01322564 | |
Sebastian LaVine | e2dff73599 | |
Hiltjo Posthuma | 34e5659db8 | |
Maarten van Gompel | 5491251610 | |
Maarten van Gompel | a5cb7d53ce | |
Maarten van Gompel | 2a84ae50f9 | |
Hiltjo Posthuma | 2306b8eb40 | |
silver | 34530800bb | |
Max Schillinger | 42380f62eb | |
Hiltjo Posthuma | b25e55e462 | |
Stacy Harper | 1d5e9346e8 | |
Hiltjo Posthuma | 4c4a085580 | |
Hiltjo Posthuma | d509e189d4 | |
Hiltjo Posthuma | d81fe4c879 | |
Hiltjo Posthuma | c91cf4a12a | |
Hiltjo Posthuma | 1cc5f87511 | |
Hiltjo Posthuma | d6026943d3 | |
Hiltjo Posthuma | 55de8b5184 | |
Hiltjo Posthuma | 7c06a0caf5 | |
Hiltjo Posthuma | 8f6a7b5e42 | |
Hiltjo Posthuma | 4b5a61b275 | |
Hiltjo Posthuma | 7980cb5f51 | |
Hiltjo Posthuma | 9c492b6913 | |
Hiltjo Posthuma | ea4b058833 | |
Hiltjo Posthuma | d19a80dfe5 | |
Maarten van Gompel | b80819aa3f | |
Maarten van Gompel | 02f13a74c3 | |
Maarten van Gompel | f2322e9c0e | |
Maarten van Gompel | 10024fc963 | |
Maarten van Gompel | 2fa04e74fe | |
Maarten van Gompel | 5fd07406ae | |
Maarten van Gompel | 444ceabde3 | |
Maarten van Gompel | a43bf5c4c1 | |
Reed Wade | 4ec3b00d6c | |
Reed Wade | 7a6742e6e4 | |
Reed Wade | b6055b3310 | |
tetrakist | 8c28fd15f3 | |
Maarten van Gompel | 869a4328c9 | |
Maarten van Gompel | 9b5ebd8447 | |
Maarten van Gompel | 72b936baf6 | |
Maarten van Gompel | bd3620acf4 | |
Maarten van Gompel | c2251315e5 | |
Maarten van Gompel | 174c86d8fa | |
Maarten van Gompel | d06db9eb4f | |
Reed Wade | 6633915997 | |
Reed Wade | d10af923a3 | |
Maarten van Gompel | 3be1e21c9f | |
Maarten van Gompel | e9208cb088 | |
Maarten van Gompel | 7f59daca5f | |
Maarten van Gompel | 6dc8c78b82 | |
Maarten van Gompel | 9fd94b637a | |
Maarten van Gompel | 6f3308b327 | |
Jochen Sprickerhof | 0ea4559388 | |
Hiltjo Posthuma | 84715dd6c6 | |
Maarten van Gompel | 1fff13a1b4 | |
Maarten van Gompel | 79ff93369c | |
Hiltjo Posthuma | 02a2f77fbb | |
Maarten van Gompel | 3a51eafd3a |
3
LICENSE
3
LICENSE
|
@ -2,7 +2,8 @@ MIT/X Consortium License
|
|||
|
||||
© 2011 Christoph Lohmann <20h@r-36.net>
|
||||
© 2008-2011 Enno Boland <g # s01 ' de>
|
||||
© 2020 Maarten van Gompel <proycon@anaproy.nl>
|
||||
© 2020-2021 Maarten van Gompel <proycon@anaproy.nl>
|
||||
© 2020-2023 Hiltjo Posthuma <hiltjo@codemadness.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
|
|
16
Makefile
16
Makefile
|
@ -3,13 +3,13 @@
|
|||
.POSIX:
|
||||
|
||||
NAME = svkbd
|
||||
VERSION = 0.2
|
||||
VERSION = 0.4.1
|
||||
|
||||
include config.mk
|
||||
|
||||
BIN = ${NAME}-${LAYOUT}
|
||||
SRC = drw.c ${NAME}.c util.c
|
||||
OBJ = ${SRC:.c=.o}
|
||||
OBJ = drw.o ${NAME}-${LAYOUT}.o util.o
|
||||
MAN1 = ${NAME}.1
|
||||
|
||||
all: ${BIN}
|
||||
|
@ -24,6 +24,9 @@ options:
|
|||
config.h:
|
||||
cp config.def.h $@
|
||||
|
||||
svkbd-${LAYOUT}.o: config.h layout.${LAYOUT}.h
|
||||
${CC} ${SVKBD_CFLAGS} ${SVKBD_CPPFLAGS} -c svkbd.c -o $@
|
||||
|
||||
.c.o:
|
||||
${CC} ${SVKBD_CFLAGS} ${SVKBD_CPPFLAGS} -c $<
|
||||
|
||||
|
@ -33,7 +36,7 @@ ${BIN}: ${OBJ}
|
|||
${CC} -o ${BIN} ${OBJ} ${SVKBD_LDFLAGS}
|
||||
|
||||
clean:
|
||||
rm -f ${NAME}-?? ${NAME}-??.o ${OBJ} ${BIN}
|
||||
rm -f ${NAME}-?? ${NAME}-*.o ${OBJ} ${BIN}
|
||||
|
||||
dist:
|
||||
rm -rf "${NAME}-${VERSION}"
|
||||
|
@ -50,11 +53,8 @@ dist:
|
|||
|
||||
install: all
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
for i in ${NAME}-??; \
|
||||
do \
|
||||
cp $$i ${DESTDIR}${PREFIX}/bin; \
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/$$i; \
|
||||
done
|
||||
cp -f ${NAME}-${LAYOUT} ${DESTDIR}${PREFIX}/bin
|
||||
chmod 755 ${DESTDIR}${PREFIX}/bin/${NAME}-${LAYOUT}
|
||||
mkdir -p "${DESTDIR}${MANPREFIX}/man1"
|
||||
sed "s/VERSION/${VERSION}/g" < ${MAN1} > ${DESTDIR}${MANPREFIX}/man1/${MAN1}
|
||||
chmod 644 ${DESTDIR}${MANPREFIX}/man1/${MAN1}
|
||||
|
|
43
README.md
43
README.md
|
@ -10,7 +10,7 @@ Installation
|
|||
$ make
|
||||
$ make install
|
||||
|
||||
This will create by default `svkbd-intl`, which is svkbd using an international
|
||||
This will create by default `svkbd-mobile-intl`, which is svkbd using an international
|
||||
layout with multiple layers and overlays, and optimised for mobile devices.
|
||||
|
||||
You can create svkbd for additional layouts by doing:
|
||||
|
@ -31,11 +31,13 @@ The following layouts are available:
|
|||
diacritics and other variants, as well as some emoji. The layers are:
|
||||
* a basic qwerty layer
|
||||
* a layer for numeric input, arrows, and punctuation
|
||||
* a layer for function keys, media keys, and arrows
|
||||
* a cyrillic layer (ЙЦУКЕН)
|
||||
* a cyrillic layer (ЙЦУКЕН based); the э key is moved to an overlay on е
|
||||
* a dialer/numeric layer
|
||||
* an arrow layer
|
||||
* a more minimal qwerty layer (bigger keys) for smaller screens/larger fingers.
|
||||
* ``mobile-plain`` - This is a plain layout with only a qwerty layer and numeric/punctuation layer. It was
|
||||
originally made for [sxmo](https://sr.ht/~mil/Sxmo/).
|
||||
* ``mobile-simple`` - This is a more minimalistic layout that is more similar to what Android and iOS offer.
|
||||
* **Traditional layouts**:
|
||||
* ``en`` - An english layout without layers (QWERTY)
|
||||
* ``de`` - A german layout (QWERTZ)
|
||||
|
@ -59,25 +61,50 @@ some space of the screen being reserved for it.
|
|||
|
||||
$ svkbd-mobile-intl -g 400x200+1+1
|
||||
|
||||
This will start svkbd-intl with a size of 400x200 and at the upper left
|
||||
This will start svkbd-mobile-intl with a size of 400x200 and at the upper left
|
||||
window corner.
|
||||
|
||||
For layouts that consist of multiple layers, you can enable layers on program start through either the ``-l`` flag or
|
||||
through the ``SVKBD_LAYERS`` environment variable. They both take a comma separated list of layer names (as defined in
|
||||
your ``layout.*.h``). Use the ``↺`` button in the bottom-left to cycle through all the layers.
|
||||
your ``layout.*.h``). Use the ``↺`` button in the bottom-left to cycle through all the layers in the exact order they
|
||||
were specified.
|
||||
|
||||
Some layouts come with overlays that will show when certain keys are hold pressed for a longer time. For
|
||||
example, a long press on the ``a`` key will enable an overview showing all kinds of diacritic combinations for ``a``.
|
||||
Some layouts come with overlays that will show when certain keys are hold pressed for a longer time. For example, a long
|
||||
press on the ``a`` key will enable an overview showing all kinds of diacritic combinations for ``a``. In the
|
||||
``mobile-intl`` layout, a long press on a punctuation key will show an overlay with all further punctuation options (the
|
||||
same for all punctuation keys). Moreover, a long press on the ``q`` key doubles as a trigger for the emoji overlay in
|
||||
this layout.
|
||||
|
||||
Overlay functionality interferes with the ability to hold a key and have it outputted repeatedly. You can disable
|
||||
overlay functionality with the ``-O`` flag or by setting the environment variable ``SVKBD_ENABLEOVERLAYS=0``. There is
|
||||
also a key on the function layer of the keyboard itself to enable/disable this behaviour on the fly. Its label shows
|
||||
``≅`` when the overlay functionality is enabled and ``≇`` when not.
|
||||
|
||||
Svkbd has been optimised for use on mobile devices with a touchscreen and implements press-on-release
|
||||
behaviour (which can be disabled), it also works fine on normal desktop systems with a regular mouse.
|
||||
|
||||
Advanced Usage
|
||||
---------------
|
||||
|
||||
Svkbd has an extra output mode where all keypresses are printed to standard output. Optionally, you can also disable the
|
||||
default X11 keypress emulation. This gives you the freedom to use svkbd in other contexts and use simple pipes to
|
||||
connect it to other tools:
|
||||
|
||||
|
||||
$ svkbd-mobile-intl -n -o | cowsay
|
||||
|
||||
This becomes especially useful if you want things like haptic feedback or audio feedback upon keypress. This is
|
||||
deliberately not implemented in svkbd itself (we want to keep things simple after all), but can be accomplished using
|
||||
the external tool [clickclack](https://git.sr.ht/~proycon/clickclack):
|
||||
|
||||
$ svkbd-mobile-intl -o | clickclack -V -f keypress.wav
|
||||
|
||||
Notes
|
||||
---------
|
||||
|
||||
This virtual keyboard does not actually modify the X keyboard layout, the ``mobile-intl``, ``mobile-plain`` and ``en`` layouts simply rely on a standard US QWERTY layout (setxkbmap us) being activated, the other layouts (``de``, ``ru``, ``sh``) require their respective XKB keymaps to be active.
|
||||
This virtual keyboard does not actually modify the X keyboard layout, the ``mobile-intl``, ``mobile-plain``,
|
||||
``mobile-simple`` and ``en`` layouts simply rely on a standard US QWERTY layout (setxkbmap us) being activated, the
|
||||
other layouts (``de``, ``ru``, ``sh``) require their respective XKB keymaps to be active.
|
||||
|
||||
If you use another XKB layout you will get unpredictable output that does not match the labels on the virtual keycaps!
|
||||
|
||||
|
|
31
config.def.h
31
config.def.h
|
@ -1,13 +1,30 @@
|
|||
static const Bool wmborder = True;
|
||||
static int fontsize = 20;
|
||||
static int fontsize = 22;
|
||||
/* overlay delay in seconds */
|
||||
static double overlay_delay = 1.0;
|
||||
static int heightfactor = 16; //one row of keys takes up 1/x of the screen height
|
||||
static const char *fonts[] = {
|
||||
"DejaVu Sans:bold:size=20"
|
||||
/* repeat delay in seconds, will not work on keys with overlays */
|
||||
static double repeat_delay = 0.75;
|
||||
/* scan rate in microseconds, affects key repetition rate */
|
||||
static int scan_rate = 50;
|
||||
/* one row of keys takes up 1/x of the screen height */
|
||||
static int heightfactor = 14;
|
||||
static int xspacing = 5;
|
||||
static int yspacing = 5;
|
||||
static const char *defaultfonts[] = {
|
||||
"DejaVu Sans:bold:size=22"
|
||||
};
|
||||
static const char *colors[SchemeLast][2] = {
|
||||
static const char *defaultcolors[SchemeLast][2] = {
|
||||
/* fg bg */
|
||||
[SchemeNorm] = { "#ffffff", "#14313d" },
|
||||
[SchemePress] = { "#ffffff", "#000000" },
|
||||
[SchemeNorm] = { "#bbbbbb", "#132a33" },
|
||||
[SchemeNormShift] = { "#008ac0", "#132a33" },
|
||||
[SchemeNormABC] = { "#ffffff", "#14313d" },
|
||||
[SchemeNormABCShift] = { "#008ac0", "#14313d" },
|
||||
[SchemePress] = { "#ffffff", "#259937" },
|
||||
[SchemePressShift] = { "#00c001", "#259937" },
|
||||
[SchemeHighlight] = { "#58a7c6", "#005577" },
|
||||
[SchemeHighlightShift] = { "#008ac0", "#005577" },
|
||||
[SchemeOverlay] = { "#ffffff", "#2b3313" },
|
||||
[SchemeOverlayShift] = { "#008ac0", "#2b3313" },
|
||||
[SchemeWindow] = { "#bbbbbb", "#132a33" },
|
||||
};
|
||||
|
||||
|
|
|
@ -24,4 +24,4 @@ LIBS = -L${X11LIB} -lX11 -lXtst -lXft ${XINERAMALIBS} \
|
|||
# use system flags
|
||||
SVKBD_CFLAGS = ${CFLAGS} ${INCS}
|
||||
SVKBD_LDFLAGS = ${LDFLAGS} ${LIBS}
|
||||
SVKBD_CPPFLAGS = ${CPPFLAGS} -DVERSION=\"VERSION\" ${XINERAMAFLAGS} -DLAYOUT=\"layout.${LAYOUT}.h\"
|
||||
SVKBD_CPPFLAGS = ${CPPFLAGS} -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -DLAYOUT=\"layout.${LAYOUT}.h\"
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
#define KEYS 63
|
||||
static Key keys_am[] = {
|
||||
{ "՝","՜", XK_Armenian_exclam, 1 },
|
||||
{ "ֆ","Ֆ", XK_Armenian_fe, 1 },
|
||||
{ "ձ","Ձ", XK_Armenian_dza, 1 },
|
||||
{ "֊","—", XK_Armenian_hyphen, 1 },
|
||||
{ ",","՟", XK_comma, 1 },
|
||||
{ "։","…", XK_Armenian_full_stop, 1 },
|
||||
{ "՞","%", XK_Armenian_question, 1 },
|
||||
{ "․","և", XK_Armenian_ligature_ew, 1 },
|
||||
{ "՛","՚", XK_Armenian_accent, 1 },
|
||||
{ ")","(", XK_parenright, 1 },
|
||||
{ "օ","Օ", XK_Armenian_o, 1 },
|
||||
{ "է","Է", XK_Armenian_e, 1 },
|
||||
{ "ղ","Ղ", XK_Armenian_ghat, 1 },
|
||||
{ "<-", 0, XK_BackSpace, 2 },
|
||||
{ "Del", 0, XK_Delete, 1},
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", 0, XK_Tab, 1 },
|
||||
{ "ճ", "Ճ", XK_Armenian_tche, 1 },
|
||||
{ "փ", "Փ", XK_Armenian_pyur, 1 },
|
||||
{ "բ", "Բ", XK_Armenian_ben, 1 },
|
||||
{ "ս", "Ս", XK_Armenian_se, 1 },
|
||||
{ "մ", "Մ", XK_Armenian_men, 1 },
|
||||
{ "ո", "Ո", XK_Armenian_vo, 1 },
|
||||
{ "ւ", "Ւ", XK_Armenian_vyun, 1 },
|
||||
{ "կ","Կ", XK_Armenian_ken, 1 },
|
||||
{ "ը", "Ը", XK_Armenian_at, 1 },
|
||||
{ "թ", "Թ", XK_Armenian_to, 1 },
|
||||
{ "ծ", "Ծ", XK_Armenian_tsa, 1 },
|
||||
{ "ց", "Ց", XK_Armenian_tso, 1 },
|
||||
{ "Return", 0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ "ջ", "Ջ", XK_Armenian_je, 1 },
|
||||
{ "վ", "Վ", XK_Armenian_vev, 1 },
|
||||
{ "գ", "Գ", XK_Armenian_gim, 1 },
|
||||
{ "ե", "Ե", XK_Armenian_yech, 1 },
|
||||
{ "ա", "Ա", XK_Armenian_ayb, 1 },
|
||||
{ "ն", "Ն", XK_Armenian_nu, 1 },
|
||||
{ "ի", "Ի", XK_Armenian_ini, 1 },
|
||||
{ "տ", "Տ", XK_Armenian_tyun, 1 },
|
||||
{ "հ", "Հ", XK_Armenian_ho, 1 },
|
||||
{ "պ", "Պ", XK_Armenian_pe, 1 },
|
||||
{ "ր", "Ր", XK_Armenian_re, 1 },
|
||||
{ "\\","/", XK_backslash, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, 0, XK_Shift_L, 3 },
|
||||
{ "ժ", "Ժ", XK_Armenian_zhe, 1 },
|
||||
{ "դ", "Դ", XK_Armenian_da, 1 },
|
||||
{ "չ", "Չ", XK_Armenian_cha, 1 },
|
||||
{ "յ", "Յ", XK_Armenian_hi, 1 },
|
||||
{ "զ", "Զ", XK_Armenian_za, 1 },
|
||||
{ "լ", "Լ", XK_Armenian_lyun, 1 },
|
||||
{ "ք", "Ք", XK_Armenian_ke, 1 },
|
||||
{ "խ", "Խ", XK_Armenian_khe, 1 },
|
||||
{ "շ", "Շ", XK_Armenian_sha, 1 },
|
||||
{ "ռ", "Ռ", XK_Armenian_ra, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", 0, XK_Control_L, 2 },
|
||||
{ "Alt", 0,XK_Alt_L, 2 },
|
||||
{ "", 0,XK_space, 5 },
|
||||
{ "Alt", 0,XK_Alt_R, 2 },
|
||||
{ "Ctrl", 0,XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
{ XK_Shift_L, Button2 },
|
||||
{ XK_Alt_L, Button3 },
|
||||
};
|
||||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
static char* layer_names[LAYERS] = {
|
||||
"am",
|
||||
};
|
||||
|
||||
static Key* available_layers[LAYERS] = {
|
||||
keys_am,
|
||||
};
|
|
@ -1,11 +1,11 @@
|
|||
#define KEYS 6
|
||||
static Key keys_arrows[] = {
|
||||
{ 0, XK_Shift_L, 2 },
|
||||
{ "←", XK_Left, 1 },
|
||||
{ "↓", XK_Down, 1 },
|
||||
{ "↑", XK_Up, 1 },
|
||||
{ "→", XK_Right, 1},
|
||||
{ "Alt", XK_Alt_L, 2 },
|
||||
{ 0, 0, XK_Shift_L, 2 },
|
||||
{ "←", 0, XK_Left, 1 },
|
||||
{ "↓", 0, XK_Down, 1 },
|
||||
{ "↑", 0, XK_Up, 1 },
|
||||
{ "→", 0, XK_Right, 1},
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
|
@ -15,7 +15,7 @@ Buttonmod buttonmods[] = {
|
|||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
|
|
126
layout.de.h
126
layout.de.h
|
@ -1,71 +1,71 @@
|
|||
#define KEYS 66
|
||||
static Key keys_de[KEYS] = {
|
||||
{ "^°′", XK_dead_circumflex, 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 },
|
||||
{ "ß?\\", XK_ssharp, 1 },
|
||||
{ "´`¸", XK_dead_acute, 1 },
|
||||
{ "<-", XK_BackSpace, 2 },
|
||||
{ "Entf", XK_Delete, 1},
|
||||
{ "^","°′", XK_dead_circumflex, 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 },
|
||||
{ "ß","?\\", XK_ssharp, 1 },
|
||||
{ "´","`¸", XK_dead_acute, 1 },
|
||||
{ "<-", 0, XK_BackSpace, 2 },
|
||||
{ "Entf", 0, XK_Delete, 1},
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", XK_Tab, 1 },
|
||||
{ "qQ@", XK_q, 1 },
|
||||
{ "wWł", XK_w, 1 },
|
||||
{ "eE€", XK_e, 1 },
|
||||
{ "rR¶", XK_r, 1 },
|
||||
{ "tTŧ", XK_t, 1 },
|
||||
{ "zZ←", XK_z, 1 },
|
||||
{ "uU↓", XK_u, 1 },
|
||||
{ "iI→", XK_i, 1 },
|
||||
{ "oOø", XK_o, 1 },
|
||||
{ "pPþ", XK_p, 1 },
|
||||
{ "üܨ", 0xfc, 1 },
|
||||
{ "+*~", XK_plus, 1 },
|
||||
{ "Enter", XK_Return, 3 },
|
||||
{ "->|", 0, XK_Tab, 1 },
|
||||
{ "q","Q@", XK_q, 1 },
|
||||
{ "w","Wł", XK_w, 1 },
|
||||
{ "e","E€", XK_e, 1 },
|
||||
{ "r","R¶", XK_r, 1 },
|
||||
{ "t","Tŧ", XK_t, 1 },
|
||||
{ "z","Z←", XK_z, 1 },
|
||||
{ "u","U↓", XK_u, 1 },
|
||||
{ "i","I→", XK_i, 1 },
|
||||
{ "o","Oø", XK_o, 1 },
|
||||
{ "p","Pþ", XK_p, 1 },
|
||||
{ "ü","ܨ", 0xfc, 1 },
|
||||
{ "+","*~", XK_plus, 1 },
|
||||
{ "Enter", 0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Caps_Lock, 2 },
|
||||
{ "aAæ", XK_a, 1 },
|
||||
{ "sSſ", XK_s, 1 },
|
||||
{ "dDð", XK_d, 1 },
|
||||
{ "fFđ", XK_f, 1 },
|
||||
{ "gGŋ", XK_g, 1 },
|
||||
{ "hHħ", XK_h, 1 },
|
||||
{ "jJ̣̣", XK_j, 1 },
|
||||
{ "kKĸ", XK_k, 1 },
|
||||
{ "lLł", XK_l, 1 },
|
||||
{ "öÖ˝", 0xf6, 1 },
|
||||
{ "äÄ^", 0xe4, 1 },
|
||||
{ "#'’", XK_numbersign, 1 },
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ "a","Aæ", XK_a, 1 },
|
||||
{ "s","Sſ", XK_s, 1 },
|
||||
{ "d","Dð", XK_d, 1 },
|
||||
{ "f","Fđ", XK_f, 1 },
|
||||
{ "g","Gŋ", XK_g, 1 },
|
||||
{ "h","Hħ", XK_h, 1 },
|
||||
{ "j","J̣̣", XK_j, 1 },
|
||||
{ "k","Kĸ", XK_k, 1 },
|
||||
{ "l","Lł", XK_l, 1 },
|
||||
{ "ö","Ö˝", 0xf6, 1 },
|
||||
{ "ä","Ä^", 0xe4, 1 },
|
||||
{ "#","'’", XK_numbersign, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Shift_L, 2 },
|
||||
{ "<>|", XK_less, 1 },
|
||||
{ "yY»", XK_y, 1 },
|
||||
{ "xX«", XK_x, 1 },
|
||||
{ "cC¢", XK_c, 1 },
|
||||
{ "vV„", XK_v, 1 },
|
||||
{ "bB“", XK_b, 1 },
|
||||
{ "nN”", XK_n, 1 },
|
||||
{ "mMµ", XK_m, 1 },
|
||||
{ ",;·", XK_comma, 1 },
|
||||
{ ".:…", XK_period, 1 },
|
||||
{ "-_–", XK_minus, 1 },
|
||||
{ 0, XK_Shift_R, 2 },
|
||||
{ 0, 0, XK_Shift_L, 2 },
|
||||
{ "<",">|", XK_less, 1 },
|
||||
{ "y","Y»", XK_y, 1 },
|
||||
{ "x","X«", XK_x, 1 },
|
||||
{ "c","C¢", XK_c, 1 },
|
||||
{ "v","V„", XK_v, 1 },
|
||||
{ "b","B“", XK_b, 1 },
|
||||
{ "n","N”", XK_n, 1 },
|
||||
{ "m","Mµ", XK_m, 1 },
|
||||
{ ",",";·", XK_comma, 1 },
|
||||
{ ".",":…", XK_period, 1 },
|
||||
{ "-","_–", XK_minus, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", XK_Control_L, 2 },
|
||||
{ "Win", XK_Super_L, 2 },
|
||||
{ "Alt", XK_Alt_L, 2 },
|
||||
{ "", XK_space, 5 },
|
||||
{ "Alt Gr", XK_ISO_Level3_Shift, 2 },
|
||||
{ "Menu", XK_Menu, 2 },
|
||||
{ "Ctrl", XK_Control_R, 2 },
|
||||
{ "Ctrl", 0, XK_Control_L, 2 },
|
||||
{ "Win", 0, XK_Super_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 5 },
|
||||
{ "Alt Gr", 0, XK_ISO_Level3_Shift, 2 },
|
||||
{ "Menu", 0, XK_Menu, 2 },
|
||||
{ "Ctrl", 0, XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
|
@ -75,7 +75,7 @@ Buttonmod buttonmods[] = {
|
|||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
|
|
121
layout.en.h
121
layout.en.h
|
@ -1,66 +1,66 @@
|
|||
#define KEYS 61
|
||||
static Key keys_en[] = {
|
||||
{ "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_minus, 1 },
|
||||
{ "=+", XK_plus, 1 },
|
||||
{ "<-", XK_BackSpace, 2 },
|
||||
{ "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_minus, 1 },
|
||||
{ "=","+", XK_plus, 1 },
|
||||
{ "⌫Bksp",0, XK_BackSpace, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", XK_Tab, 1 },
|
||||
{ 0, XK_q, 1 },
|
||||
{ 0, XK_w, 1 },
|
||||
{ 0, XK_e, 1 },
|
||||
{ 0, XK_r, 1 },
|
||||
{ 0, XK_t, 1 },
|
||||
{ 0, XK_y, 1 },
|
||||
{ 0, XK_u, 1 },
|
||||
{ 0, XK_i, 1 },
|
||||
{ 0, XK_o, 1 },
|
||||
{ 0, XK_p, 1 },
|
||||
{ "[", XK_bracketleft, 1 },
|
||||
{ "]", XK_bracketright, 1 },
|
||||
{ "Return", XK_Return, 3 },
|
||||
{ "->|",0, XK_Tab, 1 },
|
||||
{ 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_bracketleft, 1 },
|
||||
{ "]", "}", XK_bracketright, 1 },
|
||||
{ "Enter", 0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Caps_Lock, 2 },
|
||||
{ 0, XK_a, 1 },
|
||||
{ 0, XK_s, 1 },
|
||||
{ 0, XK_d, 1 },
|
||||
{ 0, XK_f, 1 },
|
||||
{ 0, XK_g, 1 },
|
||||
{ 0, XK_h, 1 },
|
||||
{ 0, XK_j, 1 },
|
||||
{ 0, XK_k, 1 },
|
||||
{ 0, XK_l, 1 },
|
||||
{ ":;", XK_semicolon, 1 },
|
||||
{ "'\"", XK_exclam, 1 },
|
||||
{ "\\|", XK_backslash, 1 },
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ 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_semicolon, 1 },
|
||||
{ "'","\"", XK_exclam, 1 },
|
||||
{ "\\", "|", XK_backslash, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Shift_L, 3 },
|
||||
{ 0, XK_z, 1 },
|
||||
{ 0, XK_x, 1 },
|
||||
{ 0, XK_c, 1 },
|
||||
{ 0, XK_v, 1 },
|
||||
{ 0, XK_b, 1 },
|
||||
{ 0, XK_n, 1 },
|
||||
{ 0, XK_m, 1 },
|
||||
{ ",", XK_colon, 1 },
|
||||
{ ".", XK_period, 1 },
|
||||
{ "/?", XK_slash, 1 },
|
||||
{ 0, XK_Shift_R, 2 },
|
||||
{ 0, 0, XK_Shift_L, 3 },
|
||||
{ 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_colon, 1 },
|
||||
{ ".", ">", XK_period, 1 },
|
||||
{ "/", "?", XK_slash, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", XK_Control_L, 2 },
|
||||
{ "Alt", XK_Alt_L, 2 },
|
||||
{ "", XK_space, 5 },
|
||||
{ "Alt", XK_Alt_R, 2 },
|
||||
{ "Ctrl", XK_Control_R, 2 },
|
||||
{ "Ctrl",0, XK_Control_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 5 },
|
||||
{ "Alt", 0, XK_Alt_R, 2 },
|
||||
{ "Ctrl", 0, XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
|
@ -70,15 +70,14 @@ Buttonmod buttonmods[] = {
|
|||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
static char* layer_names[LAYERS] = {
|
||||
"en",
|
||||
"en",
|
||||
};
|
||||
|
||||
static Key* available_layers[LAYERS] = {
|
||||
keys_en,
|
||||
keys_en,
|
||||
};
|
||||
|
||||
|
|
1150
layout.mobile-intl.h
1150
layout.mobile-intl.h
File diff suppressed because it is too large
Load Diff
|
@ -1,125 +1,122 @@
|
|||
#define KEYS 40
|
||||
#define KEYS 44
|
||||
static Key keys_en[KEYS] = {
|
||||
{ 0, XK_q, 1 },
|
||||
{ 0, XK_w, 1 },
|
||||
{ 0, XK_e, 1 },
|
||||
{ 0, XK_r, 1 },
|
||||
{ 0, XK_t, 1 },
|
||||
{ 0, XK_y, 1 },
|
||||
{ 0, XK_u, 1 },
|
||||
{ 0, XK_i, 1 },
|
||||
{ 0, XK_o, 1 },
|
||||
{ 0, XK_p, 1 },
|
||||
{ 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 },
|
||||
|
||||
{ 0 }, /* New row */
|
||||
{ 0 }, /* New row */
|
||||
|
||||
{ 0, XK_a, 1 },
|
||||
{ 0, XK_s, 1 },
|
||||
{ 0, XK_d, 1 },
|
||||
{ 0, XK_f, 1 },
|
||||
{ 0, XK_g, 1 },
|
||||
{ 0, XK_h, 1 },
|
||||
{ 0, XK_j, 1 },
|
||||
{ 0, XK_k, 1 },
|
||||
{ 0, XK_l, 1 },
|
||||
{ ";:", XK_colon, 1 },
|
||||
/*{ "'", XK_apostrophe, 2 },*/
|
||||
{ 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_colon, 1 },
|
||||
/*{ "'", XK_apostrophe, 2 },*/
|
||||
|
||||
{ 0 }, /* New row */
|
||||
{ 0 }, /* New row */
|
||||
|
||||
{ 0, XK_z, 1 },
|
||||
{ 0, XK_x, 1 },
|
||||
{ 0, XK_c, 1 },
|
||||
{ 0, XK_v, 1 },
|
||||
{ 0, XK_b, 1 },
|
||||
{ 0, XK_n, 1 },
|
||||
{ 0, XK_m, 1 },
|
||||
/*{ "/?", XK_slash, 1 },*/
|
||||
{ "Tab", XK_Tab, 1 },
|
||||
{ "⇍ Bksp", XK_BackSpace, 2 },
|
||||
{ 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_slash, 1 },*/
|
||||
{ "Tab", 0, XK_Tab, 1 },
|
||||
{ "⇍ Bksp", 0, XK_BackSpace, 2 },
|
||||
|
||||
{ 0 }, /* New row */
|
||||
{ "↺", XK_Cancel, 1},
|
||||
{ "Shft", XK_Shift_L, 1 },
|
||||
/*{ "L", XK_Left, 1 },*/
|
||||
{ "↓", XK_Down, 1 },
|
||||
{ "↑", XK_Up, 1 },
|
||||
/*{ "R", XK_Right, 1 },*/
|
||||
{ "", XK_space, 2 },
|
||||
{ "Esc", XK_Escape, 1 },
|
||||
{ "Ctrl", XK_Control_L, 1 },
|
||||
/*{ "Alt", XK_Alt_L, 1 },*/
|
||||
{ "↲ Enter", XK_Return, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "↺", 0, XK_Cancel, 1},
|
||||
{ "Shft", 0, XK_Shift_L, 1 },
|
||||
/*{ "L", XK_Left, 1 },*/
|
||||
{ "↓", 0, XK_Down, 1 },
|
||||
{ "↑", 0, XK_Up, 1 },
|
||||
/*{ "R", XK_Right, 1 },*/
|
||||
{ "", 0, XK_space, 2 },
|
||||
{ "Esc", 0, XK_Escape, 1 },
|
||||
{ "Ctrl", 0, XK_Control_L, 1 },
|
||||
/*{ "Alt", XK_Alt_L, 1 },*/
|
||||
{ "↲ Enter", 0, XK_Return, 2 },
|
||||
};
|
||||
|
||||
static Key keys_symbols[40] = {
|
||||
{ "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 },
|
||||
static Key keys_symbols[KEYS] = {
|
||||
{ "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 }, /* New row */
|
||||
{ 0 }, /* New row */
|
||||
|
||||
{ "'\"", 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 },
|
||||
{ "'", "\"", 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 }, /* New row */
|
||||
{ 0 }, /* New row */
|
||||
|
||||
{ "", XK_Shift_L|XK_bar, 1 },
|
||||
{ "⇤", XK_Home, 1 },
|
||||
{ "←", XK_Left, 1 },
|
||||
{ "→", XK_Right, 1 },
|
||||
{ "⇥", XK_End, 1 },
|
||||
{ "⇊", XK_Next, 1 },
|
||||
{ "⇈", XK_Prior, 1 },
|
||||
{ "Tab", XK_Tab, 1 },
|
||||
{ "⇍ Bksp", XK_BackSpace, 2 },
|
||||
{ "", 0, XK_Shift_L|XK_bar, 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 }, /* New row */
|
||||
{ "↺", XK_Cancel, 1},
|
||||
{ "Shft", XK_Shift_L, 1 },
|
||||
/*{ "L", XK_Left, 1 },*/
|
||||
{ "↓", XK_Down, 1 },
|
||||
{ "↑", XK_Up, 1 },
|
||||
/*{ "R", XK_Right, 1 },*/
|
||||
{ "", XK_space, 2 },
|
||||
{ "Esc", XK_Escape, 1 },
|
||||
{ "Ctrl", XK_Control_L, 1 },
|
||||
/*{ "Alt", XK_Alt_L, 1 },*/
|
||||
{ "↲ Enter", XK_Return, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "↺", 0, XK_Cancel, 1},
|
||||
{ "Shft", 0, XK_Shift_L, 1 },
|
||||
{ "↓", 0, XK_Down, 1 },
|
||||
{ "↑", 0, XK_Up, 1 },
|
||||
{ "", 0, XK_space, 2 },
|
||||
{ "Esc", 0, XK_Escape, 1 },
|
||||
{ "Ctrl", 0, XK_Control_L, 1 },
|
||||
{ "↲ Enter", 0, XK_Return, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
{ XK_Shift_L, Button2 },
|
||||
{ XK_Alt_L, Button3 },
|
||||
{ XK_Shift_L, Button2 },
|
||||
{ XK_Alt_L, Button3 },
|
||||
};
|
||||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 2
|
||||
static char* layer_names[LAYERS] = {
|
||||
"en",
|
||||
"symbols",
|
||||
"en",
|
||||
"symbols",
|
||||
};
|
||||
|
||||
static Key* available_layers[LAYERS] = {
|
||||
keys_en,
|
||||
keys_symbols,
|
||||
keys_en,
|
||||
keys_symbols,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,408 @@
|
|||
#define KEYS 43
|
||||
|
||||
static Key keys_lazy_en[KEYS] = {
|
||||
{ 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 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ 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 },
|
||||
{ "'", 0, XK_apostrophe, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "↑", 0, XK_Shift_L, 1 },
|
||||
{ 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 },
|
||||
{ "Tab", 0, XK_Tab, 1 },
|
||||
{ "⌫", 0, XK_BackSpace, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "?123", 0, XK_Cancel, 3 },
|
||||
{ "-", 0, XK_minus, 2 },
|
||||
{ "☺", 0, 0x101f642, 2 },
|
||||
{ "Ctl", 0, XK_Control_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 4 },
|
||||
{ ".", 0, XK_period, 2 },
|
||||
{ "↲Enter", 0, XK_Return, 3 }
|
||||
};
|
||||
|
||||
static Key keys_symbols[KEYS] = {
|
||||
{ "1", 0, XK_1, 1 },
|
||||
{ "2", 0, XK_2, 1 },
|
||||
{ "3", 0, XK_3, 1 },
|
||||
{ "4", 0, XK_4, 1 },
|
||||
{ "5", 0, XK_5, 1 },
|
||||
{ "6", 0, XK_6, 1 },
|
||||
{ "7", 0, XK_7, 1 },
|
||||
{ "8", 0, XK_8, 1 },
|
||||
{ "9", 0, XK_9, 1 },
|
||||
{ "0", 0, XK_0, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "!", 0, XK_1, 1, XK_Shift_L },
|
||||
{ "@", 0, XK_2, 1, XK_Shift_L },
|
||||
{ "#", 0, XK_3, 1, XK_Shift_L },
|
||||
{ "$", 0, XK_4, 1, XK_Shift_L },
|
||||
{ "%", 0, XK_5, 1, XK_Shift_L },
|
||||
{ "^", 0, XK_6, 1, XK_Shift_L },
|
||||
{ "&", 0, XK_7, 1, XK_Shift_L },
|
||||
{ "*", 0, XK_8, 1, XK_Shift_L },
|
||||
{ "(", 0, XK_9, 1, XK_Shift_L },
|
||||
{ ")", 0, XK_0, 1, XK_Shift_L },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "Esc", 0, XK_Escape, 1 },
|
||||
{ "~", 0, XK_grave, 1, XK_Shift_L },
|
||||
{ "\\", 0, XK_backslash, 1 },
|
||||
{ "|", 0, XK_backslash, 1, XK_Shift_L },
|
||||
{ "←", 0, XK_Left, 1 },
|
||||
{ "↓", 0, XK_Down, 1 },
|
||||
{ "↑", 0, XK_Up, 1 },
|
||||
{ "→", 0, XK_Right, 1 },
|
||||
{ "Tab", 0, XK_Tab, 1 },
|
||||
{ "⌫", 0, XK_BackSpace, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "abc", 0, XK_Mode_switch, 3 },
|
||||
{ "-", 0, XK_minus, 2 },
|
||||
{ "↺", 0, XK_Cancel, 2 },
|
||||
{ "Ctl", 0, XK_Control_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 4 },
|
||||
{ ".", 0, XK_period, 2 },
|
||||
{ "↲Enter", 0, XK_Return, 3 }
|
||||
};
|
||||
|
||||
static Key keys_functions[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 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "≅", 0, XK_KP_Insert, 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 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "abc", 0, XK_Mode_switch, 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 },
|
||||
{ "⌫", 0, XK_BackSpace, 2 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "↺", 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 },
|
||||
};
|
||||
|
||||
#define DIALER_KEYS 27
|
||||
|
||||
static Key keys_dialer[DIALER_KEYS] = {
|
||||
{ "Esc", 0, XK_Escape, 1 },
|
||||
{ "1!", 0, XK_1, 1 },
|
||||
{ "2@", 0, XK_2, 1 },
|
||||
{ "3#", 0, XK_3, 1 },
|
||||
{ "-_", 0, XK_minus, 1 },
|
||||
{ ",<", 0, XK_comma, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "Shift", 0, XK_Shift_L, 1 },
|
||||
{ "4$", 0, XK_4, 1 },
|
||||
{ "5%", 0, XK_5, 1 },
|
||||
{ "6^", 0, XK_6, 1 },
|
||||
{ "=+", 0, XK_equal, 1 },
|
||||
{ "/?", 0, XK_slash, 1 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "abc", 0, XK_Mode_switch, 1 },
|
||||
{ "7&", 0, XK_7, 1 },
|
||||
{ "8*", 0, XK_8, 1 },
|
||||
{ "9(", 0, XK_9, 1 },
|
||||
{ "⌫", 0, XK_BackSpace, 2 },
|
||||
|
||||
{ 0 },
|
||||
|
||||
{ "↺", 0, XK_Cancel, 1},
|
||||
{ "", 0, XK_space, 1 },
|
||||
{ "0)", 0, XK_0, 1 },
|
||||
{ ".>", 0, XK_period, 1 },
|
||||
{ "↲ Enter", 0, XK_Return, 2},
|
||||
};
|
||||
|
||||
#define OVERLAYS 193
|
||||
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, 0, XK_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 },
|
||||
{ 0, 0, XK_e },
|
||||
{ "è", 0, XK_egrave },
|
||||
{ "é", 0, XK_eacute },
|
||||
{ "ê", 0, XK_ecircumflex },
|
||||
{ "ë", 0, XK_ediaeresis },
|
||||
{ "ę", 0, XK_eogonek },
|
||||
{ "ē", 0, XK_emacron },
|
||||
{ "ė", 0, XK_eabovedot },
|
||||
{ "ě", 0, XK_ecaron },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_y },
|
||||
{ "ỳ", 0, XK_ygrave },
|
||||
{ "ý", 0, XK_yacute },
|
||||
{ "ŷ", 0, XK_ycircumflex },
|
||||
{ "ÿ", 0, XK_ydiaeresis },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_u },
|
||||
{ "ù", 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, XK_i },
|
||||
{ "ì", 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, XK_o },
|
||||
{ "ò", 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 },
|
||||
{ 0, 0, XK_d },
|
||||
{ "ď", 0, XK_dcaron },
|
||||
{ "ð", 0, XK_eth },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_c },
|
||||
{ "ç", 0, XK_ccedilla },
|
||||
{ "ĉ", 0, XK_ccircumflex },
|
||||
{ "č", 0, XK_ccaron },
|
||||
{ "ć", 0, XK_cacute },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_s },
|
||||
{ "ş", 0, XK_scedilla },
|
||||
{ "ŝ", 0, XK_scircumflex },
|
||||
{ "š", 0, XK_scaron },
|
||||
{ "ś", 0, XK_sacute },
|
||||
{ "ß", 0, XK_ssharp },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_z },
|
||||
{ "ž", 0, XK_zcaron },
|
||||
{ "ż", 0, XK_zabovedot },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_n },
|
||||
{ "ñ", 0, XK_ntilde },
|
||||
{ "ń", 0, XK_nacute },
|
||||
{ "ň", 0, XK_ncaron },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_t },
|
||||
{ "ț", 0, XK_tcedilla },
|
||||
{ "ť", 0, XK_tcaron },
|
||||
{ "þ", 0, XK_thorn },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_g },
|
||||
{ "ĝ", 0, XK_gcircumflex },
|
||||
{ "ğ", 0, XK_gbreve },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_h },
|
||||
{ "ĥ", 0, XK_hcircumflex },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_j },
|
||||
{ "ĵ", 0, XK_jcircumflex },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_l },
|
||||
{ "ł", 0, XK_lstroke },
|
||||
{ "ľ", 0, XK_lcaron },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_r },
|
||||
{ "ř", 0, XK_rcaron },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_softsign },
|
||||
{ "ъ", 0, XK_Cyrillic_hardsign },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_ie },
|
||||
{ "ё", 0, XK_Cyrillic_io },
|
||||
{ "э", 0, XK_Cyrillic_e },
|
||||
{ "Є", 0, XK_Ukrainian_ie },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_i },
|
||||
{ "і", 0, XK_Ukrainian_i },
|
||||
{ "ї", 0, XK_Ukrainian_yi },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_u },
|
||||
{ "ў", 0, XK_Byelorussian_shortu },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_shorti },
|
||||
{ "ј", 0, XK_Cyrillic_je },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_el },
|
||||
{ "љ", 0, XK_Cyrillic_lje },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_en },
|
||||
{ "њ", 0, XK_Cyrillic_nje },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_tse },
|
||||
{ "џ", 0, XK_Cyrillic_dzhe },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cyrillic_che },
|
||||
{ "ћ", 0, XK_Serbian_tshe },
|
||||
{ "ђ", 0, XK_Serbian_dje },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ "🙂", 0, 0x101f642 },
|
||||
{ "😀", 0, 0x101f600 },
|
||||
{ "😁", 0, 0x101f601 },
|
||||
{ "😂", 0, 0x101f602 },
|
||||
{ "😃", 0, 0x101f603 },
|
||||
{ "😄", 0, 0x101f604 },
|
||||
{ "😅", 0, 0x101f605 },
|
||||
{ "😆", 0, 0x101f606 },
|
||||
{ "😇", 0, 0x101f607 },
|
||||
{ "😈", 0, 0x101f608 },
|
||||
{ "😉", 0, 0x101f609 },
|
||||
{ "😊", 0, 0x101f60a },
|
||||
{ "😋", 0, 0x101f60b },
|
||||
{ "😌", 0, 0x101f60c },
|
||||
{ "😍", 0, 0x101f60d },
|
||||
{ "😎", 0, 0x101f60e },
|
||||
{ "😏", 0, 0x101f60f },
|
||||
{ "😐", 0, 0x101f610 },
|
||||
{ "😒", 0, 0x101f612 },
|
||||
{ "😓", 0, 0x101f613 },
|
||||
{ "😛", 0, 0x101f61b },
|
||||
{ "😮", 0, 0x101f62e },
|
||||
{ "😟", 0, 0x101f61f },
|
||||
{ "😟", 0, 0x101f620 },
|
||||
{ "😢", 0, 0x101f622 },
|
||||
{ "😭", 0, 0x101f62d },
|
||||
{ "😳", 0, 0x101f633 },
|
||||
{ "😴", 0, 0x101f634 },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ ".", 0, XK_period, },
|
||||
{ ":", 0, XK_colon, 26, XK_Shift_L },
|
||||
{ ";", 0, XK_colon, 0 },
|
||||
{ "!", 0, XK_1, 0, XK_Shift_L },
|
||||
{ "?", 0, XK_slash, 0, XK_Shift_L },
|
||||
{ ",", 0, XK_comma, 0 },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ "-", 0, XK_minus },
|
||||
{ "_", 0, XK_minus, 24, XK_Shift_L },
|
||||
{ "+", 0, XK_plus, 0, XK_Shift_L },
|
||||
{ "/", 0, XK_slash, 0 },
|
||||
{ "*", 0, XK_8, 0, XK_Shift_L },
|
||||
{ "=", 0, XK_plus },
|
||||
{ 0, 0, XK_Cancel },
|
||||
{ "'", 0, XK_apostrophe },
|
||||
{ "{", 0, XK_bracketleft, 7, XK_Shift_L },
|
||||
{ "}", 0, XK_bracketright, 0, XK_Shift_L },
|
||||
{ "[", 0, XK_bracketleft, 0 },
|
||||
{ "]", 0, XK_bracketright, 0 },
|
||||
{ "<", 0, XK_comma, 6, XK_Shift_L },
|
||||
{ ">", 0, XK_period, 0, XK_Shift_L },
|
||||
{ "`", 0, XK_grave, 0 },
|
||||
{ "\"", 0, XK_apostrophe, 0, XK_Shift_L },
|
||||
{ "'", 0, XK_apostrophe },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 4
|
||||
|
||||
static char* layer_names[LAYERS] = {
|
||||
"lazy en",
|
||||
"symbols",
|
||||
"functions",
|
||||
"dialer",
|
||||
};
|
||||
|
||||
static Key* available_layers[LAYERS] = {
|
||||
keys_lazy_en,
|
||||
keys_symbols,
|
||||
keys_functions,
|
||||
keys_dialer,
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
{ XK_Shift_L, Button2 },
|
||||
{ XK_Alt_L, Button3 },
|
||||
};
|
120
layout.ru.h
120
layout.ru.h
|
@ -1,68 +1,68 @@
|
|||
#define KEYS 63
|
||||
static Key keys_ru[] = {
|
||||
{ "ёЁ", XK_Cyrillic_io, 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 },
|
||||
{ "-_", XK_minus, 1 },
|
||||
{ "=+", XK_plus, 1 },
|
||||
{ "<-", XK_BackSpace, 2 },
|
||||
{ "Del", XK_Delete, 1},
|
||||
{ "ё","Ё", XK_Cyrillic_io, 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 },
|
||||
{ "-","_", XK_minus, 1 },
|
||||
{ "=","+", XK_plus, 1 },
|
||||
{ "<-", 0, XK_BackSpace, 2 },
|
||||
{ "Del", 0, XK_Delete, 1},
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", XK_Tab, 1 },
|
||||
{ "йЙ", XK_Cyrillic_shorti, 1 },
|
||||
{ "цЦ", XK_Cyrillic_tse, 1 },
|
||||
{ "уУ", XK_Cyrillic_u, 1 },
|
||||
{ "кК", XK_Cyrillic_ka, 1 },
|
||||
{ "еЕ", XK_Cyrillic_ie, 1 },
|
||||
{ "нН", XK_Cyrillic_en, 1 },
|
||||
{ "гГ", XK_Cyrillic_ghe, 1 },
|
||||
{ "шШ", XK_Cyrillic_sha, 1 },
|
||||
{ "щЩ", XK_Cyrillic_shcha, 1 },
|
||||
{ "зЗ", XK_Cyrillic_ze, 1 },
|
||||
{ "хХ", XK_Cyrillic_ha, 1 },
|
||||
{ "ъЪ", XK_Cyrillic_hardsign, 1 },
|
||||
{ "Return", XK_Return, 3 },
|
||||
{ "->|", 0, XK_Tab, 1 },
|
||||
{ "й", 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, XK_Cyrillic_hardsign, 1 },
|
||||
{ "Return", 0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Caps_Lock, 2 },
|
||||
{ "фФ", XK_Cyrillic_ef, 1 },
|
||||
{ "ыЫ", XK_Cyrillic_yeru, 1 },
|
||||
{ "вВ", XK_Cyrillic_ve, 1 },
|
||||
{ "аА", XK_Cyrillic_a, 1 },
|
||||
{ "пП", XK_Cyrillic_pe, 1 },
|
||||
{ "рР", XK_Cyrillic_er, 1 },
|
||||
{ "оО", XK_Cyrillic_o, 1 },
|
||||
{ "лЛ", XK_Cyrillic_el, 1 },
|
||||
{ "дД", XK_Cyrillic_de, 1 },
|
||||
{ "жЖ", XK_Cyrillic_zhe, 1 },
|
||||
{ "эЭ", XK_Cyrillic_e, 1 },
|
||||
{ "\\/", XK_backslash, 1 },
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ "ф", 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_e, 1 },
|
||||
{ "\\","/", XK_backslash, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Shift_L, 3 },
|
||||
{ "яЯ", XK_Cyrillic_ya, 1 },
|
||||
{ "чЧ", XK_Cyrillic_che, 1 },
|
||||
{ "сС", XK_Cyrillic_es, 1 },
|
||||
{ "мМ", XK_Cyrillic_em, 1 },
|
||||
{ "иИ", XK_Cyrillic_i, 1 },
|
||||
{ "тТ", XK_Cyrillic_te, 1 },
|
||||
{ "ьЬ", XK_Cyrillic_softsign, 1 },
|
||||
{ "бБ", XK_Cyrillic_be, 1 },
|
||||
{ "юЮ", XK_Cyrillic_yu, 1 },
|
||||
{ ".,", XK_period, 1 },
|
||||
{ 0, XK_Shift_R, 2 },
|
||||
{ 0, 0, XK_Shift_L, 3 },
|
||||
{ "я", 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 },
|
||||
{ "ю", 0, XK_Cyrillic_yu, 1 },
|
||||
{ ".", ",", XK_period, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", XK_Control_L, 2 },
|
||||
{ "Alt", XK_Alt_L, 2 },
|
||||
{ "", XK_space, 5 },
|
||||
{ "Alt", XK_Alt_R, 2 },
|
||||
{ "Ctrl", XK_Control_R, 2 },
|
||||
{ "Ctrl", 0, XK_Control_L, 2 },
|
||||
{ "Alt", 0,XK_Alt_L, 2 },
|
||||
{ "", 0,XK_space, 5 },
|
||||
{ "Alt", 0,XK_Alt_R, 2 },
|
||||
{ "Ctrl", 0,XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
|
@ -72,7 +72,7 @@ Buttonmod buttonmods[] = {
|
|||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
|
|
126
layout.sh.h
126
layout.sh.h
|
@ -1,71 +1,71 @@
|
|||
#define KEYS 66
|
||||
static Key keys_sh[] = {
|
||||
{ "`~", XK_quoteleft, 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 },
|
||||
{ "'?¨", XK_apostrophe, 1 },
|
||||
{ "+*¸", XK_plus, 1 },
|
||||
{ "<-", XK_BackSpace, 2 },
|
||||
{ "Del", XK_Delete, 1},
|
||||
{ "`","~", XK_quoteleft, 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 },
|
||||
{ "'","?¨", XK_apostrophe, 1 },
|
||||
{ "+","*¸", XK_plus, 1 },
|
||||
{ "<","-", XK_BackSpace, 2 },
|
||||
{ "Del",0, XK_Delete, 1},
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", XK_Tab, 1 },
|
||||
{ "qQ\\", XK_q, 1 },
|
||||
{ "wW|", XK_w, 1 },
|
||||
{ "eE", XK_e, 1 },
|
||||
{ "rR", XK_r, 1 },
|
||||
{ "tT", XK_t, 1 },
|
||||
{ "zZ", XK_z, 1 },
|
||||
{ "uU", XK_u, 1 },
|
||||
{ "iI", XK_i, 1 },
|
||||
{ "oO", XK_o, 1 },
|
||||
{ "pP", XK_p, 1 },
|
||||
{ "šŠ÷", XK_scaron, 1 },
|
||||
{ "đĐ×", XK_dstroke, 1 },
|
||||
{ "Enter", XK_Return, 3 },
|
||||
{ "->|", 0, XK_Tab, 1 },
|
||||
{ "q","Q\\", XK_q, 1 },
|
||||
{ "w","W|", XK_w, 1 },
|
||||
{ "e","E", XK_e, 1 },
|
||||
{ "r","R", XK_r, 1 },
|
||||
{ "t","T", XK_t, 1 },
|
||||
{ "z","Z", XK_z, 1 },
|
||||
{ "u","U", XK_u, 1 },
|
||||
{ "i","I", XK_i, 1 },
|
||||
{ "o","O", XK_o, 1 },
|
||||
{ "p","P", XK_p, 1 },
|
||||
{ "š","Š÷", XK_scaron, 1 },
|
||||
{ "đ","Đ×", XK_dstroke, 1 },
|
||||
{ "Enter",0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Caps_Lock, 2 },
|
||||
{ "aA", XK_a, 1 },
|
||||
{ "sS", XK_s, 1 },
|
||||
{ "dD", XK_d, 1 },
|
||||
{ "fF[", XK_f, 1 },
|
||||
{ "gG]", XK_g, 1 },
|
||||
{ "hH", XK_h, 1 },
|
||||
{ "jJ̣̣", XK_j, 1 },
|
||||
{ "kKł", XK_k, 1 },
|
||||
{ "lLŁ", XK_l, 1 },
|
||||
{ "čČ", XK_ccaron, 1 },
|
||||
{ "ćĆß", XK_cacute, 1 },
|
||||
{ "žŽ¤", XK_zcaron, 1 },
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ "a","A", XK_a, 1 },
|
||||
{ "s","S", XK_s, 1 },
|
||||
{ "d","D", XK_d, 1 },
|
||||
{ "f","F[", XK_f, 1 },
|
||||
{ "g","G]", XK_g, 1 },
|
||||
{ "h","H", XK_h, 1 },
|
||||
{ "j","J̣̣", XK_j, 1 },
|
||||
{ "k","Kł", XK_k, 1 },
|
||||
{ "l","LŁ", XK_l, 1 },
|
||||
{ "č","Č", XK_ccaron, 1 },
|
||||
{ "ć","Ćß", XK_cacute, 1 },
|
||||
{ "ž","Ž¤", XK_zcaron, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, XK_Shift_L, 2 },
|
||||
{ "<>«»", XK_less, 1 },
|
||||
{ "yY", XK_y, 1 },
|
||||
{ "xX", XK_x, 1 },
|
||||
{ "cC", XK_c, 1 },
|
||||
{ "vV@", XK_v, 1 },
|
||||
{ "bB{", XK_b, 1 },
|
||||
{ "nN}", XK_n, 1 },
|
||||
{ "mM§", XK_m, 1 }, /* XXX no symbol */
|
||||
{ ",;", XK_comma, 1 },
|
||||
{ ".:", XK_period, 1 },
|
||||
{ "-_", XK_minus, 1 },
|
||||
{ 0, XK_Shift_R, 2 },
|
||||
{ 0, 0, XK_Shift_L, 2 },
|
||||
{ "<",">«»", XK_less, 1 },
|
||||
{ "y","Y", XK_y, 1 },
|
||||
{ "x","X", XK_x, 1 },
|
||||
{ "c","C", XK_c, 1 },
|
||||
{ "v","V@", XK_v, 1 },
|
||||
{ "b","B{", XK_b, 1 },
|
||||
{ "n","N}", XK_n, 1 },
|
||||
{ "m","M§", XK_m, 1 }, /* XXX no symbol */
|
||||
{ ",",";", XK_comma, 1 },
|
||||
{ ".",":", XK_period, 1 },
|
||||
{ "-","_", XK_minus, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", XK_Control_L, 2 },
|
||||
{ "Win", XK_Super_L, 2 },
|
||||
{ "Alt", XK_Alt_L, 2 },
|
||||
{ "", XK_space, 5 },
|
||||
{ "Alt Gr", XK_ISO_Level3_Shift, 2 },
|
||||
{ "Menu", XK_Menu, 2 },
|
||||
{ "Ctrl", XK_Control_R, 2 },
|
||||
{ "Ctrl", 0, XK_Control_L, 2 },
|
||||
{ "Win", 0, XK_Super_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 5 },
|
||||
{ "Alt Gr", 0, XK_ISO_Level3_Shift, 2 },
|
||||
{ "Menu", 0, XK_Menu, 2 },
|
||||
{ "Ctrl", 0, XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
|
@ -75,7 +75,7 @@ Buttonmod buttonmods[] = {
|
|||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, XK_Cancel },
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
#define KEYS 66
|
||||
static Key keys_sr[] = {
|
||||
{ "`","~", XK_quoteleft, 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 },
|
||||
{ "'","?", XK_apostrophe, 1 },
|
||||
{ "+","*", XK_plus, 1 },
|
||||
{ "<-",0, XK_BackSpace, 2 },
|
||||
{ "Del",0, XK_Delete, 1},
|
||||
{ 0 }, /* New row */
|
||||
{ "->|", 0, XK_Tab, 1 },
|
||||
{ "љ","Љ", XK_Cyrillic_lje, 1 },
|
||||
{ "њ","Њ", XK_Cyrillic_nje, 1 },
|
||||
{ "е","Е", XK_Cyrillic_ie, 1 },
|
||||
{ "р","Р", XK_Cyrillic_er, 1 },
|
||||
{ "т","Т", XK_Cyrillic_te, 1 },
|
||||
{ "з","З", XK_Cyrillic_ze, 1 },
|
||||
{ "у","У", XK_Cyrillic_u, 1 },
|
||||
{ "и","И", XK_Cyrillic_i, 1 },
|
||||
{ "о","О", XK_Cyrillic_o, 1 },
|
||||
{ "п","П", XK_Cyrillic_pe, 1 },
|
||||
{ "ш","Ш", XK_Cyrillic_sha, 1 },
|
||||
{ "ђ","Ђ", XK_Serbian_dje, 1 },
|
||||
{ "Enter",0, XK_Return, 3 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, 0, XK_Caps_Lock, 2 },
|
||||
{ "а","А", XK_Cyrillic_a, 1 },
|
||||
{ "с","С", XK_Cyrillic_es, 1 },
|
||||
{ "д","Д", XK_Cyrillic_de, 1 },
|
||||
{ "ф","Ф", XK_Cyrillic_ef, 1 },
|
||||
{ "г","Г", XK_Cyrillic_ghe, 1 },
|
||||
{ "х","Х", XK_Cyrillic_ha, 1 },
|
||||
{ "j","J̣̣", XK_Cyrillic_je, 1 },
|
||||
{ "к","К", XK_Cyrillic_ka, 1 },
|
||||
{ "л","Л", XK_Cyrillic_el, 1 },
|
||||
{ "ч","Ч", XK_Cyrillic_che, 1 },
|
||||
{ "ћ","Ћ", XK_Serbian_tshe, 1 },
|
||||
{ "ж","Ж", XK_Cyrillic_zhe, 1 },
|
||||
{ 0 }, /* New row */
|
||||
{ 0, 0, XK_Shift_L, 2 },
|
||||
{ "<",">", XK_less, 1 },
|
||||
{ "ѕ","Ѕ", XK_Serbian_dze, 1 },
|
||||
{ "џ","Џ", XK_Cyrillic_dzhe, 1 },
|
||||
{ "ц","Ц", XK_Cyrillic_tse, 1 },
|
||||
{ "в","В", XK_Cyrillic_ve, 1 },
|
||||
{ "б","Б", XK_Cyrillic_be, 1 },
|
||||
{ "н","Н", XK_Cyrillic_en, 1 },
|
||||
{ "м","М", XK_Cyrillic_em, 1 },
|
||||
{ ",",";", XK_comma, 1 },
|
||||
{ ".",":", XK_period, 1 },
|
||||
{ "-","_", XK_minus, 1 },
|
||||
{ 0, 0, XK_Shift_R, 2 },
|
||||
{ 0 }, /* New row */
|
||||
{ "Ctrl", 0, XK_Control_L, 2 },
|
||||
{ "Win", 0, XK_Super_L, 2 },
|
||||
{ "Alt", 0, XK_Alt_L, 2 },
|
||||
{ "", 0, XK_space, 5 },
|
||||
{ "Alt Gr", 0, XK_ISO_Level3_Shift, 2 },
|
||||
{ "Menu", 0, XK_Menu, 2 },
|
||||
{ "Ctrl", 0, XK_Control_R, 2 },
|
||||
};
|
||||
|
||||
Buttonmod buttonmods[] = {
|
||||
{ XK_Shift_L, Button2 },
|
||||
{ XK_Alt_L, Button3 },
|
||||
};
|
||||
|
||||
#define OVERLAYS 1
|
||||
static Key overlay[OVERLAYS] = {
|
||||
{ 0, 0, XK_Cancel },
|
||||
};
|
||||
|
||||
#define LAYERS 1
|
||||
static char* layer_names[LAYERS] = {
|
||||
"sr",
|
||||
};
|
||||
|
||||
static Key* available_layers[LAYERS] = {
|
||||
keys_sr,
|
||||
};
|
48
svkbd.1
48
svkbd.1
|
@ -1,4 +1,4 @@
|
|||
.Dd August 4, 2020
|
||||
.Dd March 15, 2021
|
||||
.Dt SVKBD 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
|
@ -41,11 +41,17 @@ One row of keys takes up 1/heighfactor of the screen's total height.
|
|||
Comma separated list of layers to enable (by name). If not set, all layers
|
||||
in the layout will be available.
|
||||
The layer names are defined by the layout you compiled.
|
||||
.It Fl n
|
||||
Do not simulate key presses for X
|
||||
.It Fl R
|
||||
Disable press-on-release
|
||||
.It Fl s Ar layer
|
||||
The layer to show on program start-up (by name). If not set, the first
|
||||
layer of the layout will be shown.
|
||||
.It Fl O
|
||||
Disable overlay functionality.
|
||||
.It Fl o
|
||||
Print pressed keys to standard output
|
||||
.It Fl v
|
||||
Show the version information.
|
||||
.El
|
||||
|
@ -63,6 +69,44 @@ Set this to 0 if you want to disable overlay functionality.
|
|||
Affects the vertical space taken by the keyboard.
|
||||
One row of keys takes up 1/heighfactor of the screen's total height.
|
||||
.El
|
||||
.Sh XRESOURCES
|
||||
The appearance of svkbd can be configured via xresources:
|
||||
.Bl -tag -width Ds
|
||||
.It Ev svkbd.font
|
||||
An Xft font specification like "Monospace:bold:size=20".
|
||||
.It Ev svkbd.background
|
||||
The background colour for the keycaps (in #rrggbb syntax)
|
||||
.It Ev svkbd.foreground
|
||||
The foreground colour for the keycaps (in #rrggbb syntax)
|
||||
.It Ev svkbd.shiftforeground
|
||||
The foreground colour for the secondary labels (shift layer) on the keycaps
|
||||
.It Ev svkbd.shiftbackground
|
||||
The background colour for the secondary labels (shift layer) on the keycaps
|
||||
.It Ev svkbd.abcforeground
|
||||
.It Ev svkbd.abcbackbround
|
||||
The colour for alphabetical keys
|
||||
.It Ev svkbd.abcshiftbackground
|
||||
.It Ev svkbd.abcshiftforeground
|
||||
The colour for the secondary labels (shift layer) on alphabetical keys
|
||||
.It Ev svkbd.pressforeground
|
||||
.It Ev svkbd.pressforebackground
|
||||
The colour for keys when held pressed
|
||||
.It Ev svkbd.highlightforeground
|
||||
.It Ev svkbd.highlightforebackground
|
||||
The colour for keys when hovering over them or just after release
|
||||
.It Ev svkbd.highlightshiftforeground
|
||||
.It Ev svkbd.highlightshiftforebackground
|
||||
The colour for the secondary label on keys when hovering over them or just
|
||||
after release
|
||||
.It Ev svkbd.overlayforeground
|
||||
.It Ev svkbd.overlaybackground
|
||||
The colour for keys when they are part of an overlay
|
||||
.It Ev svkbd.overlayshiftforeground
|
||||
.It Ev svkbd.overlayshiftbackground
|
||||
The colour for the secondary label on keys when they are part of an overlay
|
||||
.El
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh SEE ALSO
|
||||
.Xr XParseGeometry 3
|
||||
.Sh AUTHORS
|
||||
|
@ -70,3 +114,5 @@ One row of keys takes up 1/heighfactor of the screen's total height.
|
|||
.An Enno Boland Aq Mt gottox@s01.de
|
||||
.An Miles Alan Aq Mt m@milesalan.com
|
||||
.An Maarten van Gompel Aq Mt proycon@anaproy.nl
|
||||
.An Tetrakist Aq Mt tetrakist@mutandum.com
|
||||
.An Stacy Aq Mt stacy@stacyharper.net
|
||||
|
|
556
svkbd.c
556
svkbd.c
|
@ -2,12 +2,13 @@
|
|||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
@ -20,6 +21,7 @@
|
|||
#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
|
||||
|
@ -29,21 +31,28 @@
|
|||
|
||||
/* macros */
|
||||
#define LENGTH(x) (sizeof x / sizeof x[0])
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)))
|
||||
#define STRINGTOKEYSYM(X) (XStringToKeySym(X))
|
||||
#define TEXTW(X) (drw_fontset_getwidth(drw, (X)))
|
||||
|
||||
/* enums */
|
||||
enum { SchemeNorm, SchemePress, SchemeHighlight, SchemeLast };
|
||||
enum {
|
||||
SchemeNorm, SchemeNormABC, SchemeNormABCShift, SchemeNormShift, SchemePress,
|
||||
SchemePressShift, SchemeHighlight, SchemeHighlightShift, SchemeOverlay,
|
||||
SchemeOverlayShift, SchemeWindow, SchemeLast
|
||||
};
|
||||
enum { NetWMWindowType, NetLast };
|
||||
|
||||
/* typedefs */
|
||||
typedef struct {
|
||||
char *label;
|
||||
char *label2;
|
||||
KeySym keysym;
|
||||
unsigned int width;
|
||||
double width;
|
||||
KeySym modifier;
|
||||
int x, y, w, h;
|
||||
Bool pressed;
|
||||
Bool highlighted;
|
||||
Bool isoverlay;
|
||||
} Key;
|
||||
|
||||
typedef struct {
|
||||
|
@ -61,11 +70,11 @@ static void configurenotify(XEvent *e);
|
|||
static void countrows();
|
||||
static int countkeys(Key *layer);
|
||||
static void drawkeyboard(void);
|
||||
static void drawkey(Key *k);
|
||||
static void drawkey(Key *k, Bool map);
|
||||
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, KeySym buttonmod);
|
||||
static double get_press_duration();
|
||||
static void run(void);
|
||||
static void setup(void);
|
||||
|
@ -76,8 +85,9 @@ static void hideoverlay();
|
|||
static void cyclelayer();
|
||||
static void setlayer();
|
||||
static void togglelayer();
|
||||
static void unpress(Key *k, KeySym mod);
|
||||
static void unpress(Key *k, KeySym buttonmod);
|
||||
static void updatekeys();
|
||||
static void printkey(Key *k, KeySym mod);
|
||||
|
||||
/* variables */
|
||||
static int screen;
|
||||
|
@ -95,20 +105,25 @@ static Drw *drw;
|
|||
static Window root, win;
|
||||
static Clr* scheme[SchemeLast];
|
||||
static Bool running = True, isdock = False;
|
||||
static KeySym pressedmod = 0;
|
||||
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 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;
|
||||
static int simulateoutput = 1; /* simulate key presses for X */
|
||||
static int printoutput = 0; /* print key pressed to stdout */
|
||||
static char *name = "svkbd";
|
||||
static int debug = 0;
|
||||
static int numlayers = 0;
|
||||
static int numkeys = 0;
|
||||
|
||||
static char *colors[11][2]; /* 11 schemes, 2 colors each */
|
||||
static char *fonts[] = { 0 };
|
||||
|
||||
static KeySym ispressingkeysym;
|
||||
|
||||
Bool ispressing = False;
|
||||
|
@ -121,14 +136,16 @@ Bool sigtermd = False;
|
|||
#endif
|
||||
#include LAYOUT
|
||||
|
||||
static Key keys[KEYS] = { NULL };
|
||||
static Key* layers[LAYERS];
|
||||
static Key keys[KEYS];
|
||||
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
|
||||
|
@ -137,25 +154,36 @@ motionnotify(XEvent *e)
|
|||
&& ev->y < keys[i].y + keys[i].h) {
|
||||
if (keys[i].highlighted != True) {
|
||||
if (ispressing) {
|
||||
keys[i].pressed = True;
|
||||
gainedfocus = i;
|
||||
} else {
|
||||
keys[i].highlighted = True;
|
||||
}
|
||||
drawkey(&keys[i]);
|
||||
drawkey(&keys[i], True);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!IsModifierKey(keys[i].keysym) && keys[i].pressed == True) {
|
||||
unpress(&keys[i], 0);
|
||||
|
||||
drawkey(&keys[i]);
|
||||
}
|
||||
if (keys[i].highlighted == True) {
|
||||
} else if (keys[i].highlighted == True) {
|
||||
keys[i].highlighted = False;
|
||||
drawkey(&keys[i]);
|
||||
drawkey(&keys[i], True);
|
||||
}
|
||||
}
|
||||
|
||||
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], True);
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -168,14 +196,23 @@ buttonpress(XEvent *e)
|
|||
|
||||
ispressing = True;
|
||||
|
||||
if (!(k = findkey(ev->x, ev->y)))
|
||||
return;
|
||||
|
||||
for (i = 0; i < LENGTH(buttonmods); i++) {
|
||||
if (ev->button == buttonmods[i].button) {
|
||||
mod = buttonmods[i].mod;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((k = findkey(ev->x, ev->y)))
|
||||
press(k, mod);
|
||||
|
||||
if (k->modifier) {
|
||||
if (mod == k->modifier)
|
||||
mod = 0;
|
||||
else
|
||||
mod = k->modifier;
|
||||
}
|
||||
press(k, mod);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -197,8 +234,12 @@ buttonrelease(XEvent *e)
|
|||
|
||||
if (ev->x < 0 || ev->y < 0) {
|
||||
unpress(NULL, mod);
|
||||
} else {
|
||||
if ((k = findkey(ev->x, ev->y)))
|
||||
} else if ((k = findkey(ev->x, ev->y))) {
|
||||
if (k->modifier == mod)
|
||||
unpress(k, 0);
|
||||
else if (k->modifier)
|
||||
unpress(k, k->modifier);
|
||||
else
|
||||
unpress(k, mod);
|
||||
}
|
||||
}
|
||||
|
@ -213,7 +254,6 @@ cleanup(void)
|
|||
drw_sync(drw);
|
||||
drw_free(drw);
|
||||
XSync(dpy, False);
|
||||
drw_free(drw);
|
||||
XDestroyWindow(dpy, win);
|
||||
XSync(dpy, False);
|
||||
XSetInputFocus(dpy, PointerRoot, RevertToPointerRoot, CurrentTime);
|
||||
|
@ -238,8 +278,13 @@ countrows(void)
|
|||
int i;
|
||||
|
||||
for (i = 0, rows = 1; i < numkeys; i++) {
|
||||
if (keys[i].keysym == 0)
|
||||
if (keys[i].keysym == 0) {
|
||||
rows++;
|
||||
if ((i > 0) && (keys[i-1].keysym == 0)) {
|
||||
rows--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -264,26 +309,38 @@ drawkeyboard(void)
|
|||
{
|
||||
int i;
|
||||
|
||||
drw_setscheme(drw, scheme[SchemeWindow]);
|
||||
drw_rect(drw, 0, 0, ww, wh, 1, 1);
|
||||
for (i = 0; i < numkeys; i++) {
|
||||
if (keys[i].keysym != 0)
|
||||
drawkey(&keys[i]);
|
||||
drawkey(&keys[i], False);
|
||||
}
|
||||
drw_map(drw, win, 0, 0, ww, wh);
|
||||
}
|
||||
|
||||
void
|
||||
drawkey(Key *k)
|
||||
drawkey(Key *k, Bool map)
|
||||
{
|
||||
int x, y, w, h;
|
||||
const char *l;
|
||||
|
||||
int use_scheme = SchemeNorm;
|
||||
|
||||
if (k->pressed)
|
||||
drw_setscheme(drw, scheme[SchemePress]);
|
||||
use_scheme = SchemePress;
|
||||
else if (k->highlighted)
|
||||
drw_setscheme(drw, scheme[SchemeHighlight]);
|
||||
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)))
|
||||
use_scheme = SchemeNormABC;
|
||||
else
|
||||
drw_setscheme(drw, scheme[SchemeNorm]);
|
||||
use_scheme = SchemeNorm;
|
||||
|
||||
drw_setscheme(drw, scheme[use_scheme]);
|
||||
drw_rect(drw, k->x, k->y, k->w, k->h, 1, 1);
|
||||
drw_rect(drw, k->x, k->y, k->w, k->h, 0, 0);
|
||||
|
||||
if (k->keysym == XK_KP_Insert) {
|
||||
if (enableoverlays) {
|
||||
|
@ -301,7 +358,26 @@ drawkey(Key *k)
|
|||
w = TEXTW(l);
|
||||
x = k->x + (k->w / 2) - (w / 2);
|
||||
drw_text(drw, x, y, w, h, 0, l, 0);
|
||||
drw_map(drw, win, k->x, k->y, k->w, k->h);
|
||||
if (k->label2) {
|
||||
if (use_scheme == SchemeNorm)
|
||||
use_scheme = SchemeNormShift;
|
||||
else if (use_scheme == SchemeNormABC)
|
||||
use_scheme = SchemeNormABCShift;
|
||||
else if (use_scheme == SchemePress)
|
||||
use_scheme = SchemePressShift;
|
||||
else if (use_scheme == SchemeHighlight)
|
||||
use_scheme = SchemeHighlightShift;
|
||||
else if (use_scheme == SchemeOverlay)
|
||||
use_scheme = SchemeOverlayShift;
|
||||
drw_setscheme(drw, scheme[use_scheme]);
|
||||
x += w;
|
||||
y -= 15;
|
||||
l = k->label2;
|
||||
w = TEXTW(l);
|
||||
drw_text(drw, x, y, w, h, 0, l, 0);
|
||||
}
|
||||
if (map)
|
||||
drw_map(drw, win, k->x, k->y, k->w, k->h);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -335,9 +411,9 @@ hasoverlay(KeySym keysym)
|
|||
begin = 0;
|
||||
for (i = 0; i < OVERLAYS; i++) {
|
||||
if (overlay[i].keysym == XK_Cancel) {
|
||||
begin = i+1;
|
||||
begin = i + 1;
|
||||
} else if (overlay[i].keysym == keysym) {
|
||||
return begin+1;
|
||||
return begin + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
@ -348,6 +424,7 @@ leavenotify(XEvent *e)
|
|||
{
|
||||
if (currentoverlay != -1)
|
||||
hideoverlay();
|
||||
ispressingkeysym = 0;
|
||||
unpress(NULL, 0);
|
||||
}
|
||||
|
||||
|
@ -360,14 +437,14 @@ record_press_begin(KeySym ks)
|
|||
}
|
||||
|
||||
void
|
||||
press(Key *k, KeySym mod)
|
||||
press(Key *k, KeySym buttonmod)
|
||||
{
|
||||
int i;
|
||||
int overlayidx = -1;
|
||||
|
||||
k->pressed = !k->pressed;
|
||||
|
||||
if (debug) printdbg("Begin press: %ld\n", k->keysym);
|
||||
printdbg("Begin click: %ld\n", k->keysym);
|
||||
pressbegin.tv_sec = 0;
|
||||
pressbegin.tv_usec = 0;
|
||||
ispressingkeysym = 0;
|
||||
|
@ -375,23 +452,21 @@ press(Key *k, KeySym mod)
|
|||
if (!IsModifierKey(k->keysym)) {
|
||||
if (enableoverlays && currentoverlay == -1)
|
||||
overlayidx = hasoverlay(k->keysym);
|
||||
if (enableoverlays && overlayidx != -1) {
|
||||
if (!pressbegin.tv_sec && !pressbegin.tv_usec) {
|
||||
/*record the begin of the press, don't simulate the actual keypress yet */
|
||||
record_press_begin(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 {
|
||||
if (debug) printdbg("Simulating press: %ld\n", k->keysym);
|
||||
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);
|
||||
}
|
||||
}
|
||||
pressedmod = mod;
|
||||
if (pressedmod) {
|
||||
simulate_keypress(mod);
|
||||
}
|
||||
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)) {
|
||||
|
@ -400,22 +475,79 @@ press(Key *k, KeySym mod)
|
|||
}
|
||||
}
|
||||
}
|
||||
drawkey(k);
|
||||
drawkey(k, True);
|
||||
}
|
||||
|
||||
int
|
||||
tmp_remap(KeySym keysym)
|
||||
{
|
||||
XChangeKeyboardMapping(dpy, tmp_keycode, 1, &keysym, 1);
|
||||
/* map lower and upper case of keysym to the temporary keycode */
|
||||
KeySym syms[2];
|
||||
XConvertCase(keysym, &syms[0], &syms[1]);
|
||||
|
||||
/* if keysym is capital letter then swap upper and lower case */
|
||||
if (keysym == syms[1])
|
||||
syms[1] = syms[0], syms[0] = keysym;
|
||||
|
||||
XChangeKeyboardMapping(dpy, tmp_keycode, syms[0] == syms[1] ? 1 : 2, syms, 1);
|
||||
XSync(dpy, False);
|
||||
|
||||
printdbg("Temporary map keysym %ld (%ld, %ld) to keycode %d\n", keysym, syms[0], syms[1], tmp_keycode);
|
||||
return tmp_keycode;
|
||||
}
|
||||
|
||||
void
|
||||
printkey(Key *k, KeySym mod)
|
||||
{
|
||||
int i, shift;
|
||||
|
||||
shift = (mod == XK_Shift_L) || (mod == XK_Shift_R) || (mod == XK_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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
printdbg("Printing key %ld (shift=%d)\n", k->keysym, shift);
|
||||
if (k->keysym == XK_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);
|
||||
|
||||
char buffer[32];
|
||||
KeySym ignore;
|
||||
Status return_status;
|
||||
int l = Xutf8LookupString(xic, &event, buffer, sizeof(buffer), &ignore, &return_status);
|
||||
buffer[l] = '\0';
|
||||
printdbg("Print buffer: [%s] (length=%d)\n", &buffer, l);
|
||||
printf("%s", buffer);
|
||||
|
||||
XDestroyIC(xic);
|
||||
XCloseIM(xim);
|
||||
}
|
||||
|
||||
void
|
||||
simulate_keypress(KeySym keysym)
|
||||
{
|
||||
KeyCode code = XKeysymToKeycode(dpy, keysym);
|
||||
KeyCode code;
|
||||
|
||||
if (!simulateoutput)
|
||||
return;
|
||||
|
||||
code = XKeysymToKeycode(dpy, keysym);
|
||||
if (code == 0)
|
||||
code = tmp_remap(keysym);
|
||||
XTestFakeKeyEvent(dpy, code, True, 0);
|
||||
|
@ -424,7 +556,12 @@ simulate_keypress(KeySym keysym)
|
|||
void
|
||||
simulate_keyrelease(KeySym keysym)
|
||||
{
|
||||
KeyCode code = XKeysymToKeycode(dpy, keysym);
|
||||
KeyCode code;
|
||||
|
||||
if (!simulateoutput)
|
||||
return;
|
||||
|
||||
code = XKeysymToKeycode(dpy, keysym);
|
||||
if (code == 0)
|
||||
code = tmp_remap(keysym);
|
||||
XTestFakeKeyEvent(dpy, code, False, 0);
|
||||
|
@ -438,16 +575,17 @@ get_press_duration(void)
|
|||
gettimeofday(&now, NULL);
|
||||
|
||||
return (double) ((now.tv_sec * 1000000L + now.tv_usec) -
|
||||
(pressbegin.tv_sec * 1000000L + pressbegin.tv_usec)) /
|
||||
(double) 1000000L;
|
||||
(pressbegin.tv_sec * 1000000L + pressbegin.tv_usec)) /
|
||||
(double) 1000000L;
|
||||
}
|
||||
|
||||
void
|
||||
unpress(Key *k, KeySym mod)
|
||||
unpress(Key *k, KeySym buttonmod)
|
||||
{
|
||||
int i;
|
||||
Bool neutralizebuttonmod = False;
|
||||
|
||||
if (k != NULL) {
|
||||
if (k) {
|
||||
switch(k->keysym) {
|
||||
case XK_Cancel:
|
||||
cyclelayer();
|
||||
|
@ -466,62 +604,57 @@ unpress(Key *k, KeySym mod)
|
|||
}
|
||||
}
|
||||
|
||||
if ((pressbegin.tv_sec || pressbegin.tv_usec) && enableoverlays && k && k->keysym == ispressingkeysym) {
|
||||
if (currentoverlay == -1) {
|
||||
if (get_press_duration() < overlay_delay) {
|
||||
if (debug) 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);
|
||||
}
|
||||
}
|
||||
pressedmod = mod;
|
||||
if (pressedmod) {
|
||||
simulate_keypress(mod);
|
||||
}
|
||||
simulate_keypress(k->keysym);
|
||||
pressbegin.tv_sec = 0;
|
||||
pressbegin.tv_usec = 0;
|
||||
} else {
|
||||
return;
|
||||
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)) {
|
||||
if (keys[i].keysym == buttonmod)
|
||||
neutralizebuttonmod = True;
|
||||
else
|
||||
simulate_keypress(keys[i].keysym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
if (k) {
|
||||
printdbg("Simulation of release: %ld\n", k->keysym);
|
||||
} else {
|
||||
printdbg("Simulation of release (all keys)\n");
|
||||
if (buttonmod && !neutralizebuttonmod) {
|
||||
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]);
|
||||
break;
|
||||
drawkey(&keys[i], True);
|
||||
}
|
||||
}
|
||||
if (i != numkeys) {
|
||||
if (pressedmod) {
|
||||
simulate_keyrelease(mod);
|
||||
}
|
||||
pressedmod = 0;
|
||||
|
||||
if (buttonmod && !neutralizebuttonmod) {
|
||||
simulate_keyrelease(buttonmod);
|
||||
}
|
||||
|
||||
if (k == NULL || !IsModifierKey(k->keysym)) {
|
||||
for (i = 0; i < numkeys; i++) {
|
||||
if (keys[i].pressed) {
|
||||
simulate_keyrelease(keys[i].keysym);
|
||||
if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
|
||||
if (!(keys[i].keysym == buttonmod && neutralizebuttonmod))
|
||||
simulate_keyrelease(keys[i].keysym);
|
||||
keys[i].pressed = 0;
|
||||
drawkey(&keys[i]);
|
||||
drawkey(&keys[i], True);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (enableoverlays && currentoverlay != -1) {
|
||||
if (enableoverlays && currentoverlay != -1 &&
|
||||
(k == NULL || !IsModifierKey(k->keysym))) {
|
||||
if (releaseprotect) {
|
||||
releaseprotect = 0;
|
||||
} else {
|
||||
|
@ -537,12 +670,13 @@ run(void)
|
|||
int xfd;
|
||||
fd_set fds;
|
||||
struct timeval tv;
|
||||
double duration = 0.0;
|
||||
double duration;
|
||||
int overlayidx;
|
||||
int i, r;
|
||||
|
||||
xfd = ConnectionNumber(dpy);
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = scan_rate;
|
||||
|
||||
XFlush(dpy);
|
||||
|
||||
|
@ -562,25 +696,33 @@ run(void)
|
|||
/* time-out expired without anything interesting happening, check for long-presses */
|
||||
if (ispressing && ispressingkeysym) {
|
||||
duration = get_press_duration();
|
||||
if (debug == 2) printdbg("%f\n", duration);
|
||||
if (get_press_duration() >= overlay_delay) {
|
||||
if (debug) printdbg("press duration %f\n", duration);
|
||||
showoverlay(hasoverlay(ispressingkeysym));
|
||||
if (debug >= 2)
|
||||
printdbg("%f\n", duration);
|
||||
overlayidx = hasoverlay(ispressingkeysym);
|
||||
duration = get_press_duration();
|
||||
if (overlayidx != -1 && duration >= overlay_delay) {
|
||||
printdbg("press duration %f, activating overlay\n", duration);
|
||||
showoverlay(overlayidx);
|
||||
pressbegin.tv_sec = 0;
|
||||
pressbegin.tv_usec = 0;
|
||||
ispressingkeysym = 0;
|
||||
} else if ((overlayidx == -1) && (duration >= repeat_delay)) {
|
||||
printdbg("press duration %f, activating repeat\n", duration);
|
||||
simulate_keyrelease(ispressingkeysym);
|
||||
simulate_keypress(ispressingkeysym);
|
||||
XSync(dpy, False);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (r == -1 || sigtermd) {
|
||||
/* an error occurred or we received a signal */
|
||||
/* E.g. Generally in scripts we want to call SIGTERM on svkbd in which case
|
||||
if the user is holding for example the enter key (to execute
|
||||
the kill or script that does the kill), that causes an issue
|
||||
since then X doesn't know the keyup is never coming.. (since
|
||||
process will be dead before finger lifts - in that case we
|
||||
just trigger out fake up presses for all keys */
|
||||
if (debug) printdbg("signal received, releasing all keys");
|
||||
if the user is holding for example the enter key (to execute
|
||||
the kill or script that does the kill), that causes an issue
|
||||
since then X doesn't know the keyup is never coming.. (since
|
||||
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);
|
||||
}
|
||||
|
@ -589,6 +731,80 @@ run(void)
|
|||
}
|
||||
}
|
||||
|
||||
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[SchemeNormABCShift][ColFg])
|
||||
colors[SchemeNormABCShift][ColFg] = estrdup(xval.addr);
|
||||
if (XrmGetResource(xdb, "svkbd.ABCshiftbackground", "*", &type, &xval) && !colors[SchemeNormABCShift][ColBg])
|
||||
colors[SchemeNormABCShift][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);
|
||||
|
||||
if (XrmGetResource(xdb, "svkbd.windowbackground", "*", &type, &xval) && !colors[SchemeWindow][ColBg])
|
||||
colors[SchemeWindow][ColBg] = estrdup(xval.addr);
|
||||
if (XrmGetResource(xdb, "svkbd.windowforeground", "*", &type, &xval) && !colors[SchemeWindow][ColFg])
|
||||
colors[SchemeWindow][ColFg] = estrdup(xval.addr);
|
||||
|
||||
XrmDestroyDatabase(xdb);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
setup(void)
|
||||
{
|
||||
|
@ -620,8 +836,23 @@ setup(void)
|
|||
sh = DisplayHeight(dpy, screen);
|
||||
}
|
||||
drw = drw_create(dpy, screen, root, sw, sh);
|
||||
if (!drw_fontset_create(drw, fonts, LENGTH(fonts)))
|
||||
|
||||
readxresources();
|
||||
|
||||
/* Apply defaults to font and colors*/
|
||||
if (!fonts[0])
|
||||
fonts[0] = estrdup(defaultfonts[0]);
|
||||
for (i = 0; i < SchemeLast; ++i) {
|
||||
for (j = 0; j < 2; ++j) {
|
||||
if (!colors[i][j])
|
||||
colors[i][j] = estrdup(defaultcolors[i][j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!drw_fontset_create(drw, (const char **) fonts, LENGTH(fonts)))
|
||||
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:
|
||||
|
@ -652,7 +883,12 @@ setup(void)
|
|||
|
||||
/* init appearance */
|
||||
for (j = 0; j < SchemeLast; j++)
|
||||
scheme[j] = drw_scm_create(drw, colors[j], 2);
|
||||
scheme[j] = drw_scm_create(drw, (const char **) colors[j], 2);
|
||||
|
||||
for (j = 0; j < SchemeLast; ++j) {
|
||||
free(colors[j][ColFg]);
|
||||
free(colors[j][ColBg]);
|
||||
}
|
||||
|
||||
/* init atoms */
|
||||
if (isdock) {
|
||||
|
@ -705,8 +941,7 @@ setup(void)
|
|||
ch->res_class = name;
|
||||
ch->res_name = name;
|
||||
|
||||
XSetWMProperties(dpy, win, &str, &str, NULL, 0, sizeh, wmh,
|
||||
ch);
|
||||
XSetWMProperties(dpy, win, &str, &str, NULL, 0, sizeh, wmh, ch);
|
||||
|
||||
XFree(keysyms);
|
||||
XFree(ch);
|
||||
|
@ -731,18 +966,21 @@ void
|
|||
updatekeys(void)
|
||||
{
|
||||
int i, j;
|
||||
int x = 0, y = 0, h, base, r = rows;
|
||||
double base;
|
||||
int x, y = 0, h, r = rows;
|
||||
|
||||
h = (wh - 1) / rows;
|
||||
for (i = 0; i < numkeys; i++, r--) {
|
||||
for (j = i, base = 0; j < numkeys && keys[j].keysym != 0; j++)
|
||||
base += keys[j].width;
|
||||
for (x = 0; i < numkeys && keys[i].keysym != 0; i++) {
|
||||
keys[i].x = x;
|
||||
keys[i].y = y;
|
||||
keys[i].w = keys[i].width * (ww - 1) / base;
|
||||
keys[i].x = x + xspacing;
|
||||
keys[i].y = y + yspacing;
|
||||
keys[i].w = keys[i].width * ww / base;
|
||||
keys[i].h = r == 1 ? wh - y - 1 : h;
|
||||
x += keys[i].w;
|
||||
keys[i].w = keys[i].w - (xspacing * 2);
|
||||
keys[i].h = keys[i].h - (yspacing * 2);
|
||||
}
|
||||
if (base != 0)
|
||||
keys[i - 1].w = ww - 1 - keys[i - 1].x;
|
||||
|
@ -753,15 +991,19 @@ updatekeys(void)
|
|||
void
|
||||
usage(char *argv0)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-hdvDO] [-g geometry] [-fn font] [-l layers] [-s initial_layer]\n", 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, " -H [int] - Height fraction, one key row takes 1/x of the screen height");
|
||||
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");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -770,6 +1012,7 @@ setlayer(void)
|
|||
{
|
||||
numkeys = countkeys(layers[currentlayer]);
|
||||
memcpy(&keys, layers[currentlayer], sizeof(Key) * numkeys);
|
||||
countrows();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -778,7 +1021,7 @@ cyclelayer(void)
|
|||
currentlayer++;
|
||||
if (currentlayer >= numlayers)
|
||||
currentlayer = 0;
|
||||
if (debug) printdbg("Cycling to layer %d\n", currentlayer);
|
||||
printdbg("Cycling to layer %d\n", currentlayer);
|
||||
setlayer();
|
||||
updatekeys();
|
||||
drawkeyboard();
|
||||
|
@ -792,7 +1035,7 @@ togglelayer(void)
|
|||
} else if (numlayers > 1) {
|
||||
currentlayer = 1;
|
||||
}
|
||||
if (debug) printdbg("Toggling layer %d\n", currentlayer);
|
||||
printdbg("Toggling layer %d\n", currentlayer);
|
||||
setlayer();
|
||||
updatekeys();
|
||||
drawkeyboard();
|
||||
|
@ -801,25 +1044,40 @@ togglelayer(void)
|
|||
void
|
||||
showoverlay(int idx)
|
||||
{
|
||||
if (debug) printdbg("Showing overlay %d\n", idx);
|
||||
int i,j;
|
||||
int i, j;
|
||||
|
||||
printdbg("Showing overlay %d\n", idx);
|
||||
|
||||
/* unpress existing key (visually only) */
|
||||
for (i = 0; i < numkeys; i++) {
|
||||
if (keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
|
||||
keys[i].pressed = 0;
|
||||
drawkey(&keys[i]);
|
||||
drawkey(&keys[i], True);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = idx, j=0; i < OVERLAYS; i++, j++) {
|
||||
if (overlay[i].keysym == XK_Cancel)
|
||||
for (i = idx, j = 0; i < OVERLAYS; i++, j++) {
|
||||
if (overlay[i].keysym == XK_Cancel) {
|
||||
break;
|
||||
while (keys[j].keysym == 0)
|
||||
}
|
||||
/* certain modifier keys and basic keys are excluded from being overlayed: */
|
||||
while (keys[j].keysym == 0 || keys[j].keysym == XK_Shift_L ||
|
||||
keys[j].keysym == XK_Shift_R || keys[j].keysym == XK_Control_L ||
|
||||
keys[j].keysym == XK_Control_R || keys[j].keysym == XK_Alt_L ||
|
||||
keys[j].keysym == XK_Alt_R || keys[j].keysym == XK_BackSpace ||
|
||||
keys[j].keysym == XK_Return || keys[j].keysym == XK_space ||
|
||||
keys[j].keysym == XK_Cancel)
|
||||
j++;
|
||||
if (overlay[i].width > 1)
|
||||
j += overlay[i].width - 1;
|
||||
if (j >= numkeys)
|
||||
break;
|
||||
keys[j].label = overlay[i].label;
|
||||
keys[j].label2 = overlay[i].label2;
|
||||
keys[j].keysym = overlay[i].keysym;
|
||||
keys[j].modifier = overlay[i].modifier;
|
||||
keys[j].isoverlay = True;
|
||||
}
|
||||
currentoverlay = idx;
|
||||
overlaykeysym = ispressingkeysym;
|
||||
|
@ -832,10 +1090,10 @@ showoverlay(int idx)
|
|||
void
|
||||
hideoverlay(void)
|
||||
{
|
||||
if (debug) printdbg("Hiding overlay, overlay was #%d\n", currentoverlay);
|
||||
printdbg("Hiding overlay, overlay was #%d\n", currentoverlay);
|
||||
currentoverlay = -1;
|
||||
overlaykeysym = 0;
|
||||
currentlayer = -1;
|
||||
currentlayer--;
|
||||
cyclelayer();
|
||||
}
|
||||
|
||||
|
@ -844,7 +1102,7 @@ sigterm(int signo)
|
|||
{
|
||||
running = False;
|
||||
sigtermd = True;
|
||||
if (debug) printdbg("SIGTERM received\n");
|
||||
printdbg("SIGTERM received\n");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -867,7 +1125,7 @@ init_layers(char *layer_names_list, const char *initial_layer_name)
|
|||
} else {
|
||||
s = strtok(layer_names_list, ",");
|
||||
while (s != NULL) {
|
||||
if (numlayers+1 > LAYERS)
|
||||
if (numlayers + 1 > LAYERS)
|
||||
die("too many layers specified");
|
||||
found = 0;
|
||||
for (j = 0; j < LAYERS; j++) {
|
||||
|
@ -895,6 +1153,9 @@ init_layers(char *layer_names_list, const char *initial_layer_name)
|
|||
void
|
||||
printdbg(const char *fmt, ...)
|
||||
{
|
||||
if (!debug)
|
||||
return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(stderr, fmt, ap);
|
||||
|
@ -919,26 +1180,26 @@ main(int argc, char *argv[])
|
|||
if ((tmp = getenv("SVKBD_ENABLEOVERLAYS")))
|
||||
enableoverlays = atoi(tmp);
|
||||
}
|
||||
if ((tmp = getenv("SVKBD_LAYERS"))) {
|
||||
if (!(layer_names_list = strdup(tmp)))
|
||||
die("memory allocation error");
|
||||
}
|
||||
if ((tmp = getenv("SVKBD_LAYERS")))
|
||||
layer_names_list = estrdup(tmp);
|
||||
|
||||
if ((tmp = getenv("SVKBD_HEIGHTFACTOR")))
|
||||
heightfactor = atoi(tmp);
|
||||
|
||||
if ((tmp = getenv("SVKBD_PRESSONRELEASE"))) /* defaults to 1 */
|
||||
pressonrelease = atoi(tmp);
|
||||
|
||||
/* parse command line arguments */
|
||||
for (i = 1; argv[i]; i++) {
|
||||
if (!strcmp(argv[i], "-v")) {
|
||||
die("svkbd-"VERSION);
|
||||
} else if (!strcmp(argv[i], "-d")) {
|
||||
isdock = True;
|
||||
continue;
|
||||
} else if (!strncmp(argv[i], "-g", 2)) {
|
||||
if (i >= argc - 1)
|
||||
continue;
|
||||
usage(argv[0]);
|
||||
|
||||
bitm = XParseGeometry(argv[i + 1], &xr, &yr, &wr, &hr);
|
||||
bitm = XParseGeometry(argv[++i], &xr, &yr, &wr, &hr);
|
||||
if (bitm & XValue)
|
||||
wx = xr;
|
||||
if (bitm & YValue)
|
||||
|
@ -951,35 +1212,44 @@ main(int argc, char *argv[])
|
|||
wx = -1;
|
||||
if (bitm & YNegative && wy == 0)
|
||||
wy = -1;
|
||||
i++;
|
||||
} else if (!strcmp(argv[i], "-fn")) { /* font or font set */
|
||||
fonts[0] = argv[++i];
|
||||
if (i >= argc - 1)
|
||||
usage(argv[0]);
|
||||
fonts[0] = estrdup(argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-D")) {
|
||||
debug = 1;
|
||||
} else if (!strcmp(argv[i], "-h")) {
|
||||
usage(argv[0]);
|
||||
} else if (!strcmp(argv[i], "-O")) {
|
||||
enableoverlays = 0;
|
||||
} else if (!strcmp(argv[i], "-o")) {
|
||||
printoutput = 1;
|
||||
} else if (!strcmp(argv[i], "-n")) {
|
||||
simulateoutput = 0;
|
||||
} else if (!strcmp(argv[i], "-R")) {
|
||||
pressonrelease = 0;
|
||||
} else if (!strcmp(argv[i], "-l")) {
|
||||
if (i >= argc - 1)
|
||||
continue;
|
||||
usage(argv[0]);
|
||||
free(layer_names_list);
|
||||
if (!(layer_names_list = strdup(argv[++i])))
|
||||
die("memory allocation error");
|
||||
layer_names_list = estrdup(argv[++i]);
|
||||
} else if (!strcmp(argv[i], "-s")) {
|
||||
if (i >= argc - 1)
|
||||
continue;
|
||||
usage(argv[0]);
|
||||
initial_layer_name = argv[++i];
|
||||
} else if (!strcmp(argv[i], "-H")) {
|
||||
if (i >= argc - 1)
|
||||
continue;
|
||||
usage(argv[0]);
|
||||
heightfactor = atoi(argv[++i]);
|
||||
} else {
|
||||
fprintf(stderr, "Invalid argument: %s\n", argv[i]);
|
||||
exit(2);
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (printoutput)
|
||||
setbuf(stdout, NULL); /* unbuffered output */
|
||||
|
||||
if (heightfactor <= 0)
|
||||
die("height factor must be a positive integer");
|
||||
|
||||
|
|
10
util.c
10
util.c
|
@ -16,6 +16,16 @@ ecalloc(size_t nmemb, size_t size)
|
|||
return p;
|
||||
}
|
||||
|
||||
char *
|
||||
estrdup(const char *s)
|
||||
{
|
||||
char *p;
|
||||
|
||||
if (!(p = strdup(s)))
|
||||
die("strdup:");
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
die(const char *fmt, ...)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue