Skip to content

Commit 8e281f1

Browse files
authored
Update main.c
1 parent 962b65b commit 8e281f1

1 file changed

Lines changed: 19 additions & 73 deletions

File tree

source-code/main.c

Lines changed: 19 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*
1515
* Run with: ./gameframe /path/to/your/app
1616
*/
17-
1817
#include <assert.h>
1918
#include <signal.h>
2019
#include <stdbool.h>
@@ -38,6 +37,7 @@
3837
#include <wlr/types/wlr_subcompositor.h>
3938
#include <wlr/types/wlr_xdg_shell.h>
4039
#include <wlr/util/log.h>
40+
#include <wlr/types/wlr_cursor.h>
4141

4242
struct gameframe_server {
4343
struct wl_display *display;
@@ -46,30 +46,25 @@ struct gameframe_server {
4646
struct wlr_allocator *allocator;
4747
struct wlr_scene *scene;
4848
struct wlr_scene_output *scene_output;
49-
5049
struct wlr_xdg_shell *xdg_shell;
5150
struct wlr_compositor *compositor;
5251
struct wlr_subcompositor *subcompositor;
53-
5452
struct wlr_output_layout *output_layout;
5553
struct wlr_seat *seat;
56-
54+
struct wlr_cursor *cursor;
5755
struct wl_listener new_output;
5856
struct wl_listener new_xdg_surface;
5957
struct wl_listener new_input;
6058
struct wl_listener request_set_cursor;
6159
struct wl_listener request_set_selection;
62-
6360
pid_t child_pid;
6461
};
65-
6662
struct gameframe_output {
6763
struct wlr_output *wlr_output;
6864
struct gameframe_server *server;
6965
struct wl_listener frame;
7066
struct wl_listener destroy;
7167
};
72-
7368
struct gameframe_view {
7469
struct wlr_xdg_toplevel *xdg_toplevel;
7570
struct wlr_scene_tree *scene_tree;
@@ -82,32 +77,25 @@ struct gameframe_view {
8277
struct wl_listener request_maximize;
8378
struct wl_listener request_fullscreen;
8479
};
85-
8680
static void output_frame(struct wl_listener *listener, void *data) {
8781
struct gameframe_output *output = wl_container_of(listener, output, frame);
8882
struct wlr_scene *scene = output->server->scene;
8983
struct wlr_scene_output *scene_output = wlr_scene_get_scene_output(scene, output->wlr_output);
90-
9184
wlr_scene_output_commit(scene_output, NULL);
92-
9385
struct timespec now;
9486
clock_gettime(CLOCK_MONOTONIC, &now);
9587
wlr_scene_output_send_frame_done(scene_output, &now);
9688
}
97-
9889
static void output_destroy(struct wl_listener *listener, void *data) {
9990
struct gameframe_output *output = wl_container_of(listener, output, destroy);
10091
wl_list_remove(&output->frame.link);
10192
wl_list_remove(&output->destroy.link);
10293
free(output);
10394
}
104-
10595
static void server_new_output(struct wl_listener *listener, void *data) {
10696
struct gameframe_server *server = wl_container_of(listener, server, new_output);
10797
struct wlr_output *wlr_output = data;
108-
10998
wlr_output_init_render(wlr_output, server->allocator, server->renderer);
110-
11199
struct wlr_output_state state;
112100
wlr_output_state_init(&state);
113101
wlr_output_state_set_enabled(&state, true);
@@ -117,33 +105,27 @@ static void server_new_output(struct wl_listener *listener, void *data) {
117105
}
118106
wlr_output_commit_state(wlr_output, &state);
119107
wlr_output_state_finish(&state);
120-
121108
struct gameframe_output *output = calloc(1, sizeof(*output));
122109
output->wlr_output = wlr_output;
123110
output->server = server;
124111
output->frame.notify = output_frame;
125112
wl_signal_add(&wlr_output->events.frame, &output->frame);
126113
output->destroy.notify = output_destroy;
127114
wl_signal_add(&wlr_output->events.destroy, &output->destroy);
128-
129115
wlr_output_layout_add_auto(server->output_layout, wlr_output);
130-
131-
server->scene_output = wlr_scene_attach_output(server->scene, wlr_output);
116+
server->scene_output = wlr_scene_output_create(server->scene, wlr_output);
132117
}
133-
134118
static void xdg_toplevel_map(struct wl_listener *listener, void *data) {
135119
struct gameframe_view *view = wl_container_of(listener, view, map);
136-
wlr_scene_tree_set_position(view->scene_tree, 0, 0);
120+
wlr_scene_node_set_position(&view->scene_tree->node, 0, 0);
137121
wlr_xdg_toplevel_set_size(view->xdg_toplevel, 0, 0); // Fullscreen implicitly
138122
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, true);
139123
}
140-
141124
static void xdg_toplevel_unmap(struct wl_listener *listener, void *data) {
142125
struct gameframe_view *view = wl_container_of(listener, view, unmap);
143126
// No-op for now
144127
}
145-
146-
static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
128+
static void view_destroy(struct wl_listener *listener, void *data) {
147129
struct gameframe_view *view = wl_container_of(listener, view, destroy);
148130
wl_list_remove(&view->map.link);
149131
wl_list_remove(&view->unmap.link);
@@ -154,45 +136,36 @@ static void xdg_toplevel_destroy(struct wl_listener *listener, void *data) {
154136
wl_list_remove(&view->request_fullscreen.link);
155137
free(view);
156138
}
157-
158139
static void xdg_toplevel_request_move(struct wl_listener *listener, void *data) {
159140
// No moving in fullscreen
160141
}
161-
162142
static void xdg_toplevel_request_resize(struct wl_listener *listener, void *data) {
163143
// No resizing in fullscreen
164144
}
165-
166145
static void xdg_toplevel_request_maximize(struct wl_listener *listener, void *data) {
167146
// Already maximized/fullscreen
168147
}
169-
170148
static void xdg_toplevel_request_fullscreen(struct wl_listener *listener, void *data) {
171149
struct gameframe_view *view = wl_container_of(listener, view, request_fullscreen);
172-
struct wlr_xdg_toplevel_set_fullscreen_event *event = data;
173-
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, event->fullscreen);
150+
struct wlr_xdg_surface *xdg_surface = data;
151+
wlr_xdg_toplevel_set_fullscreen(view->xdg_toplevel, xdg_surface->toplevel->requested.fullscreen);
174152
}
175-
176153
static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
177154
struct gameframe_server *server = wl_container_of(listener, server, new_xdg_surface);
178155
struct wlr_xdg_surface *xdg_surface = data;
179-
180156
if (xdg_surface->role != WLR_XDG_SURFACE_ROLE_TOPLEVEL) {
181157
return;
182158
}
183-
184159
struct gameframe_view *view = calloc(1, sizeof(*view));
185160
view->server = server;
186161
view->xdg_toplevel = xdg_surface->toplevel;
187162
view->scene_tree = wlr_scene_xdg_surface_create(&server->scene->tree, xdg_surface);
188-
189163
view->map.notify = xdg_toplevel_map;
190-
wl_signal_add(&xdg_surface->events.map, &view->map);
164+
wl_signal_add(&xdg_surface->surface->events.map, &view->map);
191165
view->unmap.notify = xdg_toplevel_unmap;
192-
wl_signal_add(&xdg_surface->events.unmap, &view->unmap);
193-
view->destroy.notify = xdg_toplevel_destroy;
166+
wl_signal_add(&xdg_surface->surface->events.unmap, &view->unmap);
167+
view->destroy.notify = view_destroy;
194168
wl_signal_add(&xdg_surface->events.destroy, &view->destroy);
195-
196169
view->request_move.notify = xdg_toplevel_request_move;
197170
wl_signal_add(&view->xdg_toplevel->events.request_move, &view->request_move);
198171
view->request_resize.notify = xdg_toplevel_request_resize;
@@ -202,16 +175,13 @@ static void server_new_xdg_surface(struct wl_listener *listener, void *data) {
202175
view->request_fullscreen.notify = xdg_toplevel_request_fullscreen;
203176
wl_signal_add(&view->xdg_toplevel->events.request_fullscreen, &view->request_fullscreen);
204177
}
205-
206178
static void process_keyboard(struct gameframe_server *server, struct wlr_keyboard *keyboard) {
207179
wlr_seat_set_keyboard(server->seat, keyboard);
208180
wlr_keyboard_set_repeat_info(keyboard, 25, 600);
209181
}
210-
211182
static void server_new_input(struct wl_listener *listener, void *data) {
212183
struct gameframe_server *server = wl_container_of(listener, server, new_input);
213184
struct wlr_input_device *device = data;
214-
215185
switch (device->type) {
216186
case WLR_INPUT_DEVICE_KEYBOARD: {
217187
struct wlr_keyboard *kb = wlr_keyboard_from_input_device(device);
@@ -223,106 +193,86 @@ static void server_new_input(struct wl_listener *listener, void *data) {
223193
process_keyboard(server, kb);
224194
break;
225195
}
226-
case WLR_INPUT_DEVICE_POINTER:
227-
wlr_seat_set_capabilities(server->seat, WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD);
196+
case WLR_INPUT_DEVICE_POINTER: {
197+
wlr_cursor_attach_input_device(server->cursor, device);
228198
break;
199+
}
229200
default:
230201
break;
231202
}
232-
233203
uint32_t caps = WL_SEAT_CAPABILITY_POINTER | WL_SEAT_CAPABILITY_KEYBOARD;
234204
wlr_seat_set_capabilities(server->seat, caps);
235205
}
236-
237206
static void request_set_cursor(struct wl_listener *listener, void *data) {
238207
struct gameframe_server *server = wl_container_of(listener, server, request_set_cursor);
239208
struct wlr_seat_pointer_request_set_cursor_event *event = data;
240-
struct wlr_seat_client *client = event->seat_client;
241-
242-
if (client == NULL) {
243-
return;
209+
struct wlr_seat_client *focused_client = server->seat->pointer_state.focused_client;
210+
if (focused_client != NULL && focused_client == event->seat_client) {
211+
wlr_cursor_set_surface(server->cursor, event->surface, event->hotspot_x, event->hotspot_y);
244212
}
245-
246-
wlr_seat_pointer_surface_set_cursor(server->seat, client, event->surface, event->hotspot_x, event->hotspot_y);
247213
}
248-
249214
static void request_set_selection(struct wl_listener *listener, void *data) {
250215
struct gameframe_server *server = wl_container_of(listener, server, request_set_selection);
251216
struct wlr_seat_request_set_selection_event *event = data;
252217
wlr_seat_set_selection(server->seat, event->source, event->serial);
253218
}
254-
255219
int main(int argc, char *argv[]) {
256220
wlr_log_init(WLR_DEBUG, NULL);
257-
258221
if (argc < 2) {
259222
fprintf(stderr, "Usage: %s <command>\n", argv[0]);
260223
return 1;
261224
}
262-
263225
struct gameframe_server server = {0};
264226
server.display = wl_display_create();
265227
if (server.display == NULL) {
266228
wlr_log(WLR_ERROR, "Cannot create wayland display");
267229
return 1;
268230
}
269-
270231
server.backend = wlr_backend_autocreate(wl_display_get_event_loop(server.display), NULL);
271232
if (server.backend == NULL) {
272233
wlr_log(WLR_ERROR, "Cannot create backend");
273234
return 1;
274235
}
275-
276236
server.renderer = wlr_renderer_autocreate(server.backend);
277237
if (server.renderer == NULL) {
278238
wlr_log(WLR_ERROR, "Cannot create renderer");
279239
return 1;
280240
}
281-
282241
wlr_renderer_init_wl_display(server.renderer, server.display);
283-
284242
server.allocator = wlr_allocator_autocreate(server.backend, server.renderer);
285243
if (server.allocator == NULL) {
286244
wlr_log(WLR_ERROR, "Cannot create allocator");
287245
return 1;
288246
}
289-
290247
server.compositor = wlr_compositor_create(server.display, 5, server.renderer);
291248
server.subcompositor = wlr_subcompositor_create(server.display);
292249
wlr_data_device_manager_create(server.display);
293-
294-
server.output_layout = wlr_output_layout_create();
250+
server.output_layout = wlr_output_layout_create(server.display);
251+
server.cursor = wlr_cursor_create();
252+
wlr_cursor_attach_output_layout(server.cursor, server.output_layout);
295253
server.scene = wlr_scene_create();
296-
297254
server.new_output.notify = server_new_output;
298255
wl_signal_add(&server.backend->events.new_output, &server.new_output);
299-
300256
server.xdg_shell = wlr_xdg_shell_create(server.display, 3);
301257
server.new_xdg_surface.notify = server_new_xdg_surface;
302258
wl_signal_add(&server.xdg_shell->events.new_surface, &server.new_xdg_surface);
303-
304259
server.seat = wlr_seat_create(server.display, "seat0");
305260
server.request_set_cursor.notify = request_set_cursor;
306261
wl_signal_add(&server.seat->events.request_set_cursor, &server.request_set_cursor);
307262
server.request_set_selection.notify = request_set_selection;
308263
wl_signal_add(&server.seat->events.request_set_selection, &server.request_set_selection);
309-
310264
server.new_input.notify = server_new_input;
311265
wl_signal_add(&server.backend->events.new_input, &server.new_input);
312-
313266
const char *socket = wl_display_add_socket_auto(server.display);
314267
if (socket == NULL) {
315268
wlr_log(WLR_ERROR, "Cannot add socket");
316269
return 1;
317270
}
318-
319271
if (!wlr_backend_start(server.backend)) {
320272
wlr_log(WLR_ERROR, "Cannot start backend");
321273
return 1;
322274
}
323-
324275
setenv("WAYLAND_DISPLAY", socket, true);
325-
326276
server.child_pid = fork();
327277
if (server.child_pid == 0) {
328278
execvp(argv[1], argv + 1);
@@ -332,22 +282,18 @@ int main(int argc, char *argv[]) {
332282
wlr_log(WLR_ERROR, "Cannot fork");
333283
return 1;
334284
}
335-
336285
wlr_log(WLR_INFO, "Running on WAYLAND_DISPLAY=%s", socket);
337286
wl_display_run(server.display);
338-
339287
if (server.child_pid > 0) {
340288
kill(server.child_pid, SIGTERM);
341289
waitpid(server.child_pid, NULL, 0);
342290
}
343-
344291
wl_display_destroy_clients(server.display);
345292
wl_display_destroy(server.display);
346293
wlr_scene_output_destroy(server.scene_output);
347294
wlr_output_layout_destroy(server.output_layout);
348295
wlr_allocator_destroy(server.allocator);
349296
wlr_renderer_destroy(server.renderer);
350297
wlr_backend_destroy(server.backend);
351-
352298
return 0;
353299
}

0 commit comments

Comments
 (0)