cleaned up code style, fixed buffer overflow in layers configuration, added a printdbg function.

This commit is contained in:
Maarten van Gompel 2020-08-02 20:57:06 +02:00 committed by Hiltjo Posthuma
parent 8219b6b9d1
commit 3d03b522e0
1 changed files with 55 additions and 47 deletions

102
svkbd.c
View File

@ -57,6 +57,7 @@ typedef struct {
} Buttonmod; } Buttonmod;
/* function declarations */ /* function declarations */
static void printdbg(const char * fmt, ...);
static void motionnotify(XEvent *e); static void motionnotify(XEvent *e);
static void buttonpress(XEvent *e); static void buttonpress(XEvent *e);
static void buttonrelease(XEvent *e); static void buttonrelease(XEvent *e);
@ -103,9 +104,9 @@ static KeySym pressedmod = 0;
static struct timeval pressbegin; static struct timeval pressbegin;
static int currentlayer = 0; static int currentlayer = 0;
static int enableoverlays = 1; static int enableoverlays = 1;
static int currentoverlay = -1; // -1 = no overlay static int currentoverlay = -1; /* -1 = no overlay */
static KeySym overlaykeysym = 0; //keysym for which the overlay is presented 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 releaseprotect = 0; /* set to 1 after overlay is shown, protecting against immediate release */
static int tmp_keycode = 1; static int tmp_keycode = 1;
static int rows = 0, ww = 0, wh = 0, wx = 0, wy = 0; static int rows = 0, ww = 0, wh = 0, wx = 0, wy = 0;
static char *name = "svkbd"; static char *name = "svkbd";
@ -348,7 +349,7 @@ leavenotify(XEvent *e) {
} }
void record_press_begin(KeySym ks) { void record_press_begin(KeySym ks) {
//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 */
gettimeofday(&pressbegin, NULL); gettimeofday(&pressbegin, NULL);
ispressingkeysym = ks; ispressingkeysym = ks;
} }
@ -359,7 +360,7 @@ press(Key *k, KeySym mod) {
int overlayidx = -1; int overlayidx = -1;
k->pressed = !k->pressed; k->pressed = !k->pressed;
if (debug) { printf("Begin press: %ld\n", k->keysym); fflush(stdout); } if (debug) printdbg("Begin press: %ld\n", k->keysym);
pressbegin.tv_sec = 0; pressbegin.tv_sec = 0;
pressbegin.tv_usec = 0; pressbegin.tv_usec = 0;
ispressingkeysym = 0; ispressingkeysym = 0;
@ -369,11 +370,11 @@ press(Key *k, KeySym mod) {
overlayidx = hasoverlay(k->keysym); overlayidx = hasoverlay(k->keysym);
if (enableoverlays && overlayidx != -1) { if (enableoverlays && overlayidx != -1) {
if (!pressbegin.tv_sec && !pressbegin.tv_usec) { if (!pressbegin.tv_sec && !pressbegin.tv_usec) {
//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); record_press_begin(k->keysym);
} }
} else { } else {
if (debug) { printf("Simulating press: %ld\n", k->keysym); fflush(stdout); } if (debug) printdbg("Simulating press: %ld\n", k->keysym);
for(i = 0; i < numkeys; i++) { for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && IsModifierKey(keys[i].keysym)) { if(keys[i].pressed && IsModifierKey(keys[i].keysym)) {
simulate_keypress(keys[i].keysym); simulate_keypress(keys[i].keysym);
@ -454,8 +455,8 @@ unpress(Key *k, KeySym mod) {
if ((pressbegin.tv_sec || pressbegin.tv_usec) && enableoverlays && k && k->keysym == ispressingkeysym) { if ((pressbegin.tv_sec || pressbegin.tv_usec) && enableoverlays && k && k->keysym == ispressingkeysym) {
if (currentoverlay == -1) { if (currentoverlay == -1) {
if (get_press_duration() < overlay_delay) { if (get_press_duration() < overlay_delay) {
if (debug) { printf("Delayed simulation of press after release: %ld\n", k->keysym); fflush(stdout); } if (debug) printdbg("Delayed simulation of press after release: %ld\n", k->keysym);
//simulate the press event, as we postponed it earlier in press() /* simulate the press event, as we postponed it earlier in press() */
for(i = 0; i < numkeys; i++) { for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && IsModifierKey(keys[i].keysym)) { if(keys[i].pressed && IsModifierKey(keys[i].keysym)) {
simulate_keypress(keys[i].keysym); simulate_keypress(keys[i].keysym);
@ -476,9 +477,9 @@ unpress(Key *k, KeySym mod) {
if (debug) { if (debug) {
if (k) { if (k) {
printf("Simulation of release: %ld\n", k->keysym); fflush(stdout); printdbg("Simulation of release: %ld\n", k->keysym);
} else { } else {
printf("Simulation of release (all keys)\n"); fflush(stdout); printdbg("Simulation of release (all keys)\n");
} }
} }
@ -530,7 +531,6 @@ run(void) {
tv.tv_sec = 1; tv.tv_sec = 1;
//XSync(dpy, False);
XFlush(dpy); XFlush(dpy);
while (running) { while (running) {
@ -546,12 +546,12 @@ run(void) {
} }
} }
} else { } else {
//time-out expired without anything interesting happening, check for long-presses /* time-out expired without anything interesting happening, check for long-presses */
if (ispressing && ispressingkeysym) { if (ispressing && ispressingkeysym) {
duration = get_press_duration(); duration = get_press_duration();
if (debug == 2) { printf("%f\n", duration); fflush(stdout); } if (debug == 2) printdbg("%f\n", duration);
if (get_press_duration() >= overlay_delay) { if (get_press_duration() >= overlay_delay) {
if (debug) { printf("press duration %f\n", duration); fflush(stdout); } if (debug) printdbg("press duration %f\n", duration);
showoverlay(hasoverlay(ispressingkeysym)); showoverlay(hasoverlay(ispressingkeysym));
pressbegin.tv_sec = 0; pressbegin.tv_sec = 0;
pressbegin.tv_usec = 0; pressbegin.tv_usec = 0;
@ -559,20 +559,20 @@ run(void) {
} }
} }
} }
if (r == -1 || sigtermd) { if (r == -1 || sigtermd) {
// an error occurred or we received a signal /* an error occurred or we received a signal */
// E.g. Generally in scripts we want to call SIGTERM on svkbd in which case /* 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 if the user is holding for example the enter key (to execute
// the kill or script that does the kill), that causes an issue the kill or script that does the kill), that causes an issue
// since then X doesn't know the keyup is never coming.. (since since then X doesn't know the keyup is never coming.. (since
// process will be dead before finger lifts - in that case we process will be dead before finger lifts - in that case we
// just trigger out fake up presses for all keys just trigger out fake up presses for all keys */
if (debug) { printf("signal received, releasing all keys"); fflush(stdout); } if (debug) printdbg("signal received, releasing all keys");
for (i = 0; i < numkeys; i++) { for (i = 0; i < numkeys; i++) {
XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, keys[i].keysym), False, 0); XTestFakeKeyEvent(dpy, XKeysymToKeycode(dpy, keys[i].keysym), False, 0);
} }
running = False; running = False;
} }
} }
} }
@ -610,7 +610,7 @@ setup(void) {
die("no fonts could be loaded."); die("no fonts could be loaded.");
drw_setscheme(drw, scheme[SchemeNorm]); drw_setscheme(drw, scheme[SchemeNorm]);
//find an unused keycode to use as a temporary keycode (derived from source: https://stackoverflow.com/questions/44313966/c-xtest-emitting-key-presses-for-every-unicode-character) /* find an unused keycode to use as a temporary keycode (derived from source: https://stackoverflow.com/questions/44313966/c-xtest-emitting-key-presses-for-every-unicode-character) */
KeySym *keysyms = NULL; KeySym *keysyms = NULL;
int keysyms_per_keycode = 0; int keysyms_per_keycode = 0;
int keycode_low, keycode_high; int keycode_low, keycode_high;
@ -743,7 +743,7 @@ usage(char *argv0) {
fprintf(stderr, " -O - Disable overlays\n"); fprintf(stderr, " -O - Disable overlays\n");
fprintf(stderr, " -l - Comma separated list of layers to enable\n"); fprintf(stderr, " -l - Comma separated list of layers to enable\n");
fprintf(stderr, " -s - Layer to select on program start\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");
fprintf(stderr, " -fn [font] - Set font (Xft, e.g: DejaVu Sans:bold:size=20)\n"); fprintf(stderr, " -fn [font] - Set font (Xft, e.g: DejaVu Sans:bold:size=20)\n");
exit(1); exit(1);
} }
@ -758,7 +758,7 @@ cyclelayer() {
currentlayer++; currentlayer++;
if (currentlayer >= numlayers) if (currentlayer >= numlayers)
currentlayer = 0; currentlayer = 0;
if (debug) { printf("Cycling to layer %d\n", currentlayer); fflush(stdout); } if (debug) printdbg("Cycling to layer %d\n", currentlayer);
setlayer(); setlayer();
updatekeys(); updatekeys();
drawkeyboard(); drawkeyboard();
@ -771,7 +771,7 @@ togglelayer() {
} else if (numlayers > 1) { } else if (numlayers > 1) {
currentlayer = 1; currentlayer = 1;
} }
if (debug) { printf("Toggling layer %d\n", currentlayer); fflush(stdout); } if (debug) printdbg("Toggling layer %d\n", currentlayer);
setlayer(); setlayer();
updatekeys(); updatekeys();
drawkeyboard(); drawkeyboard();
@ -780,9 +780,9 @@ togglelayer() {
void void
showoverlay(int idx) { showoverlay(int idx) {
if (debug) { printf("Showing overlay %d\n", idx); fflush(stdout); } if (debug) printdbg("Showing overlay %d\n", idx);
int i,j; int i,j;
//unpress existing key (visually only) /* unpress existing key (visually only) */
for(i = 0; i < numkeys; i++) { for(i = 0; i < numkeys; i++) {
if(keys[i].pressed && !IsModifierKey(keys[i].keysym)) { if(keys[i].pressed && !IsModifierKey(keys[i].keysym)) {
keys[i].pressed = 0; keys[i].pressed = 0;
@ -809,7 +809,7 @@ showoverlay(int idx) {
void void
hideoverlay() { hideoverlay() {
if (debug) { printf("Hiding overlay %d\n", currentoverlay); fflush(stdout); } if (debug) printdbg("Hiding overlay %d\n", currentoverlay);
currentoverlay = -1; currentoverlay = -1;
overlaykeysym = 0; overlaykeysym = 0;
currentlayer = -1; currentlayer = -1;
@ -822,7 +822,7 @@ sigterm(int sig)
{ {
running = False; running = False;
sigtermd = True; sigtermd = True;
if (debug) { printf("Sigterm received\n"); fflush(stdout); } if (debug) printdbg("Sigterm received\n");
} }
@ -868,6 +868,15 @@ init_layers(char * layer_names_list, const char * initial_layer_name) {
setlayer(); setlayer();
} }
void
printdbg(const char * fmt, ...) {
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
fflush(stderr);
}
int int
main(int argc, char *argv[]) { main(int argc, char *argv[]) {
int i, xr, yr, bitm; int i, xr, yr, bitm;
@ -878,24 +887,24 @@ main(int argc, char *argv[]) {
signal(SIGTERM, sigterm); signal(SIGTERM, sigterm);
//parse environment variables /* parse environment variables */
if (OVERLAYS <= 1) { if (OVERLAYS <= 1) {
enableoverlays = 0; enableoverlays = 0;
} else { } else {
const char* enableoverlays_env = getenv("SVKBD_ENABLEOVERLAYS"); const char* enableoverlays_env = getenv("SVKBD_ENABLEOVERLAYS");
if (enableoverlays_env != NULL) enableoverlays = atoi(enableoverlays_env); if (enableoverlays_env != NULL) enableoverlays = atoi(enableoverlays_env);
} }
const char* layers_env = getenv("SVKBD_LAYERS"); const char* layers_env = getenv("SVKBD_LAYERS");
if (layers_env != NULL) { if (layers_env != NULL) {
layer_names_list = malloc(128); if (!strdup(layer_names_list, layers_env)) {
if (!layer_names_list) die("memory allocation error\n"); die("memory allocation error\n");
strcpy(layer_names_list, layers_env); }
} }
const char* heightfactor_s = getenv("SVKBD_HEIGHTFACTOR"); const char* heightfactor_s = getenv("SVKBD_HEIGHTFACTOR");
if (heightfactor_s != NULL) if (heightfactor_s != NULL)
heightfactor = atoi(heightfactor_s); heightfactor = atoi(heightfactor_s);
//parse command line arguments /* parse command line arguments */
for (i = 1; argv[i]; i++) { for (i = 1; argv[i]; i++) {
if(!strcmp(argv[i], "-v")) { if(!strcmp(argv[i], "-v")) {
die("svkbd-"VERSION", © 2006-2020 svkbd engineers," die("svkbd-"VERSION", © 2006-2020 svkbd engineers,"
@ -932,11 +941,10 @@ main(int argc, char *argv[]) {
} else if(!strcmp(argv[i], "-l")) { } else if(!strcmp(argv[i], "-l")) {
if(i >= argc - 1) if(i >= argc - 1)
continue; continue;
if (layer_names_list == NULL) { free(layer_names_list);
layer_names_list = malloc(128); if (!strdup(layer_names_list, argv[++i])) {
if (!layer_names_list) die("memory allocation error\n"); die("memory allocation error\n");
} }
strcpy(layer_names_list, argv[++i]);
} else if(!strcmp(argv[i], "-s")) { } else if(!strcmp(argv[i], "-s")) {
if(i >= argc - 1) if(i >= argc - 1)
continue; continue;