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 7b0070bbe..0d6597802 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 754ccfa96..3ef5f4843 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 e0f5d6e72..0ff2925d7 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 450368391..c0e815ed3 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 958e90f65..87beafabe 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 2bfc59238..3f9cf84ef 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 f0d9fb4bf..cc58c223c 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 add7f42f6..7cf5727b2 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 1125bd2a3..e1c10906f 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 4817db4db..fad30d526 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 ba5d1e34b..9ed20a286 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 450368391..e53b80512 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 3f9cf84ef..2d1bc58bf 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 87a039247..3e1565cad 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 87beafabe..49670c397 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 e53b80512..eabf51197 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 cf1c2cd10..eb5d6985d 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 607cc797a..3536bbc8b 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 cebd9bbce..9c8035439 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 1068b9420..4755608f4 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 0c0ad0552..92d90de1d 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 0d6597802..2c441180a 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 | 408 +++++++++++++++++++++----------------- include/backend/drm/drm.h | 1 + 2 files changed, 230 insertions(+), 179 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 5396dcd44..a66088777 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; - } - - memset(changed_outputs, false, sizeof(changed_outputs)); - realloc_crtcs(drm, conn, changed_outputs); - - struct wlr_drm_crtc *crtc = conn->crtc; - if (!crtc) { - wlr_log(WLR_ERROR, "Unable to match %s with a CRTC", conn->output.name); + 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; + } + + wlr_log(WLR_INFO, "Modesetting '%s' with '%ux%u@%u mHz'", + conn->output.name, mode->width, mode->height, mode->refresh); + + 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 5d6ff2317..fe279917b 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 a66088777..a8cf55f65 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 2ebf2acd7..abbdab9c7 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 52972fdd4..66819c96e 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 66819c96e..4681f85a5 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 4681f85a5..c97afac64 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 c97afac64..050da2a61 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 a8cf55f65..43b6e3b13 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 b6b6a3673..c74fecda0 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 cc04c9e91..c45e8d1c9 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 9010d6e31..c11ff0173 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 7f3b346d3..fcde7b3e4 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)); }