diff --git a/README b/README deleted file mode 100644 index 266d112..0000000 --- a/README +++ /dev/null @@ -1,66 +0,0 @@ -SVKBD -===== - -This is a simple virtual keyboard, intended to be used in environments, -where no keyboard is available. - -Installation ------------- - - $ make - $ make install - -This will create by default `svkbd-sxmo`, which is svkbd using an versatile -layout with multiple layers and overlays, and optimised for mobile devices. -It was designed for [Simple X Mobile](https://sr.ht/~mil/Sxmo). - -You can create svkbd for additional layouts by doing: - - $ make LAYOUT=$layout - -This will take the file `layout.$layout.h` and create `svkbd-$layout`. -`make install` will then pick up the new file and install it accordingly. - -Usage ------ - - % svkbd-sxmo - -This will open svkbd at the bottom of the screen, showing the default -English layout. - - % svkbd-sxmo -d - -This tells svkbd-sxmo to announce itself being a dock window, which then -is managed differently between different window managers. If using dwm -and the dock patch, then this will make svkbd being managed by dwm and -some space of the screen being reserved for it. - - % svkbd-sxmo -g 400x200+1+1 - -This will start svkbd-en with a size of 400x200 and at the upper left -window corner. - -You can enable layers on the fly 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. - -The virtual keyboard comes 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``. - -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. - -Notes ---------- - -This virtual keyboard does not actually modify the X keyboard layout, it simply relies on a standard US QWERTY layout -(setxkbmap us) being activated. If you use another XKB layout you will get unpredictable output that does not match the -labels on the virtual keycaps. - -Repository ----------- - - git clone http://git.suckless.org/svkbd diff --git a/README.md b/README.md new file mode 100644 index 0000000..da863e4 --- /dev/null +++ b/README.md @@ -0,0 +1,87 @@ +SVKBD: Simple Virtual Keyboard +================================= + +This is a simple virtual keyboard, intended to be used in environments, +where no keyboard is available. + +Installation +------------ + + $ make + $ make install + +This will create by default `svkbd-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: + + $ make LAYOUT=$layout + +This will take the file `layout.$layout.h` and create `svkbd-$layout`. +`make install` will then pick up the new file and install it accordingly. + +Layouts +--------- + +The following layouts are available: + +* **Mobile Layouts:** + * ``mobile-intl`` - A small international layout optimised for mobile devices. This layout consists of multiple layers which + can be switched on the fly, and overlays that appear on long-press of certain keys, adding input ability for + 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 dialer/numeric layer + * ``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/). +* **Traditional layouts**: + * ``en`` - An english layout without layers (QWERTY) + * ``de`` - A german layout (QWERTZ) + * ``ru`` - A russian layout (ЙЦУКЕН) + * ``sh`` - A serbo-croatian layout using latin script (QWERTZ) + +Usage +----- + + $ svkbd-mobile-intl + +This will open svkbd at the bottom of the screen, showing the default +international layout. + + $ svkbd-mobile-intl -d + +This tells svkbd to announce itself being a dock window, which then +is managed differently between different window managers. If using dwm +and the dock patch, then this will make svkbd being managed by dwm and +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 +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. + +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``. + +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. + +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. + +If you use another XKB layout you will get unpredictable output that does not match the labels on the virtual keycaps! + +Repository +---------- + + git clone https://git.suckless.org/svkbd diff --git a/config.mk b/config.mk index f64c515..bc4eeca 100644 --- a/config.mk +++ b/config.mk @@ -1,4 +1,4 @@ -LAYOUT = sxmo +LAYOUT = mobile-intl # paths PREFIX = /usr/local diff --git a/layout.arrows.h b/layout.arrows.h index f356518..29c2d0c 100644 --- a/layout.arrows.h +++ b/layout.arrows.h @@ -1,11 +1,11 @@ -static Key keys[] = { +#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 }, - { "[X]", XK_Cancel, 1 }, }; Buttonmod buttonmods[] = { @@ -13,3 +13,17 @@ Buttonmod buttonmods[] = { { XK_Alt_L, Button3 }, }; +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 1 +static char* layer_names[LAYERS] = { + "arrows", +}; + +static Key* available_layers[LAYERS] = { + keys_arrows, +}; + diff --git a/layout.de.h b/layout.de.h index 2ef4b7d..d5778e5 100644 --- a/layout.de.h +++ b/layout.de.h @@ -1,4 +1,5 @@ -static Key keys[] = { +#define KEYS 66 +static Key keys_de[KEYS] = { { "^°′", XK_dead_circumflex, 1}, { "1!¹", XK_1, 1 }, { "2\"²", XK_2, 1 }, @@ -65,7 +66,6 @@ static Key keys[] = { { "Alt Gr", XK_ISO_Level3_Shift, 2 }, { "Menu", XK_Menu, 2 }, { "Ctrl", XK_Control_R, 2 }, - { "[X]", XK_Cancel, 1}, }; Buttonmod buttonmods[] = { @@ -73,3 +73,17 @@ Buttonmod buttonmods[] = { { XK_Alt_L, Button3 }, }; +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 1 +static char* layer_names[LAYERS] = { + "de", +}; + +static Key* available_layers[LAYERS] = { + keys_de, +}; + diff --git a/layout.en.h b/layout.en.h new file mode 100644 index 0000000..07cc602 --- /dev/null +++ b/layout.en.h @@ -0,0 +1,84 @@ +#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 }, + { 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 }, /* 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 }, /* 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 }, /* 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 }, +}; + +Buttonmod buttonmods[] = { + { XK_Shift_L, Button2 }, + { XK_Alt_L, Button3 }, +}; + +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 1 +static char* layer_names[LAYERS] = { + "en", +}; + +static Key* available_layers[LAYERS] = { + keys_en, +}; + diff --git a/layout.sxmo.h b/layout.mobile-intl.h similarity index 99% rename from layout.sxmo.h rename to layout.mobile-intl.h index 6aafdb3..63bf1ca 100644 --- a/layout.sxmo.h +++ b/layout.mobile-intl.h @@ -1,5 +1,4 @@ #define KEYS 43 -static Key keys[KEYS] = { NULL }; static Key keys_en[KEYS] = { { "Esc", XK_Escape, 1 }, diff --git a/layout.mobile-plain.h b/layout.mobile-plain.h new file mode 100644 index 0000000..a261862 --- /dev/null +++ b/layout.mobile-plain.h @@ -0,0 +1,125 @@ +#define KEYS 40 +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 }, /* 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 }, /* 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 }, /* 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 }, +}; + +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 }, + + { 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 }, + + { 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 }, /* 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 }, +}; + +Buttonmod buttonmods[] = { + { XK_Shift_L, Button2 }, + { XK_Alt_L, Button3 }, +}; + +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 2 +static char* layer_names[LAYERS] = { + "en", + "symbols", +}; + +static Key* available_layers[LAYERS] = { + keys_en, + keys_symbols, +}; diff --git a/layout.ru.h b/layout.ru.h index ec7b84c..3a40439 100644 --- a/layout.ru.h +++ b/layout.ru.h @@ -1,4 +1,5 @@ -static Key keys[] = { +#define KEYS 63 +static Key keys_ru[] = { { "ёЁ", XK_Cyrillic_io, 1 }, { "1!", XK_1, 1 }, { "2\"", XK_2, 1 }, @@ -62,7 +63,6 @@ static Key keys[] = { { "", XK_space, 5 }, { "Alt", XK_Alt_R, 2 }, { "Ctrl", XK_Control_R, 2 }, - { "[X]", XK_Cancel, 1}, }; Buttonmod buttonmods[] = { @@ -70,3 +70,16 @@ Buttonmod buttonmods[] = { { XK_Alt_L, Button3 }, }; +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 1 +static char* layer_names[LAYERS] = { + "ru", +}; + +static Key* available_layers[LAYERS] = { + keys_ru, +}; diff --git a/layout.sh.h b/layout.sh.h index 42d56f4..b36b70a 100644 --- a/layout.sh.h +++ b/layout.sh.h @@ -1,4 +1,5 @@ -static Key keys[] = { +#define KEYS 66 +static Key keys_sh[] = { { "`~", XK_quoteleft, 1}, { "1!~", XK_1, 1 }, { "2\"ˇ", XK_2, 1 }, @@ -65,7 +66,6 @@ static Key keys[] = { { "Alt Gr", XK_ISO_Level3_Shift, 2 }, { "Menu", XK_Menu, 2 }, { "Ctrl", XK_Control_R, 2 }, - { "[X]", XK_Cancel, 1}, }; Buttonmod buttonmods[] = { @@ -73,3 +73,16 @@ Buttonmod buttonmods[] = { { XK_Alt_L, Button3 }, }; +#define OVERLAYS 1 +static Key overlay[OVERLAYS] = { + { 0, XK_Cancel }, +}; + +#define LAYERS 1 +static char* layer_names[LAYERS] = { + "sh", +}; + +static Key* available_layers[LAYERS] = { + keys_sh, +}; diff --git a/svkbd.c b/svkbd.c index ada2b88..1ff77f9 100644 --- a/svkbd.c +++ b/svkbd.c @@ -125,6 +125,7 @@ Bool sigtermd = False; #endif #include LAYOUT +static Key keys[KEYS] = { NULL }; static Key* layers[LAYERS]; void @@ -876,9 +877,14 @@ main(int argc, char *argv[]) { signal(SIGTERM, sigterm); + //parse environment variables - const char* enableoverlays_env = getenv("SVKBD_ENABLEOVERLAYS"); - if (enableoverlays_env != NULL) enableoverlays = atoi(enableoverlays_env); + if (OVERLAYS <= 1) { + enableoverlays = 0; + } else { + const char* enableoverlays_env = getenv("SVKBD_ENABLEOVERLAYS"); + if (enableoverlays_env != NULL) enableoverlays = atoi(enableoverlays_env); + } const char* layers_env = getenv("SVKBD_LAYERS"); if (layers_env != NULL) { layer_names_list = malloc(128);