From afa0c6a835daea274ee074371a1a81f617f734da Mon Sep 17 00:00:00 2001 From: Jeffy Chen Date: Fri, 3 Jul 2020 12:37:37 +0800 Subject: [PATCH 33/98] backend-drm: Support controlling compositor dynamically Use config file to control compositor's state. Default config file is "/tmp/.weston_drm.conf", can override with "WESTON_DRM_CONFIG" environment. Supported configs format is "compositor::", for example: echo "compositor:state:sleep" > /tmp/.weston_drm.conf echo "compositor:state:block" > /tmp/.weston_drm.conf echo "compositor:state:freeze" > /tmp/.weston_drm.conf echo "compositor:state:offscreen" > /tmp/.weston_drm.conf echo "compositor:state:off" > /tmp/.weston_drm.conf echo "compositor:state:on" > /tmp/.weston_drm.conf echo "compositor:hotplug:off" > /tmp/.weston_drm.conf echo "compositor:hotplug:on" > /tmp/.weston_drm.conf echo "compositor:hotplug:force" > /tmp/.weston_drm.conf echo "compositor:cursor:hide" > /tmp/.weston_drm.conf echo "compositor:cursor:show" > /tmp/.weston_drm.conf echo "compositor:output:pin" > /tmp/.weston_drm.conf echo "compositor:output:unpin" > /tmp/.weston_drm.conf Signed-off-by: Jeffy Chen --- libweston/backend-drm/drm.c | 92 ++++++++++++++++++++++++++++++------- libweston/compositor.c | 7 ++- libweston/libinput-seat.c | 4 ++ 3 files changed, 85 insertions(+), 18 deletions(-) diff --git a/libweston/backend-drm/drm.c b/libweston/backend-drm/drm.c index e75524051..1def08f0e 100644 --- a/libweston/backend-drm/drm.c +++ b/libweston/backend-drm/drm.c @@ -213,32 +213,28 @@ close_src: static void drm_backend_update_outputs(struct drm_backend *b) { - struct weston_output *primary; + struct weston_output *base, *primary; if (!b->primary_head) return; primary = b->primary_head->base.output; - if (b->mirror_mode) { - struct weston_output *base; - - wl_list_for_each(base, &b->compositor->output_list, link) { - struct drm_output *output = to_drm_output(base); - bool is_mirror = base != primary; + wl_list_for_each(base, &b->compositor->output_list, link) { + struct drm_output *output = to_drm_output(base); + bool is_mirror = b->mirror_mode && (base != primary); - if (!output || output->is_mirror == is_mirror) - continue; + if (!output || output->is_mirror == is_mirror) + continue; - /* Make mirrors unavailable for normal views */ - output->base.unavailable = is_mirror; + /* Make mirrors unavailable for normal views */ + output->base.unavailable = is_mirror; - output->is_mirror = is_mirror; - output->state_invalid = true; + output->is_mirror = is_mirror; + output->state_invalid = true; - weston_log("Output %s changed to %s output\n", - base->name, is_mirror ? "mirror" : "main"); - } + weston_log("Output %s changed to %s output\n", + base->name, is_mirror ? "mirror" : "main"); } if (!primary) @@ -4705,6 +4701,64 @@ config_handle_output(struct drm_backend *b, const char *name, } } +static void +config_handle_compositor(struct drm_backend *b, const char *key, + const char *value) +{ + if (!strcmp(key, "state")) { + if (!strcmp(value, "sleep")) { + weston_compositor_sleep(b->compositor); + } else if (!strcmp(value, "block")) { + udev_input_disable(&b->input); + } else if (!strcmp(value, "freeze")) { + udev_input_disable(&b->input); + weston_compositor_offscreen(b->compositor); + } else if (!strcmp(value, "offscreen")) { + /* HACK: offscreen + DPMS off */ + weston_compositor_sleep(b->compositor); + weston_compositor_offscreen(b->compositor); + udev_input_enable(&b->input); + } else if (!strcmp(value, "off")) { + udev_input_disable(&b->input); + weston_compositor_sleep(b->compositor); + } else { + /* HACK: Force waking from offscreen */ + if (b->compositor->state == WESTON_COMPOSITOR_OFFSCREEN) + b->compositor->state = WESTON_COMPOSITOR_IDLE; + + weston_compositor_wake(b->compositor); + weston_compositor_damage_all(b->compositor); + udev_input_enable(&b->input); + } + } else if (!strcmp(key, "hotplug")) { + if (!strcmp(value, "off")) + wl_event_source_fd_update(b->udev_drm_source, 0); + else if (!strcmp(value, "on")) + wl_event_source_fd_update(b->udev_drm_source, + WL_EVENT_READABLE); + else if (!strcmp(value, "force")) + hotplug_timer_handler(b->drm); + } else if (!strcmp(key, "cursor")) { + if (!strcmp(value, "hide")) + b->compositor->hide_cursor = true; + else if (!strcmp(value, "show")) + b->compositor->hide_cursor = false; + + b->compositor->view_list_needs_rebuild = true; + weston_compositor_damage_all(b->compositor); + } else if (!strcmp(key, "mirror")) { + b->mirror_mode = !strcmp(value, "on"); + drm_backend_update_outputs(b); + } else if (!strcmp(key, "output")) { + if (!strcmp(value, "pin")) + b->compositor->pin_output = true; + else if (!strcmp(value, "unpin")) + b->compositor->pin_output = false; + + weston_compositor_damage_all(b->compositor); + } +} + static int config_timer_handler(void *data) { @@ -4746,7 +4800,9 @@ config_timer_handler(void *data) /** * Parse configs, formated with :: - * For example: "output:all:rotate90" + * For example: + * output:all:rotate90 + * compositor:state:off */ while (3 == fscanf(conf_fp, "%" STR(MAX_CONF_LEN) "[^:]:" @@ -4754,6 +4810,8 @@ config_timer_handler(void *data) "%" STR(MAX_CONF_LEN) "[^\n]%*c", type, key, value)) { if (!strcmp(type, "output")) config_handle_output(b, key, value); + else if (!strcmp(type, "compositor")) + config_handle_compositor(b, key, value); } fclose(conf_fp); diff --git a/libweston/compositor.c b/libweston/compositor.c index d4c4f4ed8..6313f180c 100644 --- a/libweston/compositor.c +++ b/libweston/compositor.c @@ -6206,6 +6206,10 @@ weston_compositor_wake(struct weston_compositor *compositor) { uint32_t old_state = compositor->state; + /* HACK: Avoid waking up by input */ + if (old_state == WESTON_COMPOSITOR_OFFSCREEN) + return; + /* The state needs to be changed before emitting the wake * signal because that may try to schedule a repaint which * will not work if the compositor is still sleeping */ @@ -6213,10 +6217,11 @@ weston_compositor_wake(struct weston_compositor *compositor) switch (old_state) { case WESTON_COMPOSITOR_SLEEPING: + wl_signal_emit(&compositor->wake_signal, compositor); + /* fall through */ case WESTON_COMPOSITOR_IDLE: case WESTON_COMPOSITOR_OFFSCREEN: weston_compositor_dpms(compositor, WESTON_DPMS_ON); - wl_signal_emit(&compositor->wake_signal, compositor); /* fall through */ default: wl_event_source_timer_update(compositor->idle_source, diff --git a/libweston/libinput-seat.c b/libweston/libinput-seat.c index 4f33f9bb8..aaefe6cfc 100644 --- a/libweston/libinput-seat.c +++ b/libweston/libinput-seat.c @@ -319,6 +319,10 @@ udev_input_enable(struct udev_input *input) struct udev_seat *seat; int devices_found = 0; + /* Already enabled */ + if (input->libinput_source && !input->suspended) + return 0; + loop = wl_display_get_event_loop(c->wl_display); fd = libinput_get_fd(input->libinput); input->libinput_source = -- 2.20.1