From e44ab5d5840557491a170af64cf851a9c0f201f2 Mon Sep 17 00:00:00 2001 From: random human Date: Sat, 1 Sep 2018 15:12:53 +0530 Subject: [PATCH 01/22] Add function wlr_log_get_verbosity() Returns the verbosity passed to wlr_log_init(). --- include/wlr/util/log.h | 3 +++ util/log.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/include/wlr/util/log.h b/include/wlr/util/log.h index 7b0070bb..0d659780 100644 --- a/include/wlr/util/log.h +++ b/include/wlr/util/log.h @@ -37,6 +37,9 @@ typedef void (*wlr_log_func_t)(enum wlr_log_importance importance, // If `callback` is NULL, wlr will use its default logger. void wlr_log_init(enum wlr_log_importance verbosity, wlr_log_func_t callback); +// Returns the log verbosity provided to wlr_log_init +enum wlr_log_importance wlr_log_get_verbosity(void); + #ifdef __GNUC__ #define _WLR_ATTRIB_PRINTF(start, end) __attribute__((format(printf, start, end))) #else diff --git a/util/log.c b/util/log.c index 754ccfa9..3ef5f484 100644 --- a/util/log.c +++ b/util/log.c @@ -85,3 +85,7 @@ const char *_wlr_strip_path(const char *filepath) { } return filepath; } + +enum wlr_log_importance wlr_log_get_verbosity(void) { + return log_importance; +} From 7bc26579844b2027bcc5fdde5b6978ea108f3edf Mon Sep 17 00:00:00 2001 From: random human Date: Sun, 2 Sep 2018 20:52:09 +0530 Subject: [PATCH 02/22] Free unused pointer in x11/backend.c --- backend/x11/backend.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/x11/backend.c b/backend/x11/backend.c index e0f5d6e7..0ff2925d 100644 --- a/backend/x11/backend.c +++ b/backend/x11/backend.c @@ -163,6 +163,8 @@ static bool backend_start(struct wlr_backend *backend) { 0, 0, 0); + + free(reply); } } #endif From 6946134883bcbb419f898cbbc87bfa345d070f3c Mon Sep 17 00:00:00 2001 From: cnt0 Date: Sun, 2 Sep 2018 12:56:34 +0500 Subject: [PATCH 03/22] fix incorrect NULL check --- types/tablet_v2/wlr_tablet_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c index 45036839..c0e815ed 100644 --- a/types/tablet_v2/wlr_tablet_v2.c +++ b/types/tablet_v2/wlr_tablet_v2.c @@ -163,7 +163,7 @@ static void get_tablet_seat(struct wl_client *wl_client, struct wl_resource *res struct wlr_tablet_seat_client_v2 *seat_client = calloc(1, sizeof(struct wlr_tablet_seat_client_v2)); - if (tablet_seat == NULL) { + if (seat_client == NULL) { wl_client_post_no_memory(wl_client); return; } From 7105864e13c7a83f57d22edce619fe511a9d1342 Mon Sep 17 00:00:00 2001 From: random human Date: Sun, 2 Sep 2018 21:16:24 +0530 Subject: [PATCH 04/22] Handle setting keymap in examples more securely --- examples/multi-pointer.c | 14 ++++++++++---- examples/output-layout.c | 10 ++++++++-- examples/pointer.c | 10 ++++++++-- examples/rotation.c | 10 ++++++++-- examples/simple.c | 10 ++++++++-- examples/tablet.c | 10 ++++++++-- examples/touch.c | 10 ++++++++-- 7 files changed, 58 insertions(+), 16 deletions(-) diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 958e90f6..87beafab 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -239,15 +239,21 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; case WLR_INPUT_DEVICE_POINTER:; - struct sample_cursor *cursor = calloc(1, sizeof(struct sample_cursor)); + struct sample_cursor *cursor = calloc(1, sizeof(struct sample_cursor)); struct sample_pointer *pointer = calloc(1, sizeof(struct sample_pointer)); pointer->device = device; - cursor->sample = sample; + cursor->sample = sample; cursor->device = device; cursor->cursor = wlr_cursor_create(); diff --git a/examples/output-layout.c b/examples/output-layout.c index 2bfc5923..3f9cf84e 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -239,8 +239,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; default: diff --git a/examples/pointer.c b/examples/pointer.c index f0d9fb4b..cc58c223 100644 --- a/examples/pointer.c +++ b/examples/pointer.c @@ -304,8 +304,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; default: diff --git a/examples/rotation.c b/examples/rotation.c index add7f42f..7cf5727b 100644 --- a/examples/rotation.c +++ b/examples/rotation.c @@ -188,8 +188,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; default: diff --git a/examples/simple.c b/examples/simple.c index 1125bd2a..e1c10906 100644 --- a/examples/simple.c +++ b/examples/simple.c @@ -141,8 +141,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; default: diff --git a/examples/tablet.c b/examples/tablet.c index 4817db4d..fad30d52 100644 --- a/examples/tablet.c +++ b/examples/tablet.c @@ -297,8 +297,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; case WLR_INPUT_DEVICE_TABLET_PAD:; diff --git a/examples/touch.c b/examples/touch.c index ba5d1e34..9ed20a28 100644 --- a/examples/touch.c +++ b/examples/touch.c @@ -210,8 +210,14 @@ void new_input_notify(struct wl_listener *listener, void *data) { wlr_log(WLR_ERROR, "Failed to create XKB context"); exit(1); } - wlr_keyboard_set_keymap(device->keyboard, xkb_map_new_from_names(context, - &rules, XKB_KEYMAP_COMPILE_NO_FLAGS)); + struct xkb_keymap *keymap = xkb_map_new_from_names(context, &rules, + XKB_KEYMAP_COMPILE_NO_FLAGS); + if (!keymap) { + wlr_log(WLR_ERROR, "Failed to create XKB keymap"); + exit(1); + } + wlr_keyboard_set_keymap(device->keyboard, keymap); + xkb_keymap_unref(keymap); xkb_context_unref(context); break; case WLR_INPUT_DEVICE_TOUCH:; From 568b0ffe2c84c4ac4f21287a29ec55d3530346f4 Mon Sep 17 00:00:00 2001 From: random human Date: Sun, 2 Sep 2018 22:23:02 +0530 Subject: [PATCH 05/22] Call wl_global_create first in case of failure --- types/tablet_v2/wlr_tablet_v2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c index 45036839..e53b8051 100644 --- a/types/tablet_v2/wlr_tablet_v2.c +++ b/types/tablet_v2/wlr_tablet_v2.c @@ -294,13 +294,6 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) { return NULL; } - wl_signal_init(&tablet->events.destroy); - wl_list_init(&tablet->clients); - wl_list_init(&tablet->seats); - - tablet->display_destroy.notify = handle_display_destroy; - wl_display_add_destroy_listener(display, &tablet->display_destroy); - tablet->wl_global = wl_global_create(display, &zwp_tablet_manager_v2_interface, TABLET_MANAGER_VERSION, tablet, tablet_v2_bind); @@ -309,5 +302,12 @@ struct wlr_tablet_manager_v2 *wlr_tablet_v2_create(struct wl_display *display) { return NULL; } + wl_signal_init(&tablet->events.destroy); + wl_list_init(&tablet->clients); + wl_list_init(&tablet->seats); + + tablet->display_destroy.notify = handle_display_destroy; + wl_display_add_destroy_listener(display, &tablet->display_destroy); + return tablet; } From ef5df78a271e1450311c6ca329b32156ce4f49e9 Mon Sep 17 00:00:00 2001 From: random human Date: Mon, 3 Sep 2018 03:27:28 +0530 Subject: [PATCH 06/22] Destroy layout after display in examples/output-layout --- examples/output-layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/output-layout.c b/examples/output-layout.c index 3f9cf84e..2d1bc58b 100644 --- a/examples/output-layout.c +++ b/examples/output-layout.c @@ -291,6 +291,6 @@ int main(int argc, char *argv[]) { wlr_texture_destroy(state.cat_texture); - wlr_output_layout_destroy(state.layout); wl_display_destroy(state.display); + wlr_output_layout_destroy(state.layout); } From de16defb21801399d2f4715dd5820d2f5d2a9deb Mon Sep 17 00:00:00 2001 From: random human Date: Mon, 3 Sep 2018 03:27:56 +0530 Subject: [PATCH 07/22] Release registry pointer in examples/idle --- examples/idle.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/idle.c b/examples/idle.c index 87a03924..3e1565ca 100644 --- a/examples/idle.c +++ b/examples/idle.c @@ -129,6 +129,7 @@ int main(int argc, char *argv[]) { wl_registry_add_listener(registry, ®istry_listener, NULL); wl_display_dispatch(display); wl_display_roundtrip(display); + free(registry); if (idle_manager == NULL) { fprintf(stderr, "display doesn't support idle protocol\n"); From 6af77e3d9eee492c80830f197354fdd676873469 Mon Sep 17 00:00:00 2001 From: random human Date: Mon, 3 Sep 2018 04:00:53 +0530 Subject: [PATCH 08/22] Release pointers in examples/multi-pointer --- examples/multi-pointer.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/multi-pointer.c b/examples/multi-pointer.c index 87beafab..49670c39 100644 --- a/examples/multi-pointer.c +++ b/examples/multi-pointer.c @@ -330,6 +330,11 @@ int main(int argc, char *argv[]) { cursor_destroy(cursor); } + struct sample_pointer *pointer, *tmp_pointer; + wl_list_for_each_safe(pointer, tmp_pointer, &state.pointers, link) { + free(pointer); + } + wlr_xcursor_theme_destroy(theme); wlr_output_layout_destroy(state.layout); } From 9f511ae942b27c0012cfa39d9950326d7e79f120 Mon Sep 17 00:00:00 2001 From: random human Date: Mon, 3 Sep 2018 05:05:18 +0530 Subject: [PATCH 09/22] Remove listener link after tablet_manager destroy --- types/tablet_v2/wlr_tablet_v2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/types/tablet_v2/wlr_tablet_v2.c b/types/tablet_v2/wlr_tablet_v2.c index e53b8051..eabf5119 100644 --- a/types/tablet_v2/wlr_tablet_v2.c +++ b/types/tablet_v2/wlr_tablet_v2.c @@ -283,6 +283,7 @@ void wlr_tablet_v2_destroy(struct wlr_tablet_manager_v2 *manager) { } wlr_signal_emit_safe(&manager->events.destroy, manager); + wl_list_remove(&manager->display_destroy.link); wl_global_destroy(manager->wl_global); free(manager); } From b8cc4a4152e5bf7bbe9644c63bcf0e874bb28322 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Mon, 3 Sep 2018 17:07:07 +1000 Subject: [PATCH 10/22] xwayland: Introduce set_role event --- include/wlr/xwayland.h | 2 ++ include/xwayland/xwm.h | 1 + xwayland/xwm.c | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/include/wlr/xwayland.h b/include/wlr/xwayland.h index cf1c2cd1..eb5d6985 100644 --- a/include/wlr/xwayland.h +++ b/include/wlr/xwayland.h @@ -116,6 +116,7 @@ struct wlr_xwayland_surface { char *title; char *class; char *instance; + char *role; pid_t pid; bool has_utf8_title; @@ -157,6 +158,7 @@ struct wlr_xwayland_surface { struct wl_signal unmap; struct wl_signal set_title; struct wl_signal set_class; + struct wl_signal set_role; struct wl_signal set_parent; struct wl_signal set_pid; struct wl_signal set_window_type; diff --git a/include/xwayland/xwm.h b/include/xwayland/xwm.h index 607cc797..3536bbc8 100644 --- a/include/xwayland/xwm.h +++ b/include/xwayland/xwm.h @@ -25,6 +25,7 @@ enum atom_name { WM_HINTS, WM_NORMAL_HINTS, WM_SIZE_HINTS, + WM_WINDOW_ROLE, MOTIF_WM_HINTS, UTF8_STRING, WM_S0, diff --git a/xwayland/xwm.c b/xwayland/xwm.c index cebd9bbc..9c803543 100644 --- a/xwayland/xwm.c +++ b/xwayland/xwm.c @@ -24,6 +24,7 @@ const char *atom_map[ATOM_LAST] = { "WM_HINTS", "WM_NORMAL_HINTS", "WM_SIZE_HINTS", + "WM_WINDOW_ROLE", "_MOTIF_WM_HINTS", "UTF8_STRING", "WM_S0", @@ -152,6 +153,7 @@ static struct wlr_xwayland_surface *xwayland_surface_create( wl_signal_init(&surface->events.map); wl_signal_init(&surface->events.unmap); wl_signal_init(&surface->events.set_class); + wl_signal_init(&surface->events.set_role); wl_signal_init(&surface->events.set_title); wl_signal_init(&surface->events.set_parent); wl_signal_init(&surface->events.set_pid); @@ -327,6 +329,7 @@ static void xwayland_surface_destroy( free(xsurface->title); free(xsurface->class); free(xsurface->instance); + free(xsurface->role); free(xsurface->window_type); free(xsurface->protocols); free(xsurface->hints); @@ -365,6 +368,28 @@ static void read_surface_class(struct wlr_xwm *xwm, wlr_signal_emit_safe(&surface->events.set_class, surface); } +static void read_surface_role(struct wlr_xwm *xwm, + struct wlr_xwayland_surface *xsurface, + xcb_get_property_reply_t *reply) { + if (reply->type != XCB_ATOM_STRING && + reply->type != xwm->atoms[UTF8_STRING]) { + return; + } + + size_t len = xcb_get_property_value_length(reply); + char *role = xcb_get_property_value(reply); + + free(xsurface->role); + if (len > 0) { + xsurface->role = strndup(role, len); + } else { + xsurface->role = NULL; + } + + wlr_log(WLR_DEBUG, "XCB_ATOM_WM_WINDOW_ROLE: %s", xsurface->role); + wlr_signal_emit_safe(&xsurface->events.set_role, xsurface); +} + static void read_surface_title(struct wlr_xwm *xwm, struct wlr_xwayland_surface *xsurface, xcb_get_property_reply_t *reply) { @@ -638,6 +663,8 @@ static void read_surface_property(struct wlr_xwm *xwm, read_surface_normal_hints(xwm, xsurface, reply); } else if (property == xwm->atoms[MOTIF_WM_HINTS]) { read_surface_motif_hints(xwm, xsurface, reply); + } else if (property == xwm->atoms[WM_WINDOW_ROLE]) { + read_surface_role(xwm, xsurface, reply); } else { char *prop_name = xwm_get_atom_name(xwm, property); wlr_log(WLR_DEBUG, "unhandled X11 property %u (%s) for window %u", From 93382dc4454f64642491f0b649103d1100972b1b Mon Sep 17 00:00:00 2001 From: random human Date: Sat, 1 Sep 2018 16:15:18 +0530 Subject: [PATCH 11/22] Close stdout/stderr for Xwayland Depending on the log verbosity, close the stdout/stderr streams. --- xwayland/xwayland.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/xwayland/xwayland.c b/xwayland/xwayland.c index 1068b942..4755608f 100644 --- a/xwayland/xwayland.c +++ b/xwayland/xwayland.c @@ -74,6 +74,7 @@ static int fill_arg(char ***argv, const char *fmt, ...) { return len; } +_Noreturn static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) { if (unset_cloexec(wlr_xwayland->x_fd[0]) || unset_cloexec(wlr_xwayland->x_fd[1]) || @@ -123,9 +124,26 @@ static void exec_xwayland(struct wlr_xwayland *wlr_xwayland) { wlr_xwayland->wl_fd[1], wlr_xwayland->display, wlr_xwayland->x_fd[0], wlr_xwayland->x_fd[1], wlr_xwayland->wm_fd[1]); - // TODO: close stdout/err depending on log level + // Closes stdout/stderr depending on log verbosity + enum wlr_log_importance verbosity = wlr_log_get_verbosity(); + int devnull = open("/dev/null", O_WRONLY | O_CREAT, 0666); + if (devnull < 0) { + wlr_log_errno(WLR_ERROR, "XWayland: failed to open /dev/null"); + _exit(EXIT_FAILURE); + } + if (verbosity < WLR_INFO) { + dup2(devnull, STDOUT_FILENO); + } + if (verbosity < WLR_ERROR) { + dup2(devnull, STDERR_FILENO); + } + // This returns if and only if the call fails execvp("Xwayland", argv); + + wlr_log_errno(WLR_ERROR, "failed to exec Xwayland"); + close(devnull); + _exit(EXIT_FAILURE); } static void xwayland_finish_server(struct wlr_xwayland *wlr_xwayland) { @@ -346,8 +364,6 @@ static bool xwayland_start_server(struct wlr_xwayland *wlr_xwayland) { sigprocmask(SIG_BLOCK, &sigset, NULL); if ((pid = fork()) == 0) { exec_xwayland(wlr_xwayland); - wlr_log_errno(WLR_ERROR, "failed to exec Xwayland"); - _exit(EXIT_FAILURE); } if (pid < 0) { wlr_log_errno(WLR_ERROR, "second fork failed"); From cdf41fa627dc5e226d3da2b91c1fa78fc2fc956d Mon Sep 17 00:00:00 2001 From: random human Date: Sat, 1 Sep 2018 17:06:47 +0530 Subject: [PATCH 12/22] Add support for setting log verbosity in rootston --- rootston/config.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rootston/config.c b/rootston/config.c index 0c0ad055..92d90de1 100644 --- a/rootston/config.c +++ b/rootston/config.c @@ -26,7 +26,10 @@ static void usage(const char *name, int ret) { " See `rootston.ini.example` for config\n" " file documentation.\n" " -E Command that will be ran at startup.\n" - " -D Enable damage tracking debugging.\n", + " -D Enable damage tracking debugging.\n" + " -l Set log verbosity, where,\n" + " 0:SILENT, 1:ERROR, 2:INFO, 3+:DEBUG\n" + " (default: DEBUG)\n", name); exit(ret); @@ -455,7 +458,8 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { wl_list_init(&config->bindings); int c; - while ((c = getopt(argc, argv, "C:E:hD")) != -1) { + unsigned int log_verbosity = WLR_DEBUG; + while ((c = getopt(argc, argv, "C:E:hDl:")) != -1) { switch (c) { case 'C': config->config_path = strdup(optarg); @@ -466,11 +470,18 @@ struct roots_config *roots_config_create_from_args(int argc, char *argv[]) { case 'D': config->debug_damage_tracking = true; break; + case 'l': + log_verbosity = strtoul(optarg, NULL, 10); + if (log_verbosity >= WLR_LOG_IMPORTANCE_LAST) { + log_verbosity = WLR_LOG_IMPORTANCE_LAST - 1; + } + break; case 'h': case '?': usage(argv[0], c != 'h'); } } + wlr_log_init(log_verbosity, NULL); if (!config->config_path) { // get the config path from the current directory From 6daa69fbf567f8036031867d6767158a0a6e5fe4 Mon Sep 17 00:00:00 2001 From: random human Date: Mon, 3 Sep 2018 16:21:49 +0530 Subject: [PATCH 13/22] Update wlr_log_init docs --- include/wlr/util/log.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/wlr/util/log.h b/include/wlr/util/log.h index 0d659780..2c441180 100644 --- a/include/wlr/util/log.h +++ b/include/wlr/util/log.h @@ -35,6 +35,8 @@ typedef void (*wlr_log_func_t)(enum wlr_log_importance importance, // Will log all messages less than or equal to `verbosity` // If `callback` is NULL, wlr will use its default logger. +// The function can be called multiple times to update the verbosity or +// callback function. void wlr_log_init(enum wlr_log_importance verbosity, wlr_log_func_t callback); // Returns the log verbosity provided to wlr_log_init From b877daded11612891af0406fb43cb8bcf1e02809 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 15:09:07 +0200 Subject: [PATCH 14/22] backend/drm: better hotplug handling This commit handles better situations in which the number of connected outputs is greater than the number of available CRTCs. It'll enable as many outputs as possible, and transfer CRTCs to outputs that need one on unplug. This changes CRTC and plane reallocation to happen after scanning DRM connectors instead of on modeset. This cleanups CRTCs and planes on unplug to allow them to be re-used for other outputs. On modeset, if an output doesn't have a CRTC, the desired mode is saved and used later when the output gains a CRTC. Future work includes giving priority to enabled outputs over disabled ones for CRTC allocation. This requires the compositor to know about all outputs (even outputs without CRTCs) to properly modeset outputs enabled in the compositor config file and disable outputs disabled in the config file. --- backend/drm/drm.c | 402 +++++++++++++++++++++----------------- include/backend/drm/drm.h | 1 + 2 files changed, 227 insertions(+), 176 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 5396dcd4..a6608877 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -404,9 +404,11 @@ static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in, struct wlr_drm_plane *new = &drm->type_planes[type][crtc_res[i]]; if (*old != new) { - wlr_log(WLR_DEBUG, "Assigning plane %d -> %d to CRTC %d", + wlr_log(WLR_DEBUG, + "Assigning plane %d -> %d (type %zu) to CRTC %d", *old ? (int)(*old)->id : -1, new ? (int)new->id : -1, + type, c->id); changed_outputs[crtc_res[i]] = true; @@ -420,192 +422,41 @@ static void realloc_planes(struct wlr_drm_backend *drm, const uint32_t *crtc_in, } } -static void realloc_crtcs(struct wlr_drm_backend *drm, - struct wlr_drm_connector *conn, bool *changed_outputs) { - uint32_t crtc[drm->num_crtcs]; - uint32_t crtc_res[drm->num_crtcs]; - ssize_t num_outputs = wl_list_length(&drm->outputs); - uint32_t possible_crtc[num_outputs]; - - for (size_t i = 0; i < drm->num_crtcs; ++i) { - crtc[i] = UNMATCHED; - } - - memset(possible_crtc, 0, sizeof(possible_crtc)); - - wlr_log(WLR_DEBUG, "Reallocating CRTCs for output '%s'", conn->output.name); - - ssize_t index = -1, i = -1; - struct wlr_drm_connector *c; - wl_list_for_each(c, &drm->outputs, link) { - i++; - if (c == conn) { - index = i; - } - - wlr_log(WLR_DEBUG, "output '%s' crtc=%p state=%d", - c->output.name, c->crtc, c->state); - - if (c->crtc) { - crtc[c->crtc - drm->crtcs] = i; - } - - if (c->state == WLR_DRM_CONN_CONNECTED) { - possible_crtc[i] = c->possible_crtc; - } - } - assert(index != -1); - - possible_crtc[index] = conn->possible_crtc; - match_obj(wl_list_length(&drm->outputs), possible_crtc, - drm->num_crtcs, crtc, crtc_res); - - bool matched[num_outputs]; - memset(matched, false, sizeof(matched)); - for (size_t i = 0; i < drm->num_crtcs; ++i) { - if (crtc_res[i] != UNMATCHED) { - matched[crtc_res[i]] = true; - } - } - - // There is no point doing anything if this monitor doesn't get activated - if (!matched[index]) { - wlr_log(WLR_DEBUG, "Could not match a CRTC for this output"); - return; - } - - for (size_t i = 0; i < drm->num_crtcs; ++i) { - // We don't want any of the current monitors to be deactivated. - if (crtc[i] != UNMATCHED && !matched[crtc[i]]) { - wlr_log(WLR_DEBUG, "Could not match a CRTC for other output %d", - crtc[i]); - return; - } - } - - changed_outputs[index] = true; - - for (size_t i = 0; i < drm->num_crtcs; ++i) { - if (crtc_res[i] == UNMATCHED) { - continue; - } - - if (crtc_res[i] != crtc[i]) { - changed_outputs[crtc_res[i]] = true; - struct wlr_drm_connector *c; - size_t pos = 0; - wl_list_for_each(c, &drm->outputs, link) { - if (pos == crtc_res[i]) { - break; - } - pos++; - } - c->crtc = &drm->crtcs[i]; - - wlr_log(WLR_DEBUG, "Assigning CRTC %d to output '%s'", - drm->crtcs[i].id, c->output.name); - } - } - - realloc_planes(drm, crtc_res, changed_outputs); -} - -static uint32_t get_possible_crtcs(int fd, uint32_t conn_id) { - drmModeConnector *conn = drmModeGetConnector(fd, conn_id); - if (!conn) { - wlr_log_errno(WLR_ERROR, "Failed to get DRM connector"); - return 0; - } - - if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0) { - wlr_log(WLR_ERROR, "Output is not connected"); - goto error_conn; - } - - drmModeEncoder *enc = NULL; - for (int i = 0; !enc && i < conn->count_encoders; ++i) { - enc = drmModeGetEncoder(fd, conn->encoders[i]); - } - - if (!enc) { - wlr_log(WLR_ERROR, "Failed to get DRM encoder"); - goto error_conn; - } - - uint32_t ret = enc->possible_crtcs; - drmModeFreeEncoder(enc); - drmModeFreeConnector(conn); - return ret; - -error_conn: - drmModeFreeConnector(conn); - return 0; -} - static void drm_connector_cleanup(struct wlr_drm_connector *conn); static bool drm_connector_set_mode(struct wlr_output *output, struct wlr_output_mode *mode) { struct wlr_drm_connector *conn = (struct wlr_drm_connector *)output; struct wlr_drm_backend *drm = (struct wlr_drm_backend *)output->backend; - bool changed_outputs[wl_list_length(&drm->outputs)]; - - wlr_log(WLR_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", conn->output.name, - mode->width, mode->height, mode->refresh); - - conn->possible_crtc = get_possible_crtcs(drm->fd, conn->id); - if (conn->possible_crtc == 0) { - goto error_conn; + if (conn->crtc == NULL) { + wlr_log(WLR_ERROR, "Cannot modeset '%s': no CRTC for this connector", + conn->output.name); + // Save the desired mode for later, when we'll get a proper CRTC + conn->desired_mode = mode; + return false; } - memset(changed_outputs, false, sizeof(changed_outputs)); - realloc_crtcs(drm, conn, changed_outputs); + wlr_log(WLR_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", + conn->output.name, mode->width, mode->height, mode->refresh); - struct wlr_drm_crtc *crtc = conn->crtc; - if (!crtc) { - wlr_log(WLR_ERROR, "Unable to match %s with a CRTC", conn->output.name); + if (!init_drm_plane_surfaces(conn->crtc->primary, drm, + mode->width, mode->height, GBM_FORMAT_XRGB8888)) { + wlr_log(WLR_ERROR, "Failed to initialize renderer for plane"); return false; } - wlr_log(WLR_DEBUG, "%s: crtc=%td ovr=%td pri=%td cur=%td", conn->output.name, - crtc - drm->crtcs, - crtc->overlay ? crtc->overlay - drm->overlay_planes : -1, - crtc->primary ? crtc->primary - drm->primary_planes : -1, - crtc->cursor ? crtc->cursor - drm->cursor_planes : -1); conn->state = WLR_DRM_CONN_CONNECTED; + conn->desired_mode = NULL; wlr_output_update_mode(&conn->output, mode); + wlr_output_update_enabled(&conn->output, true); + + drm_connector_start_renderer(conn); // When switching VTs, the mode is not updated but the buffers become // invalid, so we need to manually damage the output here wlr_output_damage_whole(&conn->output); - // Since realloc_crtcs can deallocate planes on OTHER outputs, - // we actually need to reinitialize any that has changed - ssize_t output_index = -1; - wl_list_for_each(conn, &drm->outputs, link) { - output_index++; - struct wlr_output_mode *mode = conn->output.current_mode; - struct wlr_drm_crtc *crtc = conn->crtc; - - if (conn->state != WLR_DRM_CONN_CONNECTED || - !changed_outputs[output_index]) { - continue; - } - - if (!init_drm_plane_surfaces(crtc->primary, drm, - mode->width, mode->height, GBM_FORMAT_XRGB8888)) { - wlr_log(WLR_ERROR, "Failed to initialize renderer for plane"); - goto error_conn; - } - - drm_connector_start_renderer(conn); - } - return true; - -error_conn: - drm_connector_cleanup(conn); - return false; } bool wlr_drm_connector_add_mode(struct wlr_output *output, @@ -855,6 +706,167 @@ static const int32_t subpixel_map[] = { [DRM_MODE_SUBPIXEL_NONE] = WL_OUTPUT_SUBPIXEL_NONE, }; +static void dealloc_crtc(struct wlr_drm_connector *conn) { + struct wlr_drm_backend *drm = (struct wlr_drm_backend *)conn->output.backend; + if (conn->crtc == NULL) { + return; + } + + for (size_t type = 0; type < 3; ++type) { + struct wlr_drm_plane *plane = conn->crtc->planes[type]; + if (plane == NULL) { + continue; + } + + finish_drm_surface(&plane->surf); + conn->crtc->planes[type] = NULL; + } + + drm->iface->conn_enable(drm, conn, false); + + conn->crtc = NULL; +} + +void realloc_crtcs(struct wlr_drm_backend *drm, bool *changed_outputs) { + size_t num_outputs = wl_list_length(&drm->outputs); + + wlr_log(WLR_DEBUG, "Reallocating CRTCs"); + + uint32_t crtc[drm->num_crtcs]; + for (size_t i = 0; i < drm->num_crtcs; ++i) { + crtc[i] = UNMATCHED; + } + + uint32_t possible_crtc[num_outputs]; + memset(possible_crtc, 0, sizeof(possible_crtc)); + + wlr_log(WLR_DEBUG, "State before reallocation:"); + ssize_t i = -1; + struct wlr_drm_connector *conn; + wl_list_for_each(conn, &drm->outputs, link) { + i++; + + wlr_log(WLR_DEBUG, " '%s' crtc=%d state=%d", conn->output.name, + conn->crtc ? (int)(conn->crtc - drm->crtcs) : -1, conn->state); + + if (conn->crtc) { + crtc[conn->crtc - drm->crtcs] = i; + } + + if (conn->state == WLR_DRM_CONN_CONNECTED || + conn->state == WLR_DRM_CONN_NEEDS_MODESET) { + possible_crtc[i] = conn->possible_crtc; + } + } + + uint32_t crtc_res[drm->num_crtcs]; + match_obj(wl_list_length(&drm->outputs), possible_crtc, + drm->num_crtcs, crtc, crtc_res); + + bool matched[num_outputs]; + memset(matched, false, sizeof(matched)); + for (size_t i = 0; i < drm->num_crtcs; ++i) { + if (crtc_res[i] != UNMATCHED) { + matched[crtc_res[i]] = true; + } + } + + for (size_t i = 0; i < drm->num_crtcs; ++i) { + // We don't want any of the current monitors to be deactivated + if (crtc[i] != UNMATCHED && !matched[crtc[i]]) { + wlr_log(WLR_DEBUG, "Could not match a CRTC for connected output %d", + crtc[i]); + return; + } + } + + for (size_t i = 0; i < drm->num_crtcs; ++i) { + if (crtc_res[i] == UNMATCHED) { + continue; + } + + if (crtc_res[i] != crtc[i]) { + changed_outputs[crtc_res[i]] = true; + + struct wlr_drm_connector *c; + size_t pos = 0; + wl_list_for_each(c, &drm->outputs, link) { + if (pos == crtc_res[i]) { + break; + } + pos++; + } + + dealloc_crtc(c); + c->crtc = &drm->crtcs[i]; + + wlr_log(WLR_DEBUG, "Assigning CRTC %zu to output %d -> %d '%s'", + i, crtc[i], crtc_res[i], c->output.name); + } + } + + wlr_log(WLR_DEBUG, "State after reallocation:"); + wl_list_for_each(conn, &drm->outputs, link) { + wlr_log(WLR_DEBUG, " '%s' crtc=%d state=%d", conn->output.name, + conn->crtc ? (int)(conn->crtc - drm->crtcs) : -1, conn->state); + } + + realloc_planes(drm, crtc_res, changed_outputs); + + // We need to reinitialize any plane that has changed + i = -1; + wl_list_for_each(conn, &drm->outputs, link) { + i++; + struct wlr_output_mode *mode = conn->output.current_mode; + + if (conn->state != WLR_DRM_CONN_CONNECTED || !changed_outputs[i]) { + continue; + } + assert(conn->crtc); + + if (!init_drm_plane_surfaces(conn->crtc->primary, drm, + mode->width, mode->height, GBM_FORMAT_XRGB8888)) { + wlr_log(WLR_ERROR, "Failed to initialize renderer for plane"); + drm_connector_cleanup(conn); + break; + } + + drm_connector_start_renderer(conn); + } +} + +static uint32_t get_possible_crtcs(int fd, uint32_t conn_id) { + drmModeConnector *conn = drmModeGetConnector(fd, conn_id); + if (!conn) { + wlr_log_errno(WLR_ERROR, "Failed to get DRM connector"); + return 0; + } + + if (conn->connection != DRM_MODE_CONNECTED || conn->count_modes == 0) { + wlr_log(WLR_ERROR, "Output is not connected"); + goto error_conn; + } + + drmModeEncoder *enc = NULL; + for (int i = 0; !enc && i < conn->count_encoders; ++i) { + enc = drmModeGetEncoder(fd, conn->encoders[i]); + } + + if (!enc) { + wlr_log(WLR_ERROR, "Failed to get DRM encoder"); + goto error_conn; + } + + uint32_t ret = enc->possible_crtcs; + drmModeFreeEncoder(enc); + drmModeFreeConnector(conn); + return ret; + +error_conn: + drmModeFreeConnector(conn); + return 0; +} + void scan_drm_connectors(struct wlr_drm_backend *drm) { wlr_log(WLR_INFO, "Scanning DRM connectors"); @@ -910,17 +922,16 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { wlr_conn->state = WLR_DRM_CONN_DISCONNECTED; wlr_conn->id = drm_conn->connector_id; + snprintf(wlr_conn->output.name, sizeof(wlr_conn->output.name), + "%s-%"PRIu32, conn_get_name(drm_conn->connector_type), + drm_conn->connector_type_id); + if (curr_enc) { wlr_conn->old_crtc = drmModeGetCrtc(drm->fd, curr_enc->crtc_id); } - snprintf(wlr_conn->output.name, sizeof(wlr_conn->output.name), - "%s-%"PRIu32, - conn_get_name(drm_conn->connector_type), - drm_conn->connector_type_id); - wl_list_insert(&drm->outputs, &wlr_conn->link); - wlr_log(WLR_INFO, "Found display '%s'", wlr_conn->output.name); + wlr_log(WLR_INFO, "Found connector '%s'", wlr_conn->output.name); } else { seen[index] = true; } @@ -976,6 +987,12 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { wl_list_insert(&wlr_conn->output.modes, &mode->wlr_mode.link); } + wlr_conn->possible_crtc = get_possible_crtcs(drm->fd, wlr_conn->id); + if (wlr_conn->possible_crtc == 0) { + wlr_log(WLR_ERROR, "No CRTC possible for connector '%s'", + wlr_conn->output.name); + } + wlr_output_update_enabled(&wlr_conn->output, wlr_conn->crtc != NULL); wlr_conn->state = WLR_DRM_CONN_NEEDS_MODESET; @@ -984,7 +1001,6 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { drm_conn->connection != DRM_MODE_CONNECTED) { wlr_log(WLR_INFO, "'%s' disconnected", wlr_conn->output.name); - wlr_output_update_enabled(&wlr_conn->output, false); drm_connector_cleanup(wlr_conn); } @@ -1011,6 +1027,26 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { free(conn); } + bool changed_outputs[wl_list_length(&drm->outputs)]; + memset(changed_outputs, false, sizeof(changed_outputs)); + for (size_t i = 0; i < new_outputs_len; ++i) { + struct wlr_drm_connector *conn = new_outputs[i]; + + ssize_t pos = -1; + struct wlr_drm_connector *c; + wl_list_for_each(c, &drm->outputs, link) { + ++pos; + if (c == conn) { + break; + } + } + assert(pos >= 0); + + changed_outputs[pos] = true; + } + + realloc_crtcs(drm, changed_outputs); + for (size_t i = 0; i < new_outputs_len; ++i) { struct wlr_drm_connector *conn = new_outputs[i]; @@ -1019,6 +1055,15 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { wlr_signal_emit_safe(&drm->backend.events.new_output, &conn->output); } + + // Try to modeset any output that has a desired mode and a CRTC (ie. was + // lacking a CRTC on last modeset) + wl_list_for_each(conn, &drm->outputs, link) { + if (conn->state == WLR_DRM_CONN_NEEDS_MODESET && conn->crtc != NULL && + conn->desired_mode != NULL) { + drm_connector_set_mode(&conn->output, conn->desired_mode); + } + } } static void page_flip_handler(int fd, unsigned seq, @@ -1114,23 +1159,28 @@ static void drm_connector_cleanup(struct wlr_drm_connector *conn) { } conn->output.current_mode = NULL; + conn->desired_mode = NULL; struct wlr_drm_mode *mode, *tmp; wl_list_for_each_safe(mode, tmp, &conn->output.modes, wlr_mode.link) { wl_list_remove(&mode->wlr_mode.link); free(mode); } + conn->output.enabled = false; + conn->output.width = conn->output.height = conn->output.refresh = 0; + memset(&conn->output.make, 0, sizeof(conn->output.make)); memset(&conn->output.model, 0, sizeof(conn->output.model)); memset(&conn->output.serial, 0, sizeof(conn->output.serial)); - conn->crtc = NULL; - conn->possible_crtc = 0; conn->pageflip_pending = false; /* Fallthrough */ case WLR_DRM_CONN_NEEDS_MODESET: wlr_log(WLR_INFO, "Emitting destruction signal for '%s'", conn->output.name); + dealloc_crtc(conn); + conn->possible_crtc = 0; + conn->desired_mode = NULL; wlr_signal_emit_safe(&conn->output.events.destroy, &conn->output); break; case WLR_DRM_CONN_DISCONNECTED: diff --git a/include/backend/drm/drm.h b/include/backend/drm/drm.h index 5d6ff231..fe279917 100644 --- a/include/backend/drm/drm.h +++ b/include/backend/drm/drm.h @@ -119,6 +119,7 @@ struct wlr_drm_connector { struct wlr_output output; enum wlr_drm_connector_state state; + struct wlr_output_mode *desired_mode; uint32_t id; struct wlr_drm_crtc *crtc; From 017cfb0b860c55d262f6ecdfa5ad2ef773b16760 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 19:44:44 +0200 Subject: [PATCH 15/22] backend/drm: log when de-allocating CRTC --- backend/drm/drm.c | 3 +++ types/wlr_output.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a6608877..a8cf55f6 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -712,6 +712,9 @@ static void dealloc_crtc(struct wlr_drm_connector *conn) { return; } + wlr_log(WLR_DEBUG, "De-allocating CRTC %zu for output '%s'", + conn->crtc - drm->crtcs, conn->output.name); + for (size_t type = 0; type < 3; ++type) { struct wlr_drm_plane *plane = conn->crtc->planes[type]; if (plane == NULL) { diff --git a/types/wlr_output.c b/types/wlr_output.c index 2ebf2acd..abbdab9c 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -768,7 +768,8 @@ bool wlr_output_cursor_set_image(struct wlr_output_cursor *cursor, return true; } - wlr_log(WLR_DEBUG, "Falling back to software cursor"); + wlr_log(WLR_DEBUG, "Falling back to software cursor on output '%s'", + cursor->output->name); output_cursor_damage_whole(cursor); return true; } From d605b2ea077f00dfa343e824610fad0c01232fbd Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 22:49:54 +0200 Subject: [PATCH 16/22] backend/drm: remove unused if --- backend/drm/util.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/backend/drm/util.c b/backend/drm/util.c index 52972fdd..66819c96 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -228,9 +228,6 @@ static bool match_obj_(struct match_state *st, size_t skips, size_t score, size_ st->replaced = replaced; memcpy(st->best, st->res, sizeof(st->best[0]) * st->num_res); - if (st->score == st->num_objs && st->replaced == 0) { - st->exit_early = true; - } st->exit_early = (st->score == st->num_res - skips || st->score == st->num_objs) && st->replaced == 0; From fb94f03b4388dd50bf908a1a0ab3d3eeccb8b1ad Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 22:50:59 +0200 Subject: [PATCH 17/22] backend/drm: prevent use of uninitialized data --- backend/drm/util.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/backend/drm/util.c b/backend/drm/util.c index 66819c96..4681f85a 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -298,6 +298,9 @@ size_t match_obj(size_t num_objs, const uint32_t objs[static restrict num_objs], size_t num_res, const uint32_t res[static restrict num_res], uint32_t out[static restrict num_res]) { uint32_t solution[num_res]; + for (size_t i = 0; i < num_res; ++i) { + solution[i] = UNMATCHED; + } struct match_state st = { .num_objs = num_objs, From 5b13b8a12c55b3216b1b92a20474efc856be5d7b Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 22:57:09 +0200 Subject: [PATCH 18/22] backend/drm: consider continue not using resources Fixes #1230 --- backend/drm/util.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/drm/util.c b/backend/drm/util.c index 4681f85a..c97afac6 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -247,13 +247,19 @@ static bool match_obj_(struct match_state *st, size_t skips, size_t score, size_ * Attempt to use the current solution first, to try and avoid * recalculating everything */ - if (st->orig[i] != UNMATCHED && !is_taken(i, st->res, st->orig[i])) { st->res[i] = st->orig[i]; if (match_obj_(st, skips, score + 1, replaced, i + 1)) { return true; } } + if (st->orig[i] == UNMATCHED) { + st->res[i] = UNMATCHED; + match_obj_(st, skips, score, replaced, i + 1); + if (st->exit_early) { + return true; + } + } if (st->orig[i] != UNMATCHED) { ++replaced; From 1342393632ca93c340fb4bc1dcb2824424bee939 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 23:08:45 +0200 Subject: [PATCH 19/22] backend/drm: cosmetic enhancements --- backend/drm/util.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/backend/drm/util.c b/backend/drm/util.c index c97afac6..050da2a6 100644 --- a/backend/drm/util.c +++ b/backend/drm/util.c @@ -265,25 +265,26 @@ static bool match_obj_(struct match_state *st, size_t skips, size_t score, size_ ++replaced; } - bool is_best = false; - for (st->res[i] = 0; st->res[i] < st->num_objs; ++st->res[i]) { + bool has_best = false; + for (size_t candidate = 0; candidate < st->num_objs; ++candidate) { // We tried this earlier - if (st->res[i] == st->orig[i]) { + if (candidate == st->orig[i]) { continue; } // Not compatible - if (!(st->objs[st->res[i]] & (1 << i))) { + if (!(st->objs[candidate] & (1 << i))) { continue; } // Already taken - if (is_taken(i, st->res, st->res[i])) { + if (is_taken(i, st->res, candidate)) { continue; } + st->res[i] = candidate; if (match_obj_(st, skips, score + 1, replaced, i + 1)) { - is_best = true; + has_best = true; } if (st->exit_early) { @@ -291,7 +292,7 @@ static bool match_obj_(struct match_state *st, size_t skips, size_t score, size_ } } - if (is_best) { + if (has_best) { return true; } From 8a6bdc193d552119c828c4f9270fe6881fe5d083 Mon Sep 17 00:00:00 2001 From: emersion Date: Tue, 4 Sep 2018 23:10:37 +0200 Subject: [PATCH 20/22] backend/drm: damage outputs when switching CRTCs --- backend/drm/drm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a8cf55f6..43b6e3b1 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -835,6 +835,8 @@ void realloc_crtcs(struct wlr_drm_backend *drm, bool *changed_outputs) { } drm_connector_start_renderer(conn); + + wlr_output_damage_whole(&conn->output); } } From 2d29cebe5f948ac67d65ff46aaa7f6108d34544f Mon Sep 17 00:00:00 2001 From: Scott Anderson Date: Wed, 5 Sep 2018 11:59:38 +1200 Subject: [PATCH 21/22] Remove indent_size from .editorconfig Some of us like to use different indent sizes. --- .editorconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index b6b6a367..c74fecda 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,10 +5,8 @@ end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = tab -indent_size = 4 trim_trailing_whitespace = true [*.xml] indent_style = space indent_size = 2 -tab_width = 8 From f6168c2afeece02b118b2bc43412fc3344e59028 Mon Sep 17 00:00:00 2001 From: nyorain Date: Fri, 7 Sep 2018 14:48:28 +0200 Subject: [PATCH 22/22] Fix #1129 and remove sx, sy from wlr_drag_icon sx, sy used to store the buffer offset of the drag surface which was then be added (by rootston) to the drag icon position. Buffer offsets are handled already in surface_intersect_output (output.c) so they were added twice for dnd surfaces. --- include/wlr/types/wlr_data_device.h | 2 -- rootston/seat.c | 8 ++++---- types/data_device/wlr_drag.c | 3 --- 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index cc04c9e9..c45e8d1c 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -93,8 +93,6 @@ struct wlr_drag_icon { bool is_pointer; int32_t touch_id; - int32_t sx, sy; - struct { struct wl_signal map; struct wl_signal unmap; diff --git a/rootston/seat.c b/rootston/seat.c index 9010d6e3..c11ff017 100644 --- a/rootston/seat.c +++ b/rootston/seat.c @@ -502,16 +502,16 @@ void roots_drag_icon_update_position(struct roots_drag_icon *icon) { struct roots_seat *seat = icon->seat; struct wlr_cursor *cursor = seat->cursor->cursor; if (wlr_icon->is_pointer) { - icon->x = cursor->x + wlr_icon->sx; - icon->y = cursor->y + wlr_icon->sy; + icon->x = cursor->x; + icon->y = cursor->y; } else { struct wlr_touch_point *point = wlr_seat_touch_get_point(seat->seat, wlr_icon->touch_id); if (point == NULL) { return; } - icon->x = seat->touch_x + wlr_icon->sx; - icon->y = seat->touch_y + wlr_icon->sy; + icon->x = seat->touch_x; + icon->y = seat->touch_y; } roots_drag_icon_damage_whole(icon); diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c index 7f3b346d..fcde7b3e 100644 --- a/types/data_device/wlr_drag.c +++ b/types/data_device/wlr_drag.c @@ -345,9 +345,6 @@ static void drag_icon_surface_role_commit(struct wlr_surface *surface) { return; } - icon->sx += icon->surface->current.dx; - icon->sy += icon->surface->current.dy; - drag_icon_set_mapped(icon, wlr_surface_has_buffer(surface)); }