xref: /aosp_15_r20/external/crosvm/gpu_display/src/display_wl.c (revision bb4ee6a4ae7042d18b07a98463b9c8b875e44b39)
1*bb4ee6a4SAndroid Build Coastguard Worker // Copyright 2018 The ChromiumOS Authors
2*bb4ee6a4SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*bb4ee6a4SAndroid Build Coastguard Worker // found in the LICENSE file.
4*bb4ee6a4SAndroid Build Coastguard Worker 
5*bb4ee6a4SAndroid Build Coastguard Worker #include <assert.h>
6*bb4ee6a4SAndroid Build Coastguard Worker #include <memory.h>
7*bb4ee6a4SAndroid Build Coastguard Worker #include <stdbool.h>
8*bb4ee6a4SAndroid Build Coastguard Worker #include <stdint.h>
9*bb4ee6a4SAndroid Build Coastguard Worker #include <stdio.h>
10*bb4ee6a4SAndroid Build Coastguard Worker #include <stdlib.h>
11*bb4ee6a4SAndroid Build Coastguard Worker 
12*bb4ee6a4SAndroid Build Coastguard Worker #include <errno.h>
13*bb4ee6a4SAndroid Build Coastguard Worker #include <fcntl.h>
14*bb4ee6a4SAndroid Build Coastguard Worker #include <poll.h>
15*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/ioctl.h>
16*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/mman.h>
17*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/socket.h>
18*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/stat.h>
19*bb4ee6a4SAndroid Build Coastguard Worker #include <sys/types.h>
20*bb4ee6a4SAndroid Build Coastguard Worker #include <unistd.h>
21*bb4ee6a4SAndroid Build Coastguard Worker 
22*bb4ee6a4SAndroid Build Coastguard Worker #include "aura-shell.h"
23*bb4ee6a4SAndroid Build Coastguard Worker #include "linux-dmabuf-unstable-v1.h"
24*bb4ee6a4SAndroid Build Coastguard Worker #include "viewporter.h"
25*bb4ee6a4SAndroid Build Coastguard Worker #include "xdg-shell.h"
26*bb4ee6a4SAndroid Build Coastguard Worker #include "virtio-gpu-metadata-v1.h"
27*bb4ee6a4SAndroid Build Coastguard Worker #include <wayland-client-core.h>
28*bb4ee6a4SAndroid Build Coastguard Worker #include <wayland-client-protocol.h>
29*bb4ee6a4SAndroid Build Coastguard Worker #include <wayland-client.h>
30*bb4ee6a4SAndroid Build Coastguard Worker 
31*bb4ee6a4SAndroid Build Coastguard Worker // BTN_LEFT is copied from linux/input-event-codes.h because the kernel headers
32*bb4ee6a4SAndroid Build Coastguard Worker // aren't readily available in some downstream projects.
33*bb4ee6a4SAndroid Build Coastguard Worker #define BTN_LEFT 0x110
34*bb4ee6a4SAndroid Build Coastguard Worker 
35*bb4ee6a4SAndroid Build Coastguard Worker #define DEFAULT_SCALE 2
36*bb4ee6a4SAndroid Build Coastguard Worker #define MAX_BUFFER_COUNT 64
37*bb4ee6a4SAndroid Build Coastguard Worker #define EVENT_BUF_SIZE 256
38*bb4ee6a4SAndroid Build Coastguard Worker 
39*bb4ee6a4SAndroid Build Coastguard Worker const int32_t DWL_KEYBOARD_KEY_STATE_RELEASED = WL_KEYBOARD_KEY_STATE_RELEASED;
40*bb4ee6a4SAndroid Build Coastguard Worker const int32_t DWL_KEYBOARD_KEY_STATE_PRESSED  = WL_KEYBOARD_KEY_STATE_PRESSED;
41*bb4ee6a4SAndroid Build Coastguard Worker 
42*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_KEYBOARD_ENTER = 0x00;
43*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_KEYBOARD_LEAVE = 0x01;
44*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_KEYBOARD_KEY   = 0x02;
45*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_POINTER_ENTER  = 0x10;
46*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_POINTER_LEAVE  = 0x11;
47*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_POINTER_MOVE   = 0x12;
48*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_POINTER_BUTTON = 0x13;
49*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_TOUCH_DOWN     = 0x20;
50*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_TOUCH_UP       = 0x21;
51*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_EVENT_TYPE_TOUCH_MOTION   = 0x22;
52*bb4ee6a4SAndroid Build Coastguard Worker 
53*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_SURFACE_FLAG_RECEIVE_INPUT = 1 << 0;
54*bb4ee6a4SAndroid Build Coastguard Worker const uint32_t DWL_SURFACE_FLAG_HAS_ALPHA     = 1 << 1;
55*bb4ee6a4SAndroid Build Coastguard Worker 
56*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_event {
57*bb4ee6a4SAndroid Build Coastguard Worker 	const void *surface_descriptor;
58*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t event_type;
59*bb4ee6a4SAndroid Build Coastguard Worker 	int32_t params[3];
60*bb4ee6a4SAndroid Build Coastguard Worker };
61*bb4ee6a4SAndroid Build Coastguard Worker 
62*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_context;
63*bb4ee6a4SAndroid Build Coastguard Worker 
64*bb4ee6a4SAndroid Build Coastguard Worker struct interfaces {
65*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context;
66*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_compositor *compositor;
67*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_subcompositor *subcompositor;
68*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_shm *shm;
69*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_seat *seat;
70*bb4ee6a4SAndroid Build Coastguard Worker 	struct zaura_shell *aura; // optional
71*bb4ee6a4SAndroid Build Coastguard Worker 	struct zwp_linux_dmabuf_v1 *linux_dmabuf;
72*bb4ee6a4SAndroid Build Coastguard Worker 	struct xdg_wm_base *xdg_wm_base;
73*bb4ee6a4SAndroid Build Coastguard Worker 	struct wp_viewporter *viewporter; // optional
74*bb4ee6a4SAndroid Build Coastguard Worker 	struct wp_virtio_gpu_metadata_v1 *virtio_gpu_metadata; // optional
75*bb4ee6a4SAndroid Build Coastguard Worker };
76*bb4ee6a4SAndroid Build Coastguard Worker 
77*bb4ee6a4SAndroid Build Coastguard Worker struct output {
78*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_output *output;
79*bb4ee6a4SAndroid Build Coastguard Worker 	struct zaura_output *aura_output;
80*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context;
81*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t id;
82*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t current_scale;
83*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t device_scale_factor;
84*bb4ee6a4SAndroid Build Coastguard Worker 	bool internal;
85*bb4ee6a4SAndroid Build Coastguard Worker };
86*bb4ee6a4SAndroid Build Coastguard Worker 
87*bb4ee6a4SAndroid Build Coastguard Worker struct input {
88*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_keyboard *wl_keyboard;
89*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_pointer *wl_pointer;
90*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_surface *keyboard_input_surface;
91*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_surface *pointer_input_surface;
92*bb4ee6a4SAndroid Build Coastguard Worker 	int32_t pointer_x;
93*bb4ee6a4SAndroid Build Coastguard Worker 	int32_t pointer_y;
94*bb4ee6a4SAndroid Build Coastguard Worker 	bool pointer_lbutton_state;
95*bb4ee6a4SAndroid Build Coastguard Worker };
96*bb4ee6a4SAndroid Build Coastguard Worker 
97*bb4ee6a4SAndroid Build Coastguard Worker typedef void (*dwl_error_callback_type)(const char *message);
98*bb4ee6a4SAndroid Build Coastguard Worker 
99*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_context {
100*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_display *display;
101*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_surface *surfaces[MAX_BUFFER_COUNT];
102*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_dmabuf *dmabufs[MAX_BUFFER_COUNT];
103*bb4ee6a4SAndroid Build Coastguard Worker 	struct interfaces ifaces;
104*bb4ee6a4SAndroid Build Coastguard Worker 	struct input input;
105*bb4ee6a4SAndroid Build Coastguard Worker 	bool output_added;
106*bb4ee6a4SAndroid Build Coastguard Worker 	struct output outputs[8];
107*bb4ee6a4SAndroid Build Coastguard Worker 
108*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_event event_cbuf[EVENT_BUF_SIZE];
109*bb4ee6a4SAndroid Build Coastguard Worker 	size_t event_read_pos;
110*bb4ee6a4SAndroid Build Coastguard Worker 	size_t event_write_pos;
111*bb4ee6a4SAndroid Build Coastguard Worker 
112*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_error_callback_type error_callback;
113*bb4ee6a4SAndroid Build Coastguard Worker };
114*bb4ee6a4SAndroid Build Coastguard Worker 
115*bb4ee6a4SAndroid Build Coastguard Worker #define outputs_for_each(context, pos, output)                                 \
116*bb4ee6a4SAndroid Build Coastguard Worker 	for (pos = 0, output = &context->outputs[pos];                         \
117*bb4ee6a4SAndroid Build Coastguard Worker 	     pos < (sizeof(context->outputs) / sizeof(context->outputs[0]));   \
118*bb4ee6a4SAndroid Build Coastguard Worker 	     pos++, output = &context->outputs[pos])
119*bb4ee6a4SAndroid Build Coastguard Worker 
120*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_dmabuf {
121*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t width;
122*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t height;
123*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t import_id;
124*bb4ee6a4SAndroid Build Coastguard Worker 	bool in_use;
125*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_buffer *buffer;
126*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context;
127*bb4ee6a4SAndroid Build Coastguard Worker };
128*bb4ee6a4SAndroid Build Coastguard Worker 
129*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_surface {
130*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context;
131*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_surface *wl_surface;
132*bb4ee6a4SAndroid Build Coastguard Worker 	struct zaura_surface *aura;
133*bb4ee6a4SAndroid Build Coastguard Worker 	struct xdg_surface *xdg_surface;
134*bb4ee6a4SAndroid Build Coastguard Worker 	struct xdg_toplevel *xdg_toplevel;
135*bb4ee6a4SAndroid Build Coastguard Worker 	struct wp_viewport *viewport;
136*bb4ee6a4SAndroid Build Coastguard Worker 	struct wp_virtio_gpu_surface_metadata_v1 *virtio_gpu_surface_metadata;
137*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_subsurface *subsurface;
138*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t width;
139*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t height;
140*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t surface_id;
141*bb4ee6a4SAndroid Build Coastguard Worker 	double scale;
142*bb4ee6a4SAndroid Build Coastguard Worker 	bool close_requested;
143*bb4ee6a4SAndroid Build Coastguard Worker 	size_t buffer_count;
144*bb4ee6a4SAndroid Build Coastguard Worker 	uint64_t buffer_use_bit_mask;
145*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_buffer *buffers[0];
146*bb4ee6a4SAndroid Build Coastguard Worker };
147*bb4ee6a4SAndroid Build Coastguard Worker 
148*bb4ee6a4SAndroid Build Coastguard Worker static_assert(sizeof(((struct dwl_surface *)0)->buffer_use_bit_mask) * 8 >=
149*bb4ee6a4SAndroid Build Coastguard Worker 		  MAX_BUFFER_COUNT,
150*bb4ee6a4SAndroid Build Coastguard Worker 	      "not enough bits in buffer_use_bit_mask");
151*bb4ee6a4SAndroid Build Coastguard Worker 
output_geometry(void * data,struct wl_output * output,int x,int y,int physical_width,int physical_height,int subpixel,const char * make,const char * model,int transform)152*bb4ee6a4SAndroid Build Coastguard Worker static void output_geometry(void *data, struct wl_output *output, int x, int y,
153*bb4ee6a4SAndroid Build Coastguard Worker 			    int physical_width, int physical_height,
154*bb4ee6a4SAndroid Build Coastguard Worker 			    int subpixel, const char *make, const char *model,
155*bb4ee6a4SAndroid Build Coastguard Worker 			    int transform)
156*bb4ee6a4SAndroid Build Coastguard Worker {
157*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
158*bb4ee6a4SAndroid Build Coastguard Worker 	(void)output;
159*bb4ee6a4SAndroid Build Coastguard Worker 	(void)x;
160*bb4ee6a4SAndroid Build Coastguard Worker 	(void)y;
161*bb4ee6a4SAndroid Build Coastguard Worker 	(void)physical_width;
162*bb4ee6a4SAndroid Build Coastguard Worker 	(void)physical_height;
163*bb4ee6a4SAndroid Build Coastguard Worker 	(void)subpixel;
164*bb4ee6a4SAndroid Build Coastguard Worker 	(void)make;
165*bb4ee6a4SAndroid Build Coastguard Worker 	(void)model;
166*bb4ee6a4SAndroid Build Coastguard Worker 	(void)transform;
167*bb4ee6a4SAndroid Build Coastguard Worker }
168*bb4ee6a4SAndroid Build Coastguard Worker 
output_mode(void * data,struct wl_output * output,uint32_t flags,int width,int height,int refresh)169*bb4ee6a4SAndroid Build Coastguard Worker static void output_mode(void *data, struct wl_output *output, uint32_t flags,
170*bb4ee6a4SAndroid Build Coastguard Worker 			int width, int height, int refresh)
171*bb4ee6a4SAndroid Build Coastguard Worker {
172*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
173*bb4ee6a4SAndroid Build Coastguard Worker 	(void)output;
174*bb4ee6a4SAndroid Build Coastguard Worker 	(void)flags;
175*bb4ee6a4SAndroid Build Coastguard Worker 	(void)width;
176*bb4ee6a4SAndroid Build Coastguard Worker 	(void)height;
177*bb4ee6a4SAndroid Build Coastguard Worker 	(void)refresh;
178*bb4ee6a4SAndroid Build Coastguard Worker }
179*bb4ee6a4SAndroid Build Coastguard Worker 
output_done(void * data,struct wl_output * output)180*bb4ee6a4SAndroid Build Coastguard Worker static void output_done(void *data, struct wl_output *output)
181*bb4ee6a4SAndroid Build Coastguard Worker {
182*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
183*bb4ee6a4SAndroid Build Coastguard Worker 	(void)output;
184*bb4ee6a4SAndroid Build Coastguard Worker }
185*bb4ee6a4SAndroid Build Coastguard Worker 
output_scale(void * data,struct wl_output * wl_output,int32_t scale_factor)186*bb4ee6a4SAndroid Build Coastguard Worker static void output_scale(void *data, struct wl_output *wl_output,
187*bb4ee6a4SAndroid Build Coastguard Worker 			 int32_t scale_factor)
188*bb4ee6a4SAndroid Build Coastguard Worker {
189*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_output;
190*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output = (struct output *)data;
191*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = output->context;
192*bb4ee6a4SAndroid Build Coastguard Worker 
193*bb4ee6a4SAndroid Build Coastguard Worker 	// If the aura interface is available, we prefer the scale factor
194*bb4ee6a4SAndroid Build Coastguard Worker 	// reported by that.
195*bb4ee6a4SAndroid Build Coastguard Worker 	if (context->ifaces.aura)
196*bb4ee6a4SAndroid Build Coastguard Worker 		return;
197*bb4ee6a4SAndroid Build Coastguard Worker 
198*bb4ee6a4SAndroid Build Coastguard Worker 	output->current_scale = 1000 * scale_factor;
199*bb4ee6a4SAndroid Build Coastguard Worker }
200*bb4ee6a4SAndroid Build Coastguard Worker 
201*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_output_listener output_listener = {
202*bb4ee6a4SAndroid Build Coastguard Worker     .geometry = output_geometry,
203*bb4ee6a4SAndroid Build Coastguard Worker     .mode = output_mode,
204*bb4ee6a4SAndroid Build Coastguard Worker     .done = output_done,
205*bb4ee6a4SAndroid Build Coastguard Worker     .scale = output_scale};
206*bb4ee6a4SAndroid Build Coastguard Worker 
aura_output_scale(void * data,struct zaura_output * aura_output,uint32_t flags,uint32_t scale)207*bb4ee6a4SAndroid Build Coastguard Worker static void aura_output_scale(void *data, struct zaura_output *aura_output,
208*bb4ee6a4SAndroid Build Coastguard Worker 			      uint32_t flags, uint32_t scale)
209*bb4ee6a4SAndroid Build Coastguard Worker {
210*bb4ee6a4SAndroid Build Coastguard Worker 	(void)aura_output;
211*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output = (struct output *)data;
212*bb4ee6a4SAndroid Build Coastguard Worker 	if (flags & ZAURA_OUTPUT_SCALE_PROPERTY_CURRENT) {
213*bb4ee6a4SAndroid Build Coastguard Worker 		output->current_scale = scale;
214*bb4ee6a4SAndroid Build Coastguard Worker 	}
215*bb4ee6a4SAndroid Build Coastguard Worker }
216*bb4ee6a4SAndroid Build Coastguard Worker 
aura_output_connection(void * data,struct zaura_output * aura_output,uint32_t connection)217*bb4ee6a4SAndroid Build Coastguard Worker static void aura_output_connection(void *data, struct zaura_output *aura_output,
218*bb4ee6a4SAndroid Build Coastguard Worker 				   uint32_t connection)
219*bb4ee6a4SAndroid Build Coastguard Worker {
220*bb4ee6a4SAndroid Build Coastguard Worker 	(void)aura_output;
221*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output = (struct output *)data;
222*bb4ee6a4SAndroid Build Coastguard Worker 	output->internal = connection == ZAURA_OUTPUT_CONNECTION_TYPE_INTERNAL;
223*bb4ee6a4SAndroid Build Coastguard Worker }
224*bb4ee6a4SAndroid Build Coastguard Worker 
aura_output_device_scale_factor(void * data,struct zaura_output * aura_output,uint32_t device_scale_factor)225*bb4ee6a4SAndroid Build Coastguard Worker static void aura_output_device_scale_factor(void *data,
226*bb4ee6a4SAndroid Build Coastguard Worker 					    struct zaura_output *aura_output,
227*bb4ee6a4SAndroid Build Coastguard Worker 					    uint32_t device_scale_factor)
228*bb4ee6a4SAndroid Build Coastguard Worker {
229*bb4ee6a4SAndroid Build Coastguard Worker 	(void)aura_output;
230*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output = (struct output *)data;
231*bb4ee6a4SAndroid Build Coastguard Worker 	output->device_scale_factor = device_scale_factor;
232*bb4ee6a4SAndroid Build Coastguard Worker }
233*bb4ee6a4SAndroid Build Coastguard Worker 
234*bb4ee6a4SAndroid Build Coastguard Worker static const struct zaura_output_listener aura_output_listener = {
235*bb4ee6a4SAndroid Build Coastguard Worker     .scale = aura_output_scale,
236*bb4ee6a4SAndroid Build Coastguard Worker     .connection = aura_output_connection,
237*bb4ee6a4SAndroid Build Coastguard Worker     .device_scale_factor = aura_output_device_scale_factor};
238*bb4ee6a4SAndroid Build Coastguard Worker 
xdg_wm_base_ping(void * data,struct xdg_wm_base * xdg_wm_base,uint32_t serial)239*bb4ee6a4SAndroid Build Coastguard Worker static void xdg_wm_base_ping(void *data, struct xdg_wm_base *xdg_wm_base,
240*bb4ee6a4SAndroid Build Coastguard Worker 			     uint32_t serial)
241*bb4ee6a4SAndroid Build Coastguard Worker {
242*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
243*bb4ee6a4SAndroid Build Coastguard Worker 	xdg_wm_base_pong(xdg_wm_base, serial);
244*bb4ee6a4SAndroid Build Coastguard Worker }
245*bb4ee6a4SAndroid Build Coastguard Worker 
246*bb4ee6a4SAndroid Build Coastguard Worker static const struct xdg_wm_base_listener xdg_wm_base_listener = {
247*bb4ee6a4SAndroid Build Coastguard Worker 	.ping = xdg_wm_base_ping,
248*bb4ee6a4SAndroid Build Coastguard Worker };
249*bb4ee6a4SAndroid Build Coastguard Worker 
250*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_keymap(void * data,struct wl_keyboard * wl_keyboard,uint32_t format,int32_t fd,uint32_t size)251*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_keymap(void *data, struct wl_keyboard *wl_keyboard,
252*bb4ee6a4SAndroid Build Coastguard Worker 			       uint32_t format, int32_t fd, uint32_t size)
253*bb4ee6a4SAndroid Build Coastguard Worker {
254*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
255*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
256*bb4ee6a4SAndroid Build Coastguard Worker 	(void)fd;
257*bb4ee6a4SAndroid Build Coastguard Worker 	(void)size;
258*bb4ee6a4SAndroid Build Coastguard Worker 	if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
259*bb4ee6a4SAndroid Build Coastguard Worker 		context->error_callback("wl_keyboard: invalid keymap format");
260*bb4ee6a4SAndroid Build Coastguard Worker 	}
261*bb4ee6a4SAndroid Build Coastguard Worker }
262*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_push_event(struct dwl_context * self,struct dwl_event * event)263*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_push_event(struct dwl_context *self,
264*bb4ee6a4SAndroid Build Coastguard Worker 				   struct dwl_event *event)
265*bb4ee6a4SAndroid Build Coastguard Worker {
266*bb4ee6a4SAndroid Build Coastguard Worker 	if (!self)
267*bb4ee6a4SAndroid Build Coastguard Worker 		return;
268*bb4ee6a4SAndroid Build Coastguard Worker 
269*bb4ee6a4SAndroid Build Coastguard Worker 	memcpy(self->event_cbuf + self->event_write_pos, event,
270*bb4ee6a4SAndroid Build Coastguard Worker 	       sizeof(struct dwl_event));
271*bb4ee6a4SAndroid Build Coastguard Worker 
272*bb4ee6a4SAndroid Build Coastguard Worker 	if (++self->event_write_pos == EVENT_BUF_SIZE)
273*bb4ee6a4SAndroid Build Coastguard Worker 		self->event_write_pos = 0;
274*bb4ee6a4SAndroid Build Coastguard Worker }
275*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_enter(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface,struct wl_array * keys)276*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_enter(void *data, struct wl_keyboard *wl_keyboard,
277*bb4ee6a4SAndroid Build Coastguard Worker 			      uint32_t serial, struct wl_surface *surface,
278*bb4ee6a4SAndroid Build Coastguard Worker 			      struct wl_array *keys)
279*bb4ee6a4SAndroid Build Coastguard Worker {
280*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
281*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
282*bb4ee6a4SAndroid Build Coastguard Worker 	(void)surface;
283*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
284*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
285*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t *key;
286*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_event event = {0};
287*bb4ee6a4SAndroid Build Coastguard Worker 	input->keyboard_input_surface = surface;
288*bb4ee6a4SAndroid Build Coastguard Worker 	wl_array_for_each(key, keys) {
289*bb4ee6a4SAndroid Build Coastguard Worker 		event.surface_descriptor = input->keyboard_input_surface;
290*bb4ee6a4SAndroid Build Coastguard Worker 		event.event_type = DWL_EVENT_TYPE_KEYBOARD_KEY;
291*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[0] = (int32_t)*key;
292*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[1] = DWL_KEYBOARD_KEY_STATE_PRESSED;
293*bb4ee6a4SAndroid Build Coastguard Worker 		dwl_context_push_event(context, &event);
294*bb4ee6a4SAndroid Build Coastguard Worker 	}
295*bb4ee6a4SAndroid Build Coastguard Worker }
296*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_key(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t time,uint32_t key,uint32_t state)297*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_key(void *data, struct wl_keyboard *wl_keyboard,
298*bb4ee6a4SAndroid Build Coastguard Worker 			    uint32_t serial, uint32_t time, uint32_t key,
299*bb4ee6a4SAndroid Build Coastguard Worker 			    uint32_t state)
300*bb4ee6a4SAndroid Build Coastguard Worker {
301*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
302*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
303*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
304*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
305*bb4ee6a4SAndroid Build Coastguard Worker 	(void)time;
306*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_event event = {0};
307*bb4ee6a4SAndroid Build Coastguard Worker 	event.surface_descriptor = input->keyboard_input_surface;
308*bb4ee6a4SAndroid Build Coastguard Worker 	event.event_type = DWL_EVENT_TYPE_KEYBOARD_KEY;
309*bb4ee6a4SAndroid Build Coastguard Worker 	event.params[0] = (int32_t)key;
310*bb4ee6a4SAndroid Build Coastguard Worker 	event.params[1] = state;
311*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_push_event(context, &event);
312*bb4ee6a4SAndroid Build Coastguard Worker }
313*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_leave(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,struct wl_surface * surface)314*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_leave(void *data, struct wl_keyboard *wl_keyboard,
315*bb4ee6a4SAndroid Build Coastguard Worker 			      uint32_t serial, struct wl_surface *surface)
316*bb4ee6a4SAndroid Build Coastguard Worker {
317*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
318*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
319*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_event event = {0};
320*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
321*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
322*bb4ee6a4SAndroid Build Coastguard Worker 	(void)surface;
323*bb4ee6a4SAndroid Build Coastguard Worker 
324*bb4ee6a4SAndroid Build Coastguard Worker 	event.surface_descriptor = input->keyboard_input_surface;
325*bb4ee6a4SAndroid Build Coastguard Worker 	event.event_type = DWL_EVENT_TYPE_KEYBOARD_LEAVE;
326*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_push_event(context, &event);
327*bb4ee6a4SAndroid Build Coastguard Worker 
328*bb4ee6a4SAndroid Build Coastguard Worker 	input->keyboard_input_surface = NULL;
329*bb4ee6a4SAndroid Build Coastguard Worker }
330*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_modifiers(void * data,struct wl_keyboard * wl_keyboard,uint32_t serial,uint32_t mods_depressed,uint32_t mods_latched,uint32_t mods_locked,uint32_t group)331*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_modifiers(void *data, struct wl_keyboard *wl_keyboard,
332*bb4ee6a4SAndroid Build Coastguard Worker 				  uint32_t serial, uint32_t mods_depressed,
333*bb4ee6a4SAndroid Build Coastguard Worker 				  uint32_t mods_latched, uint32_t mods_locked,
334*bb4ee6a4SAndroid Build Coastguard Worker 				  uint32_t group)
335*bb4ee6a4SAndroid Build Coastguard Worker {
336*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
337*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
338*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
339*bb4ee6a4SAndroid Build Coastguard Worker 	(void)mods_depressed;
340*bb4ee6a4SAndroid Build Coastguard Worker 	(void)mods_latched;
341*bb4ee6a4SAndroid Build Coastguard Worker 	(void)mods_locked;
342*bb4ee6a4SAndroid Build Coastguard Worker 	(void)group;
343*bb4ee6a4SAndroid Build Coastguard Worker }
344*bb4ee6a4SAndroid Build Coastguard Worker 
wl_keyboard_repeat_info(void * data,struct wl_keyboard * wl_keyboard,int32_t rate,int32_t delay)345*bb4ee6a4SAndroid Build Coastguard Worker static void wl_keyboard_repeat_info(void *data, struct wl_keyboard *wl_keyboard,
346*bb4ee6a4SAndroid Build Coastguard Worker 				    int32_t rate, int32_t delay)
347*bb4ee6a4SAndroid Build Coastguard Worker {
348*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
349*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_keyboard;
350*bb4ee6a4SAndroid Build Coastguard Worker 	(void)rate;
351*bb4ee6a4SAndroid Build Coastguard Worker 	(void)delay;
352*bb4ee6a4SAndroid Build Coastguard Worker }
353*bb4ee6a4SAndroid Build Coastguard Worker 
354*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_keyboard_listener wl_keyboard_listener = {
355*bb4ee6a4SAndroid Build Coastguard Worker 	.keymap = wl_keyboard_keymap,
356*bb4ee6a4SAndroid Build Coastguard Worker 	.enter = wl_keyboard_enter,
357*bb4ee6a4SAndroid Build Coastguard Worker 	.leave = wl_keyboard_leave,
358*bb4ee6a4SAndroid Build Coastguard Worker 	.key = wl_keyboard_key,
359*bb4ee6a4SAndroid Build Coastguard Worker 	.modifiers = wl_keyboard_modifiers,
360*bb4ee6a4SAndroid Build Coastguard Worker 	.repeat_info = wl_keyboard_repeat_info,
361*bb4ee6a4SAndroid Build Coastguard Worker };
362*bb4ee6a4SAndroid Build Coastguard Worker 
pointer_enter_handler(void * data,struct wl_pointer * wl_pointer,uint32_t serial,struct wl_surface * surface,wl_fixed_t x,wl_fixed_t y)363*bb4ee6a4SAndroid Build Coastguard Worker static void pointer_enter_handler(void *data, struct wl_pointer *wl_pointer,
364*bb4ee6a4SAndroid Build Coastguard Worker 				  uint32_t serial, struct wl_surface *surface,
365*bb4ee6a4SAndroid Build Coastguard Worker 				  wl_fixed_t x, wl_fixed_t y)
366*bb4ee6a4SAndroid Build Coastguard Worker {
367*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
368*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
369*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
370*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
371*bb4ee6a4SAndroid Build Coastguard Worker 
372*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_input_surface = surface;
373*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_x = wl_fixed_to_int(x);
374*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_y = wl_fixed_to_int(y);
375*bb4ee6a4SAndroid Build Coastguard Worker }
376*bb4ee6a4SAndroid Build Coastguard Worker 
pointer_leave_handler(void * data,struct wl_pointer * wl_pointer,uint32_t serial,struct wl_surface * surface)377*bb4ee6a4SAndroid Build Coastguard Worker static void pointer_leave_handler(void *data, struct wl_pointer *wl_pointer,
378*bb4ee6a4SAndroid Build Coastguard Worker 				  uint32_t serial, struct wl_surface *surface)
379*bb4ee6a4SAndroid Build Coastguard Worker {
380*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
381*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
382*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
383*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
384*bb4ee6a4SAndroid Build Coastguard Worker 	(void)surface;
385*bb4ee6a4SAndroid Build Coastguard Worker 
386*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_input_surface = NULL;
387*bb4ee6a4SAndroid Build Coastguard Worker }
388*bb4ee6a4SAndroid Build Coastguard Worker 
pointer_motion_handler(void * data,struct wl_pointer * wl_pointer,uint32_t time,wl_fixed_t x,wl_fixed_t y)389*bb4ee6a4SAndroid Build Coastguard Worker static void pointer_motion_handler(void *data, struct wl_pointer *wl_pointer,
390*bb4ee6a4SAndroid Build Coastguard Worker 				   uint32_t time, wl_fixed_t x, wl_fixed_t y)
391*bb4ee6a4SAndroid Build Coastguard Worker {
392*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
393*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
394*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_event event = {0};
395*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
396*bb4ee6a4SAndroid Build Coastguard Worker 	(void)time;
397*bb4ee6a4SAndroid Build Coastguard Worker 
398*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_x = wl_fixed_to_int(x);
399*bb4ee6a4SAndroid Build Coastguard Worker 	input->pointer_y = wl_fixed_to_int(y);
400*bb4ee6a4SAndroid Build Coastguard Worker 	if (input->pointer_lbutton_state) {
401*bb4ee6a4SAndroid Build Coastguard Worker 		event.surface_descriptor = input->pointer_input_surface;
402*bb4ee6a4SAndroid Build Coastguard Worker 		event.event_type = DWL_EVENT_TYPE_TOUCH_MOTION;
403*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[0] = input->pointer_x;
404*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[1] = input->pointer_y;
405*bb4ee6a4SAndroid Build Coastguard Worker 		dwl_context_push_event(context, &event);
406*bb4ee6a4SAndroid Build Coastguard Worker 	}
407*bb4ee6a4SAndroid Build Coastguard Worker }
408*bb4ee6a4SAndroid Build Coastguard Worker 
pointer_button_handler(void * data,struct wl_pointer * wl_pointer,uint32_t serial,uint32_t time,uint32_t button,uint32_t state)409*bb4ee6a4SAndroid Build Coastguard Worker static void pointer_button_handler(void *data, struct wl_pointer *wl_pointer,
410*bb4ee6a4SAndroid Build Coastguard Worker 				   uint32_t serial, uint32_t time, uint32_t button,
411*bb4ee6a4SAndroid Build Coastguard Worker 				   uint32_t state)
412*bb4ee6a4SAndroid Build Coastguard Worker {
413*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
414*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
415*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
416*bb4ee6a4SAndroid Build Coastguard Worker 	(void)time;
417*bb4ee6a4SAndroid Build Coastguard Worker 	(void)serial;
418*bb4ee6a4SAndroid Build Coastguard Worker 
419*bb4ee6a4SAndroid Build Coastguard Worker 	// we track only the left mouse button since we emulate a single touch device
420*bb4ee6a4SAndroid Build Coastguard Worker 	if (button == BTN_LEFT) {
421*bb4ee6a4SAndroid Build Coastguard Worker 		input->pointer_lbutton_state = state != 0;
422*bb4ee6a4SAndroid Build Coastguard Worker 		struct dwl_event event = {0};
423*bb4ee6a4SAndroid Build Coastguard Worker 		event.surface_descriptor = input->pointer_input_surface;
424*bb4ee6a4SAndroid Build Coastguard Worker 		event.event_type = (state != 0)?
425*bb4ee6a4SAndroid Build Coastguard Worker 			DWL_EVENT_TYPE_TOUCH_DOWN:DWL_EVENT_TYPE_TOUCH_UP;
426*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[0] = input->pointer_x;
427*bb4ee6a4SAndroid Build Coastguard Worker 		event.params[1] = input->pointer_y;
428*bb4ee6a4SAndroid Build Coastguard Worker 		dwl_context_push_event(context, &event);
429*bb4ee6a4SAndroid Build Coastguard Worker 	}
430*bb4ee6a4SAndroid Build Coastguard Worker }
431*bb4ee6a4SAndroid Build Coastguard Worker 
wl_pointer_frame(void * data,struct wl_pointer * wl_pointer)432*bb4ee6a4SAndroid Build Coastguard Worker static void wl_pointer_frame(void *data, struct wl_pointer *wl_pointer)
433*bb4ee6a4SAndroid Build Coastguard Worker {
434*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
435*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
436*bb4ee6a4SAndroid Build Coastguard Worker }
437*bb4ee6a4SAndroid Build Coastguard Worker 
pointer_axis_handler(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis,wl_fixed_t value)438*bb4ee6a4SAndroid Build Coastguard Worker static void pointer_axis_handler(void *data, struct wl_pointer *wl_pointer,
439*bb4ee6a4SAndroid Build Coastguard Worker 				 uint32_t time, uint32_t axis, wl_fixed_t value)
440*bb4ee6a4SAndroid Build Coastguard Worker {
441*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
442*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
443*bb4ee6a4SAndroid Build Coastguard Worker 	(void)time;
444*bb4ee6a4SAndroid Build Coastguard Worker 	(void)axis;
445*bb4ee6a4SAndroid Build Coastguard Worker 	(void)value;
446*bb4ee6a4SAndroid Build Coastguard Worker }
447*bb4ee6a4SAndroid Build Coastguard Worker 
wl_pointer_axis_source(void * data,struct wl_pointer * wl_pointer,uint32_t axis_source)448*bb4ee6a4SAndroid Build Coastguard Worker static void wl_pointer_axis_source(void *data, struct wl_pointer *wl_pointer,
449*bb4ee6a4SAndroid Build Coastguard Worker 				   uint32_t axis_source)
450*bb4ee6a4SAndroid Build Coastguard Worker {
451*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
452*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
453*bb4ee6a4SAndroid Build Coastguard Worker 	(void)axis_source;
454*bb4ee6a4SAndroid Build Coastguard Worker }
455*bb4ee6a4SAndroid Build Coastguard Worker 
wl_pointer_axis_stop(void * data,struct wl_pointer * wl_pointer,uint32_t time,uint32_t axis)456*bb4ee6a4SAndroid Build Coastguard Worker static void wl_pointer_axis_stop(void *data, struct wl_pointer *wl_pointer,
457*bb4ee6a4SAndroid Build Coastguard Worker 					uint32_t time, uint32_t axis)
458*bb4ee6a4SAndroid Build Coastguard Worker {
459*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
460*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
461*bb4ee6a4SAndroid Build Coastguard Worker 	(void)time;
462*bb4ee6a4SAndroid Build Coastguard Worker 	(void)axis;
463*bb4ee6a4SAndroid Build Coastguard Worker }
464*bb4ee6a4SAndroid Build Coastguard Worker 
wl_pointer_axis_discrete(void * data,struct wl_pointer * wl_pointer,uint32_t axis,int32_t discrete)465*bb4ee6a4SAndroid Build Coastguard Worker static void wl_pointer_axis_discrete(void *data, struct wl_pointer *wl_pointer,
466*bb4ee6a4SAndroid Build Coastguard Worker 				     uint32_t axis, int32_t discrete)
467*bb4ee6a4SAndroid Build Coastguard Worker {
468*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
469*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_pointer;
470*bb4ee6a4SAndroid Build Coastguard Worker 	(void)axis;
471*bb4ee6a4SAndroid Build Coastguard Worker 	(void)discrete;
472*bb4ee6a4SAndroid Build Coastguard Worker }
473*bb4ee6a4SAndroid Build Coastguard Worker 
474*bb4ee6a4SAndroid Build Coastguard Worker const struct wl_pointer_listener wl_pointer_listener = {
475*bb4ee6a4SAndroid Build Coastguard Worker 	.enter = pointer_enter_handler,
476*bb4ee6a4SAndroid Build Coastguard Worker 	.leave = pointer_leave_handler,
477*bb4ee6a4SAndroid Build Coastguard Worker 	.motion = pointer_motion_handler,
478*bb4ee6a4SAndroid Build Coastguard Worker 	.button = pointer_button_handler,
479*bb4ee6a4SAndroid Build Coastguard Worker 	.axis = pointer_axis_handler,
480*bb4ee6a4SAndroid Build Coastguard Worker 	.frame = wl_pointer_frame,
481*bb4ee6a4SAndroid Build Coastguard Worker 	.axis_source = wl_pointer_axis_source,
482*bb4ee6a4SAndroid Build Coastguard Worker 	.axis_stop = wl_pointer_axis_stop,
483*bb4ee6a4SAndroid Build Coastguard Worker 	.axis_discrete = wl_pointer_axis_discrete,
484*bb4ee6a4SAndroid Build Coastguard Worker };
485*bb4ee6a4SAndroid Build Coastguard Worker 
wl_seat_capabilities(void * data,struct wl_seat * wl_seat,uint32_t capabilities)486*bb4ee6a4SAndroid Build Coastguard Worker static void wl_seat_capabilities(void *data, struct wl_seat *wl_seat,
487*bb4ee6a4SAndroid Build Coastguard Worker 				 uint32_t capabilities)
488*bb4ee6a4SAndroid Build Coastguard Worker {
489*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *context = (struct dwl_context*)data;
490*bb4ee6a4SAndroid Build Coastguard Worker 	struct input *input = &context->input;
491*bb4ee6a4SAndroid Build Coastguard Worker 	bool have_keyboard = capabilities & WL_SEAT_CAPABILITY_KEYBOARD;
492*bb4ee6a4SAndroid Build Coastguard Worker 	bool have_pointer = capabilities & WL_SEAT_CAPABILITY_POINTER;
493*bb4ee6a4SAndroid Build Coastguard Worker 
494*bb4ee6a4SAndroid Build Coastguard Worker 	if (have_keyboard && input->wl_keyboard == NULL) {
495*bb4ee6a4SAndroid Build Coastguard Worker 		input->wl_keyboard = wl_seat_get_keyboard(wl_seat);
496*bb4ee6a4SAndroid Build Coastguard Worker 		wl_keyboard_add_listener(input->wl_keyboard, &wl_keyboard_listener, context);
497*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (!have_keyboard && input->wl_keyboard != NULL) {
498*bb4ee6a4SAndroid Build Coastguard Worker 		wl_keyboard_release(input->wl_keyboard);
499*bb4ee6a4SAndroid Build Coastguard Worker 		input->wl_keyboard = NULL;
500*bb4ee6a4SAndroid Build Coastguard Worker 	}
501*bb4ee6a4SAndroid Build Coastguard Worker 
502*bb4ee6a4SAndroid Build Coastguard Worker 	if (have_pointer && input->wl_pointer == NULL) {
503*bb4ee6a4SAndroid Build Coastguard Worker 		input->wl_pointer = wl_seat_get_pointer(wl_seat);
504*bb4ee6a4SAndroid Build Coastguard Worker 		wl_pointer_add_listener(input->wl_pointer, &wl_pointer_listener, context);
505*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (!have_pointer && input->wl_pointer != NULL) {
506*bb4ee6a4SAndroid Build Coastguard Worker 		wl_pointer_release(input->wl_pointer);
507*bb4ee6a4SAndroid Build Coastguard Worker 		input->wl_pointer = NULL;
508*bb4ee6a4SAndroid Build Coastguard Worker 	}
509*bb4ee6a4SAndroid Build Coastguard Worker }
510*bb4ee6a4SAndroid Build Coastguard Worker 
wl_seat_name(void * data,struct wl_seat * wl_seat,const char * name)511*bb4ee6a4SAndroid Build Coastguard Worker static void wl_seat_name(void *data, struct wl_seat *wl_seat, const char *name)
512*bb4ee6a4SAndroid Build Coastguard Worker {
513*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
514*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_seat;
515*bb4ee6a4SAndroid Build Coastguard Worker 	(void)name;
516*bb4ee6a4SAndroid Build Coastguard Worker }
517*bb4ee6a4SAndroid Build Coastguard Worker 
518*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_seat_listener wl_seat_listener = {
519*bb4ee6a4SAndroid Build Coastguard Worker 	.capabilities = wl_seat_capabilities,
520*bb4ee6a4SAndroid Build Coastguard Worker 	.name = wl_seat_name,
521*bb4ee6a4SAndroid Build Coastguard Worker };
522*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_output_add(struct dwl_context * context,struct wl_output * wl_output,uint32_t id)523*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_output_add(struct dwl_context *context,
524*bb4ee6a4SAndroid Build Coastguard Worker 				   struct wl_output *wl_output, uint32_t id)
525*bb4ee6a4SAndroid Build Coastguard Worker {
526*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
527*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output;
528*bb4ee6a4SAndroid Build Coastguard Worker 	outputs_for_each(context, i, output)
529*bb4ee6a4SAndroid Build Coastguard Worker 	{
530*bb4ee6a4SAndroid Build Coastguard Worker 		if (output->output == NULL) {
531*bb4ee6a4SAndroid Build Coastguard Worker 			context->output_added = true;
532*bb4ee6a4SAndroid Build Coastguard Worker 			output->id = id;
533*bb4ee6a4SAndroid Build Coastguard Worker 			output->output = wl_output;
534*bb4ee6a4SAndroid Build Coastguard Worker 			output->context = context;
535*bb4ee6a4SAndroid Build Coastguard Worker 			output->current_scale = 1000;
536*bb4ee6a4SAndroid Build Coastguard Worker 			output->device_scale_factor = 1000;
537*bb4ee6a4SAndroid Build Coastguard Worker 			// This is a fun little hack from reveman. The idea is
538*bb4ee6a4SAndroid Build Coastguard Worker 			// that the first display will be internal and never get
539*bb4ee6a4SAndroid Build Coastguard Worker 			// removed.
540*bb4ee6a4SAndroid Build Coastguard Worker 			output->internal = i == 0;
541*bb4ee6a4SAndroid Build Coastguard Worker 			wl_output_add_listener(output->output, &output_listener,
542*bb4ee6a4SAndroid Build Coastguard Worker 					       output);
543*bb4ee6a4SAndroid Build Coastguard Worker 			return;
544*bb4ee6a4SAndroid Build Coastguard Worker 		}
545*bb4ee6a4SAndroid Build Coastguard Worker 	}
546*bb4ee6a4SAndroid Build Coastguard Worker }
547*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_output_remove_destroy(struct dwl_context * context,uint32_t id)548*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_output_remove_destroy(struct dwl_context *context,
549*bb4ee6a4SAndroid Build Coastguard Worker 					      uint32_t id)
550*bb4ee6a4SAndroid Build Coastguard Worker {
551*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
552*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output;
553*bb4ee6a4SAndroid Build Coastguard Worker 	outputs_for_each(context, i, output)
554*bb4ee6a4SAndroid Build Coastguard Worker 	{
555*bb4ee6a4SAndroid Build Coastguard Worker 		if (output->id == id) {
556*bb4ee6a4SAndroid Build Coastguard Worker 			if (output->aura_output)
557*bb4ee6a4SAndroid Build Coastguard Worker 				zaura_output_destroy(output->aura_output);
558*bb4ee6a4SAndroid Build Coastguard Worker 			wl_output_destroy(output->output);
559*bb4ee6a4SAndroid Build Coastguard Worker 			memset(output, 0, sizeof(struct output));
560*bb4ee6a4SAndroid Build Coastguard Worker 			return;
561*bb4ee6a4SAndroid Build Coastguard Worker 		}
562*bb4ee6a4SAndroid Build Coastguard Worker 	}
563*bb4ee6a4SAndroid Build Coastguard Worker }
564*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_output_get_aura(struct dwl_context * context)565*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_output_get_aura(struct dwl_context *context)
566*bb4ee6a4SAndroid Build Coastguard Worker {
567*bb4ee6a4SAndroid Build Coastguard Worker 	if (!context->ifaces.aura)
568*bb4ee6a4SAndroid Build Coastguard Worker 		return;
569*bb4ee6a4SAndroid Build Coastguard Worker 
570*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
571*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output;
572*bb4ee6a4SAndroid Build Coastguard Worker 	outputs_for_each(context, i, output)
573*bb4ee6a4SAndroid Build Coastguard Worker 	{
574*bb4ee6a4SAndroid Build Coastguard Worker 		if (output->output != NULL && output->aura_output == NULL) {
575*bb4ee6a4SAndroid Build Coastguard Worker 			output->aura_output = zaura_shell_get_aura_output(
576*bb4ee6a4SAndroid Build Coastguard Worker 			    context->ifaces.aura, output->output);
577*bb4ee6a4SAndroid Build Coastguard Worker 			zaura_output_add_listener(
578*bb4ee6a4SAndroid Build Coastguard Worker 			    output->aura_output, &aura_output_listener, output);
579*bb4ee6a4SAndroid Build Coastguard Worker 		}
580*bb4ee6a4SAndroid Build Coastguard Worker 	}
581*bb4ee6a4SAndroid Build Coastguard Worker }
582*bb4ee6a4SAndroid Build Coastguard Worker 
registry_global(void * data,struct wl_registry * registry,uint32_t id,const char * interface,uint32_t version)583*bb4ee6a4SAndroid Build Coastguard Worker static void registry_global(void *data, struct wl_registry *registry,
584*bb4ee6a4SAndroid Build Coastguard Worker 			    uint32_t id, const char *interface,
585*bb4ee6a4SAndroid Build Coastguard Worker 			    uint32_t version)
586*bb4ee6a4SAndroid Build Coastguard Worker {
587*bb4ee6a4SAndroid Build Coastguard Worker 	(void)version;
588*bb4ee6a4SAndroid Build Coastguard Worker 	struct interfaces *ifaces = (struct interfaces *)data;
589*bb4ee6a4SAndroid Build Coastguard Worker 	if (strcmp(interface, wl_compositor_interface.name) == 0) {
590*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->compositor = (struct wl_compositor *)wl_registry_bind(
591*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &wl_compositor_interface, 3);
592*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, wl_subcompositor_interface.name) == 0) {
593*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->subcompositor =
594*bb4ee6a4SAndroid Build Coastguard Worker 		    (struct wl_subcompositor *)wl_registry_bind(
595*bb4ee6a4SAndroid Build Coastguard Worker 			registry, id, &wl_subcompositor_interface, 1);
596*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, wl_shm_interface.name) == 0) {
597*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->shm = (struct wl_shm *)wl_registry_bind(
598*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &wl_shm_interface, 1);
599*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, wl_seat_interface.name) == 0) {
600*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->seat = (struct wl_seat *)wl_registry_bind(
601*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &wl_seat_interface, 5);
602*bb4ee6a4SAndroid Build Coastguard Worker 		wl_seat_add_listener(ifaces->seat, &wl_seat_listener, ifaces->context);
603*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, wl_output_interface.name) == 0) {
604*bb4ee6a4SAndroid Build Coastguard Worker 		struct wl_output *output = (struct wl_output *)wl_registry_bind(
605*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &wl_output_interface, 2);
606*bb4ee6a4SAndroid Build Coastguard Worker 		dwl_context_output_add(ifaces->context, output, id);
607*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, "zaura_shell") == 0 && version >= 6) {
608*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->aura = (struct zaura_shell *)wl_registry_bind(
609*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &zaura_shell_interface, 6);
610*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, "zwp_linux_dmabuf_v1") == 0) {
611*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->linux_dmabuf =
612*bb4ee6a4SAndroid Build Coastguard Worker 		    (struct zwp_linux_dmabuf_v1 *)wl_registry_bind(
613*bb4ee6a4SAndroid Build Coastguard Worker 			registry, id, &zwp_linux_dmabuf_v1_interface, 1);
614*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, xdg_wm_base_interface.name) == 0) {
615*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->xdg_wm_base = (struct xdg_wm_base *)wl_registry_bind(
616*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &xdg_wm_base_interface, 1);
617*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_wm_base_add_listener(ifaces->xdg_wm_base, &xdg_wm_base_listener,
618*bb4ee6a4SAndroid Build Coastguard Worker 			NULL);
619*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, "wp_viewporter") == 0) {
620*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->viewporter = (struct wp_viewporter *)wl_registry_bind(
621*bb4ee6a4SAndroid Build Coastguard Worker 		    registry, id, &wp_viewporter_interface, 1);
622*bb4ee6a4SAndroid Build Coastguard Worker 	} else if (strcmp(interface, "wp_virtio_gpu_metadata_v1") == 0) {
623*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->virtio_gpu_metadata =
624*bb4ee6a4SAndroid Build Coastguard Worker 			(struct wp_virtio_gpu_metadata_v1 *)wl_registry_bind(
625*bb4ee6a4SAndroid Build Coastguard Worker 			registry, id, &wp_virtio_gpu_metadata_v1_interface, 1);
626*bb4ee6a4SAndroid Build Coastguard Worker 	}
627*bb4ee6a4SAndroid Build Coastguard Worker }
628*bb4ee6a4SAndroid Build Coastguard Worker 
global_remove(void * data,struct wl_registry * registry,uint32_t id)629*bb4ee6a4SAndroid Build Coastguard Worker static void global_remove(void *data, struct wl_registry *registry, uint32_t id)
630*bb4ee6a4SAndroid Build Coastguard Worker {
631*bb4ee6a4SAndroid Build Coastguard Worker 	(void)registry;
632*bb4ee6a4SAndroid Build Coastguard Worker 
633*bb4ee6a4SAndroid Build Coastguard Worker 	struct interfaces *ifaces = (struct interfaces *)data;
634*bb4ee6a4SAndroid Build Coastguard Worker 	// If the ID matches any output, this will remove it. Otherwise, this is
635*bb4ee6a4SAndroid Build Coastguard Worker 	// a no-op.
636*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_output_remove_destroy(ifaces->context, id);
637*bb4ee6a4SAndroid Build Coastguard Worker 
638*bb4ee6a4SAndroid Build Coastguard Worker 	if (ifaces->aura &&
639*bb4ee6a4SAndroid Build Coastguard Worker 	    wl_proxy_get_id((struct wl_proxy *)ifaces->aura) == id) {
640*bb4ee6a4SAndroid Build Coastguard Worker 		zaura_shell_destroy(ifaces->aura);
641*bb4ee6a4SAndroid Build Coastguard Worker 		ifaces->aura = NULL;
642*bb4ee6a4SAndroid Build Coastguard Worker 	}
643*bb4ee6a4SAndroid Build Coastguard Worker 
644*bb4ee6a4SAndroid Build Coastguard Worker 	// TODO(zachr): deal with the removal of some of the required
645*bb4ee6a4SAndroid Build Coastguard Worker 	// interfaces.
646*bb4ee6a4SAndroid Build Coastguard Worker }
647*bb4ee6a4SAndroid Build Coastguard Worker 
648*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_registry_listener registry_listener = {
649*bb4ee6a4SAndroid Build Coastguard Worker     .global = registry_global, .global_remove = global_remove};
650*bb4ee6a4SAndroid Build Coastguard Worker 
toplevel_configure(void * data,struct xdg_toplevel * xdg_toplevel,int32_t width,int32_t height,struct wl_array * states)651*bb4ee6a4SAndroid Build Coastguard Worker static void toplevel_configure(void *data,
652*bb4ee6a4SAndroid Build Coastguard Worker 			       struct xdg_toplevel *xdg_toplevel,
653*bb4ee6a4SAndroid Build Coastguard Worker 			       int32_t width, int32_t height,
654*bb4ee6a4SAndroid Build Coastguard Worker 			       struct wl_array *states)
655*bb4ee6a4SAndroid Build Coastguard Worker {
656*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
657*bb4ee6a4SAndroid Build Coastguard Worker 	(void)xdg_toplevel;
658*bb4ee6a4SAndroid Build Coastguard Worker 	(void)width;
659*bb4ee6a4SAndroid Build Coastguard Worker 	(void)height;
660*bb4ee6a4SAndroid Build Coastguard Worker 	(void)states;
661*bb4ee6a4SAndroid Build Coastguard Worker }
662*bb4ee6a4SAndroid Build Coastguard Worker 
toplevel_close(void * data,struct xdg_toplevel * xdg_toplevel)663*bb4ee6a4SAndroid Build Coastguard Worker static void toplevel_close(void *data,
664*bb4ee6a4SAndroid Build Coastguard Worker 			   struct xdg_toplevel *xdg_toplevel)
665*bb4ee6a4SAndroid Build Coastguard Worker {
666*bb4ee6a4SAndroid Build Coastguard Worker 	(void)xdg_toplevel;
667*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_surface *surface = (struct dwl_surface *)data;
668*bb4ee6a4SAndroid Build Coastguard Worker 	surface->close_requested = true;
669*bb4ee6a4SAndroid Build Coastguard Worker }
670*bb4ee6a4SAndroid Build Coastguard Worker 
671*bb4ee6a4SAndroid Build Coastguard Worker static const struct xdg_toplevel_listener toplevel_listener = {
672*bb4ee6a4SAndroid Build Coastguard Worker     .configure = toplevel_configure, .close = toplevel_close};
673*bb4ee6a4SAndroid Build Coastguard Worker 
xdg_surface_configure_handler(void * data,struct xdg_surface * xdg_surface,uint32_t serial)674*bb4ee6a4SAndroid Build Coastguard Worker static void xdg_surface_configure_handler(void *data,
675*bb4ee6a4SAndroid Build Coastguard Worker 					  struct xdg_surface *xdg_surface,
676*bb4ee6a4SAndroid Build Coastguard Worker 					  uint32_t serial)
677*bb4ee6a4SAndroid Build Coastguard Worker {
678*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
679*bb4ee6a4SAndroid Build Coastguard Worker 	xdg_surface_ack_configure(xdg_surface, serial);
680*bb4ee6a4SAndroid Build Coastguard Worker }
681*bb4ee6a4SAndroid Build Coastguard Worker 
682*bb4ee6a4SAndroid Build Coastguard Worker static const struct xdg_surface_listener xdg_surface_listener = {
683*bb4ee6a4SAndroid Build Coastguard Worker 	.configure = xdg_surface_configure_handler
684*bb4ee6a4SAndroid Build Coastguard Worker };
685*bb4ee6a4SAndroid Build Coastguard Worker 
surface_enter(void * data,struct wl_surface * wl_surface,struct wl_output * wl_output)686*bb4ee6a4SAndroid Build Coastguard Worker static void surface_enter(void *data, struct wl_surface *wl_surface,
687*bb4ee6a4SAndroid Build Coastguard Worker 			  struct wl_output *wl_output)
688*bb4ee6a4SAndroid Build Coastguard Worker {
689*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_surface *surface = (struct dwl_surface *)data;
690*bb4ee6a4SAndroid Build Coastguard Worker 
691*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output =
692*bb4ee6a4SAndroid Build Coastguard Worker 	    (struct output *)wl_output_get_user_data(wl_output);
693*bb4ee6a4SAndroid Build Coastguard Worker 
694*bb4ee6a4SAndroid Build Coastguard Worker 	surface->scale = (output->device_scale_factor / 1000.0) *
695*bb4ee6a4SAndroid Build Coastguard Worker 			 (output->current_scale / 1000.0);
696*bb4ee6a4SAndroid Build Coastguard Worker 
697*bb4ee6a4SAndroid Build Coastguard Worker 	if (surface->viewport) {
698*bb4ee6a4SAndroid Build Coastguard Worker 		wp_viewport_set_destination(
699*bb4ee6a4SAndroid Build Coastguard Worker 		    surface->viewport, ceil(surface->width / surface->scale),
700*bb4ee6a4SAndroid Build Coastguard Worker 		    ceil(surface->height / surface->scale));
701*bb4ee6a4SAndroid Build Coastguard Worker 	} else {
702*bb4ee6a4SAndroid Build Coastguard Worker 		wl_surface_set_buffer_scale(wl_surface, surface->scale);
703*bb4ee6a4SAndroid Build Coastguard Worker 	}
704*bb4ee6a4SAndroid Build Coastguard Worker 
705*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_commit(wl_surface);
706*bb4ee6a4SAndroid Build Coastguard Worker }
707*bb4ee6a4SAndroid Build Coastguard Worker 
surface_leave(void * data,struct wl_surface * wl_surface,struct wl_output * output)708*bb4ee6a4SAndroid Build Coastguard Worker static void surface_leave(void *data, struct wl_surface *wl_surface,
709*bb4ee6a4SAndroid Build Coastguard Worker 			  struct wl_output *output)
710*bb4ee6a4SAndroid Build Coastguard Worker {
711*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
712*bb4ee6a4SAndroid Build Coastguard Worker 	(void)wl_surface;
713*bb4ee6a4SAndroid Build Coastguard Worker 	(void)output;
714*bb4ee6a4SAndroid Build Coastguard Worker }
715*bb4ee6a4SAndroid Build Coastguard Worker 
716*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_surface_listener surface_listener = {
717*bb4ee6a4SAndroid Build Coastguard Worker     .enter = surface_enter, .leave = surface_leave};
718*bb4ee6a4SAndroid Build Coastguard Worker 
error_callback_stub(const char * message)719*bb4ee6a4SAndroid Build Coastguard Worker static void error_callback_stub(const char *message) {
720*bb4ee6a4SAndroid Build Coastguard Worker 	(void)message;
721*bb4ee6a4SAndroid Build Coastguard Worker }
722*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_new(dwl_error_callback_type error_callback)723*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_context *dwl_context_new(dwl_error_callback_type error_callback)
724*bb4ee6a4SAndroid Build Coastguard Worker {
725*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_context *ctx = calloc(1, sizeof(struct dwl_context));
726*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ctx)
727*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
728*bb4ee6a4SAndroid Build Coastguard Worker 	ctx->ifaces.context = ctx;
729*bb4ee6a4SAndroid Build Coastguard Worker 	ctx->error_callback = error_callback ? error_callback : error_callback_stub;
730*bb4ee6a4SAndroid Build Coastguard Worker 	return ctx;
731*bb4ee6a4SAndroid Build Coastguard Worker }
732*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_destroy(struct dwl_context ** self)733*bb4ee6a4SAndroid Build Coastguard Worker void dwl_context_destroy(struct dwl_context **self)
734*bb4ee6a4SAndroid Build Coastguard Worker {
735*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->display)
736*bb4ee6a4SAndroid Build Coastguard Worker 		wl_display_disconnect((*self)->display);
737*bb4ee6a4SAndroid Build Coastguard Worker 	free(*self);
738*bb4ee6a4SAndroid Build Coastguard Worker 	*self = NULL;
739*bb4ee6a4SAndroid Build Coastguard Worker }
740*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_setup(struct dwl_context * self,const char * socket_path)741*bb4ee6a4SAndroid Build Coastguard Worker bool dwl_context_setup(struct dwl_context *self, const char *socket_path)
742*bb4ee6a4SAndroid Build Coastguard Worker {
743*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_display *display = wl_display_connect(socket_path);
744*bb4ee6a4SAndroid Build Coastguard Worker 	if (!display) {
745*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to connect to display");
746*bb4ee6a4SAndroid Build Coastguard Worker 		return false;
747*bb4ee6a4SAndroid Build Coastguard Worker 	}
748*bb4ee6a4SAndroid Build Coastguard Worker 	self->display = display;
749*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_set_user_data(display, self);
750*bb4ee6a4SAndroid Build Coastguard Worker 
751*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_registry *registry = wl_display_get_registry(display);
752*bb4ee6a4SAndroid Build Coastguard Worker 	if (!registry) {
753*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to get registry");
754*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
755*bb4ee6a4SAndroid Build Coastguard Worker 	}
756*bb4ee6a4SAndroid Build Coastguard Worker 
757*bb4ee6a4SAndroid Build Coastguard Worker 	struct interfaces *ifaces = &self->ifaces;
758*bb4ee6a4SAndroid Build Coastguard Worker 	wl_registry_add_listener(registry, &registry_listener, ifaces);
759*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_roundtrip(display);
760*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_output_get_aura(self);
761*bb4ee6a4SAndroid Build Coastguard Worker 
762*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->shm) {
763*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface shm");
764*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
765*bb4ee6a4SAndroid Build Coastguard Worker 	}
766*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->compositor) {
767*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface compositor");
768*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
769*bb4ee6a4SAndroid Build Coastguard Worker 	}
770*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->subcompositor) {
771*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface subcompositor");
772*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
773*bb4ee6a4SAndroid Build Coastguard Worker 	}
774*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->seat) {
775*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface seat");
776*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
777*bb4ee6a4SAndroid Build Coastguard Worker 	}
778*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->linux_dmabuf) {
779*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface linux_dmabuf");
780*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
781*bb4ee6a4SAndroid Build Coastguard Worker 	}
782*bb4ee6a4SAndroid Build Coastguard Worker 	if (!ifaces->xdg_wm_base) {
783*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("missing interface xdg_wm_base");
784*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
785*bb4ee6a4SAndroid Build Coastguard Worker 	}
786*bb4ee6a4SAndroid Build Coastguard Worker 
787*bb4ee6a4SAndroid Build Coastguard Worker 	return true;
788*bb4ee6a4SAndroid Build Coastguard Worker 
789*bb4ee6a4SAndroid Build Coastguard Worker fail:
790*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_disconnect(display);
791*bb4ee6a4SAndroid Build Coastguard Worker 	self->display = NULL;
792*bb4ee6a4SAndroid Build Coastguard Worker 	return false;
793*bb4ee6a4SAndroid Build Coastguard Worker }
794*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_fd(struct dwl_context * self)795*bb4ee6a4SAndroid Build Coastguard Worker int dwl_context_fd(struct dwl_context *self)
796*bb4ee6a4SAndroid Build Coastguard Worker {
797*bb4ee6a4SAndroid Build Coastguard Worker 	return wl_display_get_fd(self->display);
798*bb4ee6a4SAndroid Build Coastguard Worker }
799*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_dispatch(struct dwl_context * self)800*bb4ee6a4SAndroid Build Coastguard Worker void dwl_context_dispatch(struct dwl_context *self)
801*bb4ee6a4SAndroid Build Coastguard Worker {
802*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_dispatch(self->display);
803*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->output_added) {
804*bb4ee6a4SAndroid Build Coastguard Worker 		self->output_added = false;
805*bb4ee6a4SAndroid Build Coastguard Worker 		dwl_context_output_get_aura(self);
806*bb4ee6a4SAndroid Build Coastguard Worker 		wl_display_roundtrip(self->display);
807*bb4ee6a4SAndroid Build Coastguard Worker 	}
808*bb4ee6a4SAndroid Build Coastguard Worker }
809*bb4ee6a4SAndroid Build Coastguard Worker 
linux_buffer_created(void * data,struct zwp_linux_buffer_params_v1 * zwp_linux_buffer_params_v1,struct wl_buffer * buffer)810*bb4ee6a4SAndroid Build Coastguard Worker static void linux_buffer_created(
811*bb4ee6a4SAndroid Build Coastguard Worker     void *data, struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1,
812*bb4ee6a4SAndroid Build Coastguard Worker     struct wl_buffer *buffer)
813*bb4ee6a4SAndroid Build Coastguard Worker {
814*bb4ee6a4SAndroid Build Coastguard Worker 	(void)zwp_linux_buffer_params_v1;
815*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_dmabuf *dmabuf = (struct dwl_dmabuf *)data;
816*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->buffer = buffer;
817*bb4ee6a4SAndroid Build Coastguard Worker }
818*bb4ee6a4SAndroid Build Coastguard Worker 
linux_buffer_failed(void * data,struct zwp_linux_buffer_params_v1 * zwp_linux_buffer_params_v1)819*bb4ee6a4SAndroid Build Coastguard Worker static void linux_buffer_failed(
820*bb4ee6a4SAndroid Build Coastguard Worker     void *data, struct zwp_linux_buffer_params_v1 *zwp_linux_buffer_params_v1)
821*bb4ee6a4SAndroid Build Coastguard Worker {
822*bb4ee6a4SAndroid Build Coastguard Worker 	(void)data;
823*bb4ee6a4SAndroid Build Coastguard Worker 	(void)zwp_linux_buffer_params_v1;
824*bb4ee6a4SAndroid Build Coastguard Worker }
825*bb4ee6a4SAndroid Build Coastguard Worker 
826*bb4ee6a4SAndroid Build Coastguard Worker static const struct zwp_linux_buffer_params_v1_listener linux_buffer_listener =
827*bb4ee6a4SAndroid Build Coastguard Worker     {.created = linux_buffer_created, .failed = linux_buffer_failed};
828*bb4ee6a4SAndroid Build Coastguard Worker 
dmabuf_buffer_release(void * data,struct wl_buffer * buffer)829*bb4ee6a4SAndroid Build Coastguard Worker static void dmabuf_buffer_release(void *data, struct wl_buffer *buffer)
830*bb4ee6a4SAndroid Build Coastguard Worker {
831*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_dmabuf *dmabuf = (struct dwl_dmabuf *)data;
832*bb4ee6a4SAndroid Build Coastguard Worker 	(void)buffer;
833*bb4ee6a4SAndroid Build Coastguard Worker 
834*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->in_use = false;
835*bb4ee6a4SAndroid Build Coastguard Worker }
836*bb4ee6a4SAndroid Build Coastguard Worker 
837*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_buffer_listener dmabuf_buffer_listener = {
838*bb4ee6a4SAndroid Build Coastguard Worker     .release = dmabuf_buffer_release};
839*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_add_dmabuf(struct dwl_context * self,struct dwl_dmabuf * dmabuf)840*bb4ee6a4SAndroid Build Coastguard Worker static bool dwl_context_add_dmabuf(struct dwl_context *self,
841*bb4ee6a4SAndroid Build Coastguard Worker 				   struct dwl_dmabuf *dmabuf)
842*bb4ee6a4SAndroid Build Coastguard Worker {
843*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
844*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
845*bb4ee6a4SAndroid Build Coastguard Worker 		if (!self->dmabufs[i]) {
846*bb4ee6a4SAndroid Build Coastguard Worker 			self->dmabufs[i] = dmabuf;
847*bb4ee6a4SAndroid Build Coastguard Worker 			return true;
848*bb4ee6a4SAndroid Build Coastguard Worker 		}
849*bb4ee6a4SAndroid Build Coastguard Worker 	}
850*bb4ee6a4SAndroid Build Coastguard Worker 
851*bb4ee6a4SAndroid Build Coastguard Worker 	return false;
852*bb4ee6a4SAndroid Build Coastguard Worker }
853*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_remove_dmabuf(struct dwl_context * self,uint32_t import_id)854*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_remove_dmabuf(struct dwl_context *self,
855*bb4ee6a4SAndroid Build Coastguard Worker 				      uint32_t import_id)
856*bb4ee6a4SAndroid Build Coastguard Worker {
857*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
858*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
859*bb4ee6a4SAndroid Build Coastguard Worker 		if (self->dmabufs[i] &&
860*bb4ee6a4SAndroid Build Coastguard Worker 		    self->dmabufs[i]->import_id == import_id) {
861*bb4ee6a4SAndroid Build Coastguard Worker 			self->dmabufs[i] = NULL;
862*bb4ee6a4SAndroid Build Coastguard Worker 		}
863*bb4ee6a4SAndroid Build Coastguard Worker 	}
864*bb4ee6a4SAndroid Build Coastguard Worker }
865*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_get_dmabuf(struct dwl_context * self,uint32_t import_id)866*bb4ee6a4SAndroid Build Coastguard Worker static struct dwl_dmabuf *dwl_context_get_dmabuf(struct dwl_context *self,
867*bb4ee6a4SAndroid Build Coastguard Worker 					         uint32_t import_id)
868*bb4ee6a4SAndroid Build Coastguard Worker {
869*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
870*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
871*bb4ee6a4SAndroid Build Coastguard Worker 		if (self->dmabufs[i] &&
872*bb4ee6a4SAndroid Build Coastguard Worker 		    self->dmabufs[i]->import_id == import_id) {
873*bb4ee6a4SAndroid Build Coastguard Worker 			return self->dmabufs[i];
874*bb4ee6a4SAndroid Build Coastguard Worker 		}
875*bb4ee6a4SAndroid Build Coastguard Worker 	}
876*bb4ee6a4SAndroid Build Coastguard Worker 
877*bb4ee6a4SAndroid Build Coastguard Worker 	return NULL;
878*bb4ee6a4SAndroid Build Coastguard Worker }
879*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_dmabuf_new(struct dwl_context * self,uint32_t import_id,int fd,uint32_t offset,uint32_t stride,uint64_t modifier,uint32_t width,uint32_t height,uint32_t fourcc)880*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_dmabuf *dwl_context_dmabuf_new(struct dwl_context *self,
881*bb4ee6a4SAndroid Build Coastguard Worker 					  uint32_t import_id,
882*bb4ee6a4SAndroid Build Coastguard Worker 					  int fd, uint32_t offset,
883*bb4ee6a4SAndroid Build Coastguard Worker 					  uint32_t stride, uint64_t modifier,
884*bb4ee6a4SAndroid Build Coastguard Worker 					  uint32_t width, uint32_t height,
885*bb4ee6a4SAndroid Build Coastguard Worker 					  uint32_t fourcc)
886*bb4ee6a4SAndroid Build Coastguard Worker {
887*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_dmabuf *dmabuf = calloc(1, sizeof(struct dwl_dmabuf));
888*bb4ee6a4SAndroid Build Coastguard Worker 	if (!dmabuf) {
889*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to allocate dwl_dmabuf");
890*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
891*bb4ee6a4SAndroid Build Coastguard Worker 	}
892*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->width = width;
893*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->height = height;
894*bb4ee6a4SAndroid Build Coastguard Worker 
895*bb4ee6a4SAndroid Build Coastguard Worker 	struct zwp_linux_buffer_params_v1 *params =
896*bb4ee6a4SAndroid Build Coastguard Worker 	    zwp_linux_dmabuf_v1_create_params(self->ifaces.linux_dmabuf);
897*bb4ee6a4SAndroid Build Coastguard Worker 	if (!params) {
898*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to allocate zwp_linux_buffer_params_v1");
899*bb4ee6a4SAndroid Build Coastguard Worker 		free(dmabuf);
900*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
901*bb4ee6a4SAndroid Build Coastguard Worker 	}
902*bb4ee6a4SAndroid Build Coastguard Worker 
903*bb4ee6a4SAndroid Build Coastguard Worker 	zwp_linux_buffer_params_v1_add_listener(params, &linux_buffer_listener,
904*bb4ee6a4SAndroid Build Coastguard Worker 						dmabuf);
905*bb4ee6a4SAndroid Build Coastguard Worker 	zwp_linux_buffer_params_v1_add(params, fd, 0 /* plane_idx */, offset,
906*bb4ee6a4SAndroid Build Coastguard Worker 				       stride, modifier >> 32,
907*bb4ee6a4SAndroid Build Coastguard Worker 				       (uint32_t)modifier);
908*bb4ee6a4SAndroid Build Coastguard Worker 	zwp_linux_buffer_params_v1_create(params, width, height, fourcc, 0);
909*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_roundtrip(self->display);
910*bb4ee6a4SAndroid Build Coastguard Worker 	zwp_linux_buffer_params_v1_destroy(params);
911*bb4ee6a4SAndroid Build Coastguard Worker 
912*bb4ee6a4SAndroid Build Coastguard Worker 	if (!dmabuf->buffer) {
913*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to get wl_buffer for dmabuf");
914*bb4ee6a4SAndroid Build Coastguard Worker 		free(dmabuf);
915*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
916*bb4ee6a4SAndroid Build Coastguard Worker 	}
917*bb4ee6a4SAndroid Build Coastguard Worker 
918*bb4ee6a4SAndroid Build Coastguard Worker 	wl_buffer_add_listener(dmabuf->buffer, &dmabuf_buffer_listener, dmabuf);
919*bb4ee6a4SAndroid Build Coastguard Worker 
920*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->import_id = import_id;
921*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->context = self;
922*bb4ee6a4SAndroid Build Coastguard Worker 	if (!dwl_context_add_dmabuf(self, dmabuf)) {
923*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to add dmabuf to context");
924*bb4ee6a4SAndroid Build Coastguard Worker 		free(dmabuf);
925*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
926*bb4ee6a4SAndroid Build Coastguard Worker 	}
927*bb4ee6a4SAndroid Build Coastguard Worker 
928*bb4ee6a4SAndroid Build Coastguard Worker 	return dmabuf;
929*bb4ee6a4SAndroid Build Coastguard Worker }
930*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_dmabuf_destroy(struct dwl_dmabuf ** self)931*bb4ee6a4SAndroid Build Coastguard Worker void dwl_dmabuf_destroy(struct dwl_dmabuf **self)
932*bb4ee6a4SAndroid Build Coastguard Worker {
933*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_remove_dmabuf((*self)->context, (*self)->import_id);
934*bb4ee6a4SAndroid Build Coastguard Worker 	wl_buffer_destroy((*self)->buffer);
935*bb4ee6a4SAndroid Build Coastguard Worker 	free(*self);
936*bb4ee6a4SAndroid Build Coastguard Worker 	*self = NULL;
937*bb4ee6a4SAndroid Build Coastguard Worker }
938*bb4ee6a4SAndroid Build Coastguard Worker 
surface_buffer_release(void * data,struct wl_buffer * buffer)939*bb4ee6a4SAndroid Build Coastguard Worker static void surface_buffer_release(void *data, struct wl_buffer *buffer)
940*bb4ee6a4SAndroid Build Coastguard Worker {
941*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_surface *surface = (struct dwl_surface *)data;
942*bb4ee6a4SAndroid Build Coastguard Worker 	(void)buffer;
943*bb4ee6a4SAndroid Build Coastguard Worker 
944*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
945*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < surface->buffer_count; i++) {
946*bb4ee6a4SAndroid Build Coastguard Worker 		if (buffer == surface->buffers[i]) {
947*bb4ee6a4SAndroid Build Coastguard Worker 			surface->buffer_use_bit_mask &= ~(1 << i);
948*bb4ee6a4SAndroid Build Coastguard Worker 			break;
949*bb4ee6a4SAndroid Build Coastguard Worker 		}
950*bb4ee6a4SAndroid Build Coastguard Worker 	}
951*bb4ee6a4SAndroid Build Coastguard Worker }
952*bb4ee6a4SAndroid Build Coastguard Worker 
953*bb4ee6a4SAndroid Build Coastguard Worker static const struct wl_buffer_listener surface_buffer_listener = {
954*bb4ee6a4SAndroid Build Coastguard Worker     .release = surface_buffer_release};
955*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_get_surface(struct dwl_context * self,uint32_t surface_id)956*bb4ee6a4SAndroid Build Coastguard Worker static struct dwl_surface *dwl_context_get_surface(struct dwl_context *self,
957*bb4ee6a4SAndroid Build Coastguard Worker 					           uint32_t surface_id)
958*bb4ee6a4SAndroid Build Coastguard Worker {
959*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
960*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
961*bb4ee6a4SAndroid Build Coastguard Worker 		if (self->surfaces[i] &&
962*bb4ee6a4SAndroid Build Coastguard Worker 		    self->surfaces[i]->surface_id == surface_id) {
963*bb4ee6a4SAndroid Build Coastguard Worker 			return self->surfaces[i];
964*bb4ee6a4SAndroid Build Coastguard Worker 		}
965*bb4ee6a4SAndroid Build Coastguard Worker 	}
966*bb4ee6a4SAndroid Build Coastguard Worker 
967*bb4ee6a4SAndroid Build Coastguard Worker 	return NULL;
968*bb4ee6a4SAndroid Build Coastguard Worker }
969*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_add_surface(struct dwl_context * self,struct dwl_surface * surface)970*bb4ee6a4SAndroid Build Coastguard Worker static bool dwl_context_add_surface(struct dwl_context *self,
971*bb4ee6a4SAndroid Build Coastguard Worker 				    struct dwl_surface *surface)
972*bb4ee6a4SAndroid Build Coastguard Worker {
973*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
974*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
975*bb4ee6a4SAndroid Build Coastguard Worker 		if (!self->surfaces[i]) {
976*bb4ee6a4SAndroid Build Coastguard Worker 			self->surfaces[i] = surface;
977*bb4ee6a4SAndroid Build Coastguard Worker 			return true;
978*bb4ee6a4SAndroid Build Coastguard Worker 		}
979*bb4ee6a4SAndroid Build Coastguard Worker 	}
980*bb4ee6a4SAndroid Build Coastguard Worker 
981*bb4ee6a4SAndroid Build Coastguard Worker 	return false;
982*bb4ee6a4SAndroid Build Coastguard Worker }
983*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_remove_surface(struct dwl_context * self,uint32_t surface_id)984*bb4ee6a4SAndroid Build Coastguard Worker static void dwl_context_remove_surface(struct dwl_context *self,
985*bb4ee6a4SAndroid Build Coastguard Worker 				       uint32_t surface_id)
986*bb4ee6a4SAndroid Build Coastguard Worker {
987*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
988*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < MAX_BUFFER_COUNT; i++) {
989*bb4ee6a4SAndroid Build Coastguard Worker 		if (self->surfaces[i] &&
990*bb4ee6a4SAndroid Build Coastguard Worker 		    self->surfaces[i]->surface_id == surface_id) {
991*bb4ee6a4SAndroid Build Coastguard Worker 			self->surfaces[i] = NULL;
992*bb4ee6a4SAndroid Build Coastguard Worker 		}
993*bb4ee6a4SAndroid Build Coastguard Worker 	}
994*bb4ee6a4SAndroid Build Coastguard Worker }
995*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_surface_new(struct dwl_context * self,uint32_t parent_id,uint32_t surface_id,int shm_fd,size_t shm_size,size_t buffer_size,uint32_t width,uint32_t height,uint32_t stride,uint32_t flags)996*bb4ee6a4SAndroid Build Coastguard Worker struct dwl_surface *dwl_context_surface_new(struct dwl_context *self,
997*bb4ee6a4SAndroid Build Coastguard Worker 					    uint32_t parent_id,
998*bb4ee6a4SAndroid Build Coastguard Worker 					    uint32_t  surface_id,
999*bb4ee6a4SAndroid Build Coastguard Worker 					    int shm_fd, size_t shm_size,
1000*bb4ee6a4SAndroid Build Coastguard Worker 					    size_t buffer_size, uint32_t width,
1001*bb4ee6a4SAndroid Build Coastguard Worker 					    uint32_t height, uint32_t stride,
1002*bb4ee6a4SAndroid Build Coastguard Worker 					    uint32_t flags)
1003*bb4ee6a4SAndroid Build Coastguard Worker {
1004*bb4ee6a4SAndroid Build Coastguard Worker 	if (buffer_size == 0)
1005*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
1006*bb4ee6a4SAndroid Build Coastguard Worker 
1007*bb4ee6a4SAndroid Build Coastguard Worker 	size_t buffer_count = shm_size / buffer_size;
1008*bb4ee6a4SAndroid Build Coastguard Worker 	if (buffer_count == 0)
1009*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
1010*bb4ee6a4SAndroid Build Coastguard Worker 	if (buffer_count > MAX_BUFFER_COUNT)
1011*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
1012*bb4ee6a4SAndroid Build Coastguard Worker 
1013*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_surface *disp_surface =
1014*bb4ee6a4SAndroid Build Coastguard Worker 	    calloc(1, sizeof(struct dwl_surface) +
1015*bb4ee6a4SAndroid Build Coastguard Worker 			  sizeof(struct wl_buffer *) * buffer_count);
1016*bb4ee6a4SAndroid Build Coastguard Worker 	if (!disp_surface)
1017*bb4ee6a4SAndroid Build Coastguard Worker 		return NULL;
1018*bb4ee6a4SAndroid Build Coastguard Worker 
1019*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->context = self;
1020*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->width = width;
1021*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->height = height;
1022*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->scale = DEFAULT_SCALE;
1023*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->buffer_count = buffer_count;
1024*bb4ee6a4SAndroid Build Coastguard Worker 
1025*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_shm_pool *shm_pool =
1026*bb4ee6a4SAndroid Build Coastguard Worker 	    wl_shm_create_pool(self->ifaces.shm, shm_fd, shm_size);
1027*bb4ee6a4SAndroid Build Coastguard Worker 	if (!shm_pool) {
1028*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to make shm pool");
1029*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
1030*bb4ee6a4SAndroid Build Coastguard Worker 	}
1031*bb4ee6a4SAndroid Build Coastguard Worker 
1032*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
1033*bb4ee6a4SAndroid Build Coastguard Worker 	uint32_t format = (flags & DWL_SURFACE_FLAG_HAS_ALPHA)?
1034*bb4ee6a4SAndroid Build Coastguard Worker 		WL_SHM_FORMAT_ARGB8888:WL_SHM_FORMAT_XRGB8888;
1035*bb4ee6a4SAndroid Build Coastguard Worker 
1036*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < buffer_count; i++) {
1037*bb4ee6a4SAndroid Build Coastguard Worker 		struct wl_buffer *buffer = wl_shm_pool_create_buffer(
1038*bb4ee6a4SAndroid Build Coastguard Worker 		    shm_pool, buffer_size * i, width, height, stride, format);
1039*bb4ee6a4SAndroid Build Coastguard Worker 		if (!buffer) {
1040*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to create buffer");
1041*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1042*bb4ee6a4SAndroid Build Coastguard Worker 		}
1043*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->buffers[i] = buffer;
1044*bb4ee6a4SAndroid Build Coastguard Worker 	}
1045*bb4ee6a4SAndroid Build Coastguard Worker 
1046*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < buffer_count; i++)
1047*bb4ee6a4SAndroid Build Coastguard Worker 		wl_buffer_add_listener(disp_surface->buffers[i],
1048*bb4ee6a4SAndroid Build Coastguard Worker 				       &surface_buffer_listener, disp_surface);
1049*bb4ee6a4SAndroid Build Coastguard Worker 
1050*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->wl_surface =
1051*bb4ee6a4SAndroid Build Coastguard Worker 	    wl_compositor_create_surface(self->ifaces.compositor);
1052*bb4ee6a4SAndroid Build Coastguard Worker 	if (!disp_surface->wl_surface) {
1053*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to make surface");
1054*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
1055*bb4ee6a4SAndroid Build Coastguard Worker 	}
1056*bb4ee6a4SAndroid Build Coastguard Worker 
1057*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_add_listener(disp_surface->wl_surface, &surface_listener,
1058*bb4ee6a4SAndroid Build Coastguard Worker 				disp_surface);
1059*bb4ee6a4SAndroid Build Coastguard Worker 
1060*bb4ee6a4SAndroid Build Coastguard Worker 	struct wl_region *region = wl_compositor_create_region(self->ifaces.compositor);
1061*bb4ee6a4SAndroid Build Coastguard Worker 	if (!region) {
1062*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to make region");
1063*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
1064*bb4ee6a4SAndroid Build Coastguard Worker 	}
1065*bb4ee6a4SAndroid Build Coastguard Worker 
1066*bb4ee6a4SAndroid Build Coastguard Worker 	bool receive_input = (flags & DWL_SURFACE_FLAG_RECEIVE_INPUT);
1067*bb4ee6a4SAndroid Build Coastguard Worker 	if (receive_input) {
1068*bb4ee6a4SAndroid Build Coastguard Worker 		wl_region_add(region, 0, 0, width, height);
1069*bb4ee6a4SAndroid Build Coastguard Worker 	} else {
1070*bb4ee6a4SAndroid Build Coastguard Worker 		// We have to add an empty region because NULL doesn't work
1071*bb4ee6a4SAndroid Build Coastguard Worker 		wl_region_add(region, 0, 0, 0, 0);
1072*bb4ee6a4SAndroid Build Coastguard Worker 	}
1073*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_set_input_region(disp_surface->wl_surface, region);
1074*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_set_opaque_region(disp_surface->wl_surface, region);
1075*bb4ee6a4SAndroid Build Coastguard Worker 	wl_region_destroy(region);
1076*bb4ee6a4SAndroid Build Coastguard Worker 
1077*bb4ee6a4SAndroid Build Coastguard Worker 	if (!parent_id) {
1078*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->xdg_surface = xdg_wm_base_get_xdg_surface(
1079*bb4ee6a4SAndroid Build Coastguard Worker 		    self->ifaces.xdg_wm_base, disp_surface->wl_surface);
1080*bb4ee6a4SAndroid Build Coastguard Worker 		if (!disp_surface->xdg_surface) {
1081*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to make xdg shell surface");
1082*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1083*bb4ee6a4SAndroid Build Coastguard Worker 		}
1084*bb4ee6a4SAndroid Build Coastguard Worker 
1085*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->xdg_toplevel =
1086*bb4ee6a4SAndroid Build Coastguard Worker 		    xdg_surface_get_toplevel(disp_surface->xdg_surface);
1087*bb4ee6a4SAndroid Build Coastguard Worker 		if (!disp_surface->xdg_toplevel) {
1088*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to make toplevel xdg shell surface");
1089*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1090*bb4ee6a4SAndroid Build Coastguard Worker 		}
1091*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_toplevel_set_title(disp_surface->xdg_toplevel, "crosvm");
1092*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_toplevel_add_listener(disp_surface->xdg_toplevel,
1093*bb4ee6a4SAndroid Build Coastguard Worker 					      &toplevel_listener, disp_surface);
1094*bb4ee6a4SAndroid Build Coastguard Worker 
1095*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_surface_add_listener(disp_surface->xdg_surface,
1096*bb4ee6a4SAndroid Build Coastguard Worker 					     &xdg_surface_listener,
1097*bb4ee6a4SAndroid Build Coastguard Worker 					     NULL);
1098*bb4ee6a4SAndroid Build Coastguard Worker 		if (self->ifaces.aura) {
1099*bb4ee6a4SAndroid Build Coastguard Worker 			disp_surface->aura = zaura_shell_get_aura_surface(
1100*bb4ee6a4SAndroid Build Coastguard Worker 			    self->ifaces.aura, disp_surface->wl_surface);
1101*bb4ee6a4SAndroid Build Coastguard Worker 			if (!disp_surface->aura) {
1102*bb4ee6a4SAndroid Build Coastguard Worker 				self->error_callback("failed to make aura surface");
1103*bb4ee6a4SAndroid Build Coastguard Worker 				goto fail;
1104*bb4ee6a4SAndroid Build Coastguard Worker 			}
1105*bb4ee6a4SAndroid Build Coastguard Worker 			zaura_surface_set_frame(
1106*bb4ee6a4SAndroid Build Coastguard Worker 			    disp_surface->aura,
1107*bb4ee6a4SAndroid Build Coastguard Worker 			    ZAURA_SURFACE_FRAME_TYPE_NORMAL);
1108*bb4ee6a4SAndroid Build Coastguard Worker 		}
1109*bb4ee6a4SAndroid Build Coastguard Worker 
1110*bb4ee6a4SAndroid Build Coastguard Worker 		// signal that the surface is ready to be configured
1111*bb4ee6a4SAndroid Build Coastguard Worker 		wl_surface_commit(disp_surface->wl_surface);
1112*bb4ee6a4SAndroid Build Coastguard Worker 
1113*bb4ee6a4SAndroid Build Coastguard Worker 		// wait for the surface to be configured
1114*bb4ee6a4SAndroid Build Coastguard Worker 		wl_display_roundtrip(self->display);
1115*bb4ee6a4SAndroid Build Coastguard Worker 	} else {
1116*bb4ee6a4SAndroid Build Coastguard Worker 		struct dwl_surface *parent_surface =
1117*bb4ee6a4SAndroid Build Coastguard Worker 			dwl_context_get_surface(self, parent_id);
1118*bb4ee6a4SAndroid Build Coastguard Worker 
1119*bb4ee6a4SAndroid Build Coastguard Worker 		if (!parent_surface) {
1120*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to find parent_surface");
1121*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1122*bb4ee6a4SAndroid Build Coastguard Worker 		}
1123*bb4ee6a4SAndroid Build Coastguard Worker 
1124*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->subsurface = wl_subcompositor_get_subsurface(
1125*bb4ee6a4SAndroid Build Coastguard Worker 		    self->ifaces.subcompositor, disp_surface->wl_surface,
1126*bb4ee6a4SAndroid Build Coastguard Worker 		    parent_surface->wl_surface);
1127*bb4ee6a4SAndroid Build Coastguard Worker 		if (!disp_surface->subsurface) {
1128*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to make subsurface");
1129*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1130*bb4ee6a4SAndroid Build Coastguard Worker 		}
1131*bb4ee6a4SAndroid Build Coastguard Worker 		wl_subsurface_set_desync(disp_surface->subsurface);
1132*bb4ee6a4SAndroid Build Coastguard Worker 	}
1133*bb4ee6a4SAndroid Build Coastguard Worker 
1134*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->ifaces.viewporter) {
1135*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->viewport = wp_viewporter_get_viewport(
1136*bb4ee6a4SAndroid Build Coastguard Worker 		    self->ifaces.viewporter, disp_surface->wl_surface);
1137*bb4ee6a4SAndroid Build Coastguard Worker 		if (!disp_surface->viewport) {
1138*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to make surface viewport");
1139*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1140*bb4ee6a4SAndroid Build Coastguard Worker 		}
1141*bb4ee6a4SAndroid Build Coastguard Worker 	}
1142*bb4ee6a4SAndroid Build Coastguard Worker 
1143*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->ifaces.virtio_gpu_metadata) {
1144*bb4ee6a4SAndroid Build Coastguard Worker 		disp_surface->virtio_gpu_surface_metadata =
1145*bb4ee6a4SAndroid Build Coastguard Worker 			wp_virtio_gpu_metadata_v1_get_surface_metadata(
1146*bb4ee6a4SAndroid Build Coastguard Worker 				self->ifaces.virtio_gpu_metadata, disp_surface->wl_surface);
1147*bb4ee6a4SAndroid Build Coastguard Worker 		if (!disp_surface->virtio_gpu_surface_metadata) {
1148*bb4ee6a4SAndroid Build Coastguard Worker 			self->error_callback("failed to make surface virtio surface metadata");
1149*bb4ee6a4SAndroid Build Coastguard Worker 			goto fail;
1150*bb4ee6a4SAndroid Build Coastguard Worker 		}
1151*bb4ee6a4SAndroid Build Coastguard Worker 	}
1152*bb4ee6a4SAndroid Build Coastguard Worker 
1153*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_attach(disp_surface->wl_surface, disp_surface->buffers[0], 0,
1154*bb4ee6a4SAndroid Build Coastguard Worker 			  0);
1155*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_damage(disp_surface->wl_surface, 0, 0, width, height);
1156*bb4ee6a4SAndroid Build Coastguard Worker 	wl_shm_pool_destroy(shm_pool);
1157*bb4ee6a4SAndroid Build Coastguard Worker 
1158*bb4ee6a4SAndroid Build Coastguard Worker 	// Needed to get outputs before iterating them.
1159*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_roundtrip(self->display);
1160*bb4ee6a4SAndroid Build Coastguard Worker 
1161*bb4ee6a4SAndroid Build Coastguard Worker 	// Assuming that this surface will enter the internal output initially,
1162*bb4ee6a4SAndroid Build Coastguard Worker 	// trigger a surface enter for that output before doing the first
1163*bb4ee6a4SAndroid Build Coastguard Worker 	// surface commit. THis is to avoid unpleasant artifacts when the
1164*bb4ee6a4SAndroid Build Coastguard Worker 	// surface first appears.
1165*bb4ee6a4SAndroid Build Coastguard Worker 	struct output *output;
1166*bb4ee6a4SAndroid Build Coastguard Worker 	outputs_for_each(self, i, output)
1167*bb4ee6a4SAndroid Build Coastguard Worker 	{
1168*bb4ee6a4SAndroid Build Coastguard Worker 		if (output->internal) {
1169*bb4ee6a4SAndroid Build Coastguard Worker 			surface_enter(disp_surface, disp_surface->wl_surface,
1170*bb4ee6a4SAndroid Build Coastguard Worker 				      output->output);
1171*bb4ee6a4SAndroid Build Coastguard Worker 		}
1172*bb4ee6a4SAndroid Build Coastguard Worker 	}
1173*bb4ee6a4SAndroid Build Coastguard Worker 
1174*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_commit(disp_surface->wl_surface);
1175*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_flush(self->display);
1176*bb4ee6a4SAndroid Build Coastguard Worker 
1177*bb4ee6a4SAndroid Build Coastguard Worker 	disp_surface->surface_id = surface_id;
1178*bb4ee6a4SAndroid Build Coastguard Worker 	if (!dwl_context_add_surface(self, disp_surface)) {
1179*bb4ee6a4SAndroid Build Coastguard Worker 		self->error_callback("failed to add surface to context");
1180*bb4ee6a4SAndroid Build Coastguard Worker 		goto fail;
1181*bb4ee6a4SAndroid Build Coastguard Worker 	}
1182*bb4ee6a4SAndroid Build Coastguard Worker 
1183*bb4ee6a4SAndroid Build Coastguard Worker 	return disp_surface;
1184*bb4ee6a4SAndroid Build Coastguard Worker fail:
1185*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->virtio_gpu_surface_metadata)
1186*bb4ee6a4SAndroid Build Coastguard Worker 		wp_virtio_gpu_surface_metadata_v1_destroy(
1187*bb4ee6a4SAndroid Build Coastguard Worker 			disp_surface->virtio_gpu_surface_metadata);
1188*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->viewport)
1189*bb4ee6a4SAndroid Build Coastguard Worker 		wp_viewport_destroy(disp_surface->viewport);
1190*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->subsurface)
1191*bb4ee6a4SAndroid Build Coastguard Worker 		wl_subsurface_destroy(disp_surface->subsurface);
1192*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->xdg_toplevel)
1193*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_toplevel_destroy(disp_surface->xdg_toplevel);
1194*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->xdg_surface)
1195*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_surface_destroy(disp_surface->xdg_surface);
1196*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->aura)
1197*bb4ee6a4SAndroid Build Coastguard Worker 		zaura_surface_destroy(disp_surface->aura);
1198*bb4ee6a4SAndroid Build Coastguard Worker 	if (disp_surface->wl_surface)
1199*bb4ee6a4SAndroid Build Coastguard Worker 		wl_surface_destroy(disp_surface->wl_surface);
1200*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < buffer_count; i++)
1201*bb4ee6a4SAndroid Build Coastguard Worker 		if (disp_surface->buffers[i])
1202*bb4ee6a4SAndroid Build Coastguard Worker 			wl_buffer_destroy(disp_surface->buffers[i]);
1203*bb4ee6a4SAndroid Build Coastguard Worker 	if (shm_pool)
1204*bb4ee6a4SAndroid Build Coastguard Worker 		wl_shm_pool_destroy(shm_pool);
1205*bb4ee6a4SAndroid Build Coastguard Worker 	free(disp_surface);
1206*bb4ee6a4SAndroid Build Coastguard Worker 	return NULL;
1207*bb4ee6a4SAndroid Build Coastguard Worker }
1208*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_destroy(struct dwl_surface ** self)1209*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_destroy(struct dwl_surface **self)
1210*bb4ee6a4SAndroid Build Coastguard Worker {
1211*bb4ee6a4SAndroid Build Coastguard Worker 	size_t i;
1212*bb4ee6a4SAndroid Build Coastguard Worker 
1213*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_context_remove_surface((*self)->context, (*self)->surface_id);
1214*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->virtio_gpu_surface_metadata)
1215*bb4ee6a4SAndroid Build Coastguard Worker 		wp_virtio_gpu_surface_metadata_v1_destroy(
1216*bb4ee6a4SAndroid Build Coastguard Worker 			(*self)->virtio_gpu_surface_metadata);
1217*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->viewport)
1218*bb4ee6a4SAndroid Build Coastguard Worker 		wp_viewport_destroy((*self)->viewport);
1219*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->subsurface)
1220*bb4ee6a4SAndroid Build Coastguard Worker 		wl_subsurface_destroy((*self)->subsurface);
1221*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->xdg_toplevel)
1222*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_toplevel_destroy((*self)->xdg_toplevel);
1223*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->xdg_surface)
1224*bb4ee6a4SAndroid Build Coastguard Worker 		xdg_surface_destroy((*self)->xdg_surface);
1225*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->aura)
1226*bb4ee6a4SAndroid Build Coastguard Worker 		zaura_surface_destroy((*self)->aura);
1227*bb4ee6a4SAndroid Build Coastguard Worker 	if ((*self)->wl_surface)
1228*bb4ee6a4SAndroid Build Coastguard Worker 		wl_surface_destroy((*self)->wl_surface);
1229*bb4ee6a4SAndroid Build Coastguard Worker 	for (i = 0; i < (*self)->buffer_count; i++)
1230*bb4ee6a4SAndroid Build Coastguard Worker 		wl_buffer_destroy((*self)->buffers[i]);
1231*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_flush((*self)->context->display);
1232*bb4ee6a4SAndroid Build Coastguard Worker 	free(*self);
1233*bb4ee6a4SAndroid Build Coastguard Worker 	*self = NULL;
1234*bb4ee6a4SAndroid Build Coastguard Worker }
1235*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_commit(struct dwl_surface * self)1236*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_commit(struct dwl_surface *self)
1237*bb4ee6a4SAndroid Build Coastguard Worker {
1238*bb4ee6a4SAndroid Build Coastguard Worker 	// It is possible that we are committing frames faster than the
1239*bb4ee6a4SAndroid Build Coastguard Worker 	// compositor can put them on the screen. This may result in dropped
1240*bb4ee6a4SAndroid Build Coastguard Worker 	// frames, but this is acceptable considering there is no good way to
1241*bb4ee6a4SAndroid Build Coastguard Worker 	// apply back pressure to the guest gpu driver right now. The intention
1242*bb4ee6a4SAndroid Build Coastguard Worker 	// of this module is to help bootstrap gpu support, so it does not have
1243*bb4ee6a4SAndroid Build Coastguard Worker 	// to have artifact free rendering.
1244*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_commit(self->wl_surface);
1245*bb4ee6a4SAndroid Build Coastguard Worker 	wl_display_flush(self->context->display);
1246*bb4ee6a4SAndroid Build Coastguard Worker }
1247*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_buffer_in_use(struct dwl_surface * self,size_t buffer_index)1248*bb4ee6a4SAndroid Build Coastguard Worker bool dwl_surface_buffer_in_use(struct dwl_surface *self, size_t buffer_index)
1249*bb4ee6a4SAndroid Build Coastguard Worker {
1250*bb4ee6a4SAndroid Build Coastguard Worker 	return (self->buffer_use_bit_mask & (1 << buffer_index)) != 0;
1251*bb4ee6a4SAndroid Build Coastguard Worker }
1252*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_flip(struct dwl_surface * self,size_t buffer_index)1253*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_flip(struct dwl_surface *self, size_t buffer_index)
1254*bb4ee6a4SAndroid Build Coastguard Worker {
1255*bb4ee6a4SAndroid Build Coastguard Worker 	if (buffer_index >= self->buffer_count)
1256*bb4ee6a4SAndroid Build Coastguard Worker 		return;
1257*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_attach(self->wl_surface, self->buffers[buffer_index], 0, 0);
1258*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_damage(self->wl_surface, 0, 0, self->width, self->height);
1259*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_surface_commit(self);
1260*bb4ee6a4SAndroid Build Coastguard Worker 	self->buffer_use_bit_mask |= 1 << buffer_index;
1261*bb4ee6a4SAndroid Build Coastguard Worker }
1262*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_flip_to(struct dwl_surface * self,uint32_t import_id)1263*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_flip_to(struct dwl_surface *self, uint32_t import_id)
1264*bb4ee6a4SAndroid Build Coastguard Worker {
1265*bb4ee6a4SAndroid Build Coastguard Worker 	// Surface and dmabuf have to exist in same context.
1266*bb4ee6a4SAndroid Build Coastguard Worker 	struct dwl_dmabuf *dmabuf = dwl_context_get_dmabuf(self->context,
1267*bb4ee6a4SAndroid Build Coastguard Worker 							   import_id);
1268*bb4ee6a4SAndroid Build Coastguard Worker 	if (!dmabuf)
1269*bb4ee6a4SAndroid Build Coastguard Worker 		return;
1270*bb4ee6a4SAndroid Build Coastguard Worker 
1271*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->width != dmabuf->width || self->height != dmabuf->height)
1272*bb4ee6a4SAndroid Build Coastguard Worker 		return;
1273*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_attach(self->wl_surface, dmabuf->buffer, 0, 0);
1274*bb4ee6a4SAndroid Build Coastguard Worker 	wl_surface_damage(self->wl_surface, 0, 0, self->width, self->height);
1275*bb4ee6a4SAndroid Build Coastguard Worker 	dwl_surface_commit(self);
1276*bb4ee6a4SAndroid Build Coastguard Worker 	dmabuf->in_use = true;
1277*bb4ee6a4SAndroid Build Coastguard Worker }
1278*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_close_requested(const struct dwl_surface * self)1279*bb4ee6a4SAndroid Build Coastguard Worker bool dwl_surface_close_requested(const struct dwl_surface *self)
1280*bb4ee6a4SAndroid Build Coastguard Worker {
1281*bb4ee6a4SAndroid Build Coastguard Worker 	return self->close_requested;
1282*bb4ee6a4SAndroid Build Coastguard Worker }
1283*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_set_position(struct dwl_surface * self,uint32_t x,uint32_t y)1284*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_set_position(struct dwl_surface *self, uint32_t x, uint32_t y)
1285*bb4ee6a4SAndroid Build Coastguard Worker {
1286*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->subsurface) {
1287*bb4ee6a4SAndroid Build Coastguard Worker 		wl_subsurface_set_position(self->subsurface, x / self->scale,
1288*bb4ee6a4SAndroid Build Coastguard Worker 					   y / self->scale);
1289*bb4ee6a4SAndroid Build Coastguard Worker 		wl_surface_commit(self->wl_surface);
1290*bb4ee6a4SAndroid Build Coastguard Worker 		wl_display_flush(self->context->display);
1291*bb4ee6a4SAndroid Build Coastguard Worker 	}
1292*bb4ee6a4SAndroid Build Coastguard Worker }
1293*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_descriptor(const struct dwl_surface * self)1294*bb4ee6a4SAndroid Build Coastguard Worker const void* dwl_surface_descriptor(const struct dwl_surface *self)
1295*bb4ee6a4SAndroid Build Coastguard Worker {
1296*bb4ee6a4SAndroid Build Coastguard Worker 	return self->wl_surface;
1297*bb4ee6a4SAndroid Build Coastguard Worker }
1298*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_pending_events(const struct dwl_context * self)1299*bb4ee6a4SAndroid Build Coastguard Worker bool dwl_context_pending_events(const struct dwl_context *self)
1300*bb4ee6a4SAndroid Build Coastguard Worker {
1301*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->event_write_pos == self->event_read_pos)
1302*bb4ee6a4SAndroid Build Coastguard Worker 		return false;
1303*bb4ee6a4SAndroid Build Coastguard Worker 
1304*bb4ee6a4SAndroid Build Coastguard Worker 	return true;
1305*bb4ee6a4SAndroid Build Coastguard Worker }
1306*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_context_next_event(struct dwl_context * self,struct dwl_event * event)1307*bb4ee6a4SAndroid Build Coastguard Worker void dwl_context_next_event(struct dwl_context *self, struct dwl_event *event)
1308*bb4ee6a4SAndroid Build Coastguard Worker {
1309*bb4ee6a4SAndroid Build Coastguard Worker 	memcpy(event, self->event_cbuf + self->event_read_pos,
1310*bb4ee6a4SAndroid Build Coastguard Worker 	       sizeof(struct dwl_event));
1311*bb4ee6a4SAndroid Build Coastguard Worker 
1312*bb4ee6a4SAndroid Build Coastguard Worker 	if (++self->event_read_pos == EVENT_BUF_SIZE)
1313*bb4ee6a4SAndroid Build Coastguard Worker 		self->event_read_pos = 0;
1314*bb4ee6a4SAndroid Build Coastguard Worker }
1315*bb4ee6a4SAndroid Build Coastguard Worker 
dwl_surface_set_scanout_id(struct dwl_surface * self,uint32_t scanout_id)1316*bb4ee6a4SAndroid Build Coastguard Worker void dwl_surface_set_scanout_id(struct dwl_surface *self, uint32_t scanout_id)
1317*bb4ee6a4SAndroid Build Coastguard Worker {
1318*bb4ee6a4SAndroid Build Coastguard Worker 	if (self->virtio_gpu_surface_metadata) {
1319*bb4ee6a4SAndroid Build Coastguard Worker 		wp_virtio_gpu_surface_metadata_v1_set_scanout_id(
1320*bb4ee6a4SAndroid Build Coastguard Worker 			self->virtio_gpu_surface_metadata, scanout_id);
1321*bb4ee6a4SAndroid Build Coastguard Worker 	}
1322*bb4ee6a4SAndroid Build Coastguard Worker }
1323