Compare commits

...

32 Commits
0.3 ... master

Author SHA1 Message Date
norayr chilingarian 92795b2a0a fix uppercase in armenian (and perhaps some other) layouts
"This patch fixes uppercase in armenian (and perhaps some other) layouts. svkbd
was previously registering a key in one modification (xorg accepts up to 4
modifications). with this patch svkbd registers 2 modifications - upper and
lower case. function tmp_remap changed in a way that if the key is not found in
a current layout, it is temporary added to it. for cyrillic layout uppercase
(when shift is pressed) letters were showing anyway, because those are somehow
found (modified) by xorg. but for armenian layout that did not work. now works."

Patch by նորայր <norayr@arnet.am>
2023-12-13 19:10:08 +01:00
Hiltjo Posthuma ff704d5d1e update LICENSE 2023-02-05 11:26:58 +01:00
Norayr Chilingarian 7fc78a0b44 dvorak layout 2023-02-05 11:25:58 +01:00
Hiltjo Posthuma 3dfb00ccf8 fix comment style 2023-02-05 11:25:46 +01:00
Norayr Chilingarian c247720ae4 armenian layout 2023-01-29 17:33:13 +01:00
Hiltjo Posthuma 38faf1cc8a bump version to 0.4.1 2022-01-07 12:38:18 +01:00
Justin Torres 5dd14703ed Fix color scheme editing on smiley with Xresources
Fixes a small oversight that was preventing the colors of the smiley on q from changing with Xresources.

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2021-10-09 10:29:10 +02:00
Max Schillinger 4061bacc1d create layout-dependent object files
When you build svkbd with different layouts, you get one binary per
layout but all binaries are identical:

    $ make LAYOUT=mobile-plain
    $ make LAYOUT=mobile-simple
    $ diff -s svkbd-mobile-plain svkbd-mobile-simple
    Files svkbd-mobile-plain and svkbd-mobile-simple are identical

The problem is that svkbd.o from the first build is being reused in the
second build.

This commit changes the Makefile to create layout-dependent object files
like svkbd-mobile-plain.o and svkbd-mobile-simple.o (instead of a shared
svkbd.o).
2021-10-01 12:32:38 +02:00
Страхиња Радић 0f07238b53 Add a Serbian layout: layout.sr.h 2021-08-02 18:20:38 +02:00
Hiltjo Posthuma 6ffe71a5f6 bump version to 0.4 2021-07-30 16:50:14 +02:00
Hiltjo Posthuma d9dcf0d113 config.mk: fix version printing for -v 2021-07-30 16:49:57 +02:00
Maarten van Gompel 4a511a6cfb minor update for emoji overlay on Q: simpler glyph
I picked a simpler glyph because the other might be more likely to not be
present in a font.
2021-07-20 11:01:01 +02:00
Hiltjo Posthuma 6a14319331 change comment-style in .c file 2021-07-12 12:51:52 +02:00
Maarten van Gompel 378a1c8b30 made the Q key double as a trigger for the emoji overlay in the default mobile-intl layout
This makes the emoji overlay accessible without sacrificing an extra key.
There are (afaik) no languages with diacritics on the Q anyway and it's
the first letter key.

A small emoji will show as 2nd label on the keycap as a hint, the caveat
being that the hint applies to a long press rather than a shift-press as
with most 2nd labels, but better than no hint at all.
2021-07-12 12:34:10 +02:00
Maarten van Gompel 3cff4547c5 code cleanup in overlay definitions (removed empty lines comments) 2021-07-12 12:34:03 +02:00
Maarten van Gompel b053404199 moved backspace key down in dialer layer (mobile-intl and simple layout), for more consistency with other layers 2021-07-12 12:33:55 +02:00
Maarten van Gompel b5775349f6 minor documentation update 2021-07-12 12:33:50 +02:00
Maarten van Gompel 2164466746 protection against segfault if overlay has more keys than the keyboard itself 2021-07-12 12:33:44 +02:00
Maarten van Gompel b70948b74c exclude certain modifier keys and basic keys from being overlayed
This ensures that modifiers like shift/ctrl can be correctly used with the overlay.
2021-07-12 12:33:39 +02:00
Maarten van Gompel e2828d4f7a added missing e caron to overlay in international and simple layouts (e.g. for czech) 2021-07-12 12:33:32 +02:00
Hiltjo Posthuma 4c9182636c no need to initialize these variables here 2021-07-03 11:45:15 +02:00
Hiltjo Posthuma 2a2acdacaa small code-style changes 2021-07-03 11:45:05 +02:00
Hiltjo Posthuma 81c96cec89 check key for NULL dereference, just in case
This matches the check pattern in other parts of the code.
2021-07-03 11:44:18 +02:00
Hiltjo Posthuma fd01322564 adjust other layouts for the second label change
From the commit:

	commit d06db9eb4f
	Author: Maarten van Gompel <proycon@anaproy.nl>
	Date:   Sat Mar 6 16:30:44 2021 +0100

	    Added a second key label for the shift-activated symbols
