Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add command autorepeat and command2() (#569) #700

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 71 additions & 14 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* © 2019 Raheman Vaiya (see also: LICENSE).
*/

#include <alloca.h>
#include <assert.h>
#include <fcntl.h>
#include <limits.h>
Expand Down Expand Up @@ -517,21 +518,74 @@ int parse_macro_expression(const char *s, struct macro *macro)
return macro_parse(ptr, macro) == 0 ? 0 : 1;
}

static int parse_command(const char *s, struct command *command)
static int parse_command(const char *s, struct command *command, char **args, struct descriptor *d)
{
int len = strlen(s);

if (len == 0 || strstr(s, "command(") != s || s[len-1] != ')')
if (len == 0 || strstr(s, "command") != s || s[len-1] != ')')
return -1;

if (len > (int)sizeof(command->cmd)) {
err("max command length (%ld) exceeded\n", sizeof(command->cmd));
return 1;
}
if (s[7] == '(') {
if (len-7 > (int)sizeof(command->cmd)) {
err("max command length (%ld) exceeded\n", sizeof(command->cmd));
return 1;
}

if (!strlen(s+9)) {
err("command requires 1 argument");
return 1;
}

strcpy(command->cmd, s+8);
command->cmd[len-9] = 0;
str_escape(command->cmd);
d->op = OP_COMMAND;

strcpy(command->cmd, s+8);
command->cmd[len-9] = 0;
str_escape(command->cmd);
return 0;
} else if (s[7] == '2' && s[8] == '(') {
size_t nargs = 0;
char *c = alloca(strlen(s+9)+1);
strcpy(c, s+9);

for (int i=0; i<=2; i++){
while (*c == ' ')
c++;

args[i] = c;
if (i < 2) {
while (*c != ',' && *c)
c++;

if (c != args[i] && *c)
(nargs)++;

*c++ = 0;
} else {
c[strlen(c)-1] = 0;
(nargs)++;
}
}

if (nargs < 3) {
err("command2 requires 3 arguments");
return 1;
}

if (strlen(c)+1 > (int)sizeof(command->cmd)) {
err("max command length (%ld) exceeded\n", sizeof(command->cmd));
return 1;
}

strcpy(command->cmd, args[2]);
str_escape(command->cmd);

d->op = OP_COMMAND2;
d->args[1].timeout = atoi(args[0]);
d->args[2].timeout = atoi(args[1]);

return 0;
} else {
return -1;
}

return 0;
}
Expand Down Expand Up @@ -580,7 +634,7 @@ static int parse_descriptor(char *s,
d->args[1].mods = mods;

return 0;
} else if ((ret=parse_command(s, &cmd)) >= 0) {
} else if ((ret=parse_command(s, &cmd, args, d)) >= 0) {
if (ret) {
return -1;
}
Expand All @@ -590,10 +644,7 @@ static int parse_descriptor(char *s,
return -1;
}


d->op = OP_COMMAND;
d->args[0].idx = config->nr_commands;

config->commands[config->nr_commands++] = cmd;

return 0;
Expand Down Expand Up @@ -738,6 +789,8 @@ static void parse_global_section(struct config *config, struct ini_section *sect

if (!strcmp(ent->key, "macro_timeout"))
config->macro_timeout = atoi(ent->val);
else if (!strcmp(ent->key, "command_timeout"))
config->command_timeout = atoi(ent->val);
else if (!strcmp(ent->key, "macro_sequence_timeout"))
config->macro_sequence_timeout = atoi(ent->val);
else if (!strcmp(ent->key, "disable_modifier_guard"))
Expand All @@ -753,6 +806,8 @@ static void parse_global_section(struct config *config, struct ini_section *sect
"%s", ent->val);
else if (!strcmp(ent->key, "macro_repeat_timeout"))
config->macro_repeat_timeout = atoi(ent->val);
else if (!strcmp(ent->key, "command_repeat_timeout"))
config->command_repeat_timeout = atoi(ent->val);
else if (!strcmp(ent->key, "layer_indicator"))
config->layer_indicator = atoi(ent->val);
else if (!strcmp(ent->key, "overload_tap_timeout"))
Expand Down Expand Up @@ -944,6 +999,8 @@ static void config_init(struct config *config)

config->macro_timeout = 600;
config->macro_repeat_timeout = 50;
config->command_timeout = 0;
config->command_repeat_timeout = 0;
}

int config_parse(struct config *config, const char *path)
Expand Down
3 changes: 3 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ enum op {
OP_MACRO,
OP_MACRO2,
OP_COMMAND,
OP_COMMAND2,
OP_TIMEOUT,

/* Experimental */
Expand Down Expand Up @@ -137,6 +138,8 @@ struct config {
long macro_sequence_timeout;
long macro_repeat_timeout;
long oneshot_timeout;
long command_timeout;
long command_repeat_timeout;

long overload_tap_timeout;

Expand Down
25 changes: 24 additions & 1 deletion src/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,7 @@ static void clear(struct keyboard *kbd)
}

kbd->active_macro = NULL;
kbd->active_command = NULL;

reset_keystate(kbd);
}
Expand Down Expand Up @@ -727,11 +728,22 @@ static long process_descriptor(struct keyboard *kbd, uint8_t code,
}

break;
case OP_COMMAND2:
case OP_COMMAND:
if (pressed) {
if (d->op == OP_COMMAND2) {
timeout = d->args[1].timeout;
kbd->command_repeat_interval = d->args[2].timeout;
} else {
timeout = kbd->config.command_timeout;
kbd->command_repeat_interval = kbd->config.command_repeat_timeout;
}
execute_command(kbd->config.commands[d->args[0].idx].cmd);
kbd->active_command = kbd->config.commands[d->args[0].idx].cmd;
clear_oneshot(kbd);
update_mods(kbd, -1, 0);

kbd->command_timeout = time + timeout;
schedule_timeout(kbd, kbd->command_timeout);
}
break;
case OP_SWAP:
Expand Down Expand Up @@ -1146,6 +1158,17 @@ static long process_event(struct keyboard *kbd, uint8_t code, int pressed, long
}
}

if (kbd->active_command) {
if (code) {
kbd->active_command = NULL;
update_mods(kbd, -1, 0);
} else if (time >= kbd->command_timeout) {
execute_command(kbd->active_command);
kbd->command_timeout = time+kbd->command_repeat_interval;
schedule_timeout(kbd, kbd->command_timeout);
}
}

if (code) {
struct descriptor d;
int dl = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/keyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@ struct keyboard {
uint8_t inhibit_modifier_guard;

struct macro *active_macro;
const char *active_command;
int active_macro_layer;
int overload_last_layer_code;

long macro_timeout;
long oneshot_timeout;
long command_timeout;

long macro_repeat_interval;
long command_repeat_interval;

long overload_start_time;

Expand Down