diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-09-23 00:29:53 -0400 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-09-23 00:30:39 -0400 |
commit | b6d7c3ed8ec6ae29af5d585db5417394ff49f3c7 (patch) | |
tree | c3faaa0fdc17e7f4d72a9843bb64d0aed0a2c396 /rootston | |
parent | 550748681db7f75888beab41a1a85eb86876604c (diff) |
Initialize display, backend; add frame handling
Diffstat (limited to 'rootston')
-rw-r--r-- | rootston/desktop.c | 59 | ||||
-rw-r--r-- | rootston/main.c | 41 | ||||
-rw-r--r-- | rootston/meson.build | 6 | ||||
-rw-r--r-- | rootston/output.c | 101 |
4 files changed, 200 insertions, 7 deletions
diff --git a/rootston/desktop.c b/rootston/desktop.c new file mode 100644 index 00000000..551d289a --- /dev/null +++ b/rootston/desktop.c @@ -0,0 +1,59 @@ +#define _POSIX_C_SOURCE 199309L +#include <time.h> +#include <stdlib.h> +#include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_compositor.h> +#include <wlr/types/wlr_wl_shell.h> +#include <wlr/types/wlr_xdg_shell_v6.h> +#include <wlr/types/wlr_gamma_control.h> +#include <wlr/util/log.h> +#include "rootston/desktop.h" +#include "rootston/server.h" + +static void handle_xdg_shell_v6_surface(struct wl_listener *listener, + void *data) { + struct roots_desktop *desktop = + wl_container_of(listener, desktop, xdg_shell_v6_surface); + struct wlr_xdg_surface_v6 *surface = data; + wlr_log(L_DEBUG, "new xdg surface: title=%s, app_id=%s", + surface->title, surface->app_id); + wlr_xdg_surface_v6_ping(surface); +} + +struct roots_desktop *desktop_create(struct roots_server *server, + struct roots_config *config) { + struct roots_desktop *desktop = calloc(1, sizeof(struct roots_desktop)); + wlr_log(L_DEBUG, "Initializing roots desktop"); + + wl_list_init(&desktop->outputs); + wl_list_init(&desktop->output_add.link); + desktop->output_add.notify = output_add_notify; + wl_list_init(&desktop->output_remove.link); + desktop->output_remove.notify = output_remove_notify; + + wl_signal_add(&server->backend->events.output_add, + &desktop->output_add); + wl_signal_add(&server->backend->events.output_remove, + &desktop->output_remove); + + desktop->server = server; + desktop->config = config; + desktop->layout = wlr_output_layout_create(); + desktop->compositor = wlr_compositor_create( + server->wl_display, server->renderer); + desktop->wl_shell = wlr_wl_shell_create(server->wl_display); + + desktop->xdg_shell_v6 = wlr_xdg_shell_v6_create(server->wl_display); + wl_signal_add(&desktop->xdg_shell_v6->events.new_surface, + &desktop->xdg_shell_v6_surface); + desktop->xdg_shell_v6_surface.notify = handle_xdg_shell_v6_surface; + + desktop->gamma_control_manager = wlr_gamma_control_manager_create( + server->wl_display); + + return desktop; +} + +void desktop_destroy(struct roots_desktop *desktop) { + // TODO +} diff --git a/rootston/main.c b/rootston/main.c index 9be2ff41..b95840a9 100644 --- a/rootston/main.c +++ b/rootston/main.c @@ -1,14 +1,45 @@ +#define _POSIX_C_SOURCE 200112L +#include <assert.h> +#include <stdlib.h> #include <wayland-server.h> +#include <wlr/backend.h> +#include <wlr/render.h> +#include <wlr/render/gles2.h> #include <wlr/util/log.h> #include "rootston/config.h" #include "rootston/server.h" -struct rootston root = { 0 }; +struct roots_server server = { 0 }; int main(int argc, char **argv) { - root.config = parse_args(argc, argv); - root.wl_display = wl_display_create(); - root.wl_event_loop = wl_display_get_event_loop(root.wl_display); - wl_display_init_shm(root.wl_display); + assert(server.config = parse_args(argc, argv)); + assert(server.wl_display = wl_display_create()); + assert(server.wl_event_loop = wl_display_get_event_loop(server.wl_display)); + + assert(server.backend = wlr_backend_autocreate(server.wl_display)); + + assert(server.renderer = wlr_gles2_renderer_create(server.backend)); + wl_display_init_shm(server.wl_display); + server.desktop = desktop_create(&server, server.config); + server.data_device_manager = wlr_data_device_manager_create( + server.wl_display); + + const char *socket = wl_display_add_socket_auto(server.wl_display); + if (!socket) { + wlr_log_errno(L_ERROR, "Unable to open wayland socket"); + wlr_backend_destroy(server.backend); + return 1; + } + + wlr_log(L_INFO, "Running compositor on wayland display '%s'", socket); + setenv("_WAYLAND_DISPLAY", socket, true); + + if (!wlr_backend_start(server.backend)) { + wlr_log(L_ERROR, "Failed to start backend"); + wlr_backend_destroy(server.backend); + return 1; + } + + wl_display_run(server.wl_display); return 0; } diff --git a/rootston/meson.build b/rootston/meson.build index 501fe17e..9342d19c 100644 --- a/rootston/meson.build +++ b/rootston/meson.build @@ -1,7 +1,9 @@ executable( - 'rooston', [ - 'main.c', + 'rootson', [ 'config.c', + 'desktop.c', 'ini.c', + 'main.c', + 'output.c', ], dependencies: wlroots ) diff --git a/rootston/output.c b/rootston/output.c new file mode 100644 index 00000000..39586e0e --- /dev/null +++ b/rootston/output.c @@ -0,0 +1,101 @@ +#define _POSIX_C_SOURCE 199309L +#include <time.h> +#include <stdlib.h> +#include <wlr/types/wlr_output_layout.h> +#include <wlr/types/wlr_compositor.h> +#include <wlr/types/wlr_wl_shell.h> +#include <wlr/types/wlr_xdg_shell_v6.h> +#include <wlr/util/log.h> +#include "rootston/server.h" +#include "rootston/desktop.h" +#include "rootston/config.h" + +static void output_frame_notify(struct wl_listener *listener, void *data) { + struct wlr_output *wlr_output = data; + struct roots_output *output = wl_container_of(listener, output, frame); + struct roots_desktop *desktop = output->desktop; + struct roots_server *server = desktop->server; + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + + wlr_output_make_current(wlr_output); + wlr_renderer_begin(server->renderer, wlr_output); + + // TODO: render views + + wlr_renderer_end(server->renderer); + wlr_output_swap_buffers(wlr_output); + + output->last_frame = desktop->last_frame = now; +} + +void output_add_notify(struct wl_listener *listener, void *data) { + struct wlr_output *wlr_output = data; + struct roots_desktop *desktop = wl_container_of(listener, desktop, output_add); + struct roots_config *config = desktop->config; + + wlr_log(L_DEBUG, "Output '%s' added", wlr_output->name); + wlr_log(L_DEBUG, "%s %s %"PRId32"mm x %"PRId32"mm", + wlr_output->make, wlr_output->model, + wlr_output->phys_width, wlr_output->phys_height); + if (wlr_output->modes->length > 0) { + wlr_output_set_mode(wlr_output, wlr_output->modes->items[0]); + } + + struct roots_output *output = calloc(1, sizeof(struct roots_output)); + clock_gettime(CLOCK_MONOTONIC, &output->last_frame); + output->desktop = desktop; + output->wlr_output = wlr_output; + output->frame.notify = output_frame_notify; + wl_list_init(&output->frame.link); + wl_signal_add(&wlr_output->events.frame, &output->frame); + wl_list_insert(&desktop->outputs, &output->link); + + struct output_config *output_config = config_get_output(config, wlr_output); + if (output_config) { + wlr_output_transform(wlr_output, output_config->transform); + wlr_output_layout_add(desktop->layout, + wlr_output, output_config->x, output_config->y); + } else { + wlr_output_layout_add_auto(desktop->layout, wlr_output); + } + + /* TODO: cursor + example_config_configure_cursor(sample->config, sample->cursor, + sample->compositor); + + // TODO the cursor must be set depending on which surface it is displayed + // over which should happen in the compositor. + if (!wlr_output_set_cursor(wlr_output, image->buffer, + image->width, image->width, image->height)) { + wlr_log(L_DEBUG, "Failed to set hardware cursor"); + return; + } + + wlr_cursor_warp(sample->cursor, NULL, sample->cursor->x, sample->cursor->y); + */ +} + +void output_remove_notify(struct wl_listener *listener, void *data) { + struct wlr_output *wlr_output = data; + struct roots_desktop *desktop = wl_container_of(listener, desktop, output_remove); + struct roots_output *output = NULL, *_output; + wl_list_for_each(_output, &desktop->outputs, link) { + if (_output->wlr_output == wlr_output) { + output = _output; + break; + } + } + if (!output) { + return; // We are unfamiliar with this output + } + wlr_output_layout_remove(desktop->layout, output->wlr_output); + // TODO: cursor + //example_config_configure_cursor(sample->config, sample->cursor, + // sample->compositor); + wl_list_remove(&output->link); + wl_list_remove(&output->frame.link); + wl_list_remove(&output->resolution.link); + free(output); +} |