Move layouts to single layout.h file & toggle layers via memcpy w/ XK_Cancel - svkbd - simple virtual keyboard
 (HTM) git clone git://git.suckless.org/svkbd
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 6e5bf2d8e4d85a19b0ee82d4fb92b850a78b3892
 (DIR) parent 0a3a153aa6cf827ccbda179e831065293bfdabdb
 (HTM) Author: Miles Alan <m@milesalan.com>
       Date:   Sun,  2 Aug 2020 15:46:07 +0200
       
       Move layouts to single layout.h file & toggle layers via memcpy w/ XK_Cancel
       
       Diffstat:
         D layout.en.h                         |      58 ------------------------------
         A layout.sxmo.h                       |     111 ++++++++++++++++++++++++++++++
         D layout.symbols.h                    |      58 ------------------------------
         M svkbd.c                             |      33 ++++++++++++++++++++++++++++++-
       
       4 files changed, 143 insertions(+), 117 deletions(-)
       ---
 (DIR) diff --git a/layout.en.h b/layout.en.h
       @@ -1,58 +0,0 @@
       -static Key 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 },
       -        { "<-", XK_BackSpace, 2 },
       -
       -        { 0 }, /* New row */
       -        { "Layer 2", XK_Cancel, 1},
       -        { "Shift", XK_Shift_L, 1 },
       -        /*{ "L", XK_Left, 1 },*/
       -        { "D", XK_Down, 1 },
       -        { "U", 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 },
       -};
 (DIR) diff --git a/layout.sxmo.h b/layout.sxmo.h
       @@ -0,0 +1,111 @@
       +static Key keys[40] = { NULL };
       +
       +static Key keys_en[40] = {
       +        { 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 },
       +        { "<-", XK_BackSpace, 2 },
       +
       +        { 0 }, /* New row */
       +        { "Layer 2", XK_Cancel, 1},
       +        { "Shift", XK_Shift_L, 1 },
       +        /*{ "L", XK_Left, 1 },*/
       +        { "D", XK_Down, 1 },
       +        { "U", 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 },
       +  { "L", XK_Left, 1 },
       +  { "R", XK_Right, 1 },
       +  { "Ctrl-C", XK_Shift_L|XK_bar, 1 },
       +  { "Ctrl-L", XK_Shift_L|XK_bar, 1 },
       +  { "Ctrl-V", XK_Shift_L|XK_bar, 1 },
       +  { "Ctrl-D", XK_Shift_L|XK_bar, 1 },
       +  { "TAB", XK_Tab, 1 },
       +  { "<-", XK_BackSpace, 2 },
       +
       +  { 0 }, /* New row */
       +  { "Layer 1", XK_Cancel, 1},
       +  { "Shift", XK_Shift_L, 1 },
       +  /*{ "L", XK_Left, 1 },*/
       +  { "D", XK_Down, 1 },
       +  { "U", 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 },
       +};
       +
 (DIR) diff --git a/layout.symbols.h b/layout.symbols.h
       @@ -1,58 +0,0 @@
       -static Key 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 */
       -
       -  { "'\"", 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 },
       -  { "L", XK_Left, 1 },
       -  { "R", XK_Right, 1 },
       -  { "Ctrl-C", XK_Shift_L|XK_bar, 1 },
       -  { "Ctrl-L", XK_Shift_L|XK_bar, 1 },
       -  { "Ctrl-V", XK_Shift_L|XK_bar, 1 },
       -  { "Ctrl-D", XK_Shift_L|XK_bar, 1 },
       -  { "TAB", XK_Tab, 1 },
       -  { "<-", XK_BackSpace, 2 },
       -
       -  { 0 }, /* New row */
       -  { "Layer 1", XK_Cancel, 1},
       -  { "Shift", XK_Shift_L, 1 },
       -  /*{ "L", XK_Left, 1 },*/
       -  { "D", XK_Down, 1 },
       -  { "U", 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 },
       -};
       -
 (DIR) diff --git a/svkbd.c b/svkbd.c
       @@ -13,6 +13,7 @@
        #include <X11/Xutil.h>
        #include <X11/Xproto.h>
        #include <X11/extensions/XTest.h>
       +#include <signal.h>
        
        /* macros */
        #define MAX(a, b)       ((a) > (b) ? (a) : (b))
       @@ -96,8 +97,10 @@ static Bool running = True, isdock = False;
        static KeySym pressedmod = 0;
        static int rows = 0, ww = 0, wh = 0, wx = 0, wy = 0;
        static char *name = "svkbd";
       +static int terminate = 0;
        
        Bool ispressing = False;
       +Bool baselayer = True;
        
        /* configuration, allows nested code to access above variables */
        #include "config.h"
       @@ -393,7 +396,10 @@ unpress(Key *k, KeySym mod) {
                if(k != NULL) {
                        switch(k->keysym) {
                        case XK_Cancel:
       -                        exit(0);
       +                        togglelayer();
       +                        break;
       +                case XK_Break:
       +                  running = False;
                        default:
                                break;
                        }
       @@ -580,11 +586,36 @@ usage(char *argv0) {
                exit(1);
        }
        
       +void
       +togglelayer() {
       +        memcpy(&keys, baselayer ? &keys_symbols : &keys_en, sizeof(keys_en));
       +        updatekeys();
       +        drawkeyboard();
       +        baselayer = !baselayer;
       +}
       +
       +void
       +sigterm(int sig)
       +{
       +        // E.g. Since sometimes we might use svkbd, to kill svkbd - e.g. in
       +        // terminal or script (pkill svkbd), .. that signal might register before
       +        // the keyup event is processed so X thinks the key is held down forever..
       +        // so here we keyup every key & exit (XK_Break) to keyup cleanup properly
       +        int i;
       +        for(i = 0; i < LENGTH(keys); i++) {
       +          XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, keys[i].keysym), False, 0);
       +        }
       +        running = False;
       +        //XTestFakeKeyEvent(dpy, XK_Break, False, 0);
       +}
       +
        int
        main(int argc, char *argv[]) {
                int i, xr, yr, bitm;
                unsigned int wr, hr;
        
       +        signal(SIGTERM, sigterm);
       +        memcpy(&keys, &keys_en, sizeof(keys_en));
                for (i = 1; argv[i]; i++) {
                        if(!strcmp(argv[i], "-v")) {
                                die("svkbd-"VERSION", © 2006-2016 svkbd engineers,"