mirror of
https://cagebreak.project-repo.co/cagebreak.git
synced 2026-08-26 15:34:18 +02:00
Implement libinput device configuration
This commit is contained in:
parent
985b5f65db
commit
f9efd40c9d
9 changed files with 429 additions and 117 deletions
|
|
@ -1,4 +1,4 @@
|
|||
*
|
||||
/*
|
||||
* Cagebreak: A Wayland tiling compositor.
|
||||
*
|
||||
* Copyright (C) 2018-2020 Jente Hidskes
|
||||
|
|
@ -362,8 +362,6 @@ main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
server.input = input_manager_create(&server);
|
||||
fprintf(stderr, "input_manager_create:%d\n",wl_list_length(&server.input->devices));
|
||||
|
||||
|
||||
data_control_manager =
|
||||
wlr_data_control_manager_v1_create(server.wl_display);
|
||||
|
|
@ -599,6 +597,7 @@ end:
|
|||
wl_display_destroy(server.wl_display);
|
||||
wlr_output_layout_destroy(server.output_layout);
|
||||
|
||||
free(server.input);
|
||||
pango_cairo_font_map_set_default(NULL);
|
||||
cairo_debug_reset_static_data();
|
||||
FcFini();
|
||||
|
|
|
|||
8
input.h
8
input.h
|
|
@ -1,12 +1,16 @@
|
|||
#ifndef _LIBINPUT_H
|
||||
#define _LIBINPUT_H
|
||||
#ifndef _CG_INPUT_H
|
||||
#define _CG_INPUT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct cg_input_device;
|
||||
struct cg_input_config;
|
||||
struct cg_server;
|
||||
|
||||
void cg_input_configure_libinput_device(struct cg_input_device *device);
|
||||
|
||||
void cg_input_apply_config(struct cg_input_config *config, struct cg_server *server);
|
||||
|
||||
void cg_input_reset_libinput_device(struct cg_input_device *device);
|
||||
|
||||
bool cg_libinput_device_is_builtin(struct cg_input_device *device);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -210,58 +211,50 @@ struct cg_input_manager *input_manager_create(struct cg_server *server) {
|
|||
return input;
|
||||
}
|
||||
|
||||
static bool device_is_touchpad(struct cg_input_device *device) {
|
||||
if (device->wlr_device->type != WLR_INPUT_DEVICE_POINTER ||
|
||||
!wlr_input_device_is_libinput(device->wlr_device)) {
|
||||
return false;
|
||||
uint32_t get_mouse_bindsym(const char *name, char **error) {
|
||||
// Get event code from name
|
||||
int code = libevdev_event_code_from_name(EV_KEY, name);
|
||||
if (code == -1) {
|
||||
size_t len = snprintf(NULL, 0, "Unknown event %s", name) + 1;
|
||||
*error = malloc(len);
|
||||
if (*error) {
|
||||
snprintf(*error, len, "Unknown event %s", name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct libinput_device *libinput_device =
|
||||
wlr_libinput_get_device_handle(device->wlr_device);
|
||||
|
||||
return libinput_device_config_tap_get_finger_count(libinput_device) > 0;
|
||||
return code;
|
||||
}
|
||||
|
||||
const char *input_device_get_type(struct cg_input_device *device) {
|
||||
switch (device->wlr_device->type) {
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
if (device_is_touchpad(device)) {
|
||||
return "touchpad";
|
||||
} else {
|
||||
return "pointer";
|
||||
}
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
return "keyboard";
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
return "touch";
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
return "tablet_tool";
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
return "tablet_pad";
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
return "switch";
|
||||
uint32_t get_mouse_bindcode(const char *name, char **error) {
|
||||
// Validate event code
|
||||
errno = 0;
|
||||
char *endptr;
|
||||
int code = strtol(name, &endptr, 10);
|
||||
if (endptr == name && code <= 0) {
|
||||
*error = strdup("Button event code must be a positive integer.");
|
||||
return 0;
|
||||
} else if (errno == ERANGE) {
|
||||
*error = strdup("Button event code out of range.");
|
||||
return 0;
|
||||
}
|
||||
return "unknown";
|
||||
const char *event = libevdev_event_code_get_name(EV_KEY, code);
|
||||
if (!event || strncmp(event, "BTN_", strlen("BTN_")) != 0) {
|
||||
size_t len = snprintf(NULL, 0, "Event code %d (%s) is not a button",
|
||||
code, event ? event : "(null)") + 1;
|
||||
*error = malloc(len);
|
||||
if (*error) {
|
||||
snprintf(*error, len, "Event code %d (%s) is not a button",
|
||||
code, event ? event : "(null)");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
struct cg_input_config *input_device_get_config(struct cg_input_device *device) {
|
||||
struct cg_server *server=device->server;
|
||||
struct cg_input_config *wildcard_config = NULL;
|
||||
struct cg_input_config *config = NULL;
|
||||
wl_list_for_each(config, &server->input_config, link) {
|
||||
if (strcmp(config->identifier, device->identifier) == 0) {
|
||||
return config;
|
||||
} else if (strcmp(config->identifier, "*") == 0) {
|
||||
wildcard_config = config;
|
||||
}
|
||||
uint32_t input_manager_get_mouse_button(const char *name, char **error) {
|
||||
uint32_t button = get_mouse_bindsym(name, error);
|
||||
if (!button && !*error) {
|
||||
button = get_mouse_bindcode(name, error);
|
||||
}
|
||||
|
||||
const char *device_type = input_device_get_type(device);
|
||||
wl_list_for_each(config, &server->input_config, link) {
|
||||
if (strncmp(config->identifier,"type:",5)&&strcmp(config->identifier + 5, device_type) == 0) {
|
||||
return config;
|
||||
}
|
||||
}
|
||||
|
||||
return wildcard_config;
|
||||
return button;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@
|
|||
struct cg_input_manager *input_manager_create(struct cg_server *server);
|
||||
struct cg_input_config *input_device_get_config(struct cg_input_device *device);
|
||||
void input_manager_handle_device_destroy(struct wl_listener *listener, void *data);
|
||||
uint32_t input_manager_get_mouse_button(const char *name, char **error);
|
||||
|
||||
struct cg_input_manager {
|
||||
struct wl_list devices;
|
||||
|
|
@ -46,7 +47,6 @@ enum cg_input_config_mapped_to {
|
|||
*/
|
||||
struct cg_input_config {
|
||||
char *identifier;
|
||||
const char *input_type;
|
||||
|
||||
int accel_profile;
|
||||
struct calibration_matrix calibration_matrix;
|
||||
|
|
@ -67,7 +67,7 @@ struct cg_input_config {
|
|||
int tap;
|
||||
int tap_button_map;
|
||||
|
||||
char *xkb_layout;
|
||||
/* char *xkb_layout;
|
||||
char *xkb_model;
|
||||
char *xkb_options;
|
||||
char *xkb_rules;
|
||||
|
|
@ -77,16 +77,16 @@ struct cg_input_config {
|
|||
bool xkb_file_is_set;
|
||||
|
||||
int xkb_numlock;
|
||||
int xkb_capslock;
|
||||
int xkb_capslock;*/
|
||||
|
||||
struct wl_list link;
|
||||
struct cg_input_config_mapped_from_region *mapped_from_region;
|
||||
|
||||
enum cg_input_config_mapped_to mapped_to;
|
||||
char *mapped_to_output;
|
||||
struct wlr_box *mapped_to_region;
|
||||
/*struct wlr_box *mapped_to_region;*/
|
||||
|
||||
struct wl_list tools;
|
||||
/*struct wl_list tools;*/
|
||||
|
||||
bool capturable;
|
||||
struct wlr_box region;
|
||||
|
|
|
|||
20
keybinding.c
20
keybinding.c
|
|
@ -12,6 +12,7 @@
|
|||
#include "keybinding.h"
|
||||
#include "message.h"
|
||||
#include "output.h"
|
||||
#include "input.h"
|
||||
#include "input_manager.h"
|
||||
#include "seat.h"
|
||||
#include "server.h"
|
||||
|
|
@ -64,6 +65,16 @@ keybinding_free(struct keybinding *keybinding, bool recursive) {
|
|||
case KEYBINDING_CONFIGURE_OUTPUT:
|
||||
free(keybinding->data.o_cfg->output_name);
|
||||
free(keybinding->data.o_cfg);
|
||||
break;
|
||||
case KEYBINDING_CONFIGURE_INPUT:
|
||||
free(keybinding->data.i_cfg->identifier);
|
||||
if(keybinding->data.i_cfg->mapped_from_region) {
|
||||
free(keybinding->data.i_cfg->mapped_from_region);
|
||||
}
|
||||
if(keybinding->data.i_cfg->mapped_to_output) {
|
||||
free(keybinding->data.i_cfg->mapped_to_output);
|
||||
}
|
||||
free(keybinding->data.o_cfg);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -871,6 +882,12 @@ keybinding_configure_output(struct cg_server *server,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
keybinding_configure_input(struct cg_server *server,
|
||||
struct cg_input_config *cfg) {
|
||||
cg_input_apply_config(cfg,server);
|
||||
}
|
||||
|
||||
void
|
||||
keybinding_configure_input_dev(struct cg_server *server, struct cg_input_config *cfg) {
|
||||
|
||||
|
|
@ -1001,6 +1018,9 @@ run_action(enum keybinding_action action, struct cg_server *server,
|
|||
case KEYBINDING_CONFIGURE_OUTPUT:
|
||||
keybinding_configure_output(server, data.o_cfg);
|
||||
break;
|
||||
case KEYBINDING_CONFIGURE_INPUT:
|
||||
keybinding_configure_input(server, data.i_cfg);
|
||||
break;
|
||||
case KEYBINDING_CLOSE_VIEW:
|
||||
keybinding_close_view(
|
||||
server->curr_output->workspaces[server->curr_output->curr_workspace]
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "config.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
struct cg_server;
|
||||
|
|
@ -24,6 +25,8 @@ enum keybinding_action {
|
|||
KEYBINDING_CYCLE_OUTPUT, // data.b is 0 if forward, 1 if reverse
|
||||
KEYBINDING_CONFIGURE_OUTPUT, // data.o_cfg is the desired output
|
||||
// configuration
|
||||
KEYBINDING_CONFIGURE_INPUT, // data.i_cfg is the desired input
|
||||
// configuration
|
||||
KEYBINDING_QUIT,
|
||||
KEYBINDING_NOOP,
|
||||
KEYBINDING_SWITCH_WORKSPACE, // data.u is the desired workspace
|
||||
|
|
@ -61,6 +64,7 @@ union keybinding_params {
|
|||
float color[3];
|
||||
struct keybinding *kb;
|
||||
struct cg_output_config *o_cfg;
|
||||
struct cg_input_config *i_cfg;
|
||||
};
|
||||
|
||||
struct keybinding {
|
||||
|
|
|
|||
147
libinput.c
147
libinput.c
|
|
@ -207,76 +207,137 @@ struct cg_output *output_by_name_or_id(const char *name_or_id, struct cg_server
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void cg_input_configure_libinput_device(struct cg_input_device *input_device) {
|
||||
struct cg_input_config *ic = input_device_get_config(input_device);
|
||||
if (!ic || !wlr_input_device_is_libinput(input_device->wlr_device)) {
|
||||
static bool device_is_touchpad(struct cg_input_device *device) {
|
||||
if (device->wlr_device->type != WLR_INPUT_DEVICE_POINTER ||
|
||||
!wlr_input_device_is_libinput(device->wlr_device)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct libinput_device *libinput_device =
|
||||
wlr_libinput_get_device_handle(device->wlr_device);
|
||||
|
||||
return libinput_device_config_tap_get_finger_count(libinput_device) > 0;
|
||||
}
|
||||
|
||||
const char *input_device_get_type(struct cg_input_device *device) {
|
||||
switch (device->wlr_device->type) {
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
if (device_is_touchpad(device)) {
|
||||
return "touchpad";
|
||||
} else {
|
||||
return "pointer";
|
||||
}
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
return "keyboard";
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
return "touch";
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
return "tablet_tool";
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
return "tablet_pad";
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
return "switch";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void apply_config_to_device(struct cg_input_config *config, struct cg_input_device *input_device) {
|
||||
if (!wlr_input_device_is_libinput(input_device->wlr_device)) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct libinput_device *device =
|
||||
wlr_libinput_get_device_handle(input_device->wlr_device);
|
||||
wlr_log(WLR_DEBUG, "cg_input_configure_libinput_device('%s' on '%s')",
|
||||
ic->identifier, input_device->identifier);
|
||||
|
||||
bool changed = false;
|
||||
if (ic->mapped_to_output &&
|
||||
!output_by_name_or_id(ic->mapped_to_output,input_device->server)) {
|
||||
if (config->mapped_to_output &&
|
||||
!output_by_name_or_id(config->mapped_to_output,input_device->server)) {
|
||||
wlr_log(WLR_DEBUG,
|
||||
"%s '%s' is mapped to offline output '%s'; disabling input",
|
||||
ic->input_type, ic->identifier, ic->mapped_to_output);
|
||||
changed |= set_send_events(device,
|
||||
"'%s' is mapped to offline output '%s'; disabling input",
|
||||
config->identifier, config->mapped_to_output);
|
||||
set_send_events(device,
|
||||
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED);
|
||||
} else if (ic->send_events != INT_MIN) {
|
||||
changed |= set_send_events(device, ic->send_events);
|
||||
} else if (config->send_events != INT_MIN) {
|
||||
set_send_events(device, config->send_events);
|
||||
} else {
|
||||
// Have to reset to the default mode here, otherwise if ic->send_events
|
||||
// is unset and a mapped output just came online after being disabled,
|
||||
// we'd remain stuck sending no events.
|
||||
changed |= set_send_events(device,
|
||||
set_send_events(device,
|
||||
libinput_device_config_send_events_get_default_mode(device));
|
||||
}
|
||||
|
||||
if (ic->tap != INT_MIN) {
|
||||
changed |= set_tap(device, ic->tap);
|
||||
if (config->tap != INT_MIN) {
|
||||
set_tap(device, config->tap);
|
||||
}
|
||||
if (ic->tap_button_map != INT_MIN) {
|
||||
changed |= set_tap_button_map(device, ic->tap_button_map);
|
||||
if (config->tap_button_map != INT_MIN) {
|
||||
set_tap_button_map(device, config->tap_button_map);
|
||||
}
|
||||
if (ic->drag != INT_MIN) {
|
||||
changed |= set_tap_drag(device, ic->drag);
|
||||
if (config->drag != INT_MIN) {
|
||||
set_tap_drag(device, config->drag);
|
||||
}
|
||||
if (ic->drag_lock != INT_MIN) {
|
||||
changed |= set_tap_drag_lock(device, ic->drag_lock);
|
||||
if (config->drag_lock != INT_MIN) {
|
||||
set_tap_drag_lock(device, config->drag_lock);
|
||||
}
|
||||
if (ic->pointer_accel != FLT_MIN) {
|
||||
changed |= set_accel_speed(device, ic->pointer_accel);
|
||||
if (config->pointer_accel != FLT_MIN) {
|
||||
set_accel_speed(device, config->pointer_accel);
|
||||
}
|
||||
if (ic->accel_profile != INT_MIN) {
|
||||
changed |= set_accel_profile(device, ic->accel_profile);
|
||||
if (config->accel_profile != INT_MIN) {
|
||||
set_accel_profile(device, config->accel_profile);
|
||||
}
|
||||
if (ic->natural_scroll != INT_MIN) {
|
||||
changed |= set_natural_scroll(device, ic->natural_scroll);
|
||||
if (config->natural_scroll != INT_MIN) {
|
||||
set_natural_scroll(device, config->natural_scroll);
|
||||
}
|
||||
if (ic->left_handed != INT_MIN) {
|
||||
changed |= set_left_handed(device, ic->left_handed);
|
||||
if (config->left_handed != INT_MIN) {
|
||||
set_left_handed(device, config->left_handed);
|
||||
}
|
||||
if (ic->click_method != INT_MIN) {
|
||||
changed |= set_click_method(device, ic->click_method);
|
||||
if (config->click_method != INT_MIN) {
|
||||
set_click_method(device, config->click_method);
|
||||
}
|
||||
if (ic->middle_emulation != INT_MIN) {
|
||||
changed |= set_middle_emulation(device, ic->middle_emulation);
|
||||
if (config->middle_emulation != INT_MIN) {
|
||||
set_middle_emulation(device, config->middle_emulation);
|
||||
}
|
||||
if (ic->scroll_method != INT_MIN) {
|
||||
changed |= set_scroll_method(device, ic->scroll_method);
|
||||
if (config->scroll_method != INT_MIN) {
|
||||
set_scroll_method(device, config->scroll_method);
|
||||
}
|
||||
if (ic->scroll_button != INT_MIN) {
|
||||
changed |= set_scroll_button(device, ic->scroll_button);
|
||||
if (config->scroll_button != INT_MIN) {
|
||||
set_scroll_button(device, config->scroll_button);
|
||||
}
|
||||
if (ic->dwt != INT_MIN) {
|
||||
changed |= set_dwt(device, ic->dwt);
|
||||
if (config->dwt != INT_MIN) {
|
||||
set_dwt(device, config->dwt);
|
||||
}
|
||||
if (ic->calibration_matrix.configured) {
|
||||
changed |= set_calibration_matrix(device, ic->calibration_matrix.matrix);
|
||||
if (config->calibration_matrix.configured) {
|
||||
set_calibration_matrix(device, config->calibration_matrix.matrix);
|
||||
}
|
||||
}
|
||||
|
||||
void cg_input_apply_config(struct cg_input_config *config, struct cg_server *server) {
|
||||
struct cg_input_device *device=NULL;
|
||||
wl_list_for_each(device,&server->input->devices,link) {
|
||||
if (strcmp(config->identifier, device->identifier) != 0&&strcmp(config->identifier, "*") != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *device_type = input_device_get_type(device);
|
||||
if (strncmp(config->identifier,"type:",5)==0&&strcmp(config->identifier + 5, device_type) != 0) {
|
||||
continue;
|
||||
}
|
||||
apply_config_to_device(config,device);
|
||||
}
|
||||
}
|
||||
|
||||
void cg_input_configure_libinput_device(struct cg_input_device *input_device) {
|
||||
struct cg_server *server=input_device->server;
|
||||
struct cg_input_config *config = NULL;
|
||||
|
||||
wl_list_for_each(config, &server->input_config, link) {
|
||||
if (strcmp(config->identifier, input_device->identifier) != 0&&strcmp(config->identifier, "*") != 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const char *device_type = input_device_get_type(input_device);
|
||||
if (!(strncmp(config->identifier,"type:",5)&&strcmp(config->identifier + 5, device_type) == 0)) {
|
||||
continue;
|
||||
}
|
||||
apply_config_to_device(config,input_device);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ pango = dependency('pango')
|
|||
pangocairo = dependency('pangocairo')
|
||||
fontconfig = dependency('fontconfig')
|
||||
libinput = dependency('libinput')
|
||||
libevdev = dependency('libevdev')
|
||||
libudev = dependency('libudev')
|
||||
math = cc.find_library('m')
|
||||
|
||||
|
|
@ -191,6 +192,7 @@ cagebreak_dependencies_dict = {
|
|||
'xkbcommon': [xkbcommon,true],
|
||||
'fontconfig': [fontconfig,true],
|
||||
'libinput': [libinput,true],
|
||||
'libevdev': [libevdev,true],
|
||||
'libudev': [libudev,true],
|
||||
'pixman': [pixman,true],
|
||||
'pango': [pango,true],
|
||||
|
|
@ -208,6 +210,7 @@ reproducible_build_versions = {
|
|||
'xkbcommon': '1.3.0',
|
||||
'fontconfig': '2.13.94',
|
||||
'libinput': '2.13.94',
|
||||
'libevdev': '2.13.94',
|
||||
'libudev': '2.13.94',
|
||||
'pixman': '0.40.0',
|
||||
'pango': '1.48.7',
|
||||
|
|
|
|||
264
parse.c
264
parse.c
|
|
@ -1,11 +1,14 @@
|
|||
#define _POSIX_C_SOURCE 200812L
|
||||
|
||||
#include <limits.h>
|
||||
#include <float.h>
|
||||
#include <string.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <libinput.h>
|
||||
|
||||
#include "keybinding.h"
|
||||
#include "output.h"
|
||||
#include "input_manager.h"
|
||||
#include "parse.h"
|
||||
#include "server.h"
|
||||
|
||||
|
|
@ -106,6 +109,242 @@ parse_keybinding(struct cg_server *server, char **saveptr, char **errstr) {
|
|||
return keybinding;
|
||||
}
|
||||
|
||||
float
|
||||
parse_float(char **saveptr, const char *delim) {
|
||||
char *uint_str = strtok_r(NULL, delim, saveptr);
|
||||
if(uint_str == NULL) {
|
||||
wlr_log(WLR_ERROR, "Expected a float, got nothing");
|
||||
return -1;
|
||||
}
|
||||
float ufloat = strtof(uint_str, NULL);
|
||||
if(ufloat != NAN && ufloat != INFINITY && errno!=ERANGE) {
|
||||
return ufloat;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Error parsing float");
|
||||
return FLT_MIN;
|
||||
}
|
||||
}
|
||||
|
||||
struct cg_input_config *
|
||||
parse_input_config(char **saveptr, char **errstr) {
|
||||
struct cg_input_config *cfg = calloc(1,sizeof(struct cg_input_config));
|
||||
char *value=NULL;
|
||||
char *ident = NULL;
|
||||
if(cfg == NULL) {
|
||||
*errstr =
|
||||
log_error("Failed to allocate memory for output configuration");
|
||||
goto error;
|
||||
}
|
||||
|
||||
cfg->tap = INT_MIN;
|
||||
cfg->tap_button_map = INT_MIN;
|
||||
cfg->drag = INT_MIN;
|
||||
cfg->drag_lock = INT_MIN;
|
||||
cfg->dwt = INT_MIN;
|
||||
cfg->send_events = INT_MIN;
|
||||
cfg->click_method = INT_MIN;
|
||||
cfg->middle_emulation = INT_MIN;
|
||||
cfg->natural_scroll = INT_MIN;
|
||||
cfg->accel_profile = INT_MIN;
|
||||
cfg->pointer_accel = FLT_MIN;
|
||||
cfg->scroll_factor = FLT_MIN;
|
||||
cfg->scroll_button = INT_MIN;
|
||||
cfg->scroll_method = INT_MIN;
|
||||
cfg->left_handed = INT_MIN;
|
||||
cfg->repeat_delay = INT_MIN;
|
||||
cfg->repeat_rate = INT_MIN;
|
||||
/*cfg->xkb_numlock = INT_MIN;
|
||||
cfg->xkb_capslock = INT_MIN;
|
||||
cfg->xkb_file_is_set = false;
|
||||
wl_list_init(&cfg->tools);*/
|
||||
|
||||
ident = strtok_r(NULL, " ", saveptr);
|
||||
|
||||
if(ident == NULL) {
|
||||
*errstr = log_error("Expected identifier of input device to configure, got none");
|
||||
goto error;
|
||||
}
|
||||
cfg->identifier=strdup(ident);
|
||||
|
||||
char *setting = strtok_r(NULL, " ", saveptr);
|
||||
if(setting == NULL) {
|
||||
*errstr =
|
||||
log_error("Expected setting to be set on input device, got none");
|
||||
goto error;
|
||||
}
|
||||
|
||||
value = strdup(*saveptr);
|
||||
|
||||
if(value == NULL) {
|
||||
*errstr =
|
||||
log_error("Failed to obtain value for input device configuration of device \"%s\"",ident);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(strcmp(setting,"accel_profile") == 0) {
|
||||
if(strcmp(value,"adaptive") == 0) {
|
||||
cfg->accel_profile=LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||
} else if(strcmp(value,"flat") == 0) {
|
||||
cfg->accel_profile=LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT;
|
||||
} else {
|
||||
*errstr = log_error("Invalid profile \"%s\" for accel_profile configuration", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"calibration_matrix") == 0) {
|
||||
cfg->calibration_matrix.configured=true;
|
||||
for(int i=0;i<6;++i) {
|
||||
cfg->calibration_matrix.matrix[i]=parse_float(saveptr," ");
|
||||
if(cfg->calibration_matrix.matrix[i]==FLT_MIN) {
|
||||
*errstr = log_error("Failed to read calibration matrix, expected 6 floating point values separated by spaces");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
} else if(strcmp(setting,"click_method") == 0) {
|
||||
if(strcmp(value,"none")) {
|
||||
cfg->click_method=LIBINPUT_CONFIG_CLICK_METHOD_NONE;
|
||||
} else if(strcmp(value,"button_areas")) {
|
||||
cfg->click_method=LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS;
|
||||
} else if(strcmp(value,"clickfinger")) {
|
||||
cfg->click_method=LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
|
||||
} else {
|
||||
*errstr = log_error("Invalid method \"%s\" for click_method configuration", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"drag") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->drag=LIBINPUT_CONFIG_DRAG_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->drag=LIBINPUT_CONFIG_DRAG_DISABLED;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"drag\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"drag_lock") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->drag_lock=LIBINPUT_CONFIG_DRAG_LOCK_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->drag_lock=LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"drag_lock\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"dwt") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->dwt=LIBINPUT_CONFIG_DWT_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->dwt=LIBINPUT_CONFIG_DWT_DISABLED;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"dwt\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"events") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->send_events=LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->send_events=LIBINPUT_CONFIG_SEND_EVENTS_DISABLED;
|
||||
} else if(strcmp(value,"disabled_on_external_mouse") == 0) {
|
||||
cfg->send_events=LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"events\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"left_handed") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->left_handed=true;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->left_handed=false;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"left_handed\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"middle_emulation") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->middle_emulation=LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->middle_emulation=LIBINPUT_CONFIG_MIDDLE_EMULATION_DISABLED;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"middle_emulation\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"natural_scroll") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->natural_scroll=true;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->natural_scroll=false;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"natural_scroll\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"pointer_accel") == 0) {
|
||||
cfg->pointer_accel=parse_float(saveptr, " ");
|
||||
if(cfg->pointer_accel==FLT_MIN) {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"pointer_accel\", expected float value", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"scroll_button") == 0) {
|
||||
char *err=NULL;
|
||||
cfg->scroll_button=input_manager_get_mouse_button(value,&err);
|
||||
if(err) {
|
||||
*errstr = log_error("Error parsing button for \"scroll_button\" setting. Returned error \"%s\"", err);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"scroll_factor") == 0) {
|
||||
cfg->scroll_factor=parse_float(saveptr, " ");
|
||||
if(cfg->scroll_factor==FLT_MIN) {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"scroll_factor\", expected float value", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"scroll_method") == 0) {
|
||||
if(strcmp(value,"none") == 0) {
|
||||
cfg->scroll_method=LIBINPUT_CONFIG_SCROLL_NO_SCROLL;
|
||||
} else if(strcmp(value,"two_finger") == 0) {
|
||||
cfg->scroll_method=LIBINPUT_CONFIG_SCROLL_2FG;
|
||||
} else if(strcmp(value,"edge") == 0) {
|
||||
cfg->scroll_method=LIBINPUT_CONFIG_SCROLL_EDGE;
|
||||
} else if(strcmp(value,"on_button_down") == 0) {
|
||||
cfg->scroll_method=LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"scroll_method\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"tap") == 0) {
|
||||
if(strcmp(value,"enabled") == 0) {
|
||||
cfg->tap=LIBINPUT_CONFIG_TAP_ENABLED;
|
||||
} else if(strcmp(value,"disabled") == 0) {
|
||||
cfg->tap=LIBINPUT_CONFIG_TAP_DISABLED;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"tap\"", value);
|
||||
goto error;
|
||||
}
|
||||
} else if(strcmp(setting,"tap_button_map") == 0) {
|
||||
if(strcmp(value,"lrm") == 0) {
|
||||
cfg->tap=LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||
} else if(strcmp(value,"lmr") == 0) {
|
||||
cfg->tap=LIBINPUT_CONFIG_TAP_MAP_LMR;
|
||||
} else {
|
||||
*errstr = log_error("Invalid option \"%s\" to setting \"tap_button_map\"", value);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
free(value);
|
||||
return cfg;
|
||||
|
||||
error:
|
||||
if(cfg) {
|
||||
if(cfg->identifier) {
|
||||
free(cfg->identifier);
|
||||
}
|
||||
free(cfg);
|
||||
}
|
||||
if(value) {
|
||||
free(value);
|
||||
}
|
||||
wlr_log(WLR_ERROR,
|
||||
"Input configuration must be of the form 'input \"<ident>\" <setting> <value>'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct keybinding *
|
||||
parse_bind(struct cg_server *server, char **saveptr, char **errstr) {
|
||||
struct keybinding *keybinding = parse_keybinding(server, saveptr, errstr);
|
||||
|
|
@ -242,23 +481,6 @@ parse_uint(char **saveptr, const char *delim) {
|
|||
}
|
||||
}
|
||||
|
||||
float
|
||||
parse_float(char **saveptr, const char *delim) {
|
||||
char *uint_str = strtok_r(NULL, delim, saveptr);
|
||||
if(uint_str == NULL) {
|
||||
wlr_log(WLR_ERROR, "Expected a non-negative float, got nothing");
|
||||
return -1;
|
||||
}
|
||||
float ufloat = strtof(uint_str, NULL);
|
||||
if(ufloat >= 0) {
|
||||
return ufloat;
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Error parsing non-negative float. Must be a number "
|
||||
"larger or equal to 0");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
parse_output_config_keyword(char *key_str, enum output_status *status) {
|
||||
if(key_str == NULL) {
|
||||
|
|
@ -353,7 +575,7 @@ parse_output_config(char **saveptr, char **errstr) {
|
|||
cfg->refresh_rate = parse_float(saveptr, " ");
|
||||
if(cfg->refresh_rate <= 0.0) {
|
||||
*errstr = log_error(
|
||||
"Error parsing refresh rate of output configuration for output %s",
|
||||
"Error parsing refresh rate of output configuration for output %s, expected positive float",
|
||||
name);
|
||||
goto error;
|
||||
}
|
||||
|
|
@ -562,6 +784,12 @@ parse_command(struct cg_server *server, struct keybinding *keybinding,
|
|||
if(keybinding->data.o_cfg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
} else if(strcmp(action, "input") == 0) {
|
||||
keybinding->action = KEYBINDING_CONFIGURE_INPUT;
|
||||
keybinding->data.i_cfg = parse_input_config(&saveptr, errstr);
|
||||
if(keybinding->data.i_cfg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
*errstr = log_error("Error, unsupported action \"%s\".", action);
|
||||
return -1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue