|  |  |  | @ -44,12 +44,15 @@ | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #include <wayland-client.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include "shared/zalloc.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "xdg-shell-unstable-v5-client-protocol.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "xdg-shell-unstable-v6-client-protocol.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "fullscreen-shell-unstable-v1-client-protocol.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "linux-dmabuf-unstable-v1-client-protocol.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define CLEAR(x) memset(&(x), 0, sizeof(x)) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | redraw(void *data, struct wl_callback *callback, uint32_t time); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static int | 
			
		
	
		
			
				
					|  |  |  |  | xioctl(int fh, int request, void *arg) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
	
		
			
				
					|  |  |  | @ -94,7 +97,7 @@ struct display { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_compositor *compositor; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_seat *seat; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_keyboard *keyboard; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct xdg_shell *shell; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct zxdg_shell_v6 *shell; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct zwp_fullscreen_shell_v1 *fshell; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct zwp_linux_dmabuf_v1 *dmabuf; | 
			
		
	
		
			
				
					|  |  |  |  | 	bool requested_format_found; | 
			
		
	
	
		
			
				
					|  |  |  | @ -119,9 +122,12 @@ struct buffer { | 
			
		
	
		
			
				
					|  |  |  |  | struct window { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct display *display; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_surface *surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct xdg_surface *xdg_surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct zxdg_surface_v6 *xdg_surface; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct zxdg_toplevel_v6 *xdg_toplevel; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct buffer buffers[NUM_BUFFERS]; | 
			
		
	
		
			
				
					|  |  |  |  | 	struct wl_callback *callback; | 
			
		
	
		
			
				
					|  |  |  |  | 	bool wait_for_configure; | 
			
		
	
		
			
				
					|  |  |  |  | 	bool initialized; | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static bool running = true; | 
			
		
	
	
		
			
				
					|  |  |  | @ -524,21 +530,38 @@ start_capture(struct display *display) | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | handle_configure(void *data, struct xdg_surface *surface, | 
			
		
	
		
			
				
					|  |  |  |  | 		 int32_t width, int32_t height, | 
			
		
	
		
			
				
					|  |  |  |  | 		 struct wl_array *states, uint32_t serial) | 
			
		
	
		
			
				
					|  |  |  |  | xdg_surface_handle_configure(void *data, struct zxdg_surface_v6 *surface, | 
			
		
	
		
			
				
					|  |  |  |  | 			     uint32_t serial) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct window *window = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	zxdg_surface_v6_ack_configure(surface, serial); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (window->initialized && window->wait_for_configure) | 
			
		
	
		
			
				
					|  |  |  |  | 		redraw(window, NULL, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 	window->wait_for_configure = false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct zxdg_surface_v6_listener xdg_surface_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_surface_handle_configure, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | handle_delete(void *data, struct xdg_surface *xdg_surface) | 
			
		
	
		
			
				
					|  |  |  |  | xdg_toplevel_handle_configure(void *data, struct zxdg_toplevel_v6 *toplevel, | 
			
		
	
		
			
				
					|  |  |  |  | 			      int32_t width, int32_t height, | 
			
		
	
		
			
				
					|  |  |  |  | 			      struct wl_array *states) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	running = false; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct xdg_surface_listener xdg_surface_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | 	handle_configure, | 
			
		
	
		
			
				
					|  |  |  |  | 	handle_delete, | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | xdg_toplevel_handle_close(void *data, struct zxdg_toplevel_v6 *xdg_toplevel) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	running = 0; | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct zxdg_toplevel_v6_listener xdg_toplevel_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_toplevel_handle_configure, | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_toplevel_handle_close, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static struct window * | 
			
		
	
	
		
			
				
					|  |  |  | @ -556,15 +579,26 @@ create_window(struct display *display) | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (display->shell) { | 
			
		
	
		
			
				
					|  |  |  |  | 		window->xdg_surface = | 
			
		
	
		
			
				
					|  |  |  |  | 			xdg_shell_get_xdg_surface(display->shell, | 
			
		
	
		
			
				
					|  |  |  |  | 			                          window->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 			zxdg_shell_v6_get_xdg_surface(display->shell, | 
			
		
	
		
			
				
					|  |  |  |  | 						      window->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		assert(window->xdg_surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_surface_add_listener(window->xdg_surface, | 
			
		
	
		
			
				
					|  |  |  |  | 		                         &xdg_surface_listener, window); | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_surface_v6_add_listener(window->xdg_surface, | 
			
		
	
		
			
				
					|  |  |  |  | 					     &xdg_surface_listener, window); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		window->xdg_toplevel = | 
			
		
	
		
			
				
					|  |  |  |  | 			zxdg_surface_v6_get_toplevel(window->xdg_surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		assert(window->xdg_toplevel); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_toplevel_v6_add_listener(window->xdg_toplevel, | 
			
		
	
		
			
				
					|  |  |  |  | 					      &xdg_toplevel_listener, window); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_surface_set_title(window->xdg_surface, "simple-dmabuf-v4l"); | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_toplevel_v6_set_title(window->xdg_toplevel, "simple-dmabuf-v4l"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 		window->wait_for_configure = true; | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_surface_commit(window->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (display->fshell) { | 
			
		
	
		
			
				
					|  |  |  |  | 		zwp_fullscreen_shell_v1_present_surface(display->fshell, | 
			
		
	
		
			
				
					|  |  |  |  | 		                                        window->surface, | 
			
		
	
	
		
			
				
					|  |  |  | @ -586,8 +620,10 @@ destroy_window(struct window *window) | 
			
		
	
		
			
				
					|  |  |  |  | 	if (window->callback) | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_callback_destroy(window->callback); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (window->xdg_toplevel) | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_toplevel_v6_destroy(window->xdg_toplevel); | 
			
		
	
		
			
				
					|  |  |  |  | 	if (window->xdg_surface) | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_surface_destroy(window->xdg_surface); | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_surface_v6_destroy(window->xdg_surface); | 
			
		
	
		
			
				
					|  |  |  |  | 	wl_surface_destroy(window->surface); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	for (i = 0; i < NUM_BUFFERS; i++) { | 
			
		
	
	
		
			
				
					|  |  |  | @ -738,21 +774,15 @@ static const struct wl_seat_listener seat_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | xdg_shell_ping(void *data, struct xdg_shell *shell, uint32_t serial) | 
			
		
	
		
			
				
					|  |  |  |  | xdg_shell_ping(void *data, struct zxdg_shell_v6 *shell, uint32_t serial) | 
			
		
	
		
			
				
					|  |  |  |  | { | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_shell_pong(shell, serial); | 
			
		
	
		
			
				
					|  |  |  |  | 	zxdg_shell_v6_pong(shell, serial); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static const struct xdg_shell_listener xdg_shell_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | static const struct zxdg_shell_v6_listener xdg_shell_listener = { | 
			
		
	
		
			
				
					|  |  |  |  | 	xdg_shell_ping, | 
			
		
	
		
			
				
					|  |  |  |  | }; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | #define XDG_VERSION 5 /* The version of xdg-shell that we implement */ | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef static_assert | 
			
		
	
		
			
				
					|  |  |  |  | static_assert(XDG_VERSION == XDG_SHELL_VERSION_CURRENT, | 
			
		
	
		
			
				
					|  |  |  |  |               "Interface version doesn't match implementation version"); | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static void | 
			
		
	
		
			
				
					|  |  |  |  | registry_handle_global(void *data, struct wl_registry *registry, | 
			
		
	
		
			
				
					|  |  |  |  |                        uint32_t id, const char *interface, uint32_t version) | 
			
		
	
	
		
			
				
					|  |  |  | @ -767,11 +797,10 @@ registry_handle_global(void *data, struct wl_registry *registry, | 
			
		
	
		
			
				
					|  |  |  |  | 		d->seat = wl_registry_bind(registry, | 
			
		
	
		
			
				
					|  |  |  |  | 		                           id, &wl_seat_interface, 1); | 
			
		
	
		
			
				
					|  |  |  |  | 		wl_seat_add_listener(d->seat, &seat_listener, d); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(interface, "xdg_shell") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(interface, "zxdg_shell_v6") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		d->shell = wl_registry_bind(registry, | 
			
		
	
		
			
				
					|  |  |  |  | 		                            id, &xdg_shell_interface, 1); | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_shell_use_unstable_version(d->shell, XDG_VERSION); | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_shell_add_listener(d->shell, &xdg_shell_listener, d); | 
			
		
	
		
			
				
					|  |  |  |  | 		                            id, &zxdg_shell_v6_interface, 1); | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_shell_v6_add_listener(d->shell, &xdg_shell_listener, d); | 
			
		
	
		
			
				
					|  |  |  |  | 	} else if (strcmp(interface, "zwp_fullscreen_shell_v1") == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 		d->fshell = wl_registry_bind(registry, | 
			
		
	
		
			
				
					|  |  |  |  | 		                             id, &zwp_fullscreen_shell_v1_interface, | 
			
		
	
	
		
			
				
					|  |  |  | @ -840,7 +869,7 @@ destroy_display(struct display *display) | 
			
		
	
		
			
				
					|  |  |  |  | 		zwp_linux_dmabuf_v1_destroy(display->dmabuf); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (display->shell) | 
			
		
	
		
			
				
					|  |  |  |  | 		xdg_shell_destroy(display->shell); | 
			
		
	
		
			
				
					|  |  |  |  | 		zxdg_shell_v6_destroy(display->shell); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (display->fshell) | 
			
		
	
		
			
				
					|  |  |  |  | 		zwp_fullscreen_shell_v1_release(display->fshell); | 
			
		
	
	
		
			
				
					|  |  |  | @ -933,7 +962,10 @@ main(int argc, char **argv) | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!start_capture(display)) | 
			
		
	
		
			
				
					|  |  |  |  | 		return 1; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	redraw(window, NULL, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 	window->initialized = true; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!window->wait_for_configure) | 
			
		
	
		
			
				
					|  |  |  |  | 		redraw(window, NULL, 0); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	while (running && ret != -1) | 
			
		
	
		
			
				
					|  |  |  |  | 		ret = wl_display_dispatch(display->display); | 
			
		
	
	
		
			
				
					|  |  |  | 
 |