main neuswc / libswc / xdg_output.c
 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}