1/* swc: libswc/xdg_output.c
2 *
3 * Copyright (c) 2026 sewn <sewn@disroot.org>
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 */
23
24#include "xdg_output.h"
25#include "output.h"
26#include "screen.h"
27#include "util.h"
28
29#include "xdg-output-unstable-v1-server-protocol.h"
30
31static const struct zxdg_output_v1_interface output_impl = {
32 .destroy = destroy_resource,
33};
34
35static void
36get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output_resource)
37{
38 struct output *output =
39 wl_resource_get_user_data(output_resource);
40 struct swc_rectangle *geom = &output->screen->base.geometry;
41 struct wl_resource *wl_output_resource;
42
43 resource = wl_resource_create(client, &zxdg_output_v1_interface, wl_resource_get_version(resource), id);
44 if (!resource) {
45 wl_client_post_no_memory(client);
46 return;
47 }
48
49 wl_resource_set_implementation(resource, &output_impl, NULL, NULL);
50 zxdg_output_v1_send_logical_position(resource, geom->x, geom->y);
51 zxdg_output_v1_send_logical_size(resource, geom->width, geom->height);
52 if (wl_resource_get_version(resource) >= 2) {
53 zxdg_output_v1_send_name(resource, output->name);
54 zxdg_output_v1_send_description(resource, output->name);
55 }
56 zxdg_output_v1_send_done(resource);
57
58 wl_output_resource =
59 wl_resource_find_for_client(&output->resources, client);
60 if (wl_output_resource && wl_resource_get_version(wl_output_resource) >= 2) {
61 wl_output_send_done(wl_output_resource);
62 }
63}
64
65static const struct zxdg_output_manager_v1_interface output_manager_impl = {
66 .destroy = destroy_resource,
67 .get_xdg_output = get_output,
68};
69
70static void
71bind_output_manager(struct wl_client *client, void *data, uint32_t version, uint32_t id)
72{
73 struct wl_resource *resource;
74
75 resource = wl_resource_create(client, &zxdg_output_manager_v1_interface, version, id);
76 if (!resource) {
77 wl_client_post_no_memory(client);
78 return;
79 }
80 wl_resource_set_implementation(resource, &output_manager_impl, NULL, NULL);
81}
82
83struct wl_global *
84xdg_output_manager_create(struct wl_display *display)
85{
86 return wl_global_create(display, &zxdg_output_manager_v1_interface, 3, NULL, &bind_output_manager);
87}