2021-07-03 11:30:53 +02:00
Sebastian LaVine e2dff73599 Fix broken key definitions in layout.en.h
There were two problems with this file.

First, there were commas missing from the definitions for XK_7, XK_0,
XK_minus, and XK_plus. This prevented svkbd from even compiling.

Secondly, XK_Return was misdefined. This resulted in an immediate
segmentation fault upon loading the program.
2021-07-03 11:02:50 +02:00
Hiltjo Posthuma 34e5659db8 remove unused variable 2021-06-13 23:19:45 +02:00
Maarten van Gompel 5491251610 added an additional minimal mobile layer 2021-06-13 23:15:46 +02:00
Maarten van Gompel a5cb7d53ce increase spacing, set scheme for window, make window render faster by removing unnecessary map requests to X 2021-06-13 23:15:39 +02:00
Maarten van Gompel 2a84ae50f9 adding dead spacing between keys to prevent misclicks and adapting keyboard layout to a less rigid grid (all aimed to reduce typos) 2021-06-13 23:15:32 +02:00
Hiltjo Posthuma 2306b8eb40 remove unneeded initialization to zero
This removes a warning when compiling with -Wall (tested with clang 11.1.0).
2021-06-13 22:35:16 +02:00
silver 34530800bb Fix error in >1 wide key width calc, also 2021
Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2021-06-13 22:33:11 +02:00
Max Schillinger 42380f62eb allow neutralizing a key modifier by applying the same modifier again
svkbd allows you to create keys for symbols of the second (=shift) layer by defining them with a modifier included, like:

    { "|", "|", XK_backslash, 1, XK_Shift_L },

This key creates a pipe symbol by sending shift + backslash. But unfortunately, this way you can't emit get the original symbol (backslash) anymore. So you still need a separate key for typing a backslash, wasting precious space on the screen.

The appended patch fixes this by allowing to neutralize the shift by tapping this key with shift. It works both by tapping first shift, then the pipe key on the on-screen keyboard, or by clicking the pipe key with the middle mouse button (assuming XK_Shift_L is set as the button 2 mod).

This way you can create a "flipped" backslash/pipe key:

    { "|", "\\", XK_backslash, 1, XK_Shift_L },

This patch works equally for AltGr symbols in a `de`-based layout. For example:

    { "~", "+", XK_plus, 1, XK_ISO_Level3_Shift },

(In the German QWERTZ layout, you enter "~" with AltGr-"+".)

Best regards,
Max

Signed-off-by: Maarten van Gompel <proycon@anaproy.nl>
2021-06-13 22:33:03 +02:00
15 changed files with 557 additions and 200 deletions

View File

@ -3,6 +3,7 @@ MIT/X Consortium License
© 2011 Christoph Lohmann <20h@r-36.net>
© 2008-2011 Enno Boland <g # s01 ' de>
© 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"),

View File

@ -3,13 +3,13 @@
.POSIX:
NAME = svkbd
VERSION = 0.3
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,7 +24,8 @@ options:
config.h:
cp config.def.h $@
svkbd.o: config.h layout.${LAYOUT}.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 $<
@ -35,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}"

View File

@ -34,6 +34,7 @@ The following layouts are available:
* 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.
@ -60,15 +61,19 @@ 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

View File

