mirror of
https://cagebreak.project-repo.co/cagebreak.git
synced 2026-08-24 06:24:19 +02:00
Release 1.8.0
- Add libinput configuration - Add virtual keyboard and pointer support
This commit is contained in:
parent
18f45aba37
commit
df167f2839
29 changed files with 1529 additions and 149 deletions
21
README.md
21
README.md
|
|
@ -70,7 +70,7 @@ for this to work.
|
|||
#### Man Pages
|
||||
|
||||
Cagebreak has man pages. To use them, make sure that you have `pandoc`
|
||||
installed. Then, add `-Dman-pages=true to the `meson` command.
|
||||
installed. Then, add `-Dman-pages=true` to the `meson` command.
|
||||
|
||||
### Running Cagebreak
|
||||
|
||||
|
|
@ -204,6 +204,21 @@ For every release after 1.0.5, hashes will be provided.
|
|||
|
||||
For every release after 1.7.0, hashes will be provided for man pages too.
|
||||
|
||||
1.8.0 cagebreak
|
||||
|
||||
* sha 256: ac84aa4a08c311da79ca29d92eef4254cb625674b255dbb75621ee6b171a1d79
|
||||
* sha 512: c047bb1986fd1d444547e4d64aa7ef9138b3d30327ac3ad9b4c6976e8df6638bae07c39293b5bc9c20e959c0a22b0e40eb2b23b4766d9a5531377ff954b16229
|
||||
|
||||
1.8.0 cagebreak.1
|
||||
|
||||
* sha 256: 4de43de7bde67d6d806d206dffc34389f0b5c3ba648bfef673b7bc0adeb29202
|
||||
* sha 512: 72aac9a2e9a47f2f85949222d5944dc293332a616e3b961c625fe876172f66638038057c30aa18904d6d969451f468b4fe45e918c0b204cf6952d58ea4c69c33
|
||||
|
||||
1.8.0 cagebreak-config.5
|
||||
|
||||
* sha 256: 678aadde06b5ff6bfbd9bc9460423210f9599bcaa0e50c2eae076dc6d6852781
|
||||
* sha 512: 72056018fc1c559f26bd7e007b3f1db7d478cec7ec9337620e03a1e3d06910e244a52e8f655ea4f5d73669ffe064bbd23506005d9a6c06764b0f820d7a1df43f
|
||||
|
||||
1.7.4 cagebreak
|
||||
|
||||
* sha 256: c7442db906239b13f8d09e91cbe01f9e47b2a2c75bbb4b52adefd15dfbfa820f
|
||||
|
|
@ -512,6 +527,10 @@ Adds support for non-build dependencies and an option for builds without pandoc.
|
|||
|
||||
Improve window ordering.
|
||||
|
||||
### Release 1.8.0
|
||||
|
||||
Adds libinput configuration and virtual keyboard and pointer support.
|
||||
|
||||
## Contributors
|
||||
|
||||
* Aisha Tammy
|
||||
|
|
|
|||
32
cagebreak.c
32
cagebreak.c
|
|
@ -44,6 +44,7 @@
|
|||
#endif
|
||||
|
||||
#include "idle_inhibit_v1.h"
|
||||
#include "input_manager.h"
|
||||
#include "ipc_server.h"
|
||||
#include "keybinding.h"
|
||||
#include "message.h"
|
||||
|
|
@ -60,6 +61,8 @@
|
|||
#define WAIT_ANY -1
|
||||
#endif
|
||||
|
||||
bool show_info = false;
|
||||
|
||||
void
|
||||
set_sig_handler(int sig, void (*action)(int)) {
|
||||
struct sigaction act;
|
||||
|
|
@ -133,7 +136,8 @@ usage(FILE *file, const char *const cage) {
|
|||
" -D\t Turn on damage tracking debugging\n"
|
||||
#endif
|
||||
" -h\t Display this help message\n"
|
||||
" -v\t Show the version number and exit\n",
|
||||
" -v\t Show the version number and exit\n"
|
||||
" -s\t Show information about the current setup and exit\n",
|
||||
cage);
|
||||
}
|
||||
|
||||
|
|
@ -141,9 +145,9 @@ static bool
|
|||
parse_args(struct cg_server *server, int argc, char *argv[]) {
|
||||
int c;
|
||||
#ifdef DEBUG
|
||||
while((c = getopt(argc, argv, "rDhv")) != -1) {
|
||||
while((c = getopt(argc, argv, "rDhvs")) != -1) {
|
||||
#else
|
||||
while((c = getopt(argc, argv, "rhv")) != -1) {
|
||||
while((c = getopt(argc, argv, "rhvs")) != -1) {
|
||||
#endif
|
||||
switch(c) {
|
||||
case 'r':
|
||||
|
|
@ -163,6 +167,9 @@ parse_args(struct cg_server *server, int argc, char *argv[]) {
|
|||
case 'v':
|
||||
fprintf(stdout, "Cagebreak version " CG_VERSION "\n");
|
||||
exit(0);
|
||||
case 's':
|
||||
show_info = true;
|
||||
break;
|
||||
default:
|
||||
usage(stderr, argv[0]);
|
||||
return false;
|
||||
|
|
@ -264,6 +271,9 @@ main(int argc, char *argv[]) {
|
|||
wlr_log_init(WLR_ERROR, NULL);
|
||||
#endif
|
||||
|
||||
wl_list_init(&server.input_config);
|
||||
wl_list_init(&server.output_config);
|
||||
|
||||
server.modes = malloc(4 * sizeof(char *));
|
||||
if(!server.modes) {
|
||||
wlr_log(WLR_ERROR, "Error allocating mode array");
|
||||
|
|
@ -328,8 +338,6 @@ main(int argc, char *argv[]) {
|
|||
goto end;
|
||||
}
|
||||
|
||||
wl_list_init(&server.output_config);
|
||||
|
||||
renderer = wlr_backend_get_renderer(backend);
|
||||
wlr_renderer_init_wl_display(renderer, server.wl_display);
|
||||
|
||||
|
|
@ -358,6 +366,8 @@ main(int argc, char *argv[]) {
|
|||
goto end;
|
||||
}
|
||||
|
||||
server.input = input_manager_create(&server);
|
||||
|
||||
data_control_manager =
|
||||
wlr_data_control_manager_v1_create(server.wl_display);
|
||||
if(!data_control_manager) {
|
||||
|
|
@ -523,6 +533,17 @@ main(int argc, char *argv[]) {
|
|||
wlr_xwayland_set_seat(xwayland, server.seat->seat);
|
||||
#endif
|
||||
|
||||
if(show_info) {
|
||||
char *msg = server_show_info(&server);
|
||||
if(msg != NULL) {
|
||||
fprintf(stderr, "%s", msg);
|
||||
free(msg);
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "Failed to get info on cagebreak setup\n");
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if(ipc_init(&server) != 0) {
|
||||
wlr_log(WLR_ERROR, "Failed to initialize IPC");
|
||||
ret = 1;
|
||||
|
|
@ -592,6 +613,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();
|
||||
|
|
|
|||
|
|
@ -78,3 +78,11 @@ definekey top XF86MonBrightnessUp exec xbacklight -inc 1
|
|||
output eDP-1 pos 0 0 res 1366x768 rate 60
|
||||
output eDP-1 disable
|
||||
output eDP-1 enable
|
||||
|
||||
#####################
|
||||
#Input configuration
|
||||
#####################
|
||||
|
||||
input 1234:0:Device_Ident click_method clickfinger
|
||||
input type:pointer scroll_method two_finger
|
||||
input * calibration_matrix 1 2 3 4 5 6
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
|
|
@ -47,6 +48,7 @@
|
|||
#endif
|
||||
|
||||
#include "../idle_inhibit_v1.h"
|
||||
#include "../input_manager.h"
|
||||
#include "../keybinding.h"
|
||||
#include "../output.h"
|
||||
#include "../parse.h"
|
||||
|
|
@ -132,6 +134,7 @@ LLVMFuzzerInitialize(int *argc, char ***argv) {
|
|||
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_manager = NULL;
|
||||
struct wlr_export_dmabuf_manager_v1 *export_dmabuf_manager = NULL;
|
||||
struct wlr_screencopy_manager_v1 *screencopy_manager = NULL;
|
||||
struct wlr_data_control_manager_v1 *data_control_manager = NULL;
|
||||
struct wlr_xdg_output_manager_v1 *output_manager = NULL;
|
||||
struct wlr_gamma_control_manager_v1 *gamma_control_manager = NULL;
|
||||
int ret = 0;
|
||||
|
|
@ -146,6 +149,8 @@ LLVMFuzzerInitialize(int *argc, char ***argv) {
|
|||
wlr_log_init(WLR_ERROR, NULL);
|
||||
#endif
|
||||
|
||||
wl_list_init(&server.input_config);
|
||||
|
||||
/* Wayland requires XDG_RUNTIME_DIR to be set. */
|
||||
if(!getenv("XDG_RUNTIME_DIR")) {
|
||||
wlr_log(WLR_ERROR, "XDG_RUNTIME_DIR is not set in the environment");
|
||||
|
|
@ -235,6 +240,16 @@ LLVMFuzzerInitialize(int *argc, char ***argv) {
|
|||
goto end;
|
||||
}
|
||||
|
||||
server.input = input_manager_create(&server);
|
||||
|
||||
data_control_manager =
|
||||
wlr_data_control_manager_v1_create(server.wl_display);
|
||||
if(!data_control_manager) {
|
||||
wlr_log(WLR_ERROR, "Unable to create the data control manager");
|
||||
ret = 1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* Configure a listener to be notified when new outputs are
|
||||
* available on the backend. We use this only to detect the
|
||||
* first output and ignore subsequent outputs. */
|
||||
|
|
@ -509,29 +524,14 @@ destroy_input_device(char *line, struct cg_server *server) {
|
|||
--devn;
|
||||
}
|
||||
} else if(strncmp(line, "p", 1) == 0) {
|
||||
if(wl_list_empty(&server->seat->pointers)) {
|
||||
if(wl_list_empty(&server->input->devices)) {
|
||||
return;
|
||||
}
|
||||
devn = devn % wl_list_length(&server->seat->pointers);
|
||||
struct cg_pointer *pointer, *pointer_tmp;
|
||||
wl_list_for_each_safe(pointer, pointer_tmp, &server->seat->pointers,
|
||||
link) {
|
||||
devn = devn % wl_list_length(&server->input->devices);
|
||||
struct cg_input_device *dev, *dev_tmp;
|
||||
wl_list_for_each_safe(dev, dev_tmp, &server->input->devices, link) {
|
||||
if(devn == 0) {
|
||||
pointer->destroy.notify(&pointer->destroy, NULL);
|
||||
break;
|
||||
}
|
||||
--devn;
|
||||
}
|
||||
} else if(strncmp(line, "t", 1) == 0) {
|
||||
if(wl_list_empty(&server->seat->touch)) {
|
||||
return;
|
||||
}
|
||||
devn = devn % wl_list_length(&server->seat->touch);
|
||||
struct cg_touch *touch, *touch_tmp;
|
||||
wl_list_for_each_safe(touch, touch_tmp, &server->seat->touch,
|
||||
link) {
|
||||
if(devn == 0) {
|
||||
touch->destroy.notify(&touch->destroy, NULL);
|
||||
dev->device_destroy.notify(&dev->device_destroy, NULL);
|
||||
break;
|
||||
}
|
||||
--devn;
|
||||
|
|
|
|||
22
input.h
Normal file
22
input.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#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);
|
||||
|
||||
#endif
|
||||
271
input_manager.c
Normal file
271
input_manager.c
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
/*
|
||||
* Cagebreak: A Wayland tiling compositor.
|
||||
*
|
||||
* Copyright (C) 2020 The Cagebreak Authors
|
||||
* Copyright (C) 2018-2020 Jente Hidskes
|
||||
*
|
||||
* See the LICENSE file accompanying this file.
|
||||
*/
|
||||
|
||||
#define _POSIX_C_SOURCE 200812L
|
||||
|
||||
#include "input_manager.h"
|
||||
#include "config.h"
|
||||
#include "input.h"
|
||||
#include "seat.h"
|
||||
#include "server.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <libevdev/libevdev.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
void
|
||||
strip_whitespace(char *str) {
|
||||
static const char whitespace[] = " \f\n\r\t\v";
|
||||
size_t len = strlen(str);
|
||||
size_t start = strspn(str, whitespace);
|
||||
memmove(str, &str[start], len + 1 - start);
|
||||
|
||||
if(*str) {
|
||||
for(len -= start + 1; isspace(str[len]); --len) {
|
||||
}
|
||||
str[len + 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
char *
|
||||
input_device_get_identifier(struct wlr_input_device *device) {
|
||||
int vendor = device->vendor;
|
||||
int product = device->product;
|
||||
char *name = strdup(device->name ? device->name : "");
|
||||
strip_whitespace(name);
|
||||
|
||||
char *p = name;
|
||||
for(; *p; ++p) {
|
||||
// There are in fact input devices with unprintable characters in its
|
||||
// name
|
||||
if(*p == ' ' || !isprint(*p)) {
|
||||
*p = '_';
|
||||
}
|
||||
}
|
||||
|
||||
const char *fmt = "%d:%d:%s";
|
||||
int len = snprintf(NULL, 0, fmt, vendor, product, name) + 1;
|
||||
char *identifier = malloc(len);
|
||||
if(!identifier) {
|
||||
wlr_log(WLR_ERROR, "Unable to allocate unique input device name");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
snprintf(identifier, len, fmt, vendor, product, name);
|
||||
free(name);
|
||||
return identifier;
|
||||
}
|
||||
|
||||
void
|
||||
input_manager_handle_device_destroy(struct wl_listener *listener, void *data) {
|
||||
struct cg_input_device *input_device =
|
||||
wl_container_of(listener, input_device, device_destroy);
|
||||
|
||||
if(!input_device) {
|
||||
wlr_log(WLR_ERROR, "Could not find cagebreak input device to destroy");
|
||||
return;
|
||||
}
|
||||
|
||||
seat_remove_device(input_device->server->seat, input_device);
|
||||
|
||||
wl_list_remove(&input_device->link);
|
||||
wl_list_remove(&input_device->device_destroy.link);
|
||||
free(input_device->identifier);
|
||||
free(input_device);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_new_input(struct wl_listener *listener, void *data) {
|
||||
struct cg_input_manager *input =
|
||||
wl_container_of(listener, input, new_input);
|
||||
struct cg_server *server = input->server;
|
||||
struct wlr_input_device *device = data;
|
||||
|
||||
struct cg_input_device *input_device =
|
||||
calloc(1, sizeof(struct cg_input_device));
|
||||
if(!input_device) {
|
||||
wlr_log(WLR_ERROR, "Could not allocate input device");
|
||||
return;
|
||||
}
|
||||
device->data = input_device;
|
||||
|
||||
input_device->wlr_device = device;
|
||||
input_device->identifier = input_device_get_identifier(device);
|
||||
input_device->server = server;
|
||||
input_device->pointer = NULL;
|
||||
input_device->touch = NULL;
|
||||
|
||||
wl_list_insert(&input->devices, &input_device->link);
|
||||
|
||||
cg_input_configure_libinput_device(input_device);
|
||||
|
||||
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
|
||||
input_device->device_destroy.notify = input_manager_handle_device_destroy;
|
||||
|
||||
struct cg_seat *seat = server->seat;
|
||||
seat_add_device(seat, input_device);
|
||||
}
|
||||
|
||||
void
|
||||
handle_virtual_keyboard(struct wl_listener *listener, void *data) {
|
||||
struct cg_input_manager *input_manager =
|
||||
wl_container_of(listener, input_manager, virtual_keyboard_new);
|
||||
struct wlr_virtual_keyboard_v1 *keyboard = data;
|
||||
struct wlr_input_device *device = &keyboard->input_device;
|
||||
|
||||
struct cg_seat *seat = input_manager->server->seat;
|
||||
|
||||
struct cg_input_device *input_device =
|
||||
calloc(1, sizeof(struct cg_input_device));
|
||||
if(!input_device) {
|
||||
wlr_log(WLR_ERROR, "could not allocate input device");
|
||||
return;
|
||||
}
|
||||
device->data = input_device;
|
||||
|
||||
input_device->is_virtual = true;
|
||||
input_device->wlr_device = device;
|
||||
input_device->identifier = input_device_get_identifier(device);
|
||||
wl_list_insert(&input_manager->devices, &input_device->link);
|
||||
input_device->server = input_manager->server;
|
||||
input_device->pointer = NULL;
|
||||
input_device->touch = NULL;
|
||||
|
||||
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
|
||||
input_device->device_destroy.notify = input_manager_handle_device_destroy;
|
||||
|
||||
seat_add_device(seat, input_device);
|
||||
}
|
||||
|
||||
void
|
||||
handle_virtual_pointer(struct wl_listener *listener, void *data) {
|
||||
struct cg_input_manager *input_manager =
|
||||
wl_container_of(listener, input_manager, virtual_pointer_new);
|
||||
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
|
||||
struct wlr_virtual_pointer_v1 *pointer = event->new_pointer;
|
||||
struct wlr_input_device *device = &pointer->input_device;
|
||||
|
||||
struct cg_seat *seat = input_manager->server->seat;
|
||||
|
||||
struct cg_input_device *input_device =
|
||||
calloc(1, sizeof(struct cg_input_device));
|
||||
if(!input_device) {
|
||||
wlr_log(WLR_ERROR, "could not allocate input device");
|
||||
return;
|
||||
}
|
||||
device->data = input_device;
|
||||
|
||||
input_device->is_virtual = true;
|
||||
input_device->wlr_device = device;
|
||||
input_device->identifier = input_device_get_identifier(device);
|
||||
wl_list_insert(&input_manager->devices, &input_device->link);
|
||||
input_device->server = input_manager->server;
|
||||
input_device->pointer = NULL;
|
||||
input_device->touch = NULL;
|
||||
|
||||
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
|
||||
input_device->device_destroy.notify = input_manager_handle_device_destroy;
|
||||
|
||||
seat_add_device(seat, input_device);
|
||||
|
||||
if(event->suggested_output) {
|
||||
wlr_cursor_map_input_to_output(seat->cursor, device,
|
||||
event->suggested_output);
|
||||
}
|
||||
}
|
||||
|
||||
struct cg_input_manager *
|
||||
input_manager_create(struct cg_server *server) {
|
||||
struct cg_input_manager *input = calloc(1, sizeof(struct cg_input_manager));
|
||||
if(!input) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wl_list_init(&input->devices);
|
||||
input->server = server;
|
||||
|
||||
input->new_input.notify = handle_new_input;
|
||||
wl_signal_add(&server->backend->events.new_input, &input->new_input);
|
||||
|
||||
input->virtual_keyboard =
|
||||
wlr_virtual_keyboard_manager_v1_create(server->wl_display);
|
||||
wl_signal_add(&input->virtual_keyboard->events.new_virtual_keyboard,
|
||||
&input->virtual_keyboard_new);
|
||||
input->virtual_keyboard_new.notify = handle_virtual_keyboard;
|
||||
|
||||
input->virtual_pointer =
|
||||
wlr_virtual_pointer_manager_v1_create(server->wl_display);
|
||||
wl_signal_add(&input->virtual_pointer->events.new_virtual_pointer,
|
||||
&input->virtual_pointer_new);
|
||||
input->virtual_pointer_new.notify = handle_virtual_pointer;
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
return button;
|
||||
}
|
||||
111
input_manager.h
Normal file
111
input_manager.h
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#ifndef CG_INPUT_MANAGER_H
|
||||
#define CG_INPUT_MANAGER_H
|
||||
|
||||
#include "seat.h"
|
||||
#include "server.h"
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_box.h>
|
||||
|
||||
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;
|
||||
struct cg_server *server;
|
||||
|
||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard;
|
||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer;
|
||||
|
||||
struct wl_listener new_input;
|
||||
struct wl_listener virtual_keyboard_new;
|
||||
struct wl_listener virtual_pointer_new;
|
||||
};
|
||||
|
||||
struct cg_input_config_mapped_from_region {
|
||||
double x1, y1;
|
||||
double x2, y2;
|
||||
bool mm;
|
||||
};
|
||||
|
||||
struct calibration_matrix {
|
||||
bool configured;
|
||||
float matrix[6];
|
||||
};
|
||||
|
||||
enum cg_input_config_mapped_to {
|
||||
MAPPED_TO_DEFAULT,
|
||||
MAPPED_TO_OUTPUT,
|
||||
MAPPED_TO_REGION,
|
||||
};
|
||||
|
||||
/**
|
||||
* options for input devices
|
||||
*/
|
||||
struct cg_input_config {
|
||||
char *identifier;
|
||||
|
||||
int accel_profile;
|
||||
struct calibration_matrix calibration_matrix;
|
||||
int click_method;
|
||||
int drag;
|
||||
int drag_lock;
|
||||
int dwt;
|
||||
int left_handed;
|
||||
int middle_emulation;
|
||||
int natural_scroll;
|
||||
float pointer_accel;
|
||||
float scroll_factor;
|
||||
/*int repeat_delay;
|
||||
int repeat_rate;*/
|
||||
int scroll_button;
|
||||
int scroll_method;
|
||||
int send_events;
|
||||
int tap;
|
||||
int tap_button_map;
|
||||
|
||||
/*char *xkb_layout;
|
||||
char *xkb_model;
|
||||
char *xkb_options;
|
||||
char *xkb_rules;
|
||||
char *xkb_variant;
|
||||
char *xkb_file;
|
||||
|
||||
bool xkb_file_is_set;
|
||||
|
||||
int xkb_numlock;
|
||||
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 wl_list tools;*/
|
||||
|
||||
bool capturable;
|
||||
struct wlr_box region;
|
||||
};
|
||||
|
||||
struct cg_input_device {
|
||||
char *identifier;
|
||||
struct cg_server *server;
|
||||
struct wlr_input_device *wlr_device;
|
||||
struct wl_list link;
|
||||
struct wl_listener device_destroy;
|
||||
bool is_virtual;
|
||||
|
||||
/* Only one of the following is non-NULL depending on the type of the input
|
||||
* device */
|
||||
struct cg_pointer *pointer;
|
||||
struct cg_touch *touch;
|
||||
};
|
||||
|
||||
#endif
|
||||
43
keybinding.c
43
keybinding.c
|
|
@ -9,6 +9,8 @@
|
|||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "input.h"
|
||||
#include "input_manager.h"
|
||||
#include "keybinding.h"
|
||||
#include "message.h"
|
||||
#include "output.h"
|
||||
|
|
@ -63,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;
|
||||
}
|
||||
|
|
@ -103,6 +115,9 @@ keybinding_list_init() {
|
|||
|
||||
void
|
||||
keybinding_list_free(struct keybinding_list *list) {
|
||||
if(!list) {
|
||||
return;
|
||||
}
|
||||
for(unsigned int i = 0; i < list->length; ++i) {
|
||||
keybinding_free(list->keybindings[i], true);
|
||||
}
|
||||
|
|
@ -689,6 +704,18 @@ keybinding_show_time(struct cg_server *server) {
|
|||
free(msg);
|
||||
}
|
||||
|
||||
void
|
||||
keybinding_show_info(struct cg_server *server) {
|
||||
char *msg = server_show_info(server);
|
||||
|
||||
if(!msg) {
|
||||
return;
|
||||
}
|
||||
|
||||
message_printf(server->curr_output, "%s", msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
void
|
||||
keybinding_move_view_to_next_output(struct cg_server *server) {
|
||||
if(wl_list_length(&server->outputs) <= 1) {
|
||||
|
|
@ -870,6 +897,16 @@ 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) {}
|
||||
|
||||
/* Hint: see keybinding.h for details on "data" */
|
||||
int
|
||||
run_action(enum keybinding_action action, struct cg_server *server,
|
||||
|
|
@ -918,6 +955,9 @@ run_action(enum keybinding_action action, struct cg_server *server,
|
|||
case KEYBINDING_SHOW_TIME:
|
||||
keybinding_show_time(server);
|
||||
break;
|
||||
case KEYBINDING_SHOW_INFO:
|
||||
keybinding_show_info(server);
|
||||
break;
|
||||
case KEYBINDING_RESIZE_TILE_HORIZONTAL:
|
||||
resize_tile(server, data.i, 0);
|
||||
break;
|
||||
|
|
@ -995,6 +1035,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]
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -36,6 +39,7 @@ enum keybinding_action {
|
|||
KEYBINDING_MOVE_VIEW_TO_WORKSPACE, // data.u is the desired workspace
|
||||
KEYBINDING_MOVE_VIEW_TO_NEXT_OUTPUT,
|
||||
KEYBINDING_SHOW_TIME,
|
||||
KEYBINDING_SHOW_INFO,
|
||||
|
||||
KEYBINDING_SWAP_LEFT,
|
||||
KEYBINDING_SWAP_RIGHT,
|
||||
|
|
@ -61,6 +65,7 @@ union keybinding_params {
|
|||
float color[3];
|
||||
struct keybinding *kb;
|
||||
struct cg_output_config *o_cfg;
|
||||
struct cg_input_config *i_cfg;
|
||||
};
|
||||
|
||||
struct keybinding {
|
||||
|
|
|
|||
442
libinput.c
Normal file
442
libinput.c
Normal file
|
|
@ -0,0 +1,442 @@
|
|||
#include "input.h"
|
||||
#include "input_manager.h"
|
||||
#include "output.h"
|
||||
#include <float.h>
|
||||
#include <libinput.h>
|
||||
#include <libudev.h>
|
||||
#include <limits.h>
|
||||
#include <strings.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
static void
|
||||
log_status(enum libinput_config_status status) {
|
||||
if(status != LIBINPUT_CONFIG_STATUS_SUCCESS) {
|
||||
wlr_log(WLR_ERROR, "Failed to apply libinput config: %s",
|
||||
libinput_config_status_to_str(status));
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
set_send_events(struct libinput_device *device, uint32_t mode) {
|
||||
if(libinput_device_config_send_events_get_mode(device) == mode) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "send_events_set_mode(%" PRIu32 ")", mode);
|
||||
log_status(libinput_device_config_send_events_set_mode(device, mode));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_tap(struct libinput_device *device, enum libinput_config_tap_state tap) {
|
||||
if(libinput_device_config_tap_get_finger_count(device) <= 0 ||
|
||||
libinput_device_config_tap_get_enabled(device) == tap) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "tap_set_enabled(%d)", tap);
|
||||
log_status(libinput_device_config_tap_set_enabled(device, tap));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_tap_button_map(struct libinput_device *device,
|
||||
enum libinput_config_tap_button_map map) {
|
||||
if(libinput_device_config_tap_get_finger_count(device) <= 0 ||
|
||||
libinput_device_config_tap_get_button_map(device) == map) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "tap_set_button_map(%d)", map);
|
||||
log_status(libinput_device_config_tap_set_button_map(device, map));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_tap_drag(struct libinput_device *device,
|
||||
enum libinput_config_drag_state drag) {
|
||||
if(libinput_device_config_tap_get_finger_count(device) <= 0 ||
|
||||
libinput_device_config_tap_get_drag_enabled(device) == drag) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "tap_set_drag_enabled(%d)", drag);
|
||||
log_status(libinput_device_config_tap_set_drag_enabled(device, drag));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_tap_drag_lock(struct libinput_device *device,
|
||||
enum libinput_config_drag_lock_state lock) {
|
||||
if(libinput_device_config_tap_get_finger_count(device) <= 0 ||
|
||||
libinput_device_config_tap_get_drag_lock_enabled(device) == lock) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "tap_set_drag_lock_enabled(%d)", lock);
|
||||
log_status(libinput_device_config_tap_set_drag_lock_enabled(device, lock));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_accel_speed(struct libinput_device *device, double speed) {
|
||||
if(!libinput_device_config_accel_is_available(device) ||
|
||||
libinput_device_config_accel_get_speed(device) == speed) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "accel_set_speed(%f)", speed);
|
||||
log_status(libinput_device_config_accel_set_speed(device, speed));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_accel_profile(struct libinput_device *device,
|
||||
enum libinput_config_accel_profile profile) {
|
||||
if(!libinput_device_config_accel_is_available(device) ||
|
||||
libinput_device_config_accel_get_profile(device) == profile) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "accel_set_profile(%d)", profile);
|
||||
log_status(libinput_device_config_accel_set_profile(device, profile));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_natural_scroll(struct libinput_device *d, bool n) {
|
||||
if(!libinput_device_config_scroll_has_natural_scroll(d) ||
|
||||
libinput_device_config_scroll_get_natural_scroll_enabled(d) == n) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "scroll_set_natural_scroll(%d)", n);
|
||||
log_status(libinput_device_config_scroll_set_natural_scroll_enabled(d, n));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_left_handed(struct libinput_device *device, bool left) {
|
||||
if(!libinput_device_config_left_handed_is_available(device) ||
|
||||
libinput_device_config_left_handed_get(device) == left) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "left_handed_set(%d)", left);
|
||||
log_status(libinput_device_config_left_handed_set(device, left));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_click_method(struct libinput_device *device,
|
||||
enum libinput_config_click_method method) {
|
||||
uint32_t click = libinput_device_config_click_get_methods(device);
|
||||
if((click & ~LIBINPUT_CONFIG_CLICK_METHOD_NONE) == 0 ||
|
||||
libinput_device_config_click_get_method(device) == method) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "click_set_method(%d)", method);
|
||||
log_status(libinput_device_config_click_set_method(device, method));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_middle_emulation(struct libinput_device *dev,
|
||||
enum libinput_config_middle_emulation_state mid) {
|
||||
if(!libinput_device_config_middle_emulation_is_available(dev) ||
|
||||
libinput_device_config_middle_emulation_get_enabled(dev) == mid) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "middle_emulation_set_enabled(%d)", mid);
|
||||
log_status(libinput_device_config_middle_emulation_set_enabled(dev, mid));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_scroll_method(struct libinput_device *device,
|
||||
enum libinput_config_scroll_method method) {
|
||||
uint32_t scroll = libinput_device_config_scroll_get_methods(device);
|
||||
if((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 ||
|
||||
libinput_device_config_scroll_get_method(device) == method) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "scroll_set_method(%d)", method);
|
||||
log_status(libinput_device_config_scroll_set_method(device, method));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_scroll_button(struct libinput_device *dev, uint32_t button) {
|
||||
uint32_t scroll = libinput_device_config_scroll_get_methods(dev);
|
||||
if((scroll & ~LIBINPUT_CONFIG_SCROLL_NO_SCROLL) == 0 ||
|
||||
libinput_device_config_scroll_get_button(dev) == button) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "scroll_set_button(%" PRIu32 ")", button);
|
||||
log_status(libinput_device_config_scroll_set_button(dev, button));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_dwt(struct libinput_device *device, bool dwt) {
|
||||
if(!libinput_device_config_dwt_is_available(device) ||
|
||||
libinput_device_config_dwt_get_enabled(device) == dwt) {
|
||||
return false;
|
||||
}
|
||||
wlr_log(WLR_DEBUG, "dwt_set_enabled(%d)", dwt);
|
||||
log_status(libinput_device_config_dwt_set_enabled(device, dwt));
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
set_calibration_matrix(struct libinput_device *dev, float mat[6]) {
|
||||
if(!libinput_device_config_calibration_has_matrix(dev)) {
|
||||
return false;
|
||||
}
|
||||
bool changed = false;
|
||||
float current[6];
|
||||
libinput_device_config_calibration_get_matrix(dev, current);
|
||||
for(int i = 0; i < 6; i++) {
|
||||
if(current[i] != mat[i]) {
|
||||
changed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(changed) {
|
||||
wlr_log(WLR_DEBUG, "calibration_set_matrix(%f, %f, %f, %f, %f, %f)",
|
||||
mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
|
||||
log_status(libinput_device_config_calibration_set_matrix(dev, mat));
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void
|
||||
output_get_identifier(char *identifier, size_t len, struct cg_output *output) {
|
||||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
snprintf(identifier, len, "%s %s %s", wlr_output->make, wlr_output->model,
|
||||
wlr_output->serial);
|
||||
}
|
||||
|
||||
struct cg_output *
|
||||
output_by_name_or_id(const char *name_or_id, struct cg_server *server) {
|
||||
struct cg_output *output = NULL;
|
||||
wl_list_for_each(output, &server->outputs, link) {
|
||||
char identifier[128];
|
||||
output_get_identifier(identifier, sizeof(identifier), output);
|
||||
if(strcasecmp(identifier, name_or_id) == 0 ||
|
||||
strcasecmp(output->wlr_output->name, name_or_id) == 0) {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
if(config->mapped_to_output &&
|
||||
!output_by_name_or_id(config->mapped_to_output, input_device->server)) {
|
||||
wlr_log(WLR_DEBUG,
|
||||
"'%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(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.
|
||||
set_send_events(
|
||||
device,
|
||||
libinput_device_config_send_events_get_default_mode(device));
|
||||
}
|
||||
|
||||
if(config->tap != INT_MIN) {
|
||||
set_tap(device, config->tap);
|
||||
}
|
||||
if(config->tap_button_map != INT_MIN) {
|
||||
set_tap_button_map(device, config->tap_button_map);
|
||||
}
|
||||
if(config->drag != INT_MIN) {
|
||||
set_tap_drag(device, config->drag);
|
||||
}
|
||||
if(config->drag_lock != INT_MIN) {
|
||||
set_tap_drag_lock(device, config->drag_lock);
|
||||
}
|
||||
if(config->pointer_accel != FLT_MIN) {
|
||||
set_accel_speed(device, config->pointer_accel);
|
||||
}
|
||||
if(config->accel_profile != INT_MIN) {
|
||||
set_accel_profile(device, config->accel_profile);
|
||||
}
|
||||
if(config->natural_scroll != INT_MIN) {
|
||||
set_natural_scroll(device, config->natural_scroll);
|
||||
}
|
||||
if(config->left_handed != INT_MIN) {
|
||||
set_left_handed(device, config->left_handed);
|
||||
}
|
||||
if(config->click_method != INT_MIN) {
|
||||
set_click_method(device, config->click_method);
|
||||
}
|
||||
if(config->middle_emulation != INT_MIN) {
|
||||
set_middle_emulation(device, config->middle_emulation);
|
||||
}
|
||||
if(config->scroll_method != INT_MIN) {
|
||||
set_scroll_method(device, config->scroll_method);
|
||||
}
|
||||
if(config->scroll_button != INT_MIN) {
|
||||
set_scroll_button(device, config->scroll_button);
|
||||
}
|
||||
if(config->dwt != INT_MIN) {
|
||||
set_dwt(device, config->dwt);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cg_input_reset_libinput_device(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_reset_libinput_device(%s)",
|
||||
input_device->identifier);
|
||||
bool changed = false;
|
||||
|
||||
changed |= set_send_events(
|
||||
device, libinput_device_config_send_events_get_default_mode(device));
|
||||
changed |=
|
||||
set_tap(device, libinput_device_config_tap_get_default_enabled(device));
|
||||
changed |= set_tap_button_map(
|
||||
device, libinput_device_config_tap_get_default_button_map(device));
|
||||
changed |= set_tap_drag(
|
||||
device, libinput_device_config_tap_get_default_drag_enabled(device));
|
||||
changed |= set_tap_drag_lock(
|
||||
device,
|
||||
libinput_device_config_tap_get_default_drag_lock_enabled(device));
|
||||
changed |= set_accel_speed(
|
||||
device, libinput_device_config_accel_get_default_speed(device));
|
||||
changed |= set_accel_profile(
|
||||
device, libinput_device_config_accel_get_default_profile(device));
|
||||
changed |= set_natural_scroll(
|
||||
device,
|
||||
libinput_device_config_scroll_get_default_natural_scroll_enabled(
|
||||
device));
|
||||
changed |= set_left_handed(
|
||||
device, libinput_device_config_left_handed_get_default(device));
|
||||
changed |= set_click_method(
|
||||
device, libinput_device_config_click_get_default_method(device));
|
||||
changed |= set_middle_emulation(
|
||||
device,
|
||||
libinput_device_config_middle_emulation_get_default_enabled(device));
|
||||
changed |= set_scroll_method(
|
||||
device, libinput_device_config_scroll_get_default_method(device));
|
||||
changed |= set_scroll_button(
|
||||
device, libinput_device_config_scroll_get_default_button(device));
|
||||
changed |=
|
||||
set_dwt(device, libinput_device_config_dwt_get_default_enabled(device));
|
||||
|
||||
float matrix[6];
|
||||
libinput_device_config_calibration_get_default_matrix(device, matrix);
|
||||
changed |= set_calibration_matrix(device, matrix);
|
||||
}
|
||||
|
||||
bool
|
||||
cg_libinput_device_is_builtin(struct cg_input_device *cg_device) {
|
||||
if(!wlr_input_device_is_libinput(cg_device->wlr_device)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
struct libinput_device *device =
|
||||
wlr_libinput_get_device_handle(cg_device->wlr_device);
|
||||
struct udev_device *udev_device = libinput_device_get_udev_device(device);
|
||||
if(!udev_device) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *id_path =
|
||||
udev_device_get_property_value(udev_device, "ID_PATH");
|
||||
if(!id_path) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char prefix[] = "platform-";
|
||||
return strncmp(id_path, prefix, strlen(prefix)) == 0;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
cagebreak-config(1) "Version 1.7.4" "Cagebreak Manual"
|
||||
cagebreak-config(1) "Version 1.8.0" "Cagebreak Manual"
|
||||
|
||||
# NAME
|
||||
|
||||
|
|
@ -93,6 +93,75 @@ by prepending a line with the # symbol.
|
|||
*hsplit*
|
||||
Split current tile horizontally
|
||||
|
||||
*input <identifier> <setting> <value>*
|
||||
Set the setting "<setting>" to "<value>" for device "<identifier>". The identifier can either be "\*" (wildcard), of the form "type:<device_type>" or the identifier of the device as printed for example by *cagebreak -s*. The supported input types are
|
||||
- touchpad
|
||||
- pointer
|
||||
- keyboard
|
||||
- touch
|
||||
- tablet_tool
|
||||
- tablet_pad
|
||||
- switch
|
||||
|
||||
Configurations are applied sequentially. Currently, only libinput devices may be configured. The available settings and their corresponding values are as follows:
|
||||
|
||||
*accel_profile adaptive|flat*
|
||||
Sets the pointer acceleration profile for the specified input device.
|
||||
|
||||
*calibration_matrix <6 space-separated floating point values>*
|
||||
Sets the calibration matrix.
|
||||
|
||||
*click_method none|button_areas|clickfinger*
|
||||
Changes the click method for the specified device.
|
||||
|
||||
*drag enabled|disabled*
|
||||
Enables or disables tap-and-drag for specified input device.
|
||||
|
||||
*drag_lock enabled|disabled*
|
||||
Enables or disables drag lock for specified input device.
|
||||
|
||||
*dwt enabled|disabled*
|
||||
Enables or disables disable-while-typing for the specified input device.
|
||||
|
||||
*enabled|disabled|disabled_on_external_mouse*
|
||||
Enables or disables send_events for specified input device. Disabling
|
||||
send_events disables the input device.
|
||||
|
||||
*left_handed enabled|disabled*
|
||||
Enables or disables left handed mode for specified input device.
|
||||
|
||||
*middle_emulation enabled|disabled*
|
||||
Enables or disables middle click emulation.
|
||||
|
||||
*natural_scroll enabled|disabled*
|
||||
Enables or disables natural (inverted) scrolling for the specified input
|
||||
device.
|
||||
|
||||
*pointer_accel [<-1|1>]*
|
||||
Changes the pointer acceleration for the specified input device.
|
||||
|
||||
*scroll_button disable|<event-code-or-name>*
|
||||
Sets the button used for scroll_method on_button_down. The button can
|
||||
be given as an event name or code, which can be obtained from *libinput
|
||||
debug-events*. If set to
|
||||
_disable_, it disables the scroll_method on_button_down.
|
||||
|
||||
*scroll_factor <floating point value>*
|
||||
Changes the scroll factor for the specified input device. Scroll speed will
|
||||
be scaled by the given value, which must be non-negative.
|
||||
|
||||
*scroll_method none|two_finger|edge|on_button_down*
|
||||
Changes the scroll method for the specified input device.
|
||||
|
||||
*tap enabled|disabled*
|
||||
Enables or disables tap for specified input device.
|
||||
|
||||
*tap_button_map lrm|lmr*
|
||||
Specifies which button mapping to use for tapping. _lrm_ treats 1 finger as
|
||||
left click, 2 fingers as right click, and 3 fingers as middle click. _lmr_
|
||||
treats 1 finger as left click, 2 fingers as middle click, and 3 fingers as
|
||||
right click.
|
||||
|
||||
*mode <mode>*
|
||||
Enter mode "<mode>". After a keybinding is processed, return to default mode
|
||||
|
||||
|
|
@ -140,6 +209,10 @@ by prepending a line with the # symbol.
|
|||
*resizeup*
|
||||
Resize the current tile towards the top
|
||||
|
||||
*show_info*
|
||||
Display info about the current setup. In particular, print the identifiers
|
||||
of the available inputs and outputs.
|
||||
|
||||
*setmode <mode>*
|
||||
Set the default mode to <mode>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
cagebreak(1) "Version 1.7.4" "Cagebreak Manual"
|
||||
cagebreak(1) "Version 1.8.0" "Cagebreak Manual"
|
||||
|
||||
# NAME
|
||||
|
||||
|
|
@ -38,6 +38,9 @@ are displayed in a message box at the top right of the screen.
|
|||
*-r*
|
||||
Rotate the output 90 degrees clockwise, can be specified up to three times
|
||||
|
||||
*-s*
|
||||
Show all available inputs and outputs
|
||||
|
||||
*-v*
|
||||
Show version number and exit
|
||||
|
||||
|
|
|
|||
27
meson.build
27
meson.build
|
|
@ -1,5 +1,5 @@
|
|||
project('cagebreak', 'c',
|
||||
version: '1.7.4',
|
||||
version: '1.8.0',
|
||||
license: 'MIT',
|
||||
default_options: [
|
||||
'c_std=c11',
|
||||
|
|
@ -53,7 +53,7 @@ if is_freebsd
|
|||
)
|
||||
endif
|
||||
|
||||
wlroots = dependency('wlroots', version: ['>=0.14.0', '< 0.15.0'])
|
||||
wlroots = dependency('wlroots', version: ['>=0.14.1', '< 0.15.0'])
|
||||
wayland_protos = dependency('wayland-protocols', version: '>=1.14')
|
||||
wayland_server = dependency('wayland-server')
|
||||
wayland_cursor = dependency('wayland-cursor')
|
||||
|
|
@ -64,6 +64,9 @@ cairo = dependency('cairo')
|
|||
pango = dependency('pango')
|
||||
pangocairo = dependency('pangocairo')
|
||||
fontconfig = dependency('fontconfig')
|
||||
libinput = dependency('libinput')
|
||||
libevdev = dependency('libevdev')
|
||||
libudev = dependency('libudev')
|
||||
math = cc.find_library('m')
|
||||
|
||||
wl_protocol_dir = wayland_protos.get_pkgconfig_variable('pkgdatadir')
|
||||
|
|
@ -123,6 +126,7 @@ conf_data.set_quoted('CG_VERSION', version)
|
|||
cagebreak_main_file = [ 'cagebreak.c', ]
|
||||
cagebreak_source_strings = [
|
||||
'idle_inhibit_v1.c',
|
||||
'input_manager.c',
|
||||
'ipc_server.c',
|
||||
'keybinding.c',
|
||||
'workspace.c',
|
||||
|
|
@ -133,6 +137,7 @@ cagebreak_source_strings = [
|
|||
'util.c',
|
||||
'view.c',
|
||||
'xdg_shell.c',
|
||||
'libinput.c',
|
||||
'server.c',
|
||||
'message.c',
|
||||
'pango.c',
|
||||
|
|
@ -186,6 +191,9 @@ cagebreak_dependencies_dict = {
|
|||
'wlroots': [wlroots,true],
|
||||
'xkbcommon': [xkbcommon,true],
|
||||
'fontconfig': [fontconfig,true],
|
||||
'libinput': [libinput,true],
|
||||
'libevdev': [libevdev,true],
|
||||
'libudev': [libudev,true],
|
||||
'pixman': [pixman,true],
|
||||
'pango': [pango,true],
|
||||
'cairo': [cairo,true],
|
||||
|
|
@ -198,13 +206,16 @@ reproducible_build_versions = {
|
|||
'wayland_server': '1.19.0',
|
||||
'wayland_client': '1.19.0',
|
||||
'wayland_cursor': '1.19.0',
|
||||
'wlroots': '0.14.0',
|
||||
'xkbcommon': '1.3.0',
|
||||
'wlroots': '0.14.1',
|
||||
'xkbcommon': '1.3.1',
|
||||
'fontconfig': '2.13.94',
|
||||
'libinput': '1.19.0',
|
||||
'libevdev': '1.11.0',
|
||||
'libudev': '249',
|
||||
'pixman': '0.40.0',
|
||||
'pango': '1.48.6',
|
||||
'pango': '1.48.10',
|
||||
'cairo': '1.17.4',
|
||||
'pangocairo': '1.48.6',
|
||||
'pangocairo': '1.48.10',
|
||||
'math': '-1'
|
||||
}
|
||||
|
||||
|
|
@ -257,7 +268,7 @@ if get_option('man-pages')
|
|||
output : 'cagebreak.1',
|
||||
input : 'man/cagebreak.1.md',
|
||||
capture : true,
|
||||
command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())],
|
||||
command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())],
|
||||
install: true,
|
||||
install_dir: mandir1
|
||||
)
|
||||
|
|
@ -266,7 +277,7 @@ if get_option('man-pages')
|
|||
output : 'cagebreak-config.5',
|
||||
input : 'man/cagebreak-config.5.md',
|
||||
capture : true,
|
||||
command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1625064321 ; @0@ < @INPUT@'.format(scdoc.path())],
|
||||
command : [sh, '-c', 'export SOURCE_DATE_EPOCH=1632645085 ; @0@ < @INPUT@'.format(scdoc.path())],
|
||||
install: true,
|
||||
install_dir: mandir5
|
||||
)
|
||||
|
|
|
|||
25
message.c
25
message.c
|
|
@ -12,6 +12,7 @@
|
|||
#include "output.h"
|
||||
#include "pango.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
|
||||
cairo_subpixel_order_t
|
||||
to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) {
|
||||
|
|
@ -32,14 +33,14 @@ to_cairo_subpixel_order(const enum wl_output_subpixel subpixel) {
|
|||
|
||||
struct wlr_texture *
|
||||
create_message_texture(const char *string, const struct cg_output *output) {
|
||||
const int PADDING = 2;
|
||||
const int MESSAGE_HEIGHT = 17 + 2 * PADDING;
|
||||
const int WIDTH_PADDING = 8;
|
||||
const int HEIGHT_PADDING = 2;
|
||||
const char *font = "pango:Monospace 10";
|
||||
|
||||
struct wlr_texture *texture;
|
||||
double scale = output->wlr_output->scale;
|
||||
int width = 0;
|
||||
int height = MESSAGE_HEIGHT * scale;
|
||||
int height = 0;
|
||||
|
||||
// We must use a non-nil cairo_t for cairo_set_font_options to work.
|
||||
// Therefore, we cannot use cairo_create(NULL).
|
||||
|
|
@ -59,8 +60,9 @@ create_message_texture(const char *string, const struct cg_output *output) {
|
|||
cairo_font_options_set_subpixel_order(
|
||||
fo, to_cairo_subpixel_order(output->wlr_output->subpixel));
|
||||
cairo_set_font_options(c, fo);
|
||||
get_text_size(c, font, &width, NULL, NULL, scale, "%s", string);
|
||||
width += 2 * PADDING;
|
||||
get_text_size(c, font, &width, &height, NULL, scale, "%s", string);
|
||||
width += 2 * WIDTH_PADDING;
|
||||
height += 2 * HEIGHT_PADDING;
|
||||
cairo_surface_destroy(dummy_surface);
|
||||
cairo_destroy(c);
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ create_message_texture(const char *string, const struct cg_output *output) {
|
|||
cairo_set_line_width(cairo, 2);
|
||||
cairo_rectangle(cairo, 0, 0, width, height);
|
||||
cairo_stroke(cairo);
|
||||
cairo_move_to(cairo, PADDING, PADDING);
|
||||
cairo_move_to(cairo, WIDTH_PADDING, HEIGHT_PADDING);
|
||||
|
||||
pango_printf(cairo, font, scale, "%s", string);
|
||||
|
||||
|
|
@ -149,17 +151,14 @@ message_set_output(struct cg_output *output, const char *string,
|
|||
|
||||
void
|
||||
message_printf(struct cg_output *output, const char *fmt, ...) {
|
||||
uint16_t buf_len = 256;
|
||||
char *buffer = (char *)malloc(buf_len * sizeof(char));
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char *buffer = malloc_vsprintf_va_list(fmt, ap);
|
||||
va_end(ap);
|
||||
if(buffer == NULL) {
|
||||
wlr_log(WLR_ERROR, "Failed to allocate buffer in message_printf");
|
||||
return;
|
||||
}
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buffer, buf_len, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
struct wlr_box *box = malloc(sizeof(struct wlr_box));
|
||||
if(box == NULL) {
|
||||
|
|
|
|||
2
pango.c
2
pango.c
|
|
@ -25,7 +25,7 @@ get_pango_layout(cairo_t *cairo, const char *font, const char *text,
|
|||
pango_attr_list_insert(attrs, pango_attr_scale_new(scale));
|
||||
PangoFontDescription *desc = pango_font_description_from_string(font);
|
||||
pango_layout_set_font_description(layout, desc);
|
||||
pango_layout_set_single_paragraph_mode(layout, 1);
|
||||
pango_layout_set_single_paragraph_mode(layout, false);
|
||||
pango_layout_set_attributes(layout, attrs);
|
||||
pango_attr_list_unref(attrs);
|
||||
pango_font_description_free(desc);
|
||||
|
|
|
|||
310
parse.c
310
parse.c
|
|
@ -1,30 +1,23 @@
|
|||
#define _POSIX_C_SOURCE 200812L
|
||||
|
||||
#include <float.h>
|
||||
#include <libinput.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <wlr/util/log.h>
|
||||
|
||||
#include "input_manager.h"
|
||||
#include "keybinding.h"
|
||||
#include "output.h"
|
||||
#include "parse.h"
|
||||
#include "server.h"
|
||||
|
||||
char *
|
||||
malloc_vsprintf(const char *fmt, va_list ap) {
|
||||
va_list ap2;
|
||||
va_copy(ap2, ap);
|
||||
int len = vsnprintf(NULL, 0, fmt, ap);
|
||||
char *ret = malloc(sizeof(char) * (len + 1));
|
||||
vsnprintf(ret, len + 1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
return ret;
|
||||
}
|
||||
#include "util.h"
|
||||
|
||||
char *
|
||||
log_error(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char *ret = malloc_vsprintf(fmt, args);
|
||||
char *ret = malloc_vsprintf_va_list(fmt, args);
|
||||
if(ret != NULL) {
|
||||
wlr_log(WLR_ERROR, "%s", ret);
|
||||
}
|
||||
|
|
@ -106,6 +99,267 @@ 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);
|
||||
free(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 +496,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) {
|
||||
|
|
@ -352,9 +589,10 @@ 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",
|
||||
name);
|
||||
*errstr =
|
||||
log_error("Error parsing refresh rate of output configuration for "
|
||||
"output %s, expected positive float",
|
||||
name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -383,6 +621,8 @@ parse_command(struct cg_server *server, struct keybinding *keybinding,
|
|||
keybinding->action = KEYBINDING_SPLIT_HORIZONTAL;
|
||||
} else if(strcmp(action, "quit") == 0) {
|
||||
keybinding->action = KEYBINDING_QUIT;
|
||||
} else if(strcmp(action, "show_info") == 0) {
|
||||
keybinding->action = KEYBINDING_SHOW_INFO;
|
||||
} else if(strcmp(action, "close") == 0) {
|
||||
keybinding->action = KEYBINDING_CLOSE_VIEW;
|
||||
} else if(strcmp(action, "focus") == 0) {
|
||||
|
|
@ -562,6 +802,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;
|
||||
|
|
|
|||
6
parse.h
6
parse.h
|
|
@ -4,9 +4,15 @@
|
|||
|
||||
#define MAX_LINE_SIZE 256
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct cg_server;
|
||||
|
||||
int
|
||||
parse_rc_line(struct cg_server *server, char *line, char **errstr);
|
||||
char *
|
||||
parse_malloc_vsprintf(const char *fmt, ...);
|
||||
char *
|
||||
parse_malloc_vsprintf_va_list(const char *fmt, va_list list);
|
||||
|
||||
#endif /* end of include guard PARSE_H */
|
||||
|
|
|
|||
145
seat.c
145
seat.c
|
|
@ -31,6 +31,7 @@
|
|||
#include <wlr/xwayland.h>
|
||||
#endif
|
||||
|
||||
#include "input_manager.h"
|
||||
#include "keybinding.h"
|
||||
#include "message.h"
|
||||
#include "output.h"
|
||||
|
|
@ -112,13 +113,13 @@ static void
|
|||
update_capabilities(const struct cg_seat *seat) {
|
||||
uint32_t caps = 0;
|
||||
|
||||
if(!wl_list_empty(&seat->keyboard_groups)) {
|
||||
if(seat->num_keyboards > 0) {
|
||||
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
}
|
||||
if(!wl_list_empty(&seat->pointers)) {
|
||||
if(seat->num_pointers > 0) {
|
||||
caps |= WL_SEAT_CAPABILITY_POINTER;
|
||||
}
|
||||
if(!wl_list_empty(&seat->touch)) {
|
||||
if(seat->num_touch > 0) {
|
||||
caps |= WL_SEAT_CAPABILITY_TOUCH;
|
||||
}
|
||||
wlr_seat_set_capabilities(seat->seat, caps);
|
||||
|
|
@ -133,20 +134,21 @@ update_capabilities(const struct cg_seat *seat) {
|
|||
}
|
||||
|
||||
static void
|
||||
handle_touch_destroy(struct wl_listener *listener, void *_data) {
|
||||
struct cg_touch *touch = wl_container_of(listener, touch, destroy);
|
||||
struct cg_seat *seat = touch->seat;
|
||||
|
||||
remove_touch(struct cg_seat *seat, struct cg_touch *touch) {
|
||||
if(!touch) {
|
||||
return;
|
||||
}
|
||||
wl_list_remove(&touch->link);
|
||||
wlr_cursor_detach_input_device(seat->cursor, touch->device);
|
||||
wl_list_remove(&touch->destroy.link);
|
||||
wlr_cursor_detach_input_device(seat->cursor, touch->device->wlr_device);
|
||||
--seat->num_touch;
|
||||
free(touch);
|
||||
|
||||
update_capabilities(seat);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) {
|
||||
new_touch(struct cg_seat *seat, struct cg_input_device *input_device) {
|
||||
struct wlr_input_device *device = input_device->wlr_device;
|
||||
struct cg_touch *touch = calloc(1, sizeof(struct cg_touch));
|
||||
if(!touch) {
|
||||
wlr_log(WLR_ERROR, "Cannot allocate touch");
|
||||
|
|
@ -154,12 +156,10 @@ handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) {
|
|||
}
|
||||
|
||||
touch->seat = seat;
|
||||
touch->device = device;
|
||||
touch->device = input_device;
|
||||
wlr_cursor_attach_input_device(seat->cursor, device);
|
||||
|
||||
wl_list_insert(&seat->touch, &touch->link);
|
||||
touch->destroy.notify = handle_touch_destroy;
|
||||
wl_signal_add(&touch->device->events.destroy, &touch->destroy);
|
||||
input_device->touch = touch;
|
||||
++seat->num_touch;
|
||||
|
||||
if(device->output_name != NULL) {
|
||||
struct cg_output *output;
|
||||
|
|
@ -174,20 +174,20 @@ handle_new_touch(struct cg_seat *seat, struct wlr_input_device *device) {
|
|||
}
|
||||
|
||||
static void
|
||||
handle_pointer_destroy(struct wl_listener *listener, void *_data) {
|
||||
struct cg_pointer *pointer = wl_container_of(listener, pointer, destroy);
|
||||
struct cg_seat *seat = pointer->seat;
|
||||
|
||||
wl_list_remove(&pointer->link);
|
||||
wlr_cursor_detach_input_device(seat->cursor, pointer->device);
|
||||
wl_list_remove(&pointer->destroy.link);
|
||||
remove_pointer(struct cg_seat *seat, struct cg_pointer *pointer) {
|
||||
if(!pointer) {
|
||||
return;
|
||||
}
|
||||
wlr_cursor_detach_input_device(seat->cursor, pointer->device->wlr_device);
|
||||
--seat->num_pointers;
|
||||
free(pointer);
|
||||
|
||||
update_capabilities(seat);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_new_pointer(struct cg_seat *seat, struct wlr_input_device *device) {
|
||||
new_pointer(struct cg_seat *seat, struct cg_input_device *input_device) {
|
||||
struct wlr_input_device *device = input_device->wlr_device;
|
||||
struct cg_pointer *pointer = calloc(1, sizeof(struct cg_pointer));
|
||||
if(!pointer) {
|
||||
wlr_log(WLR_ERROR, "Cannot allocate pointer");
|
||||
|
|
@ -195,12 +195,10 @@ handle_new_pointer(struct cg_seat *seat, struct wlr_input_device *device) {
|
|||
}
|
||||
|
||||
pointer->seat = seat;
|
||||
pointer->device = device;
|
||||
pointer->device = input_device;
|
||||
wlr_cursor_attach_input_device(seat->cursor, device);
|
||||
|
||||
wl_list_insert(&seat->pointers, &pointer->link);
|
||||
pointer->destroy.notify = handle_pointer_destroy;
|
||||
wl_signal_add(&device->events.destroy, &pointer->destroy);
|
||||
input_device->pointer = pointer;
|
||||
++seat->num_pointers;
|
||||
|
||||
if(device->output_name != NULL) {
|
||||
struct cg_output *output;
|
||||
|
|
@ -431,21 +429,16 @@ cleanup:
|
|||
}
|
||||
|
||||
static void
|
||||
handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) {
|
||||
new_keyboard(struct cg_seat *seat, struct cg_input_device *input_device) {
|
||||
struct wlr_input_device *device = input_device->wlr_device;
|
||||
struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||
if(!context) {
|
||||
wlr_log(WLR_ERROR, "Unable to create XBK context");
|
||||
wlr_log(WLR_ERROR, "Unable to create XKB context");
|
||||
return;
|
||||
}
|
||||
|
||||
struct xkb_rule_names rules = {0};
|
||||
rules.rules = getenv("XKB_DEFAULT_RULES");
|
||||
rules.model = getenv("XKB_DEFAULT_MODEL");
|
||||
rules.layout = getenv("XKB_DEFAULT_LAYOUT");
|
||||
rules.variant = getenv("XKB_DEFAULT_VARIANT");
|
||||
rules.options = getenv("XKB_DEFAULT_OPTIONS");
|
||||
struct xkb_keymap *keymap =
|
||||
xkb_map_new_from_names(context, &rules, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
xkb_map_new_from_names(context, NULL, XKB_KEYMAP_COMPILE_NO_FLAGS);
|
||||
if(!keymap) {
|
||||
wlr_log(WLR_ERROR,
|
||||
"Unable to configure keyboard: keymap does not exist");
|
||||
|
|
@ -460,24 +453,64 @@ handle_new_keyboard(struct cg_seat *seat, struct wlr_input_device *device) {
|
|||
wlr_keyboard_set_repeat_info(device->keyboard, 25, 600);
|
||||
|
||||
cg_keyboard_group_add(device, seat);
|
||||
++seat->num_keyboards;
|
||||
|
||||
wlr_seat_set_keyboard(seat->seat, device);
|
||||
}
|
||||
|
||||
static void
|
||||
handle_new_input(struct wl_listener *listener, void *data) {
|
||||
struct cg_seat *seat = wl_container_of(listener, seat, new_input);
|
||||
struct wlr_input_device *device = data;
|
||||
|
||||
switch(device->type) {
|
||||
void
|
||||
seat_add_device(struct cg_seat *seat, struct cg_input_device *device) {
|
||||
switch(device->wlr_device->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
handle_new_keyboard(seat, device);
|
||||
new_keyboard(seat, device);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
handle_new_pointer(seat, device);
|
||||
new_pointer(seat, device);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
handle_new_touch(seat, device);
|
||||
new_touch(seat, device);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
wlr_log(WLR_DEBUG, "Switch input is not implemented");
|
||||
return;
|
||||
case WLR_INPUT_DEVICE_TABLET_TOOL:
|
||||
case WLR_INPUT_DEVICE_TABLET_PAD:
|
||||
wlr_log(WLR_DEBUG, "Tablet input is not implemented");
|
||||
return;
|
||||
}
|
||||
|
||||
update_capabilities(seat);
|
||||
}
|
||||
|
||||
void
|
||||
remove_keyboard(struct cg_seat *seat, struct cg_input_device *keyboard) {
|
||||
if(!keyboard) {
|
||||
return;
|
||||
}
|
||||
struct wlr_seat *wlr_seat = seat->seat;
|
||||
struct wlr_keyboard *wlr_keyboard = keyboard->wlr_device->keyboard;
|
||||
if(keyboard->wlr_device->keyboard->group) {
|
||||
wlr_keyboard_group_remove_keyboard(wlr_keyboard->group, wlr_keyboard);
|
||||
}
|
||||
if(wlr_seat_get_keyboard(wlr_seat) == wlr_keyboard) {
|
||||
wlr_seat_set_keyboard(wlr_seat, NULL);
|
||||
}
|
||||
--seat->num_keyboards;
|
||||
}
|
||||
|
||||
void
|
||||
seat_remove_device(struct cg_seat *seat, struct cg_input_device *device) {
|
||||
switch(device->wlr_device->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
remove_keyboard(seat, device);
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
remove_pointer(seat, device->pointer);
|
||||
device->pointer = NULL;
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_TOUCH:
|
||||
remove_touch(seat, device->touch);
|
||||
device->touch = NULL;
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_SWITCH:
|
||||
wlr_log(WLR_DEBUG, "Switch input is not implemented");
|
||||
|
|
@ -801,15 +834,11 @@ handle_destroy(struct wl_listener *listener, void *_data) {
|
|||
wl_event_source_remove(group->key_repeat_timer);
|
||||
free(group);
|
||||
}
|
||||
struct cg_pointer *pointer, *pointer_tmp;
|
||||
wl_list_for_each_safe(pointer, pointer_tmp, &seat->pointers, link) {
|
||||
handle_pointer_destroy(&pointer->destroy, NULL);
|
||||
|
||||
struct cg_input_device *it, *it_tmp;
|
||||
wl_list_for_each_safe(it, it_tmp, &seat->server->input->devices, link) {
|
||||
input_manager_handle_device_destroy(&it->device_destroy, NULL);
|
||||
}
|
||||
struct cg_touch *touch, *touch_tmp;
|
||||
wl_list_for_each_safe(touch, touch_tmp, &seat->touch, link) {
|
||||
handle_touch_destroy(&touch->destroy, NULL);
|
||||
}
|
||||
wl_list_remove(&seat->new_input.link);
|
||||
|
||||
wlr_xcursor_manager_destroy(seat->xcursor_manager);
|
||||
if(seat->cursor) {
|
||||
|
|
@ -898,11 +927,9 @@ seat_create(struct cg_server *server, struct wlr_backend *backend) {
|
|||
&seat->request_set_primary_selection);
|
||||
|
||||
wl_list_init(&seat->keyboard_groups);
|
||||
wl_list_init(&seat->pointers);
|
||||
wl_list_init(&seat->touch);
|
||||
|
||||
seat->new_input.notify = handle_new_input;
|
||||
wl_signal_add(&backend->events.new_input, &seat->new_input);
|
||||
seat->num_keyboards = 0;
|
||||
seat->num_pointers = 0;
|
||||
seat->num_touch = 0;
|
||||
|
||||
wl_list_init(&seat->drag_icons);
|
||||
seat->request_start_drag.notify = handle_request_start_drag;
|
||||
|
|
|
|||
20
seat.h
20
seat.h
|
|
@ -7,6 +7,7 @@ struct cg_server;
|
|||
struct cg_view;
|
||||
struct wlr_cursor;
|
||||
struct wlr_input_device;
|
||||
struct cg_input_device;
|
||||
struct wlr_seat;
|
||||
struct wlr_xcursor_manager;
|
||||
struct wlr_backend;
|
||||
|
|
@ -20,9 +21,10 @@ struct cg_seat {
|
|||
struct wl_listener destroy;
|
||||
|
||||
struct wl_list keyboard_groups;
|
||||
struct wl_list pointers;
|
||||
struct wl_list touch;
|
||||
struct wl_listener new_input;
|
||||
|
||||
uint16_t num_keyboards;
|
||||
uint16_t num_pointers;
|
||||
uint16_t num_touch;
|
||||
|
||||
struct wlr_cursor *cursor;
|
||||
struct wlr_xcursor_manager *xcursor_manager;
|
||||
|
|
@ -70,17 +72,13 @@ struct cg_keyboard_group {
|
|||
struct cg_pointer {
|
||||
struct wl_list link; // seat::pointers
|
||||
struct cg_seat *seat;
|
||||
struct wlr_input_device *device;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct cg_input_device *device;
|
||||
};
|
||||
|
||||
struct cg_touch {
|
||||
struct wl_list link; // seat::touch
|
||||
struct cg_seat *seat;
|
||||
struct wlr_input_device *device;
|
||||
|
||||
struct wl_listener destroy;
|
||||
struct cg_input_device *device;
|
||||
};
|
||||
|
||||
struct cg_drag_icon {
|
||||
|
|
@ -102,5 +100,9 @@ struct cg_view *
|
|||
seat_get_focus(const struct cg_seat *seat);
|
||||
void
|
||||
seat_set_focus(struct cg_seat *seat, struct cg_view *view);
|
||||
void
|
||||
seat_add_device(struct cg_seat *seat, struct cg_input_device *device);
|
||||
void
|
||||
seat_remove_device(struct cg_seat *seat, struct cg_input_device *device);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
38
server.c
38
server.c
|
|
@ -9,11 +9,16 @@
|
|||
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_box.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
||||
#include "input_manager.h"
|
||||
#include "output.h"
|
||||
#include "server.h"
|
||||
#include "util.h"
|
||||
|
||||
void
|
||||
display_terminate(struct cg_server *server) {
|
||||
|
|
@ -35,3 +40,36 @@ get_mode_index_from_name(char *const *modes, const char *mode_name) {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *
|
||||
server_show_info(struct cg_server *server) {
|
||||
char *output_str = strdup(""), *output_str_tmp;
|
||||
struct cg_output *output;
|
||||
wl_list_for_each(output, &server->outputs, link) {
|
||||
if(!output_str) {
|
||||
return NULL;
|
||||
}
|
||||
output_str_tmp = output_str;
|
||||
output_str = malloc_vsprintf("%s\t * %s\n", output_str,
|
||||
output->wlr_output->name);
|
||||
free(output_str_tmp);
|
||||
}
|
||||
char *input_str = strdup(""), *input_str_tmp;
|
||||
struct cg_input_device *input;
|
||||
wl_list_for_each(input, &server->input->devices, link) {
|
||||
if(!input_str) {
|
||||
return NULL;
|
||||
}
|
||||
input_str_tmp = input_str;
|
||||
if(strcmp(input->identifier, "") != 0) {
|
||||
input_str =
|
||||
malloc_vsprintf("%s\t * %s\n", input_str, input->identifier);
|
||||
}
|
||||
free(input_str_tmp);
|
||||
}
|
||||
char *ret =
|
||||
malloc_vsprintf("Outputs:\n%sInputs:\n%s", output_str, input_str);
|
||||
free(output_str);
|
||||
free(input_str);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
5
server.h
5
server.h
|
|
@ -13,12 +13,14 @@ struct keybinding_list;
|
|||
struct wlr_output_layout;
|
||||
struct wlr_idle_inhibit_manager_v1;
|
||||
struct cg_output_config;
|
||||
struct cg_input_manager;
|
||||
|
||||
struct cg_server {
|
||||
struct wl_display *wl_display;
|
||||
struct wl_event_loop *event_loop;
|
||||
|
||||
struct cg_seat *seat;
|
||||
struct cg_input_manager *input;
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_idle *idle;
|
||||
struct wlr_idle_inhibit_manager_v1 *idle_inhibit_v1;
|
||||
|
|
@ -39,6 +41,7 @@ struct cg_server {
|
|||
|
||||
struct keybinding_list *keybindings;
|
||||
struct wl_list output_config;
|
||||
struct wl_list input_config;
|
||||
|
||||
enum wl_output_transform output_transform;
|
||||
|
||||
|
|
@ -58,5 +61,7 @@ void
|
|||
display_terminate(struct cg_server *server);
|
||||
int
|
||||
get_mode_index_from_name(char *const *modes, const char *mode_name);
|
||||
char *
|
||||
server_show_info(struct cg_server *server);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
BIN
signatures/1.7.4-cagebreak-config.5.sig
Normal file
BIN
signatures/1.7.4-cagebreak-config.5.sig
Normal file
Binary file not shown.
BIN
signatures/1.7.4-cagebreak.1.sig
Normal file
BIN
signatures/1.7.4-cagebreak.1.sig
Normal file
Binary file not shown.
BIN
signatures/1.7.4.sig
Normal file
BIN
signatures/1.7.4.sig
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
20
util.c
20
util.c
|
|
@ -10,6 +10,7 @@
|
|||
#include <wlr/types/wlr_box.h>
|
||||
|
||||
#include "util.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
scale_length(int length, int offset, double scale) {
|
||||
|
|
@ -33,3 +34,22 @@ scale_box(struct wlr_box *box, double scale) {
|
|||
box->x = (int)round(box->x * scale);
|
||||
box->y = (int)round(box->y * scale);
|
||||
}
|
||||
|
||||
char *
|
||||
malloc_vsprintf_va_list(const char *fmt, va_list ap) {
|
||||
va_list ap2;
|
||||
va_copy(ap2, ap);
|
||||
int len = vsnprintf(NULL, 0, fmt, ap);
|
||||
char *ret = malloc(sizeof(char) * (len + 1));
|
||||
vsnprintf(ret, len + 1, fmt, ap2);
|
||||
va_end(ap2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
malloc_vsprintf(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
char *ret = malloc_vsprintf_va_list(fmt, args);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
|||
7
util.h
7
util.h
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CG_UTIL_H
|
||||
#define CG_UTIL_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
struct wlr_box;
|
||||
|
||||
/** Apply scale to a width or height. */
|
||||
|
|
@ -10,4 +12,9 @@ scale_length(int length, int offset, double scale);
|
|||
void
|
||||
scale_box(struct wlr_box *box, double scale);
|
||||
|
||||
char *
|
||||
malloc_vsprintf(const char *fmt, ...);
|
||||
char *
|
||||
malloc_vsprintf_va_list(const char *fmt, va_list list);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue