diff options
Diffstat (limited to 'wayland/registry.c')
-rw-r--r-- | wayland/registry.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/wayland/registry.c b/wayland/registry.c new file mode 100644 index 00000000..a7eb89d1 --- /dev/null +++ b/wayland/registry.c | |||
@@ -0,0 +1,116 @@ | |||
1 | #include <wayland-client.h> | ||
2 | #include <stdlib.h> | ||
3 | #include <string.h> | ||
4 | #include "wayland-desktop-shell-client-protocol.h" | ||
5 | #include "client/registry.h" | ||
6 | #include "log.h" | ||
7 | |||
8 | static void display_handle_mode(void *data, struct wl_output *wl_output, | ||
9 | uint32_t flags, int32_t width, int32_t height, int32_t refresh) { | ||
10 | struct output_state *state = data; | ||
11 | if (flags & WL_OUTPUT_MODE_CURRENT) { | ||
12 | state->flags = flags; | ||
13 | state->width = width; | ||
14 | state->height = height; | ||
15 | } | ||
16 | } | ||
17 | |||
18 | static void display_handle_geometry(void *data, struct wl_output *wl_output, | ||
19 | int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, | ||
20 | int32_t subpixel, const char *make, const char *model, int32_t transform) { | ||
21 | // this space intentionally left blank | ||
22 | } | ||
23 | |||
24 | static void display_handle_done(void *data, struct wl_output *wl_output) { | ||
25 | // this space intentionally left blank | ||
26 | } | ||
27 | |||
28 | static void display_handle_scale(void *data, struct wl_output *wl_output, int32_t factor) { | ||
29 | // this space intentionally left blank | ||
30 | } | ||
31 | |||
32 | static const struct wl_output_listener output_listener = { | ||
33 | .mode = display_handle_mode, | ||
34 | .geometry = display_handle_geometry, | ||
35 | .done = display_handle_done, | ||
36 | .scale = display_handle_scale | ||
37 | }; | ||
38 | |||
39 | static void registry_global(void *data, struct wl_registry *registry, | ||
40 | uint32_t name, const char *interface, uint32_t version) { | ||
41 | struct registry *reg = data; | ||
42 | |||
43 | if (strcmp(interface, wl_compositor_interface.name) == 0) { | ||
44 | reg->compositor = wl_registry_bind(registry, name, &wl_compositor_interface, version); | ||
45 | } else if (strcmp(interface, wl_shm_interface.name) == 0) { | ||
46 | reg->shm = wl_registry_bind(registry, name, &wl_shm_interface, version); | ||
47 | } else if (strcmp(interface, wl_shell_interface.name) == 0) { | ||
48 | reg->shell = wl_registry_bind(registry, name, &wl_shell_interface, version); | ||
49 | } else if (strcmp(interface, wl_seat_interface.name) == 0) { | ||
50 | reg->seat = wl_registry_bind(registry, name, &wl_seat_interface, version); | ||
51 | reg->pointer = wl_seat_get_pointer(reg->seat); | ||
52 | } else if (strcmp(interface, wl_output_interface.name) == 0) { | ||
53 | struct wl_output *output = wl_registry_bind(registry, name, &wl_output_interface, version); | ||
54 | struct output_state *ostate = malloc(sizeof(struct output_state)); | ||
55 | ostate->output = output; | ||
56 | wl_output_add_listener(output, &output_listener, ostate); | ||
57 | list_add(reg->outputs, ostate); | ||
58 | } else if (strcmp(interface, desktop_shell_interface.name) == 0) { | ||
59 | reg->desktop_shell = wl_registry_bind(registry, name, &desktop_shell_interface, version); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | static void registry_global_remove(void *data, struct wl_registry *registry, uint32_t name) { | ||
64 | // this space intentionally left blank | ||
65 | } | ||
66 | |||
67 | static const struct wl_registry_listener registry_listener = { | ||
68 | .global = registry_global, | ||
69 | .global_remove = registry_global_remove | ||
70 | }; | ||
71 | |||
72 | struct registry *registry_poll(void) { | ||
73 | struct registry *registry = malloc(sizeof(struct registry)); | ||
74 | memset(registry, 0, sizeof(struct registry)); | ||
75 | registry->outputs = create_list(); | ||
76 | |||
77 | registry->display = wl_display_connect(NULL); | ||
78 | if (!registry->display) { | ||
79 | sway_log(L_ERROR, "Error opening display"); | ||
80 | registry_teardown(registry); | ||
81 | return NULL; | ||
82 | } | ||
83 | |||
84 | struct wl_registry *reg = wl_display_get_registry(registry->display); | ||
85 | wl_registry_add_listener(reg, ®istry_listener, registry); | ||
86 | wl_display_dispatch(registry->display); | ||
87 | wl_display_roundtrip(registry->display); | ||
88 | wl_registry_destroy(reg); | ||
89 | |||
90 | return registry; | ||
91 | } | ||
92 | |||
93 | void registry_teardown(struct registry *registry) { | ||
94 | if (registry->pointer) { | ||
95 | wl_pointer_destroy(registry->pointer); | ||
96 | } | ||
97 | if (registry->seat) { | ||
98 | wl_seat_destroy(registry->seat); | ||
99 | } | ||
100 | if (registry->shell) { | ||
101 | wl_shell_destroy(registry->shell); | ||
102 | } | ||
103 | if (registry->shm) { | ||
104 | wl_shm_destroy(registry->shm); | ||
105 | } | ||
106 | if (registry->compositor) { | ||
107 | wl_compositor_destroy(registry->compositor); | ||
108 | } | ||
109 | if (registry->display) { | ||
110 | wl_display_disconnect(registry->display); | ||
111 | } | ||
112 | if (registry->outputs) { | ||
113 | // TODO: Free the outputs themselves | ||
114 | list_free(registry->outputs); | ||
115 | } | ||
116 | } | ||