]> git.mdlowis.com Git - proto/labwc.git/commitdiff
output: add output_init() and refactor
authorJohan Malm <jgm323@gmail.com>
Tue, 29 Sep 2020 18:53:46 +0000 (19:53 +0100)
committerJohan Malm <jgm323@gmail.com>
Tue, 29 Sep 2020 18:53:46 +0000 (19:53 +0100)
include/labwc.h
src/output.c
src/server.c

index b801e246b8492ceab1d19a9538280aef026d8e4a..dedae5c4c2f11adbc815062a39aa933826ea35de 100644 (file)
@@ -45,6 +45,7 @@ enum cursor_mode {
 struct server {
        struct wl_display *wl_display;
        struct wlr_renderer *renderer;
+       struct wlr_backend *backend;
 
        struct wlr_xdg_shell *xdg_shell;
        struct wl_listener new_xdg_surface;
@@ -88,6 +89,7 @@ struct output {
        struct server *server;
        struct wlr_output *wlr_output;
        struct wl_listener frame;
+       struct wl_listener destroy;
 };
 
 enum view_type { LAB_XDG_SHELL_VIEW, LAB_XWAYLAND_VIEW };
@@ -232,8 +234,7 @@ void cursor_new(struct server *server, struct wlr_input_device *device);
 
 void keyboard_new(struct server *server, struct wlr_input_device *device);
 
-void output_frame(struct wl_listener *listener, void *data);
-void output_new(struct wl_listener *listener, void *data);
+void output_init(struct server *server);
 
 struct border deco_thickness(struct view *view);
 struct wlr_box deco_max_extents(struct view *view);
index a2c1df95dff37026853a14f32438f60c148960bf..7058b01c58362d14f9106d9b1dabd493256af912 100644 (file)
@@ -1,3 +1,4 @@
+#include <wlr/types/wlr_xdg_output_v1.h>
 #include "labwc.h"
 #include "theme/theme.h"
 
@@ -231,11 +232,13 @@ render_surface(struct wlr_surface *surface, int sx, int sy, void *data)
        wlr_surface_send_frame_done(surface, rdata->when);
 }
 
-void
-output_frame(struct wl_listener *listener, void *data)
+static void
+output_frame_notify(struct wl_listener *listener, void *data)
 {
-       /* This function is called every time an output is ready to display a
-        * frame, generally at the output's refresh rate (e.g. 60Hz). */
+       /*
+        * This function is called every time an output is ready to display a
+        * frame, generally at the output's refresh rate (e.g. 60Hz).
+        */
        struct output *output = wl_container_of(listener, output, frame);
        struct wlr_renderer *renderer = output->server->renderer;
 
@@ -246,19 +249,17 @@ output_frame(struct wl_listener *listener, void *data)
        if (!wlr_output_attach_render(output->wlr_output, NULL)) {
                return;
        }
+
        /* The "effective" resolution can change if you rotate your outputs. */
        int width, height;
        wlr_output_effective_resolution(output->wlr_output, &width, &height);
-       /* Begin the renderer (calls glViewport and some other GL sanity checks)
-        */
+
+       /* Calls glViewport and some other GL sanity checks */
        wlr_renderer_begin(renderer, width, height);
 
        float color[4] = { 0.3, 0.3, 0.3, 1.0 };
        wlr_renderer_clear(renderer, color);
 
-       /* Each subsequent window we render is rendered on top of the last.
-        * Because our view list is ordered front-to-back, we iterate over it
-        * backwards. */
        struct view *view;
        wl_list_for_each_reverse (view, &output->server->views, link) {
                if (!view->mapped)
@@ -305,23 +306,23 @@ output_frame(struct wl_listener *listener, void *data)
                render_surface(s, 0, 0, &rdata);
        }
 
-       /* Hardware cursors are rendered by the GPU on a separate plane, and can
-        * be moved around without re-rendering what's beneath them - which is
-        * more efficient. However, not all hardware supports hardware cursors.
-        * For this reason, wlroots provides a software fallback, which we ask
-        * it to render here. wlr_cursor handles configuring hardware vs
-        * software cursors for you,
-        * and this function is a no-op when hardware cursors are in use. */
+       /* Just in case hardware cursors not supported by GPU */
        wlr_output_render_software_cursors(output->wlr_output, NULL);
 
-       /* Conclude rendering and swap the buffers, showing the final frame
-        * on-screen. */
        wlr_renderer_end(renderer);
        wlr_output_commit(output->wlr_output);
 }
 
-void
-output_new(struct wl_listener *listener, void *data)
+static void
+output_destroy_notify(struct wl_listener *listener, void *data)
+{
+        struct output *output = wl_container_of(listener, output, destroy);
+        wl_list_remove(&output->link);
+}
+
+
+static void
+new_output_notify(struct wl_listener *listener, void *data)
 {
        /* This event is rasied by the backend when a new output (aka a display
         * or monitor) becomes available. */
@@ -329,39 +330,51 @@ output_new(struct wl_listener *listener, void *data)
        struct wlr_output *wlr_output = data;
 
        /*
-        * Some backends don't have modes. DRM+KMS does, and we need to set a
-        * mode before we can use the output. The mode is a tuple of (width,
-        * height, refresh rate), and each monitor supports only a specific set
-        * of modes. We just pick the monitor's preferred mode.
+        * The mode is a tuple of (width, height, refresh rate).
         * TODO: support user configuration
         */
-       if (!wl_list_empty(&wlr_output->modes)) {
-               struct wlr_output_mode *mode =
-                       wlr_output_preferred_mode(wlr_output);
+       struct wlr_output_mode *mode = wlr_output_preferred_mode(wlr_output);
+       if (mode) {
                wlr_output_set_mode(wlr_output, mode);
-               wlr_output_enable(wlr_output, true);
-               if (!wlr_output_commit(wlr_output)) {
-                       return;
-               }
+               wlr_output_commit(wlr_output);
        }
 
-       /* Allocates and configures our state for this output */
        struct output *output = calloc(1, sizeof(struct output));
        output->wlr_output = wlr_output;
        output->server = server;
-       /* Sets up a listener for the frame notify event. */
-       output->frame.notify = output_frame;
+       output->frame.notify = output_frame_notify;
        wl_signal_add(&wlr_output->events.frame, &output->frame);
        wl_list_insert(&server->outputs, &output->link);
+       output->destroy.notify = output_destroy_notify;
+       wl_signal_add(&wlr_output->events.destroy, &output->destroy);
 
-       /* Adds this to the output layout. The add_auto function arranges
-        * outputs from left-to-right in the order they appear. A more
-        * sophisticated compositor would let the user configure the arrangement
-        * of outputs in the layout.
-        *
-        * The output layout utility automatically adds a wl_output global to
-        * the display, which Wayland clients can see to find out information
-        * about the output (such as DPI, scale factor, manufacturer, etc).
+       /*
+        * Arrange outputs from left-to-right in the order they appear.
+        * TODO: support configuration in run-time
         */
        wlr_output_layout_add_auto(server->output_layout, wlr_output);
+       wlr_output_schedule_frame(wlr_output);
+}
+
+void
+output_init(struct server *server)
+{
+       server->new_output.notify = new_output_notify;
+       wl_signal_add(&server->backend->events.new_output, &server->new_output);
+
+       /*
+        * Create an output layout, which is a wlroots utility for working with
+        * an arrangement of screens in a physical layout.
+        */
+       server->output_layout = wlr_output_layout_create();
+       if (!server->output_layout) {
+               wlr_log(WLR_ERROR, "unable to create output layout");
+               exit(EXIT_FAILURE);
+       }
+
+       /* Enable screen recording with wf-recorder */
+       wlr_xdg_output_manager_v1_create(server->wl_display,
+               server->output_layout);
+
+       wl_list_init(&server->outputs);
 }
index 3164ded879db6d5b416d9e5faca56b2e0a223d14..d3d696c2bc0360c9462a1a715693fda54cd297f8 100644 (file)
@@ -9,9 +9,7 @@
 #include <wlr/types/wlr_gamma_control_v1.h>
 #include <wlr/types/wlr_primary_selection_v1.h>
 #include <wlr/types/wlr_screencopy_v1.h>
-#include <wlr/types/wlr_xdg_output_v1.h>
 
-static struct wlr_backend *backend;
 static struct wlr_compositor *compositor;
 static struct wl_event_source *sighup_source;
 
@@ -117,18 +115,14 @@ server_init(struct server *server)
                event_loop, SIGHUP, handle_signal, &server->wl_display);
 
        /*
-        * The backend is a wlroots feature which abstracts the underlying
-        * input and output hardware. the autocreate option will choose the
-        * most suitable backend based on the current environment, such as
-        * opening an x11 window if an x11 server is running. the null
-        * argument here optionally allows you to pass in a custom renderer if
-        * wlr_renderer doesn't meet your needs. the backend uses the
-        * renderer, for example, to fall back to software cursors if the
-        * backend does not support hardware cursors (some older gpus don't).
+        * The backend is a feature which abstracts the underlying input and
+        * output hardware. The autocreate option will choose the most suitable
+        * backend based on the current environment, such as opening an x11
+        * window if an x11 server is running.
         */
-       backend = wlr_backend_autocreate(server->wl_display, NULL);
-       if (!backend) {
-               wlr_log(WLR_ERROR, "unable to create the wlroots backend");
+       server->backend = wlr_backend_autocreate(server->wl_display, NULL);
+       if (!server->backend) {
+               wlr_log(WLR_ERROR, "unable to create backend");
                exit(EXIT_FAILURE);
        }
 
@@ -138,22 +132,11 @@ server_init(struct server *server)
         * formats it supports for shared memory, this configures that for
         * clients.
         */
-       server->renderer = wlr_backend_get_renderer(backend);
+       server->renderer = wlr_backend_get_renderer(server->backend);
        wlr_renderer_init_wl_display(server->renderer, server->wl_display);
 
        wl_list_init(&server->views);
        wl_list_init(&server->unmanaged_surfaces);
-       wl_list_init(&server->outputs);
-
-       /*
-        * Create an output layout, which a wlroots utility for working with
-        * an arrangement of screens in a physical layout.
-        */
-       server->output_layout = wlr_output_layout_create();
-       if (!server->output_layout) {
-               wlr_log(WLR_ERROR, "unable to create output layout");
-               exit(EXIT_FAILURE);
-       }
 
        /*
         * Create some hands-off wlroots interfaces. The compositor is
@@ -176,12 +159,7 @@ server_init(struct server *server)
                exit(EXIT_FAILURE);
        }
 
-       /*
-        * Configure a listener to be notified when new outputs are available
-        * on the backend.
-        */
-       server->new_output.notify = output_new;
-       wl_signal_add(&backend->events.new_output, &server->new_output);
+       output_init(server);
 
        /*
         * Configures a seat, which is a single "seat" at which a user sits
@@ -218,7 +196,7 @@ server_init(struct server *server)
 
        wl_list_init(&server->keyboards);
        server->new_input.notify = server_new_input;
-       wl_signal_add(&backend->events.new_input, &server->new_input);
+       wl_signal_add(&server->backend->events.new_input, &server->new_input);
        server->request_cursor.notify = seat_request_cursor;
        wl_signal_add(&server->seat->events.request_set_cursor,
                      &server->request_cursor);
@@ -263,8 +241,6 @@ server_init(struct server *server)
        wlr_data_control_manager_v1_create(server->wl_display);
        wlr_gamma_control_manager_v1_create(server->wl_display);
        wlr_primary_selection_v1_device_manager_create(server->wl_display);
-       wlr_xdg_output_manager_v1_create(server->wl_display,
-                                        server->output_layout);
 
        /* Init xwayland */
        server->xwayland =
@@ -320,7 +296,7 @@ server_start(struct server *server)
         * Start the backend. This will enumerate outputs and inputs, become
         * the DRM master, etc
         */
-       if (!wlr_backend_start(backend)) {
+       if (!wlr_backend_start(server->backend)) {
                wlr_log(WLR_ERROR, "unable to start the wlroots backend");
                exit(EXIT_FAILURE);
        }