@ -1,9 +1,15 @@
static const Bool wmborder = True;
static int fontsize = 22;
static double overlay_delay = 1.0; //in seconds
static double repeat_delay = 0.75; //in seconds, will not work on keys with overlays
static int scan_rate = 50; //scan rate in microseconds, affects key repetition rate
static int heightfactor = 14; //one row of keys takes up 1/x of the screen height
/* overlay delay in seconds */
static double overlay_delay = 1.0;
/* 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"
};
@ -19,5 +25,6 @@ static const char *defaultcolors[SchemeLast][2] = {
[SchemeHighlightShift] = { "#008ac0", "#005577" },
[SchemeOverlay] = { "#ffffff", "#2b3313" },
[SchemeOverlayShift] = { "#008ac0", "#2b3313" },
[SchemeWindow] = { "#bbbbbb", "#132a33" },
};

View File

@ -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} -D_DEFAULT_SOURCE -DVERSION=\"VERSION\" ${XINERAMAFLAGS} -DLAYOUT=\"layout.${LAYOUT}.h\"
SVKBD_CPPFLAGS = ${CPPFLAGS} -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\" ${XINERAMAFLAGS} -DLAYOUT=\"layout.${LAYOUT}.h\"

85
layout.am.h Normal file
View File

@ -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,
};

View File

@ -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

View File

@ -75,7 +75,7 @@ Buttonmod buttonmods[] = {
#define OVERLAYS 1
static Key overlay[OVERLAYS] = {
{ 0, XK_Cancel },
{ 0, 0, XK_Cancel },
};
#define LAYERS 1

View File

@ -6,12 +6,12 @@ static Key keys_en[] = {
{ "4","$", XK_4, 1 },
{ "5","%", XK_5, 1 },
{ "6","^", XK_6, 1 },
{ "7","&" XK_7, 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_0, 1 },
{ "-","_", XK_minus, 1 },
{ "=","+", XK_plus, 1 },
{ "⌫Bksp",0, XK_BackSpace, 2 },
{ 0 }, /* New row */
{ "->|",0, XK_Tab, 1 },
@ -27,7 +27,7 @@ static Key keys_en[] = {
{ 0, 0, XK_p, 1 },
{ "[","{", XK_bracketleft, 1 },
{ "]", "}", XK_bracketright, 1 },
{ "Return", XK_Return, 3 },
{ "Enter", 0, XK_Return, 3 },
{ 0 }, /* New row */
{ 0, 0, XK_Caps_Lock, 2 },
{ 0, 0, XK_a, 1 },
@ -70,7 +70,7 @@ Buttonmod buttonmods[] = {
#define OVERLAYS 1
static Key overlay[OVERLAYS] = {
{ 0, XK_Cancel },
{ 0, 0, XK_Cancel },
};
#define LAYERS 1

View File

@ -1,4 +1,4 @@
#define KEYS 55
#define KEYS 57
static Key keys_en[KEYS] = {
{ "Esc", "", XK_Escape, 1 },
@ -12,10 +12,130 @@ static Key keys_en[KEYS] = {
{ "8", "*", XK_8, 1 },
{ "9", "(", XK_9, 1 },
{ "0", ")", XK_0, 1 },
{ "-", "_", XK_minus, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Tab, 0.75 },
{ 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_slash, .75 },
{ 0 }, /* New row */
{ "^", 0, XK_Control_L, 1 },
{ 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, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Shift_L, 1.5 },
{ 0, 0, XK_z, 1 },
{ 0, 0, XK_x, 1 },
{ 0, 0, XK_c, 1 },
{ 0, 0, XK_v, 1 },
{ 0, 0, XK_b, 1 },
{ 0, 0, XK_n, 1 },
{ 0, 0, XK_m, 1 },
{ ",", "<", XK_comma, 1 },
{ ".", ">", XK_period, 1 },
{ "", 0, XK_BackSpace, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Cancel, 1},
{ "Alt", 0, XK_Alt_L, 1 },
{ "", 0, XK_space, 4 },
{ "", 0, XK_Down, 1 },
{ "", 0, XK_Up, 1 },
{ "↲ Enter", 0, XK_Return, 2 },
};
static Key keys_dvorak[KEYS] = {
{ "Esc", "", XK_Escape, 1 },
{ "1", "!", XK_1, 1 },
{ "2", "@", XK_2, 1 },
{ "3", "#", XK_3, 1 },
{ "4", "$", XK_4, 1 },
{ "5", "%", XK_5, 1 },
{ "6", "^", XK_6, 1 },
{ "7", "&", XK_7, 1 },
{ "8", "*", XK_8, 1 },
{ "9", "(", XK_9, 1 },
{ "0", ")", XK_0, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Tab, 0.75 },
{ ";", ":", XK_colon, 1 },
{ ",", "<", XK_comma, 1 },
{ ".", ">", XK_period, 1 },
{ 0, 0, XK_p, 1 },
{ 0, 0, XK_y, 1 },
{ 0, 0, XK_f, 1 },
{ 0, 0, XK_g, 1 },
{ 0, 0, XK_c, 1 },
{ 0, 0, XK_r, 1 },
{ 0, 0, XK_l, 1 },
{ "/", "?", XK_slash, .75 },
{ 0 }, /* New row */
{ "^", 0, XK_Control_L, 1 },
{ 0, 0, XK_a, 1 },
{ 0, 0, XK_o, 1 },
{ 0, 0, XK_e, 1 },
{ 0, 0, XK_u, 1 },
{ 0, 0, XK_i, 1 },
{ 0, 0, XK_d, 1 },
{ 0, 0, XK_h, 1 },
{ 0, 0, XK_t, 1 },
{ 0, 0, XK_n, 1 },
{ 0, 0, XK_s, 1 },
{ "-", "_", XK_minus, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Shift_L, 1.5 },
{ "'", "\"", XK_apostrophe, 1 },
{ 0, 0, XK_q, 1 },
{ 0, 0, XK_j, 1 },
{ 0, 0, XK_k, 1 },
{ 0, 0, XK_x, 1 },
{ 0, 0, XK_b, 1 },
{ 0, 0, XK_m, 1 },
{ 0, 0, XK_w, 1 },
{ 0, 0, XK_v, 1 },
{ 0, 0, XK_z, 1 },
{ "", 0, XK_BackSpace, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Cancel, 1},
{ "Alt", 0, XK_Alt_L, 1 },
{ "", 0, XK_space, 4 },
{ "", 0, XK_Down, 1 },
{ "", 0, XK_Up, 1 },
{ "↲ Enter", 0, XK_Return, 2 },
};
static Key keys_minimal[KEYS] = {
{ 0, "", XK_q, 1 },
{ 0, 0, XK_w, 1 },
{ 0, 0, XK_e, 1 },
{ 0, 0, XK_r, 1 },
@ -25,7 +145,6 @@ static Key keys_en[KEYS] = {
{ 0, 0, XK_i, 1 },
{ 0, 0, XK_o, 1 },
{ 0, 0, XK_p, 1 },
{ "'", "\"", XK_apostrophe, 1 },
{ 0 }, /* New row */
@ -38,11 +157,10 @@ static Key keys_en[KEYS] = {
{ 0, 0, XK_j, 1 },
{ 0, 0, XK_k, 1 },
{ 0, 0, XK_l, 1 },
{ "/", "?", XK_slash, 1 },
{ "Tab", 0, XK_Tab, 1 },
{ 0 }, /* New row */
{ "", 0, XK_Shift_L, 1.5 },
{ 0, 0, XK_z, 1 },
{ 0, 0, XK_x, 1 },
{ 0, 0, XK_c, 1 },
@ -50,25 +168,21 @@ static Key keys_en[KEYS] = {
{ 0, 0, XK_b, 1 },
{ 0, 0, XK_n, 1 },
{ 0, 0, XK_m, 1 },
{ ",", "<", XK_comma, 1 },
{ ".", ">", XK_period, 1 },
{ "⌫Bksp", 0, XK_BackSpace, 2 },
{ "", 0, XK_BackSpace, 1.5 },
{ 0 }, /* New row */
{ "", 0, XK_Cancel, 1},
{ "Shift", 0, XK_Shift_L, 2 },
{ "Ctrl", 0, XK_Control_L, 1 },
{ "Alt", 0, XK_Alt_L, 1 },
{ "", 0, XK_space, 2 },
{ "", 0, XK_Down, 1 },
{ "", 0, XK_Up, 1 },
{ "'", "\"", XK_apostrophe, 1 },
{ ",", "<", XK_comma, 1 },
{ "", 0, XK_space, 4 },
{ ".", ">", XK_period, 1 },
{ "↲ Enter", 0, XK_Return, 2 },
};
#define OVERLAYS 197
#define OVERLAYS 226
static Key overlay[OVERLAYS] = {
{ 0, 0, XK_a }, //Overlay for a
//---
{ "à", 0, XK_agrave },
{ "á", 0, XK_aacute },
{ "â", 0, XK_acircumflex },
@ -80,9 +194,7 @@ static Key overlay[OVERLAYS] = {
{ "å", 0, XK_aring },
{ "æ", 0, XK_ae },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_e }, //Overlay for e (first item after boundary defines the trigger)
//---
{ "è", 0, XK_egrave },
{ "é", 0, XK_eacute },
{ "ê", 0, XK_ecircumflex },
@ -90,18 +202,15 @@ static Key overlay[OVERLAYS] = {
{ "ę", 0, XK_eogonek },
{ "ē", 0, XK_emacron },
{ "ė", 0, XK_eabovedot },
{ "ě", 0, XK_ecaron },
{ 0, 0, XK_Cancel },
//--
{ 0, 0, XK_y }, //New overlay
//---
{ "", 0, XK_ygrave },
{ "ý", 0, XK_yacute },
{ "ŷ", 0, XK_ycircumflex },
{ "ÿ", 0, XK_ydiaeresis },
{ 0, 0, XK_Cancel },
//--
{ 0, 0, XK_u }, //New overlay
//---
{ "ù", 0, XK_ugrave },
{ "ú", 0, XK_uacute },
{ "û", 0, XK_ucircumflex },
@ -112,9 +221,7 @@ static Key overlay[OVERLAYS] = {
{ "ŭ", 0, XK_ubreve},
{ "ű", 0, XK_udoubleacute },
{ 0, 0, XK_Cancel },
//--
{ 0, 0, XK_i }, //New overlay
//---
{ "ì", 0, XK_igrave },
{ "í", 0, XK_iacute },
{ "î", 0, XK_icircumflex },
@ -123,9 +230,7 @@ static Key overlay[OVERLAYS] = {
{ "ī", 0, XK_imacron },
{ "ı", 0, XK_idotless },
{ 0, 0, XK_Cancel },
//--
{ 0, 0, XK_o }, //New overlay
//---
{ "ò", 0, XK_ograve },
{ "ó", 0, XK_oacute },
{ "ô", 0, XK_ocircumflex },
@ -137,128 +242,86 @@ static Key overlay[OVERLAYS] = {
{ "ő", 0, XK_odoubleacute },
{ "œ", 0, XK_oe },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_d }, //New overlay
//---
{ "ď", 0, XK_dcaron },
{ "ð", 0, XK_eth },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_c }, //New overlay
//---
{ "ç", 0, XK_ccedilla },
{ "ĉ", 0, XK_ccircumflex },
{ "č", 0, XK_ccaron },
{ "ć", 0, XK_cacute },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_s }, //New overlay
//---
{ "ş", 0, XK_scedilla },
{ "ŝ", 0, XK_scircumflex },
{ "š", 0, XK_scaron },
{ "ś", 0, XK_sacute },
{ "ß", 0, XK_ssharp },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_z }, //New overlay
//---
{ "ž", 0, XK_zcaron },
{ "ż", 0, XK_zabovedot },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_n }, //New overlay
//---
{ "ñ", 0, XK_ntilde },
{ "ń", 0, XK_nacute },
{ "ň", 0, XK_ncaron },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//
{ 0, 0, XK_t }, //New overlay
//---
{ "ț", 0, XK_tcedilla },
{ "ť", 0, XK_tcaron },
{ "þ", 0, XK_thorn },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//----
{ 0, 0, XK_g }, //New overlay
//---
{ "ĝ", 0, XK_gcircumflex },
{ "ğ", 0, XK_gbreve },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//
{ 0, 0, XK_h }, //New overlay
//---
{ "ĥ", 0, XK_hcircumflex },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//
{ 0, 0, XK_j }, //New overlay
//---
{ "ĵ", 0, XK_jcircumflex },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_l }, //New overlay
//---
{ "ł", 0, XK_lstroke },
{ "ľ", 0, XK_lcaron },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ 0, 0, XK_r }, //New overlay
//---
{ "ř", 0, XK_rcaron },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_softsign }, //New overlay
//---
{ "ъ", 0, XK_Cyrillic_hardsign },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_ie }, //New overlay
//---
{ "ё", 0, XK_Cyrillic_io },
{ "э", 0, XK_Cyrillic_e },
{ "Є", 0, XK_Ukrainian_ie },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_i }, //New overlay
//---
{ "і", 0, XK_Ukrainian_i },
{ "ї", 0, XK_Ukrainian_yi },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_u }, //New overlay
//---
{ "ў", 0, XK_Byelorussian_shortu },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_shorti }, //New overlay
//---
{ "ј", 0, XK_Cyrillic_je },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_el }, //New overlay
//---
{ "љ", 0, XK_Cyrillic_lje },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_en }, //New overlay
//---
{ "њ", 0, XK_Cyrillic_nje },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_tse }, //New overlay
//---
{ "џ", 0, XK_Cyrillic_dzhe },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ 0, 0, XK_Cyrillic_che }, //New overlay
//---
{ "ћ", 0, XK_Serbian_tshe },
{ "ђ", 0, XK_Serbian_dje },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//---
{ "🙂", 0, 0x101f642 }, //emoji overlay
//---
{ "🙂", 0, 0x101f642 }, //New overlay -> emoji overlay
{ "😀", 0, 0x101f600 },
{ "😁", 0, 0x101f601 },
{ "😂", 0, 0x101f602 },
@ -287,9 +350,36 @@ static Key overlay[OVERLAYS] = {
{ "😳", 0, 0x101f633 },
{ "😴", 0, 0x101f634 },
{ 0, 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
{ "/?", 0, XK_slash }, //punctuation overlay
//--
{ "q", 0, XK_q }, //New overlay -> emoji overlay on Q key (for minimal layer)
{ "😀", 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 }, /* XK_Cancel signifies overlay boundary */
{ "/?", 0, XK_slash }, //New overlay - punctuation overlay
{ "1", "!", XK_1, 1 },
{ "2", "@", XK_2, 1 },
{ "3", "#", XK_3, 1 },
@ -446,10 +536,73 @@ static Key keys_navigation[KEYS] = {
{ "", 0, XK_Down, 1 },
{ "Tab", 0, XK_Tab, 1 },
{ "↲ Enter", 0, XK_Return, 1},
{ 0 }, /* Last item (double 0) */
{ 0 }, /* Last item (double 0) */
{ 0 }, /* Last item (double 0) */
{ 0 }, /* Last item (double 0) */
};
static Key keys_am[KEYS] = {
{ "՝","՜", 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 }, /* New row */
{ "ճ", "Ճ", 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 },
{ 0 }, /* New row */
{ "ջ", "Ջ", 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 },
{ 0 }, /* New row */
{ "123", 0, XK_Mode_switch, 1 },
{ "ժ", "Ժ", 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 },
{ "⌫Bksp", 0, XK_BackSpace, 2 },
{ 0 }, /* New row */
{ "", 0, XK_Cancel, 1},
{ "Shift", 0, XK_Shift_L, 2 },
{ "", 0, XK_space, 2 },
{ "↲ Enter", 0, XK_Return, 2 },
};
static Key keys_ru[KEYS] = {
{ "Esc", 0, XK_Escape, 1 },
@ -520,23 +673,23 @@ static Key keys_dialer[KEYS] = {
{ "1", "!" , XK_1, 1 },
{ "2", "@", XK_2, 1 },
{ "3", "#", XK_3, 1 },
{ "⌫Bksp", 0, XK_BackSpace, 2 },
{ "-", "_", XK_minus, 1 },
{ ",", "<", XK_comma, 1 },
{ 0 }, /* New row */
{ "Shift", 0, XK_Shift_L, 1 },
{ "4", "$", XK_4, 1 },
{ "5", "%", XK_5, 1 },
{ "6", "^", XK_6, 1 },
{ "-", "_", XK_minus, 1 },
{ ",", "<", XK_comma, 1 },
{ "=", "+", XK_equal, 1 },
{ "/", "?", XK_slash, 1 },
{ 0 }, /* New row */
{ "abc", 0, XK_Mode_switch, 1 },
{ "7", "&", XK_7, 1 },
{ "8", "*", XK_8, 1 },
{ "9", "(", XK_9, 1 },
{ "=", "+", XK_equal, 1 },
{ "/", "?", XK_slash, 1 },
{ "⌫Bksp", 0, XK_BackSpace, 2 },
{ 0 }, /* New row */
{ "", 0, XK_Cancel, 1},
@ -548,13 +701,16 @@ static Key keys_dialer[KEYS] = {
{ 0 }, /* Last item (double 0) */
};
#define LAYERS 5
#define LAYERS 8
static char* layer_names[LAYERS] = {
"en",
"symbols",
"navigation",
"dialer",
"ru",
"minimal",
"dvorak",
"am",
"ru"
};
static Key* available_layers[LAYERS] = {
@ -562,11 +718,13 @@ static Key* available_layers[LAYERS] = {
keys_symbols,
keys_navigation,
keys_dialer,
keys_ru
keys_minimal,
keys_dvorak,
keys_am,
keys_ru,
};
Buttonmod buttonmods[] = {
{ XK_Shift_L, Button2 },
{ XK_Alt_L, Button3 },
{ XK_Shift_L, Button2 },
{ XK_Alt_L, Button3 },
};

View File

@ -159,7 +159,8 @@ static Key keys_dialer[DIALER_KEYS] = {
{ "1!", 0, XK_1, 1 },
{ "2@", 0, XK_2, 1 },
{ "3#", 0, XK_3, 1 },
{ "", 0, XK_BackSpace, 2 },
{ "-_", 0, XK_minus, 1 },
{ ",<", 0, XK_comma, 1 },
{ 0 },
@ -167,8 +168,8 @@ static Key keys_dialer[DIALER_KEYS] = {
{ "4$", 0, XK_4, 1 },
{ "5%", 0, XK_5, 1 },
{ "6^", 0, XK_6, 1 },
{ "-_", 0, XK_minus, 1 },
{ ",<", 0, XK_comma, 1 },
{ "=+", 0, XK_equal, 1 },
{ "/?", 0, XK_slash, 1 },
{ 0 },
@ -176,8 +177,7 @@ static Key keys_dialer[DIALER_KEYS] = {
{ "7&", 0, XK_7, 1 },
{ "8*", 0, XK_8, 1 },
{ "9(", 0, XK_9, 1 },
{ "=+", 0, XK_equal, 1 },
{ "/?", 0, XK_slash, 1 },
{ "", 0, XK_BackSpace, 2 },
{ 0 },
@ -188,7 +188,7 @@ static Key keys_dialer[DIALER_KEYS] = {
{ "↲ Enter", 0, XK_Return, 2},
};
#define OVERLAYS 192
#define OVERLAYS 193
static Key overlay[OVERLAYS] = {
{ 0, 0, XK_a },
@ -203,7 +203,6 @@ static Key overlay[OVERLAYS] = {
{ "å", 0, XK_aring },
{ "æ", 0, XK_ae },
{ 0, 0, XK_Cancel },
{ 0, 0, XK_e },
{ "è", 0, XK_egrave },
{ "é", 0, XK_eacute },
@ -212,15 +211,14 @@ static Key overlay[OVERLAYS] = {
{ "ę", 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 },
@ -232,7 +230,6 @@ static Key overlay[OVERLAYS] = {
{ "ŭ", 0, XK_ubreve},
{ "ű", 0, XK_udoubleacute },
{ 0, 0, XK_Cancel },
{ 0, 0, XK_i },
{ "ì", 0, XK_igrave },
{ "í", 0, XK_iacute },
@ -242,8 +239,6 @@ static Key overlay[OVERLAYS] = {
{ "ī", 0, XK_imacron },
{ "ı", 0, XK_idotless },
{ 0, 0, XK_Cancel },
{ 0, 0, XK_o },
{ "ò", 0, XK_ograve },
{ "ó", 0, XK_oacute },
@ -256,19 +251,16 @@ static Key overlay[OVERLAYS] = {
{ "ő", 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 },
@ -276,86 +268,68 @@ static Key overlay[OVERLAYS] = {
{ "ś", 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 },
@ -377,7 +351,7 @@ static Key overlay[OVERLAYS] = {
{ "😒", 0, 0x101f612 },
{ "😓", 0, 0x101f613 },
{ "😛", 0, 0x101f61b },
{ "😮", 0, 0x101f62e, 2 }, // skip shift
{ "😮", 0, 0x101f62e },
{ "😟", 0, 0x101f61f },
{ "😟", 0, 0x101f620 },
{ "😢", 0, 0x101f622 },
@ -385,7 +359,6 @@ static Key overlay[OVERLAYS] = {
{ "😳", 0, 0x101f633 },
{ "😴", 0, 0x101f634 },
{ 0, 0, XK_Cancel },
{ ".", 0, XK_period, },
{ ":", 0, XK_colon, 26, XK_Shift_L },
{ ";", 0, XK_colon, 0 },
@ -393,7 +366,6 @@ static Key overlay[OVERLAYS] = {
{ "?", 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 },
@ -401,7 +373,6 @@ static Key overlay[OVERLAYS] = {
{ "*", 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 },

View File

@ -72,7 +72,7 @@ Buttonmod buttonmods[] = {
#define OVERLAYS 1
static Key overlay[OVERLAYS] = {
{ 0, XK_Cancel },
{ 0, 0, XK_Cancel },
};
#define LAYERS 1

View File

@ -75,7 +75,7 @@ Buttonmod buttonmods[] = {
#define OVERLAYS 1
static Key overlay[OVERLAYS] = {
{ 0, XK_Cancel },
{ 0, 0, XK_Cancel },
};
#define LAYERS 1

88
layout.sr.h Normal file
View File

@ -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,
};

141
svkbd.c
View File

@ -38,7 +38,7 @@
enum {
SchemeNorm, SchemeNormABC, SchemeNormABCShift, SchemeNormShift, SchemePress,
SchemePressShift, SchemeHighlight, SchemeHighlightShift, SchemeOverlay,
SchemeOverlayShift, SchemeLast
SchemeOverlayShift, SchemeWindow, SchemeLast
};
enum { NetWMWindowType, NetLast };
@ -47,7 +47,7 @@ typedef struct {
char *label;
char *label2;
KeySym keysym;
unsigned int width;
double width;
KeySym modifier;
int x, y, w, h;
Bool pressed;
@ -70,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);
@ -85,7 +85,7 @@ 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);
@ -121,7 +121,7 @@ static int debug = 0;
static int numlayers = 0;
static int numkeys = 0;
static char *colors[10][2]; /* 10 schemes, 2 colors each */
static char *colors[11][2]; /* 11 schemes, 2 colors each */
static char *fonts[] = { 0 };
static KeySym ispressingkeysym;
@ -136,8 +136,8 @@ 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)
@ -158,22 +158,23 @@ motionnotify(XEvent *e)
} else {
keys[i].highlighted = True;
}
drawkey(&keys[i]);
drawkey(&keys[i], True);
}
continue;
} 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) {
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]);
drawkey(&keys[i], True);
}
}
@ -198,16 +199,19 @@ buttonpress(XEvent *e)
if (!(k = findkey(ev->x, ev->y)))
return;
if (k->modifier) {
mod = k->modifier;
} else {
for (i = 0; i < LENGTH(buttonmods); i++) {
if (ev->button == buttonmods[i].button) {
mod = buttonmods[i].mod;
break;
}
for (i = 0; i < LENGTH(buttonmods); i++) {
if (ev->button == buttonmods[i].button) {
mod = buttonmods[i].mod;
break;
}
}
if (k->modifier) {
if (mod == k->modifier)
mod = 0;
else
mod = k->modifier;
}
press(k, mod);
}
@ -231,7 +235,9 @@ buttonrelease(XEvent *e)
if (ev->x < 0 || ev->y < 0) {
unpress(NULL, mod);
} else if ((k = findkey(ev->x, ev->y))) {
if (k->modifier)
if (k->modifier == mod)
unpress(k, 0);
else if (k->modifier)
unpress(k, k->modifier);
else
unpress(k, mod);
@ -303,14 +309,17 @@ 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;
@ -367,7 +376,8 @@ drawkey(Key *k)
w = TEXTW(l);
drw_text(drw, x, y, w, h, 0, l, 0);
}
drw_map(drw, win, k->x, k->y, k->w, k->h);
if (map)
drw_map(drw, win, k->x, k->y, k->w, k->h);
}
void
@ -443,7 +453,7 @@ press(Key *k, KeySym buttonmod)
if (enableoverlays && currentoverlay == -1)
overlayidx = hasoverlay(k->keysym);
if ((pressonrelease) || (enableoverlays && overlayidx != -1)) {
/*record the begin of the press, don't simulate the actual keypress yet */
/* record the begin of the press, don't simulate the actual keypress yet */
record_press_begin(k->keysym);
} else {
printdbg("Simulating press: %ld (mod %ld)\n", k->keysym, buttonmod);
@ -465,15 +475,24 @@ press(Key *k, KeySym buttonmod)
}
}
}
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;
}
@ -564,8 +583,9 @@ void
unpress(Key *k, KeySym buttonmod)
{
int i;
Bool neutralizebuttonmod = False;
if (k != NULL) {
if (k) {
switch(k->keysym) {
case XK_Cancel:
cyclelayer();
@ -589,10 +609,13 @@ unpress(Key *k, KeySym buttonmod)
/* 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);
if (keys[i].keysym == buttonmod)
neutralizebuttonmod = True;
else
simulate_keypress(keys[i].keysym);
}
}
if (buttonmod) {
if (buttonmod && !neutralizebuttonmod) {
simulate_keypress(buttonmod);
}
simulate_keypress(k->keysym);
@ -611,25 +634,27 @@ unpress(Key *k, KeySym buttonmod)
if (printoutput)
printkey(&keys[i], buttonmod);
keys[i].pressed = 0;
drawkey(&keys[i]);
drawkey(&keys[i], True);
}
}
if (buttonmod) {
if (buttonmod && !neutralizebuttonmod) {
simulate_keyrelease(buttonmod);
}
if ((k == NULL) || (!IsModifierKey(k->keysym))) {
if (k == NULL || !IsModifierKey(k->keysym)) {
for (i = 0; i < numkeys; i++) {
if (keys[i].pressed && IsModifierKey(keys[i].keysym)) {
simulate_keyrelease(keys[i].keysym);
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 && !IsModifierKey(k->keysym)) {
if (enableoverlays && currentoverlay != -1 &&
(k == NULL || !IsModifierKey(k->keysym))) {
if (releaseprotect) {
releaseprotect = 0;
} else {
@ -645,8 +670,8 @@ run(void)
int xfd;
fd_set fds;
struct timeval tv;
double duration = 0.0;
int overlayidx = -1;
double duration;
int overlayidx;
int i, r;
xfd = ConnectionNumber(dpy);
@ -675,7 +700,7 @@ run(void)
printdbg("%f\n", duration);
overlayidx = hasoverlay(ispressingkeysym);
duration = get_press_duration();
if ((overlayidx != -1) && (duration >= overlay_delay)) {
if (overlayidx != -1 && duration >= overlay_delay) {
printdbg("press duration %f, activating overlay\n", duration);
showoverlay(overlayidx);
pressbegin.tv_sec = 0;
@ -736,10 +761,10 @@ readxresources(void)
if (XrmGetResource(xdb, "svkbd.ABCbackground", "*", &type, &xval) && !colors[SchemeNormABC][ColBg])
colors[SchemeNormABC][ColBg] = estrdup(xval.addr);
if (XrmGetResource(xdb, "svkbd.ABCshiftforeground", "*", &type, &xval) && !colors[SchemeNormShift][ColFg])
colors[SchemeNormShift][ColFg] = estrdup(xval.addr);
if (XrmGetResource(xdb, "svkbd.ABCshiftbackground", "*", &type, &xval) && !colors[SchemeNormShift][ColBg])
colors[SchemeNormShift][ColBg] = estrdup(xval.addr);
if (XrmGetResource(xdb, "svkbd.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);
@ -771,6 +796,11 @@ readxresources(void)
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);
}
}
@ -936,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;
@ -1019,19 +1052,27 @@ showoverlay(int idx)
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++) {
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;