Introduction
Introduction Statistics Contact Development Disclaimer Help
Added a dialer/numpad keyboard, added the ability to handle layouts with less k…
git clone git://git.suckless.org/svkbd
Log
Files
Refs
README
LICENSE
---
commit 4dab556580d2249e3f1597219b9c65bf8660f5e8
parent 99935775afce355bd16964b9a1b96ec35247292a
Author: Maarten van Gompel <[email protected]>
Date: Sun, 2 Aug 2020 15:46:16 +0200
Added a dialer/numpad keyboard, added the ability to handle layouts with less k…
Diffstat:
M README | 7 +++++++
M config.def.h | 1 +
M layout.sxmo.h | 39 +++++++++++++++++++++++++++++…
M svkbd.c | 107 +++++++++++++++++++++++------…
4 files changed, 125 insertions(+), 29 deletions(-)
---
diff --git a/README b/README
@@ -53,6 +53,13 @@ overlay functionality with the ``-O`` flag or by setting the…
also a key on the function layer of the keyboard itself to enable/disable this…
``≅`` when the overlay functionality is enabled and ``≇`` when not.
+Notes
+---------
+
+This virtual keyboard does not actually modify the X keyboard layout, it simpl…
+(setxkbmap us) being activated. If you use another XKB layout you will get unp…
+labels on the virtual keycaps.
+
Repository
----------
diff --git a/config.def.h b/config.def.h
@@ -1,6 +1,7 @@
static const Bool wmborder = True;
static int fontsize = 20;
static double overlay_delay = 1.0;
+static int heightfactor = 16; //one row of keys takes up 1/x of the screen hei…
static const char *fonts[] = {
"DejaVu Sans:bold:size=20"
};
diff --git a/layout.sxmo.h b/layout.sxmo.h
@@ -68,7 +68,7 @@ static Key overlay[OVERLAYS] = {
{ "æ", XK_ae },
{ 0, XK_Cancel }, /* XK_Cancel signifies overlay boundary */
//--
- { 0, XK_e }, //Overlay for e
+ { 0, XK_e }, //Overlay for e (first item after boundary defines the tr…
//---
{ "è", XK_egrave },
{ "é", XK_eacute },
@@ -465,11 +465,45 @@ static Key keys_ru[KEYS] = {
{ "↲ Enter", XK_Return, 2 },
};
-#define LAYERS 4
+static Key keys_dialer[KEYS] = {
+ { "Esc", XK_Escape, 1 },
+ { "1!", XK_1, 1 },
+ { "2@", XK_2, 1 },
+ { "3#", XK_3, 1 },
+ { "⌫Bksp", XK_BackSpace, 2 },
+ { 0 }, /* New row */
+
+ { "Shift", XK_Shift_L, 1 },
+ { "4$", XK_4, 1 },
+ { "5%", XK_5, 1 },
+ { "6^", XK_6, 1 },
+ { "-_", XK_minus, 1 },
+ { ",<", XK_comma, 1 },
+ { 0 }, /* New row */
+
+ { "abc", XK_Mode_switch, 1 },
+ { "7&", XK_7, 1 },
+ { "8*", XK_8, 1 },
+ { "9(", XK_9, 1 },
+ { "=+", XK_equal, 1 },
+ { "/?", XK_slash, 1 },
+ { 0 }, /* New row */
+
+ { "↺", XK_Cancel, 1},
+ { "", XK_space, 1 },
+ { "0)", XK_0, 1 },
+ { ".>", XK_period, 1 },
+ { "↲ Enter", XK_Return, 2},
+ { 0 }, /* New row */
+ { 0 }, /* Last item (double 0) */
+};
+
+#define LAYERS 5
static char* layer_names[LAYERS] = {
"en",
"symbols",
"functions",
+ "dialer",
"ru",
};
@@ -477,6 +511,7 @@ static Key* available_layers[LAYERS] = {
keys_en,
keys_symbols,
keys_functions,
+ keys_dialer,
keys_ru
};
diff --git a/svkbd.c b/svkbd.c
@@ -63,6 +63,7 @@ static void buttonrelease(XEvent *e);
static void cleanup(void);
static void configurenotify(XEvent *e);
static void countrows();
+static int countkeys(Key *k);
static void drawkeyboard(void);
static void drawkey(Key *k);
static void expose(XEvent *e);
@@ -77,6 +78,7 @@ static void simulate_keyrelease(KeySym keysym);
static void showoverlay(int idx);
static void hideoverlay();
static void cyclelayer();
+static void setlayer();
static void togglelayer();
static void unpress(Key *k, KeySym mod);
static void updatekeys();
@@ -109,6 +111,7 @@ static int rows = 0, ww = 0, wh = 0, wx = 0, wy = 0;
static char *name = "svkbd";
static int debug = 0;
static int numlayers = 0;
+static int numkeys = 0;
static KeySym ispressingkeysym;
@@ -130,7 +133,7 @@ motionnotify(XEvent *e)
XPointerMovedEvent *ev = &e->xmotion;
int i;
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].keysym && ev->x > keys[i].x
&& ev->x < keys[i].x + keys[i].w
&& ev->y > keys[i].y
@@ -221,7 +224,7 @@ cleanup(void) {
}
}
if (debug) { printf("Cleanup: simulating key release\n"); fflu…
- for (i = 0; i < LENGTH(keys); i++) {
+ for (i = 0; i < numkeys; i++) {
XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, keys[i].k…
}
}
@@ -253,18 +256,34 @@ void
countrows() {
int i = 0;
- for(i = 0, rows = 1; i < LENGTH(keys); i++) {
+ for(i = 0, rows = 1; i < numkeys; i++) {
if(keys[i].keysym == 0)
rows++;
}
}
+int
+countkeys(Key * layer) {
+ int keys = 0;
+ int i;
+
+ for(i = 0; i < KEYS; i++) {
+ if (i > 0 && layer[i].keysym == 0 && layer[i-1].keysym == 0) {
+ keys--;
+ break;
+ }
+ keys++;
+ }
+
+ return keys;
+}
+
void
drawkeyboard(void) {
int i;
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].keysym != 0)
drawkey(&keys[i]);
}
@@ -315,7 +334,7 @@ Key *
findkey(int x, int y) {
int i;
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].keysym && x > keys[i].x &&
x < keys[i].x + keys[i].w &&
y > keys[i].y && y < keys[i].y + keys[i].h) {
@@ -375,7 +394,7 @@ press(Key *k, KeySym mod) {
}
} else {
if (debug) { printf("Simulating press: %ld\n", k->keys…
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && IsModifierKey(keys[i].ke…
simulate_keypress(keys[i].keysym);
}
@@ -386,7 +405,7 @@ press(Key *k, KeySym mod) {
}
simulate_keypress(k->keysym);
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && IsModifierKey(keys[i].ke…
simulate_keyrelease(keys[i].keysym);
}
@@ -457,7 +476,7 @@ unpress(Key *k, KeySym mod) {
if (get_press_duration() < overlay_delay) {
if (debug) { printf("Delayed simulation of pre…
//simulate the press event, as we postponed it…
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && IsModifierKey(ke…
simulate_keypress(keys[i].keys…
}
@@ -484,7 +503,7 @@ unpress(Key *k, KeySym mod) {
}
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
simulate_keyrelease(keys[i].keysym);
keys[i].pressed = 0;
@@ -492,13 +511,13 @@ unpress(Key *k, KeySym mod) {
break;
}
}
- if(i != LENGTH(keys)) {
+ if(i != numkeys) {
if(pressedmod) {
simulate_keyrelease(mod);
}
pressedmod = 0;
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed) {
simulate_keyrelease(keys[i].keysym);
keys[i].pressed = 0;
@@ -634,7 +653,7 @@ setup(void) {
if(!ww)
ww = sw;
if(!wh)
- wh = sh * rows / 32;
+ wh = sh * rows / heightfactor;
if(!wx)
wx = 0;
@@ -645,7 +664,7 @@ setup(void) {
if(wy < 0)
wy = sh + wy - wh;
- for(i = 0; i < LENGTH(keys); i++)
+ for(i = 0; i < numkeys; i++)
keys[i].pressed = 0;
wa.override_redirect = !wmborder;
@@ -702,10 +721,10 @@ updatekeys() {
int x = 0, y = 0, h, base, r = rows;
h = (wh - 1) / rows;
- for(i = 0; i < LENGTH(keys); i++, r--) {
- for(j = i, base = 0; j < LENGTH(keys) && keys[j].keysym != 0; …
+ 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 < LENGTH(keys) && keys[i].keysym != 0; i++) {
+ 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;
@@ -720,23 +739,30 @@ updatekeys() {
void
usage(char *argv0) {
- fprintf(stderr, "usage: %s [-hdvDOl] [-g geometry] [-fn font]\n", argv…
+ fprintf(stderr, "usage: %s [-hdvDO] [-g geometry] [-fn font] [-l layer…
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, " -l - Comma separated list of layers to enab…
+ fprintf(stderr, " -s - Layer to select on program start\n");
+ fprintf(stderr, " -H [int] - Height fraction, one key row tak…
fprintf(stderr, " -fn [font] - Set font (Xft, e.g: DejaVu Sans:bold:s…
exit(1);
}
+void setlayer() {
+ numkeys = countkeys(layers[currentlayer]);
+ memcpy(&keys, layers[currentlayer], sizeof(Key) * numkeys);
+}
+
void
cyclelayer() {
currentlayer++;
if (currentlayer >= numlayers)
currentlayer = 0;
if (debug) { printf("Cycling to layer %d\n", currentlayer); fflush(std…
- memcpy(&keys, layers[currentlayer], sizeof(keys_en));
+ setlayer();
updatekeys();
drawkeyboard();
}
@@ -749,7 +775,7 @@ togglelayer() {
currentlayer = 1;
}
if (debug) { printf("Toggling layer %d\n", currentlayer); fflush(stdou…
- memcpy(&keys, layers[currentlayer], sizeof(keys_en));
+ setlayer();
updatekeys();
drawkeyboard();
}
@@ -760,7 +786,7 @@ showoverlay(int idx) {
if (debug) { printf("Showing overlay %d\n", idx); fflush(stdout); }
int i,j;
//unpress existing key (visually only)
- for(i = 0; i < LENGTH(keys); i++) {
+ for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
keys[i].pressed = 0;
drawkey(&keys[i]);
@@ -804,21 +830,32 @@ sigterm(int sig)
void
-init_layers(char * layer_names_list) {
+init_layers(char * layer_names_list, const char * initial_layer_name) {
+ int j;
if (layer_names_list == NULL) {
numlayers = LAYERS;
memcpy(&layers, &available_layers, sizeof(available_layers));
+ if (initial_layer_name != NULL) {
+ for (j = 0; j < LAYERS; j++) {
+ if (strcmp(layer_names[j], initial_layer_name)…
+ currentlayer = j;
+ break;
+ }
+ }
+ }
} else {
char * s;
- int j;
s = strtok(layer_names_list, ",");
while (s != NULL) {
if (numlayers+1 > LAYERS) die("too many layers specifi…
int found = 0;
for (j = 0; j < LAYERS; j++) {
if (strcmp(layer_names[j], s) == 0) {
+ fprintf(stderr, "Adding layer %s\n", s…
layers[numlayers] = available_layers[j…
- printf("Adding layer %s\n", s);
+ if (initial_layer_name != NULL && strc…
+ currentlayer = numlayers;
+ }
found = 1;
break;
}
@@ -831,17 +868,19 @@ init_layers(char * layer_names_list) {
s = strtok(NULL,",");
}
}
+ setlayer();
}
int
main(int argc, char *argv[]) {
int i, xr, yr, bitm;
unsigned int wr, hr;
+ char * initial_layer_name = NULL;
char * layer_names_list = NULL;
- memcpy(&keys, &keys_en, sizeof(keys_en));
signal(SIGTERM, sigterm);
+ //parse environment variables
const char* enableoverlays_env = getenv("SVKBD_ENABLEOVERLAYS");
if (enableoverlays_env != NULL) enableoverlays = atoi(enableoverlays_e…
const char* layers_env = getenv("SVKBD_LAYERS");
@@ -849,8 +888,11 @@ main(int argc, char *argv[]) {
layer_names_list = malloc(128);
strcpy(layer_names_list, layers_env);
}
+ const char* heightfactor_s = getenv("SVKBD_HEIGHTFACTOR");
+ if (heightfactor_s != NULL)
+ heightfactor = atoi(heightfactor_s);
-
+ //parse command line arguments
for (i = 1; argv[i]; i++) {
if(!strcmp(argv[i], "-v")) {
die("svkbd-"VERSION", © 2006-2020 svkbd engineers,"
@@ -888,11 +930,22 @@ main(int argc, char *argv[]) {
if(i >= argc - 1)
continue;
if (layer_names_list == NULL) layer_names_list = mallo…
- strcpy(layer_names_list, argv[i+1]);
+ strcpy(layer_names_list, argv[++i]);
+ } else if(!strcmp(argv[i], "-s")) {
+ if(i >= argc - 1)
+ continue;
+ initial_layer_name = argv[++i];
+ } else if(!strcmp(argv[i], "-H")) {
+ if(i >= argc - 1)
+ continue;
+ heightfactor = atoi(argv[++i]);
+ } else {
+ fprintf(stderr, "Invalid argument: %s\n", argv[i]);
+ exit(2);
}
}
- init_layers(layer_names_list);
+ init_layers(layer_names_list, initial_layer_name);
if(!setlocale(LC_CTYPE, "") || !XSupportsLocale())
fprintf(stderr, "warning: no locale support\n");
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.