diff --git a/include/kiwmi/desktop/output.h b/include/kiwmi/desktop/output.h new file mode 100644 index 0000000..276f23f --- /dev/null +++ b/include/kiwmi/desktop/output.h @@ -0,0 +1,15 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef KIWMI_DESKTOP_OUTPUT_H +#define KIWMI_DESKTOP_OUTPUT_H + +#include + +void new_output_notify(struct wl_listener *listener, void *data); + +#endif /* KIWMI_DESKTOP_OUTPUT_H */ diff --git a/include/kiwmi/output.h b/include/kiwmi/output.h new file mode 100644 index 0000000..fce4aff --- /dev/null +++ b/include/kiwmi/output.h @@ -0,0 +1,26 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#ifndef KIWMI_OUTPUT_H +#define KIWMI_OUTPUT_H + +#include +#include + +#include "kiwmi/server.h" + +struct kiwmi_output { + struct wl_list link; + struct kiwmi_server *server; + struct wlr_output *wlr_output; + struct wl_listener frame; + struct wl_listener destroy; +}; + +struct kiwmi_output *output_create(struct wlr_output *wlr_output, struct kiwmi_server *server); + +#endif /* KIWMI_OUTPUT_H */ diff --git a/include/kiwmi/server.h b/include/kiwmi/server.h index aaab5b1..4f96819 100644 --- a/include/kiwmi/server.h +++ b/include/kiwmi/server.h @@ -21,10 +21,12 @@ struct kiwmi_server { struct wlr_data_device_manager *data_device_manager; struct wlr_output_layout *output_layout; const char *socket; + struct wl_list outputs; // struct kiwmi_output::link + struct wl_listener new_output; }; bool server_init(struct kiwmi_server *server); -void server_run(struct kiwmi_server *server); +bool server_run(struct kiwmi_server *server); void server_fini(struct kiwmi_server *server); #endif /* KIWMI_SERVER_H */ diff --git a/kiwmi/desktop/output.c b/kiwmi/desktop/output.c new file mode 100644 index 0000000..72c29ad --- /dev/null +++ b/kiwmi/desktop/output.c @@ -0,0 +1,41 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "kiwmi/desktop/output.h" + +#include +#include +#include + +#include "kiwmi/output.h" +#include "kiwmi/server.h" + +void +new_output_notify(struct wl_listener *listener, void *data) +{ + struct kiwmi_server *server = wl_container_of(listener, server, new_output); + struct wlr_output *wlr_output = data; + + wlr_log(WLR_DEBUG, "New output %p: %s", wlr_output, wlr_output->name); + + if (!wl_list_empty(&wlr_output->modes)) { + struct wlr_output_mode *mode = wl_container_of(wlr_output->modes.prev, mode, link); + wlr_output_set_mode(wlr_output, mode); + } + + struct kiwmi_output *output = output_create(wlr_output, server); + if (!output) { + wlr_log(WLR_ERROR, "Failed to create output"); + return; + } + + wl_list_insert(&server->outputs, &output->link); + + wlr_output_layout_add_auto(server->output_layout, wlr_output); + + wlr_output_create_global(wlr_output); +} diff --git a/kiwmi/main.c b/kiwmi/main.c index 1eedf71..1ccd33f 100644 --- a/kiwmi/main.c +++ b/kiwmi/main.c @@ -26,7 +26,10 @@ main(void) wlr_log(WLR_INFO, "Starting kiwmi v" KIWMI_VERSION); - server_run(&server); + if (!server_run(&server)) { + wlr_log(WLR_ERROR, "Failed to run server"); + exit(EXIT_FAILURE); + } server_fini(&server); } diff --git a/kiwmi/meson.build b/kiwmi/meson.build index 150c379..72efcab 100644 --- a/kiwmi/meson.build +++ b/kiwmi/meson.build @@ -1,6 +1,8 @@ kiwmi_sources = files( 'main.c', 'server.c', + 'output.c', + 'desktop/output.c', ) kiwmi_deps = [ diff --git a/kiwmi/output.c b/kiwmi/output.c new file mode 100644 index 0000000..3783dca --- /dev/null +++ b/kiwmi/output.c @@ -0,0 +1,71 @@ +/* Copyright (c), Niclas Meyer + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at https://mozilla.org/MPL/2.0/. + */ + +#include "kiwmi/output.h" + +#include + +#include +#include +#include + +#include "kiwmi/server.h" + +static void output_frame_notify(struct wl_listener *listener, void *data); +static void output_destroy_nofity(struct wl_listener *listener, void *data); + +struct kiwmi_output * +output_create(struct wlr_output *wlr_output, struct kiwmi_server *server) +{ + struct kiwmi_output *output = calloc(1, sizeof(*output)); + if (!output) { + return NULL; + } + + output->wlr_output = wlr_output; + output->server = server; + + output->frame.notify = output_frame_notify; + wl_signal_add(&wlr_output->events.frame, &output->frame); + + output->destroy.notify = output_destroy_nofity; + wl_signal_add(&wlr_output->events.destroy, &output->destroy); + + return output; +} + +static void +output_frame_notify(struct wl_listener *listener, void *data) +{ + struct kiwmi_output *output = wl_container_of(listener, output, frame); + struct wlr_output *wlr_output = data; + struct wlr_renderer *renderer = wlr_backend_get_renderer(wlr_output->backend); + + wlr_output_make_current(wlr_output, NULL); + wlr_renderer_begin(renderer, wlr_output->width, wlr_output->height); + { + float color[] = {0.18f, 0.20f, 0.25f, 1.0f}; + wlr_renderer_clear(renderer, color); + wlr_output_render_software_cursors(wlr_output, NULL); + wlr_output_swap_buffers(wlr_output, NULL, NULL); + } + wlr_renderer_end(renderer); +} + +static void +output_destroy_nofity(struct wl_listener *listener, void *data) +{ + struct kiwmi_output *output = wl_container_of(listener, output, destroy); + + wlr_output_layout_remove(output->server->output_layout, output->wlr_output); + + wl_list_remove(&output->link); + wl_list_remove(&output->frame.link); + wl_list_remove(&output->frame.link); + + free(output); +} diff --git a/kiwmi/server.c b/kiwmi/server.c index 2a99a4a..e3abe5a 100644 --- a/kiwmi/server.c +++ b/kiwmi/server.c @@ -17,6 +17,8 @@ #include #include +#include "kiwmi/desktop/output.h" + bool server_init(struct kiwmi_server *server) { @@ -26,6 +28,7 @@ server_init(struct kiwmi_server *server) server->backend = wlr_backend_autocreate(server->wl_display, NULL); if (!server->backend) { wlr_log(WLR_ERROR, "Failed to create backend"); + wl_display_destroy(server->wl_display); return false; } @@ -37,6 +40,19 @@ server_init(struct kiwmi_server *server) server->output_layout = wlr_output_layout_create(); + wl_list_init(&server->outputs); + + server->new_output.notify = new_output_notify; + wl_signal_add(&server->backend->events.new_output, &server->new_output); + + return true; +} + +bool +server_run(struct kiwmi_server *server) +{ + wlr_log(WLR_DEBUG, "Running Wayland server on display '%s'", server->socket); + server->socket = wl_display_add_socket_auto(server->wl_display); if (!server->socket) { wlr_log(WLR_ERROR, "Failed to open Wayland socket"); @@ -54,15 +70,9 @@ server_init(struct kiwmi_server *server) setenv("WAYLAND_DISPLAY", server->socket, true); - return true; -} - -void -server_run(struct kiwmi_server *server) -{ - wlr_log(WLR_DEBUG, "Running Wayland server on display '%s'", server->socket); - wl_display_run(server->wl_display); + + return true; } void