Beispiel #1
0
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;
}
Beispiel #3
0
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, &macro)) {
			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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}