static int ratbag_cmd_button_set_key(const struct ratbag_cmd *cmd, struct ratbag *ratbag, struct ratbag_cmd_options *options, int argc, char **argv) { struct ratbag_device *device; struct ratbag_button *button; int keycode; char *str; int rc; if (argc < 1) return ERR_USAGE; str = argv[0]; keycode = libevdev_event_code_from_name(EV_KEY, str); if (keycode == -1) { error("Failed to resolve keycode '%s'\n", str); return ERR_USAGE; } device = options->device; if (!ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY)) return ERR_UNSUPPORTED; button = options->button; rc = ratbag_button_set_key(button, keycode, NULL, 0); if (rc != 0) return ERR_DEVICE; return SUCCESS; }
static int parse_event_code(int type, const char *str) { int code; code = libevdev_event_code_from_name(type, str); if (code != -1) return code; if (safe_atoi(str, &code)) return code; return -1; }
static int ratbag_cmd_change_button(const struct ratbag_cmd *cmd, struct ratbag *ratbag, struct ratbag_cmd_options *options, int argc, char **argv) { const char *action_str, *action_arg; struct ratbag_device *device; struct ratbag_button *button = NULL; struct ratbag_profile *profile = NULL; struct ratbag_button_macro *m = NULL; int button_index; enum ratbag_button_action_type action_type; int rc = ERR_DEVICE; unsigned int btnkey; enum ratbag_button_action_special special; struct macro macro = {0}; int i; if (argc != 3) return ERR_USAGE; button_index = atoi(argv[0]); action_str = argv[1]; action_arg = argv[2]; argc -= 3; argv += 3; if (streq(action_str, "button")) { action_type = RATBAG_BUTTON_ACTION_TYPE_BUTTON; btnkey = atoi(action_arg); } else if (streq(action_str, "key")) { action_type = RATBAG_BUTTON_ACTION_TYPE_KEY; btnkey = libevdev_event_code_from_name(EV_KEY, action_arg); if (!btnkey) { error("Failed to resolve key %s\n", action_arg); return ERR_USAGE; } } else if (streq(action_str, "special")) { action_type = RATBAG_BUTTON_ACTION_TYPE_SPECIAL; special = str_to_special_action(action_arg); if (special == RATBAG_BUTTON_ACTION_SPECIAL_INVALID) { error("Invalid special command '%s'\n", action_arg); return ERR_USAGE; } } else if (streq(action_str, "macro")) { action_type = RATBAG_BUTTON_ACTION_TYPE_MACRO; if (str_to_macro(action_arg, ¯o)) { error("Invalid special command '%s'\n", action_arg); return ERR_USAGE; } } else { return ERR_USAGE; } device = options->device; profile = options->profile; if (!ratbag_device_has_capability(device, RATBAG_DEVICE_CAP_BUTTON_KEY)) { error("Device '%s' has no programmable buttons\n", ratbag_device_get_name(device)); rc = ERR_UNSUPPORTED; goto out; } button = ratbag_profile_get_button(profile, button_index); if (!button) { error("Invalid button number %d\n", button_index); rc = ERR_UNSUPPORTED; goto out; } switch (action_type) { case RATBAG_BUTTON_ACTION_TYPE_BUTTON: rc = ratbag_button_set_button(button, btnkey); break; case RATBAG_BUTTON_ACTION_TYPE_KEY: rc = ratbag_button_set_key(button, btnkey, NULL, 0); break; case RATBAG_BUTTON_ACTION_TYPE_SPECIAL: rc = ratbag_button_set_special(button, special); break; case RATBAG_BUTTON_ACTION_TYPE_MACRO: m = ratbag_button_macro_new(macro.name); for (i = 0; i < ARRAY_LENGTH(macro.events); i++) { if (macro.events[i].type == RATBAG_MACRO_EVENT_NONE) break; ratbag_button_macro_set_event(m, i, macro.events[i].type, macro.events[i].data); } rc = ratbag_button_set_macro(button, m); ratbag_button_macro_unref(m); break; default: error("well, that shouldn't have happened\n"); abort(); break; } if (rc) { error("Unable to perform button %d mapping %s %s\n", button_index, action_str, action_arg); rc = ERR_UNSUPPORTED; goto out; } rc = ratbag_profile_set_active(profile); if (rc) { error("Unable to apply the current profile: %s (%d)\n", strerror(-rc), rc); rc = ERR_DEVICE; goto out; } out: button = ratbag_button_unref(button); return rc; }
static int str_to_macro(const char *action_arg, struct macro *m) { char *str, *s; enum ratbag_macro_event_type type; int code; int idx = 0; int rc = ERR_USAGE; /* FIXME: handle per-device maximum lengths of macros */ if (!action_arg) return -EINVAL; str = strdup_safe(action_arg); s = str; m->name = "<cmdline>"; while (idx < ARRAY_LENGTH(m->events)) { char *token; token = strsep(&s, " "); if (!token) break; if (strlen(token) == 0) continue; switch(token[0]) { case '+': type = RATBAG_MACRO_EVENT_KEY_PRESSED; token++; break; case '-': type = RATBAG_MACRO_EVENT_KEY_RELEASED; token++; break; case 't': type = RATBAG_MACRO_EVENT_WAIT; token++; break; default: type = RATBAG_MACRO_EVENT_NONE; break; } if (type == RATBAG_MACRO_EVENT_WAIT) { char *endptr; code = strtol(token, &endptr, 10); if (*endptr != '\0') { error("Invalid token name: %s\n", token); goto out; } } else { code = libevdev_event_code_from_name(EV_KEY, token); if (code == -1) { error("Invalid token name: %s\n", token); goto out; } } if (type == RATBAG_MACRO_EVENT_NONE) { m->events[idx].type = RATBAG_MACRO_EVENT_KEY_PRESSED; m->events[idx].data = code; type = RATBAG_MACRO_EVENT_KEY_RELEASED; idx++; } m->events[idx].data = code; m->events[idx].type = type; idx++; } rc = SUCCESS; out: free(str); return rc; }
int tools_parse_args(int argc, char **argv, struct tools_context *context) { struct tools_options *options = &context->options; while (1) { int c; int option_index = 0; static struct option opts[] = { { "device", 1, 0, OPT_DEVICE }, { "udev", 0, 0, OPT_UDEV }, { "grab", 0, 0, OPT_GRAB }, { "help", 0, 0, OPT_HELP }, { "verbose", 0, 0, OPT_VERBOSE }, { "enable-tap", 0, 0, OPT_TAP_ENABLE }, { "disable-tap", 0, 0, OPT_TAP_DISABLE }, { "enable-drag", 0, 0, OPT_DRAG_ENABLE }, { "disable-drag", 0, 0, OPT_DRAG_DISABLE }, { "enable-drag-lock", 0, 0, OPT_DRAG_LOCK_ENABLE }, { "disable-drag-lock", 0, 0, OPT_DRAG_LOCK_DISABLE }, { "enable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_ENABLE }, { "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE }, { "enable-left-handed", 0, 0, OPT_LEFT_HANDED_ENABLE }, { "disable-left-handed", 0, 0, OPT_LEFT_HANDED_DISABLE }, { "enable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_ENABLE }, { "disable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_DISABLE }, { "enable-dwt", 0, 0, OPT_DWT_ENABLE }, { "disable-dwt", 0, 0, OPT_DWT_DISABLE }, { "set-click-method", 1, 0, OPT_CLICK_METHOD }, { "set-scroll-method", 1, 0, OPT_SCROLL_METHOD }, { "set-scroll-button", 1, 0, OPT_SCROLL_BUTTON }, { "set-profile", 1, 0, OPT_PROFILE }, { "speed", 1, 0, OPT_SPEED }, { 0, 0, 0, 0} }; c = getopt_long(argc, argv, "h", opts, &option_index); if (c == -1) break; #ifndef __linux__ program_invocation_short_name = argv[0]; #endif switch(c) { case 'h': case OPT_HELP: tools_usage(); exit(0); case OPT_DEVICE: options->backend = BACKEND_DEVICE; if (!optarg) { tools_usage(); return 1; } options->device = optarg; break; case OPT_UDEV: options->backend = BACKEND_UDEV; if (optarg) options->seat = optarg; break; case OPT_GRAB: options->grab = 1; break; case OPT_VERBOSE: options->verbose = 1; break; case OPT_TAP_ENABLE: options->tapping = 1; break; case OPT_TAP_DISABLE: options->tapping = 0; break; case OPT_DRAG_ENABLE: options->drag = 1; break; case OPT_DRAG_DISABLE: options->drag = 0; break; case OPT_DRAG_LOCK_ENABLE: options->drag_lock = 1; break; case OPT_DRAG_LOCK_DISABLE: options->drag_lock = 0; break; case OPT_NATURAL_SCROLL_ENABLE: options->natural_scroll = 1; break; case OPT_NATURAL_SCROLL_DISABLE: options->natural_scroll = 0; break; case OPT_LEFT_HANDED_ENABLE: options->left_handed = 1; break; case OPT_LEFT_HANDED_DISABLE: options->left_handed = 0; break; case OPT_MIDDLEBUTTON_ENABLE: options->middlebutton = 1; break; case OPT_MIDDLEBUTTON_DISABLE: options->middlebutton = 0; break; case OPT_DWT_ENABLE: options->dwt = LIBINPUT_CONFIG_DWT_ENABLED; break; case OPT_DWT_DISABLE: options->dwt = LIBINPUT_CONFIG_DWT_DISABLED; break; case OPT_CLICK_METHOD: if (!optarg) { tools_usage(); return 1; } if (streq(optarg, "none")) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE; } else if (streq(optarg, "clickfinger")) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; } else if (streq(optarg, "buttonareas")) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; } else { tools_usage(); return 1; } break; case OPT_SCROLL_METHOD: if (!optarg) { tools_usage(); return 1; } if (streq(optarg, "none")) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL; } else if (streq(optarg, "twofinger")) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; } else if (streq(optarg, "edge")) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE; } else if (streq(optarg, "button")) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; } else { tools_usage(); return 1; } break; case OPT_SCROLL_BUTTON: if (!optarg) { tools_usage(); return 1; } options->scroll_button = libevdev_event_code_from_name(EV_KEY, optarg); if (options->scroll_button == -1) { fprintf(stderr, "Invalid button %s\n", optarg); return 1; } break; case OPT_SPEED: if (!optarg) { tools_usage(); return 1; } options->speed = atof(optarg); break; case OPT_PROFILE: if (!optarg) { tools_usage(); return 1; } if (streq(optarg, "adaptive")) { options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE; } else if (streq(optarg, "flat")) { options->profile = LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT; } else { tools_usage(); return 1; } break; default: tools_usage(); return 1; } } if (optind < argc) { tools_usage(); return 1; } return 0; }
int tools_parse_args(int argc, char **argv, struct tools_options *options) { while (1) { int c; int option_index = 0; static struct option opts[] = { { "device", 1, 0, OPT_DEVICE }, { "udev", 0, 0, OPT_UDEV }, { "help", 0, 0, OPT_HELP }, { "verbose", 0, 0, OPT_VERBOSE }, { "enable-tap", 0, 0, OPT_TAP_ENABLE }, { "disable-tap", 0, 0, OPT_TAP_DISABLE }, { "enable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_ENABLE }, { "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE }, { "enable-left-handed", 0, 0, OPT_LEFT_HANDED_ENABLE }, { "disable-left-handed", 0, 0, OPT_LEFT_HANDED_DISABLE }, { "enable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_ENABLE }, { "disable-middlebutton", 0, 0, OPT_MIDDLEBUTTON_DISABLE }, { "set-click-method", 1, 0, OPT_CLICK_METHOD }, { "set-scroll-method", 1, 0, OPT_SCROLL_METHOD }, { "set-scroll-button", 1, 0, OPT_SCROLL_BUTTON }, { "speed", 1, 0, OPT_SPEED }, { 0, 0, 0, 0} }; c = getopt_long(argc, argv, "h", opts, &option_index); if (c == -1) break; switch(c) { case 'h': /* --help */ case OPT_HELP: tools_usage(); exit(0); case OPT_DEVICE: /* --device */ options->backend = BACKEND_DEVICE; if (!optarg) { tools_usage(); return 1; } options->device = optarg; break; case OPT_UDEV: /* --udev */ options->backend = BACKEND_UDEV; if (optarg) options->seat = optarg; break; case OPT_VERBOSE: /* --verbose */ options->verbose = 1; break; case OPT_TAP_ENABLE: options->tapping = 1; break; case OPT_TAP_DISABLE: options->tapping = 0; break; case OPT_NATURAL_SCROLL_ENABLE: options->natural_scroll = 1; break; case OPT_NATURAL_SCROLL_DISABLE: options->natural_scroll = 0; break; case OPT_LEFT_HANDED_ENABLE: options->left_handed = 1; break; case OPT_LEFT_HANDED_DISABLE: options->left_handed = 0; break; case OPT_MIDDLEBUTTON_ENABLE: options->middlebutton = 1; break; case OPT_MIDDLEBUTTON_DISABLE: options->middlebutton = 0; break; case OPT_CLICK_METHOD: if (!optarg) { tools_usage(); return 1; } if (strcmp(optarg, "none") == 0) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_NONE; } else if (strcmp(optarg, "clickfinger") == 0) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER; } else if (strcmp(optarg, "buttonareas") == 0) { options->click_method = LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS; } else { tools_usage(); return 1; } break; case OPT_SCROLL_METHOD: if (!optarg) { tools_usage(); return 1; } if (strcmp(optarg, "none") == 0) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_NO_SCROLL; } else if (strcmp(optarg, "twofinger") == 0) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_2FG; } else if (strcmp(optarg, "edge") == 0) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_EDGE; } else if (strcmp(optarg, "button") == 0) { options->scroll_method = LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN; } else { tools_usage(); return 1; } break; case OPT_SCROLL_BUTTON: if (!optarg) { tools_usage(); return 1; } options->scroll_button = libevdev_event_code_from_name(EV_KEY, optarg); if (options->scroll_button == -1) { fprintf(stderr, "Invalid button %s\n", optarg); return 1; } break; case OPT_SPEED: if (!optarg) { tools_usage(); return 1; } options->speed = atof(optarg); break; default: tools_usage(); return 1; } } if (optind < argc) { tools_usage(); return 1; } return 0; }