1 #ifdef HAVE_CONFIG_H
2 # include <config.h>
3 #endif
4
5 #include "ecore_wl2_private.h"
6 #include "efl-hints-client-protocol.h"
7
8 static void _ecore_wl2_window_hide_send(Ecore_Wl2_Window *window);
9
10 void
_ecore_wl2_window_semi_free(Ecore_Wl2_Window * window)11 _ecore_wl2_window_semi_free(Ecore_Wl2_Window *window)
12 {
13 if (window->xdg_popup) xdg_popup_destroy(window->xdg_popup);
14 window->xdg_popup = NULL;
15
16 if (window->xdg_toplevel) xdg_toplevel_destroy(window->xdg_toplevel);
17 window->xdg_toplevel = NULL;
18
19 if (window->xdg_surface) xdg_surface_destroy(window->xdg_surface);
20 window->xdg_surface = NULL;
21
22 if (window->zxdg_popup) zxdg_popup_v6_destroy(window->zxdg_popup);
23 window->zxdg_popup = NULL;
24
25 if (window->zxdg_toplevel) zxdg_toplevel_v6_destroy(window->zxdg_toplevel);
26 window->zxdg_toplevel = NULL;
27
28 if (window->zxdg_surface) zxdg_surface_v6_destroy(window->zxdg_surface);
29 window->zxdg_surface = NULL;
30
31 if (window->www_surface)
32 www_surface_destroy(window->www_surface);
33 window->www_surface = NULL;
34
35 if (window->surface) wl_surface_destroy(window->surface);
36 window->surface = NULL;
37 window->surface_id = -1;
38
39 if (window->callback) wl_callback_destroy(window->callback);
40 window->callback = NULL;
41
42 window->outputs = eina_list_free(window->outputs);
43
44 ecore_wl2_window_surface_flush(window, EINA_TRUE);
45
46 window->commit_pending = EINA_FALSE;
47 }
48
49 static void
_ecore_wl2_window_activate_send(Ecore_Wl2_Window * window)50 _ecore_wl2_window_activate_send(Ecore_Wl2_Window *window)
51 {
52 Ecore_Wl2_Event_Window_Activate *ev;
53
54 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Activate));
55 if (!ev) return;
56
57 ev->win = window;
58 if (window->parent)
59 ev->parent_win = window->parent;
60 ev->event_win = window;
61 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ACTIVATE, ev, NULL, NULL);
62 }
63
64 static void
_ecore_wl2_window_deactivate_send(Ecore_Wl2_Window * window)65 _ecore_wl2_window_deactivate_send(Ecore_Wl2_Window *window)
66 {
67 Ecore_Wl2_Event_Window_Deactivate *ev;
68
69 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Deactivate));
70 if (!ev) return;
71
72 ev->win = window;
73 if (window->parent)
74 ev->parent_win = window->parent;
75 ev->event_win = window;
76 ecore_event_add(ECORE_WL2_EVENT_WINDOW_DEACTIVATE, ev, NULL, NULL);
77 }
78
79 static void
_ecore_wl2_window_configure_send(Ecore_Wl2_Window * win)80 _ecore_wl2_window_configure_send(Ecore_Wl2_Window *win)
81 {
82 Ecore_Wl2_Event_Window_Configure *ev;
83
84 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure));
85 if (!ev) return;
86
87 ev->win = win;
88 ev->event_win = win;
89
90 if ((win->set_config.geometry.w == win->def_config.geometry.w) &&
91 (win->set_config.geometry.h == win->def_config.geometry.h))
92 ev->w = ev->h = 0;
93 else if ((!win->def_config.geometry.w) && (!win->def_config.geometry.h) &&
94 (!win->def_config.fullscreen) &&
95 (!win->def_config.maximized) &&
96 ((win->def_config.fullscreen != win->req_config.fullscreen) ||
97 (win->def_config.maximized != win->req_config.maximized)))
98 ev->w = win->saved.w, ev->h = win->saved.h;
99 else
100 ev->w = win->def_config.geometry.w, ev->h = win->def_config.geometry.h;
101
102 ev->edges = !!win->def_config.resizing;
103 if (win->def_config.fullscreen)
104 ev->states |= ECORE_WL2_WINDOW_STATE_FULLSCREEN;
105 if (win->def_config.maximized)
106 ev->states |= ECORE_WL2_WINDOW_STATE_MAXIMIZED;
107
108 win->req_config = win->def_config;
109 ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE, ev, NULL, NULL);
110
111 if (win->def_config.focused)
112 _ecore_wl2_window_activate_send(win);
113 else
114 _ecore_wl2_window_deactivate_send(win);
115 }
116
117 static void
_configure_complete(Ecore_Wl2_Window * window)118 _configure_complete(Ecore_Wl2_Window *window)
119 {
120 Ecore_Wl2_Event_Window_Configure_Complete *ev;
121
122 window->pending.configure = EINA_FALSE;
123
124 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Configure_Complete));
125 if (!ev) return;
126
127 ev->win = window;
128 ecore_event_add(ECORE_WL2_EVENT_WINDOW_CONFIGURE_COMPLETE, ev, NULL, NULL);
129
130 }
131
132 #include "window_v6.x"
133
134 static void
_www_surface_end_drag(void * data,struct www_surface * www_surface EINA_UNUSED)135 _www_surface_end_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
136 {
137 Ecore_Wl2_Window *window = data;
138 Ecore_Wl2_Event_Window_WWW_Drag *ev;
139
140 ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
141 EINA_SAFETY_ON_NULL_RETURN(ev);
142 ev->window = window;
143 ev->dragging = 0;
144
145 ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
146 }
147
148 static void
_www_surface_start_drag(void * data,struct www_surface * www_surface EINA_UNUSED)149 _www_surface_start_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
150 {
151 Ecore_Wl2_Window *window = data;
152 Ecore_Wl2_Event_Window_WWW_Drag *ev;
153
154 ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
155 EINA_SAFETY_ON_NULL_RETURN(ev);
156 ev->window = window;
157 ev->dragging = 1;
158
159 ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
160 }
161
162 static void
_www_surface_status(void * data,struct www_surface * www_surface EINA_UNUSED,int32_t x_rel,int32_t y_rel,uint32_t timestamp)163 _www_surface_status(void *data, struct www_surface *www_surface EINA_UNUSED, int32_t x_rel, int32_t y_rel, uint32_t timestamp)
164 {
165 Ecore_Wl2_Window *window = data;
166 Ecore_Wl2_Event_Window_WWW *ev;
167
168 ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW));
169 EINA_SAFETY_ON_NULL_RETURN(ev);
170 ev->window = window;
171 ev->x_rel = x_rel;
172 ev->y_rel = y_rel;
173 ev->timestamp = timestamp;
174
175 ecore_event_add(_ecore_wl2_event_window_www, ev, NULL, NULL);
176 }
177
178 static struct www_surface_listener _www_surface_listener =
179 {
180 .status = _www_surface_status,
181 .start_drag = _www_surface_start_drag,
182 .end_drag = _www_surface_end_drag,
183 };
184
185 void
_ecore_wl2_window_www_surface_init(Ecore_Wl2_Window * window)186 _ecore_wl2_window_www_surface_init(Ecore_Wl2_Window *window)
187 {
188 if (!window->surface) return;
189 if (!window->display->wl.www) return;
190 if (window->www_surface) return;
191 window->www_surface = www_create(window->display->wl.www, window->surface);
192 www_surface_set_user_data(window->www_surface, window);
193 www_surface_add_listener(window->www_surface, &_www_surface_listener,
194 window);
195 }
196
197
198 static void
_xdg_surface_cb_configure(void * data,struct xdg_surface * xdg_surface EINA_UNUSED,uint32_t serial)199 _xdg_surface_cb_configure(void *data, struct xdg_surface *xdg_surface EINA_UNUSED, uint32_t serial)
200 {
201 Ecore_Wl2_Window *window;
202
203 window = data;
204 window->def_config.serial = serial;
205
206 if (window->pending.configure)
207 {
208 window->saved.w = window->set_config.geometry.w;
209 window->saved.h = window->set_config.geometry.h;
210 }
211 if (window->pending.configure && window->updating)
212 ERR("Window shouldn't be rendering before initial configure");
213
214 if (!window->updating)
215 _ecore_wl2_window_configure_send(window);
216
217 if (window->pending.configure)
218 _configure_complete(window);
219 }
220
221 static const struct xdg_surface_listener _xdg_surface_listener =
222 {
223 _xdg_surface_cb_configure,
224 };
225
226 static void
_xdg_toplevel_cb_configure(void * data,struct xdg_toplevel * xdg_toplevel EINA_UNUSED,int32_t width,int32_t height,struct wl_array * states)227 _xdg_toplevel_cb_configure(void *data, struct xdg_toplevel *xdg_toplevel EINA_UNUSED, int32_t width, int32_t height, struct wl_array *states)
228 {
229 Ecore_Wl2_Window *win = data;
230 uint32_t *s;
231
232 win->def_config.maximized = EINA_FALSE;
233 win->def_config.fullscreen = EINA_FALSE;
234 win->def_config.focused = EINA_FALSE;
235 win->def_config.resizing = EINA_FALSE;
236 win->def_config.geometry.w = width;
237 win->def_config.geometry.h = height;
238
239 wl_array_for_each(s, states)
240 {
241 switch (*s)
242 {
243 case ZXDG_TOPLEVEL_V6_STATE_MAXIMIZED:
244 win->def_config.maximized = EINA_TRUE;
245 break;
246 case ZXDG_TOPLEVEL_V6_STATE_FULLSCREEN:
247 win->def_config.fullscreen = EINA_TRUE;
248 break;
249 case ZXDG_TOPLEVEL_V6_STATE_RESIZING:
250 win->def_config.resizing = EINA_TRUE;
251 break;
252 case ZXDG_TOPLEVEL_V6_STATE_ACTIVATED:
253 win->def_config.focused = EINA_TRUE;
254 default:
255 break;
256 }
257 }
258 }
259
260 static void
_xdg_toplevel_cb_close(void * data,struct xdg_toplevel * xdg_toplevel EINA_UNUSED)261 _xdg_toplevel_cb_close(void *data, struct xdg_toplevel *xdg_toplevel EINA_UNUSED)
262 {
263 Ecore_Wl2_Window *win;
264
265 win = data;
266 if (!win) return;
267 if (win->cb_close)
268 {
269 win->cb_close(win->cb_close_data, win);
270 win->cb_close = NULL;
271 }
272 ecore_wl2_window_free(win);
273 }
274
275 static const struct xdg_toplevel_listener _xdg_toplevel_listener =
276 {
277 _xdg_toplevel_cb_configure,
278 _xdg_toplevel_cb_close,
279 };
280
281 static void
_xdg_popup_cb_configure(void * data,struct xdg_popup * xdg_popup EINA_UNUSED,int32_t x EINA_UNUSED,int32_t y EINA_UNUSED,int32_t width,int32_t height)282 _xdg_popup_cb_configure(void *data, struct xdg_popup *xdg_popup EINA_UNUSED, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, int32_t width, int32_t height)
283 {
284 Ecore_Wl2_Window *win = data;
285 win->def_config.geometry.w = width;
286 win->def_config.geometry.h = height;
287 }
288
289 static void
_xdg_popup_cb_done(void * data,struct xdg_popup * xdg_popup EINA_UNUSED)290 _xdg_popup_cb_done(void *data, struct xdg_popup *xdg_popup EINA_UNUSED)
291 {
292 Ecore_Wl2_Window *win;
293
294 win = data;
295 if (!win) return;
296
297 if (win->grab) _ecore_wl2_input_ungrab(win->grab);
298
299 _ecore_wl2_window_hide_send(win);
300 }
301
302 static const struct xdg_popup_listener _xdg_popup_listener =
303 {
304 _xdg_popup_cb_configure,
305 _xdg_popup_cb_done,
306 };
307
308 static void
_ecore_wl2_window_xdg_popup_create(Ecore_Wl2_Window * win)309 _ecore_wl2_window_xdg_popup_create(Ecore_Wl2_Window *win)
310 {
311 int gw, gh;
312 struct xdg_positioner *pos;
313
314 EINA_SAFETY_ON_NULL_RETURN(win->parent);
315 pos = xdg_wm_base_create_positioner(win->display->wl.xdg_wm_base);
316 if (!pos) return;
317
318 ecore_wl2_window_geometry_get(win, NULL, NULL, &gw, &gh);
319 xdg_positioner_set_anchor_rect(pos, 0, 0, 1, 1);
320 xdg_positioner_set_size(pos, gw, gh);
321 xdg_positioner_set_anchor(pos, XDG_POSITIONER_ANCHOR_TOP_LEFT);
322 xdg_positioner_set_gravity(pos, ZXDG_POSITIONER_V6_ANCHOR_BOTTOM |
323 ZXDG_POSITIONER_V6_ANCHOR_RIGHT);
324
325 win->xdg_popup = xdg_surface_get_popup(win->xdg_surface,
326 win->parent->xdg_surface, pos);
327
328 xdg_positioner_destroy(pos);
329 if (win->grab)
330 xdg_popup_grab(win->xdg_popup, win->grab->wl.seat,
331 wl_display_get_serial(win->display->wl.display));
332 xdg_popup_set_user_data(win->xdg_popup, win);
333 xdg_popup_add_listener(win->xdg_popup, &_xdg_popup_listener, win);
334
335 win->pending.configure = EINA_TRUE;
336
337 ecore_wl2_window_commit(win, EINA_TRUE);
338 }
339
340 static void
_window_shell_surface_create(Ecore_Wl2_Window * window)341 _window_shell_surface_create(Ecore_Wl2_Window *window)
342 {
343 if (window->xdg_surface) return;
344 window->xdg_surface =
345 xdg_wm_base_get_xdg_surface(window->display->wl.xdg_wm_base,
346 window->surface);
347 xdg_surface_set_user_data(window->xdg_surface, window);
348 xdg_surface_add_listener(window->xdg_surface,
349 &_xdg_surface_listener, window);
350
351 window->xdg_configure_ack = xdg_surface_ack_configure;
352 window->pending.configure = EINA_TRUE;
353 if (window->display->wl.efl_hints)
354 {
355 if (window->aspect.set)
356 efl_hints_set_aspect(window->display->wl.efl_hints, window->xdg_surface,
357 window->aspect.w, window->aspect.h, window->aspect.aspect);
358 if (window->weight.set)
359 efl_hints_set_weight(window->display->wl.efl_hints, window->xdg_surface,
360 window->weight.w, window->weight.h);
361 }
362
363 if (window->type == ECORE_WL2_WINDOW_TYPE_MENU)
364 _ecore_wl2_window_xdg_popup_create(window);
365 else
366 {
367 struct xdg_toplevel *ptop = NULL;
368
369 window->xdg_toplevel =
370 xdg_surface_get_toplevel(window->xdg_surface);
371 xdg_toplevel_set_user_data(window->xdg_toplevel, window);
372 xdg_toplevel_add_listener(window->xdg_toplevel,
373 &_xdg_toplevel_listener, window);
374
375 if (window->deferred_minimize)
376 xdg_toplevel_set_minimized(window->xdg_toplevel);
377 window->deferred_minimize = EINA_FALSE;
378
379 if (window->title)
380 xdg_toplevel_set_title(window->xdg_toplevel, window->title);
381 if (window->class)
382 xdg_toplevel_set_app_id(window->xdg_toplevel, window->class);
383
384 window->xdg_set_min_size = xdg_toplevel_set_min_size;
385 window->xdg_set_max_size = xdg_toplevel_set_max_size;
386
387 if (window->parent)
388 ptop = window->parent->xdg_toplevel;
389
390 if (ptop)
391 xdg_toplevel_set_parent(window->xdg_toplevel, ptop);
392
393 if (window->set_config.maximized)
394 xdg_toplevel_set_maximized(window->xdg_toplevel);
395
396 if (window->set_config.fullscreen)
397 xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
398 }
399
400 ecore_wl2_window_commit(window, EINA_TRUE);
401 }
402
403 void
_ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window * window)404 _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
405 {
406 if (!window->surface) return;
407 if (window->display->wl.xdg_wm_base) _window_shell_surface_create(window);
408 if (window->display->wl.zxdg_shell) _window_v6_shell_surface_create(window);
409
410 if (window->display->wl.session_recovery)
411 {
412 if (window->uuid)
413 {
414 int gx, gy, gw, gh;
415
416 zwp_e_session_recovery_set_uuid(window->display->wl.session_recovery,
417 window->surface, window->uuid);
418
419 ecore_wl2_window_geometry_get(window, &gx, &gy, &gw, &gh);
420 if (window->xdg_surface)
421 xdg_surface_set_window_geometry(window->xdg_surface,
422 gx, gy, gw, gh);
423 if (window->zxdg_surface)
424 zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
425 gx, gy, gw, gh);
426
427 ecore_wl2_window_opaque_region_set(window,
428 window->opaque.x,
429 window->opaque.y,
430 window->opaque.w,
431 window->opaque.h);
432 }
433 else
434 zwp_e_session_recovery_get_uuid(window->display->wl.session_recovery, window->surface);
435 }
436 }
437
438 static void
_surface_enter(void * data,struct wl_surface * surf EINA_UNUSED,struct wl_output * op)439 _surface_enter(void *data, struct wl_surface *surf EINA_UNUSED, struct wl_output *op)
440 {
441 Ecore_Wl2_Window *win;
442 Ecore_Wl2_Output *output;
443
444 win = data;
445
446 output = _ecore_wl2_output_find(win->display, op);
447 EINA_SAFETY_ON_NULL_RETURN(output);
448
449 win->outputs = eina_list_append(win->outputs, output);
450 }
451
452 static void
_surface_leave(void * data,struct wl_surface * surf EINA_UNUSED,struct wl_output * op)453 _surface_leave(void *data, struct wl_surface *surf EINA_UNUSED, struct wl_output *op)
454 {
455 Ecore_Wl2_Window *win;
456 Ecore_Wl2_Output *output;
457
458 win = data;
459 output = _ecore_wl2_output_find(win->display, op);
460 EINA_SAFETY_ON_NULL_RETURN(output);
461
462 win->outputs = eina_list_remove(win->outputs, output);
463 if (!win->outputs)
464 {
465 Ecore_Wl2_Event_Window_Offscreen *ev;
466 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Offscreen));
467 if (ev)
468 {
469 ev->win = win;
470 ecore_event_add(ECORE_WL2_EVENT_WINDOW_OFFSCREEN, ev, NULL, NULL);
471 }
472 }
473 }
474
475 static const struct wl_surface_listener _surface_listener =
476 {
477 _surface_enter,
478 _surface_leave,
479 };
480
481 void
_ecore_wl2_window_surface_create(Ecore_Wl2_Window * window)482 _ecore_wl2_window_surface_create(Ecore_Wl2_Window *window)
483 {
484 if (!window->display->wl.compositor) return;
485
486 if (!window->surface)
487 {
488 window->surface =
489 wl_compositor_create_surface(window->display->wl.compositor);
490 if (!window->surface)
491 {
492 ERR("Failed to create surface for window");
493 return;
494 }
495 wl_surface_set_user_data(window->surface, window);
496
497 window->surface_id =
498 wl_proxy_get_id((struct wl_proxy *)window->surface);
499
500 wl_surface_add_listener(window->surface, &_surface_listener, window);
501 if (window->display->wl.efl_aux_hints)
502 {
503 efl_aux_hints_get_supported_aux_hints(window->display->wl.efl_aux_hints, window->surface);
504 if (_ecore_wl2_display_sync_get())
505 wl_display_roundtrip(window->display->wl.display);
506 }
507 }
508 }
509
510 static void
_ecore_wl2_window_show_send(Ecore_Wl2_Window * window)511 _ecore_wl2_window_show_send(Ecore_Wl2_Window *window)
512 {
513 Ecore_Wl2_Event_Window_Show *ev;
514
515 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Show));
516 if (!ev) return;
517
518 ev->win = window;
519 if (window->parent)
520 ev->parent_win = window->parent;
521 ev->event_win = window;
522 window->visible = EINA_TRUE;
523 ecore_event_add(ECORE_WL2_EVENT_WINDOW_SHOW, ev, NULL, NULL);
524 }
525
526 static void
_ecore_wl2_window_hide_send(Ecore_Wl2_Window * window)527 _ecore_wl2_window_hide_send(Ecore_Wl2_Window *window)
528 {
529 Ecore_Wl2_Event_Window_Hide *ev;
530
531 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Hide));
532 if (!ev) return;
533
534 ev->win = window;
535 if (window->parent)
536 ev->parent_win = window->parent;
537 ev->event_win = window;
538 window->visible = EINA_FALSE;
539 ecore_event_add(ECORE_WL2_EVENT_WINDOW_HIDE, ev, NULL, NULL);
540 }
541
542 static void
_ecore_wl2_window_create_destroy_send(Ecore_Wl2_Window * window,Eina_Bool create)543 _ecore_wl2_window_create_destroy_send(Ecore_Wl2_Window *window, Eina_Bool create)
544 {
545 Ecore_Wl2_Event_Window_Common *ev;
546
547 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Common));
548 if (!ev) return;
549
550 ev->win = window;
551 if (window->parent)
552 ev->parent_win = window->parent;
553 ev->event_win = window;
554
555 if (create) ecore_event_add(ECORE_WL2_EVENT_WINDOW_CREATE, ev, NULL, NULL);
556 else ecore_event_add(ECORE_WL2_EVENT_WINDOW_DESTROY, ev, NULL, NULL);
557 }
558
559 EAPI Ecore_Wl2_Window *
ecore_wl2_window_new(Ecore_Wl2_Display * display,Ecore_Wl2_Window * parent,int x,int y,int w,int h)560 ecore_wl2_window_new(Ecore_Wl2_Display *display, Ecore_Wl2_Window *parent, int x, int y, int w, int h)
561 {
562 Ecore_Wl2_Window *win;
563
564 EINA_SAFETY_ON_NULL_RETURN_VAL(display, NULL);
565 if (display->pid) CRI("CANNOT CREATE WINDOW WITH SERVER DISPLAY");
566
567 /* try to allocate space for window structure */
568 win = calloc(1, sizeof(Ecore_Wl2_Window));
569 if (!win) return NULL;
570 display->refs++;
571
572 win->display = display;
573 win->parent = parent;
574
575 win->set_config.geometry.x = x;
576 win->set_config.geometry.y = y;
577 win->set_config.geometry.w = w;
578 win->set_config.geometry.h = h;
579
580 win->opaque.x = x;
581 win->opaque.y = y;
582 win->opaque.w = w;
583 win->opaque.h = h;
584
585 win->pending.configure = EINA_TRUE;
586 display->windows =
587 eina_inlist_append(display->windows, EINA_INLIST_GET(win));
588
589 _ecore_wl2_window_surface_create(win);
590
591 _ecore_wl2_window_create_destroy_send(win, EINA_TRUE);
592
593 return win;
594 }
595
596 EAPI void
ecore_wl2_window_close_callback_set(Ecore_Wl2_Window * window,void (* cb)(void * data,Ecore_Wl2_Window * win),void * data)597 ecore_wl2_window_close_callback_set(Ecore_Wl2_Window *window, void (*cb) (void *data, Ecore_Wl2_Window *win), void *data)
598 {
599 EINA_SAFETY_ON_NULL_RETURN(window);
600 window->cb_close = cb;
601 window->cb_close_data = data;
602 }
603
604 EAPI struct wl_surface *
ecore_wl2_window_surface_get(Ecore_Wl2_Window * window)605 ecore_wl2_window_surface_get(Ecore_Wl2_Window *window)
606 {
607 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
608
609 _ecore_wl2_window_surface_create(window);
610
611 return window->surface;
612 }
613
614 EAPI int
ecore_wl2_window_surface_id_get(Ecore_Wl2_Window * window)615 ecore_wl2_window_surface_id_get(Ecore_Wl2_Window *window)
616 {
617 EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
618 return window->surface_id;
619 }
620
621 EAPI void
ecore_wl2_window_show(Ecore_Wl2_Window * window)622 ecore_wl2_window_show(Ecore_Wl2_Window *window)
623 {
624 EINA_SAFETY_ON_NULL_RETURN(window);
625
626 _ecore_wl2_window_surface_create(window);
627
628 if (window->input_set)
629 ecore_wl2_window_input_region_set(window, window->input_rect.x,
630 window->input_rect.y,
631 window->input_rect.w,
632 window->input_rect.h);
633 if (window->opaque_set)
634 ecore_wl2_window_opaque_region_set(window, window->opaque.x,
635 window->opaque.y, window->opaque.w,
636 window->opaque.h);
637
638 if ((window->type != ECORE_WL2_WINDOW_TYPE_DND) &&
639 (window->type != ECORE_WL2_WINDOW_TYPE_NONE))
640 {
641 _ecore_wl2_window_shell_surface_init(window);
642 _ecore_wl2_window_www_surface_init(window);
643 _ecore_wl2_window_show_send(window);
644 }
645 else
646 _configure_complete(window);
647 }
648
649 EAPI void
ecore_wl2_window_hide(Ecore_Wl2_Window * window)650 ecore_wl2_window_hide(Ecore_Wl2_Window *window)
651 {
652 EINA_SAFETY_ON_NULL_RETURN(window);
653
654 _ecore_wl2_window_hide_send(window);
655
656 if (window->commit_pending)
657 {
658 /* We've probably been hidden while an animator
659 * is ticking. Cancel the callback.
660 */
661 window->commit_pending = EINA_FALSE;
662 if (window->callback)
663 {
664 wl_callback_destroy(window->callback);
665 window->callback = NULL;
666 }
667 }
668
669 if (window->surface)
670 {
671 wl_surface_attach(window->surface, NULL, 0, 0);
672 ecore_wl2_window_commit(window, EINA_TRUE);
673 window->commit_pending = EINA_FALSE;
674 }
675
676 /* The commit added a callback, disconnect it */
677 if (window->callback)
678 {
679 wl_callback_destroy(window->callback);
680 window->callback = NULL;
681 }
682
683 window->set_config.serial = 0;
684 window->req_config.serial = 0;
685 window->def_config.serial = 0;
686 window->zxdg_configure_ack = NULL;
687 window->xdg_configure_ack = NULL;
688 window->xdg_set_min_size = NULL;
689 window->xdg_set_max_size = NULL;
690 window->zxdg_set_min_size = NULL;
691 window->zxdg_set_max_size = NULL;
692 }
693
694 static void
_ecore_wl2_window_aux_hint_free(Ecore_Wl2_Window * win)695 _ecore_wl2_window_aux_hint_free(Ecore_Wl2_Window *win)
696 {
697 const char *supported;
698
699 EINA_LIST_FREE(win->supported_aux_hints, supported)
700 if (supported) eina_stringshare_del(supported);
701 }
702
703 EAPI void
ecore_wl2_window_free(Ecore_Wl2_Window * window)704 ecore_wl2_window_free(Ecore_Wl2_Window *window)
705 {
706 Ecore_Wl2_Display *display;
707 Ecore_Wl2_Input *input;
708 Ecore_Wl2_Subsurface *subsurf;
709 Eina_Inlist *tmp;
710
711 EINA_SAFETY_ON_NULL_RETURN(window);
712
713 if (window->visible) _ecore_wl2_window_hide_send(window);
714
715 _ecore_wl2_window_create_destroy_send(window, EINA_FALSE);
716
717 display = window->display;
718
719 EINA_INLIST_FOREACH(display->inputs, input)
720 _ecore_wl2_input_window_remove(input, window);
721
722 EINA_INLIST_FOREACH_SAFE(window->subsurfs, tmp, subsurf)
723 _ecore_wl2_subsurf_free(subsurf);
724
725 _ecore_wl2_window_aux_hint_free(window);
726
727 if (window->callback) wl_callback_destroy(window->callback);
728 window->callback = NULL;
729
730 if (window->uuid && window->surface && window->display->wl.session_recovery)
731 zwp_e_session_recovery_destroy_uuid(window->display->wl.session_recovery,
732 window->surface, window->uuid);
733
734 _ecore_wl2_window_semi_free(window);
735
736 eina_stringshare_replace(&window->uuid, NULL);
737
738 if (window->title) eina_stringshare_del(window->title);
739 if (window->class) eina_stringshare_del(window->class);
740 if (window->role) eina_stringshare_del(window->role);
741
742 if (window->wm_rot.available_rots) free(window->wm_rot.available_rots);
743 window->wm_rot.available_rots = NULL;
744
745 display->windows =
746 eina_inlist_remove(display->windows, EINA_INLIST_GET(window));
747
748 ecore_wl2_display_disconnect(window->display);
749 free(window);
750 }
751
752 EAPI void
ecore_wl2_window_move(Ecore_Wl2_Window * window,Ecore_Wl2_Input * input)753 ecore_wl2_window_move(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
754 {
755 EINA_SAFETY_ON_NULL_RETURN(window);
756 EINA_SAFETY_ON_NULL_RETURN(window->display->inputs);
757
758 if (!input)
759 {
760 ERR("NULL input parameter is deprecated");
761 input = EINA_INLIST_CONTAINER_GET(window->display->inputs, Ecore_Wl2_Input);
762 }
763 if (window->xdg_toplevel)
764 xdg_toplevel_move(window->xdg_toplevel, input->wl.seat,
765 window->display->serial);
766 if (window->zxdg_toplevel)
767 zxdg_toplevel_v6_move(window->zxdg_toplevel, input->wl.seat,
768 window->display->serial);
769 ecore_wl2_display_flush(window->display);
770
771 _ecore_wl2_input_ungrab(input);
772 }
773
774 EAPI void
ecore_wl2_window_resize(Ecore_Wl2_Window * window,Ecore_Wl2_Input * input,int location)775 ecore_wl2_window_resize(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input, int location)
776 {
777 EINA_SAFETY_ON_NULL_RETURN(window);
778 EINA_SAFETY_ON_NULL_RETURN(window->display->inputs);
779
780 if (!input)
781 {
782 ERR("NULL input parameter is deprecated");
783 input = EINA_INLIST_CONTAINER_GET(window->display->inputs, Ecore_Wl2_Input);
784 }
785
786 if (window->xdg_toplevel)
787 xdg_toplevel_resize(window->xdg_toplevel, input->wl.seat,
788 window->display->serial, location);
789 if (window->zxdg_toplevel)
790 zxdg_toplevel_v6_resize(window->zxdg_toplevel, input->wl.seat,
791 window->display->serial, location);
792 ecore_wl2_display_flush(window->display);
793
794 _ecore_wl2_input_ungrab(input);
795 }
796
797 EAPI Eina_Bool
ecore_wl2_window_alpha_get(Ecore_Wl2_Window * window)798 ecore_wl2_window_alpha_get(Ecore_Wl2_Window *window)
799 {
800 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
801
802 return window->alpha;
803 }
804
805 EAPI void
ecore_wl2_window_alpha_set(Ecore_Wl2_Window * window,Eina_Bool alpha)806 ecore_wl2_window_alpha_set(Ecore_Wl2_Window *window, Eina_Bool alpha)
807 {
808 Ecore_Wl2_Surface *surf;
809
810 EINA_SAFETY_ON_NULL_RETURN(window);
811
812 if (window->alpha == alpha) return;
813
814 window->alpha = alpha;
815 surf = window->wl2_surface;
816 if (surf)
817 ecore_wl2_surface_reconfigure(surf, surf->w, surf->h, 0, alpha);
818 }
819
820 EAPI void
ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window * window,int x,int y,int w,int h)821 ecore_wl2_window_opaque_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
822 {
823 int nx = 0, ny = 0, nw = 0, nh = 0;
824
825 EINA_SAFETY_ON_NULL_RETURN(window);
826
827 switch (window->rotation)
828 {
829 case 0:
830 nx = x;
831 ny = y;
832 nw = w;
833 nh = h;
834 break;
835 case 90:
836 nx = y;
837 ny = x;
838 nw = h;
839 nh = w;
840 break;
841 case 180:
842 nx = x;
843 ny = x + y;
844 nw = w;
845 nh = h;
846 break;
847 case 270:
848 nx = x + y;
849 ny = x;
850 nw = h;
851 nh = w;
852 break;
853 default:
854 break;
855 }
856
857 if ((window->opaque.x == nx) && (window->opaque.y == ny) &&
858 (window->opaque.w == nw) && (window->opaque.h == nh))
859 return;
860
861 window->opaque.x = nx;
862 window->opaque.y = ny;
863 window->opaque.w = nw;
864 window->opaque.h = nh;
865 window->opaque_set = x || y || w || h;
866 window->pending.opaque = EINA_TRUE;
867 }
868
869 EAPI void
ecore_wl2_window_opaque_region_get(Ecore_Wl2_Window * window,int * x,int * y,int * w,int * h)870 ecore_wl2_window_opaque_region_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
871 {
872 EINA_SAFETY_ON_NULL_RETURN(window);
873
874 if (x) *x = window->opaque.x;
875 if (y) *y = window->opaque.y;
876 if (w) *w = window->opaque.w;
877 if (h) *h = window->opaque.h;
878 }
879
880 EAPI void
ecore_wl2_window_input_region_set(Ecore_Wl2_Window * window,int x,int y,int w,int h)881 ecore_wl2_window_input_region_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
882 {
883 int nx = 0, ny = 0, nw = 0, nh = 0;
884
885 EINA_SAFETY_ON_NULL_RETURN(window);
886
887 switch (window->rotation)
888 {
889 case 0:
890 nx = x;
891 ny = y;
892 nw = w;
893 nh = h;
894 break;
895 case 90:
896 nx = y;
897 ny = x;
898 nw = h;
899 nh = w;
900 break;
901 case 180:
902 nx = x;
903 ny = x + y;
904 nw = w;
905 nh = h;
906 break;
907 case 270:
908 nx = x + y;
909 ny = x;
910 nw = h;
911 nh = w;
912 break;
913 default:
914 break;
915 }
916
917 if ((window->input_rect.x == nx) && (window->input_rect.y == ny) &&
918 (window->input_rect.w == nw) && (window->input_rect.h == nh))
919 return;
920
921 window->input_rect.x = nx;
922 window->input_rect.y = ny;
923 window->input_rect.w = nw;
924 window->input_rect.h = nh;
925 window->input_set = x || y || w || h;
926 window->pending.input = EINA_TRUE;
927 }
928
929 EAPI void
ecore_wl2_window_input_region_get(Ecore_Wl2_Window * window,int * x,int * y,int * w,int * h)930 ecore_wl2_window_input_region_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
931 {
932 EINA_SAFETY_ON_NULL_RETURN(window);
933
934 if (x) *x = window->input_rect.x;
935 if (y) *y = window->input_rect.y;
936 if (w) *w = window->input_rect.w;
937 if (h) *h = window->input_rect.h;
938 }
939
940 EAPI Eina_Bool
ecore_wl2_window_maximized_get(Ecore_Wl2_Window * window)941 ecore_wl2_window_maximized_get(Ecore_Wl2_Window *window)
942 {
943 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
944
945 return window->set_config.maximized;
946 }
947
948 EAPI void
ecore_wl2_window_maximized_set(Ecore_Wl2_Window * window,Eina_Bool maximized)949 ecore_wl2_window_maximized_set(Ecore_Wl2_Window *window, Eina_Bool maximized)
950 {
951 Eina_Bool prev;
952
953 EINA_SAFETY_ON_NULL_RETURN(window);
954
955 prev = window->set_config.maximized;
956 maximized = !!maximized;
957 if (prev == maximized) return;
958
959 window->set_config.maximized = maximized;
960 if (window->updating)
961 {
962 window->pending.maximized = EINA_TRUE;
963 return;
964 }
965
966 if (maximized)
967 {
968 if (!window->set_config.fullscreen)
969 window->saved = window->set_config.geometry;
970
971 if (window->xdg_toplevel)
972 xdg_toplevel_set_maximized(window->xdg_toplevel);
973 if (window->zxdg_toplevel)
974 zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
975 }
976 else
977 {
978 if (window->xdg_toplevel)
979 xdg_toplevel_unset_maximized(window->xdg_toplevel);
980 if (window->zxdg_toplevel)
981 zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
982 }
983 ecore_wl2_display_flush(window->display);
984 }
985
986 EAPI Eina_Bool
ecore_wl2_window_fullscreen_get(Ecore_Wl2_Window * window)987 ecore_wl2_window_fullscreen_get(Ecore_Wl2_Window *window)
988 {
989 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
990
991 return window->set_config.fullscreen;
992 }
993
994 EAPI void
ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window * window,Eina_Bool fullscreen)995 ecore_wl2_window_fullscreen_set(Ecore_Wl2_Window *window, Eina_Bool fullscreen)
996 {
997 Eina_Bool prev;
998
999 EINA_SAFETY_ON_NULL_RETURN(window);
1000
1001 prev = window->set_config.fullscreen;
1002 fullscreen = !!fullscreen;
1003 if (prev == fullscreen) return;
1004
1005 window->set_config.fullscreen = fullscreen;
1006 if (window->updating)
1007 {
1008 window->pending.fullscreen = EINA_TRUE;
1009 return;
1010 }
1011
1012 if (fullscreen)
1013 {
1014 if (!window->set_config.maximized)
1015 window->saved = window->set_config.geometry;
1016
1017 if (window->xdg_toplevel)
1018 xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
1019 if (window->zxdg_toplevel)
1020 zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
1021 }
1022 else
1023 {
1024 if (window->xdg_toplevel)
1025 xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
1026 if (window->zxdg_toplevel)
1027 zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
1028 }
1029 ecore_wl2_display_flush(window->display);
1030 }
1031
1032 EAPI int
ecore_wl2_window_rotation_get(Ecore_Wl2_Window * window)1033 ecore_wl2_window_rotation_get(Ecore_Wl2_Window *window)
1034 {
1035 EINA_SAFETY_ON_NULL_RETURN_VAL(window, -1);
1036
1037 return window->rotation;
1038 }
1039
1040 EAPI void
ecore_wl2_window_rotation_set(Ecore_Wl2_Window * window,int rotation)1041 ecore_wl2_window_rotation_set(Ecore_Wl2_Window *window, int rotation)
1042 {
1043 EINA_SAFETY_ON_NULL_RETURN(window);
1044
1045 window->rotation = rotation;
1046 }
1047
1048 EAPI void
ecore_wl2_window_title_set(Ecore_Wl2_Window * window,const char * title)1049 ecore_wl2_window_title_set(Ecore_Wl2_Window *window, const char *title)
1050 {
1051 EINA_SAFETY_ON_NULL_RETURN(window);
1052
1053 eina_stringshare_replace(&window->title, title);
1054 if (!window->title) return;
1055 if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
1056
1057 if (window->xdg_toplevel)
1058 xdg_toplevel_set_title(window->xdg_toplevel, window->title);
1059 if (window->zxdg_toplevel)
1060 zxdg_toplevel_v6_set_title(window->zxdg_toplevel, window->title);
1061 ecore_wl2_display_flush(window->display);
1062 }
1063
1064 EAPI const char *
ecore_wl2_window_title_get(Ecore_Wl2_Window * window)1065 ecore_wl2_window_title_get(Ecore_Wl2_Window *window)
1066 {
1067 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1068
1069 return window->title ? window->title : NULL;
1070 }
1071
1072 EAPI void
ecore_wl2_window_class_set(Ecore_Wl2_Window * window,const char * clas)1073 ecore_wl2_window_class_set(Ecore_Wl2_Window *window, const char *clas)
1074 {
1075 EINA_SAFETY_ON_NULL_RETURN(window);
1076
1077 eina_stringshare_replace(&window->class, clas);
1078 if (!window->class) return;
1079 if (!window->xdg_toplevel && !window->zxdg_toplevel) return;
1080
1081 if (window->xdg_toplevel)
1082 xdg_toplevel_set_app_id(window->xdg_toplevel, window->class);
1083 if (window->zxdg_toplevel)
1084 zxdg_toplevel_v6_set_app_id(window->zxdg_toplevel, window->class);
1085 ecore_wl2_display_flush(window->display);
1086 }
1087
1088 EAPI const char *
ecore_wl2_window_class_get(Ecore_Wl2_Window * window)1089 ecore_wl2_window_class_get(Ecore_Wl2_Window *window)
1090 {
1091 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1092
1093 return window->class ? window->class : NULL;
1094 }
1095
1096 EAPI void
ecore_wl2_window_geometry_get(Ecore_Wl2_Window * window,int * x,int * y,int * w,int * h)1097 ecore_wl2_window_geometry_get(Ecore_Wl2_Window *window, int *x, int *y, int *w, int *h)
1098 {
1099 EINA_SAFETY_ON_NULL_RETURN(window);
1100
1101 if (x) *x = window->set_config.geometry.x;
1102 if (y) *y = window->set_config.geometry.y;
1103 if (w) *w = window->set_config.geometry.w;
1104 if (h) *h = window->set_config.geometry.h;
1105 }
1106
1107 EAPI void
ecore_wl2_window_geometry_set(Ecore_Wl2_Window * window,int x,int y,int w,int h)1108 ecore_wl2_window_geometry_set(Ecore_Wl2_Window *window, int x, int y, int w, int h)
1109 {
1110 EINA_SAFETY_ON_NULL_RETURN(window);
1111
1112 if ((window->set_config.geometry.x == x) &&
1113 (window->set_config.geometry.y == y) &&
1114 (window->set_config.geometry.w == w) &&
1115 (window->set_config.geometry.h == h))
1116 return;
1117
1118 window->set_config.geometry.x = x;
1119 window->set_config.geometry.y = y;
1120 window->set_config.geometry.w = w;
1121 window->set_config.geometry.h = h;
1122 window->pending.geom = EINA_TRUE;
1123 }
1124
1125 EAPI void
ecore_wl2_window_iconified_set(Ecore_Wl2_Window * window,Eina_Bool iconified)1126 ecore_wl2_window_iconified_set(Ecore_Wl2_Window *window, Eina_Bool iconified)
1127 {
1128 EINA_SAFETY_ON_NULL_RETURN(window);
1129
1130 iconified = !!iconified;
1131
1132 if (!window->xdg_toplevel && !window->zxdg_toplevel)
1133 {
1134 window->deferred_minimize = iconified;
1135 return;
1136 }
1137
1138 if (iconified)
1139 {
1140 if (window->xdg_toplevel)
1141 xdg_toplevel_set_minimized(window->xdg_toplevel);
1142 if (window->zxdg_toplevel)
1143 zxdg_toplevel_v6_set_minimized(window->zxdg_toplevel);
1144 ecore_wl2_display_flush(window->display);
1145 }
1146 }
1147
1148 EAPI void
ecore_wl2_window_type_set(Ecore_Wl2_Window * window,Ecore_Wl2_Window_Type type)1149 ecore_wl2_window_type_set(Ecore_Wl2_Window *window, Ecore_Wl2_Window_Type type)
1150 {
1151 EINA_SAFETY_ON_NULL_RETURN(window);
1152 window->type = type;
1153 }
1154
1155 EAPI void
ecore_wl2_window_popup_input_set(Ecore_Wl2_Window * window,Ecore_Wl2_Input * input)1156 ecore_wl2_window_popup_input_set(Ecore_Wl2_Window *window, Ecore_Wl2_Input *input)
1157 {
1158 EINA_SAFETY_ON_NULL_RETURN(window);
1159 EINA_SAFETY_ON_NULL_RETURN(input);
1160 EINA_SAFETY_ON_TRUE_RETURN(window->type != ECORE_WL2_WINDOW_TYPE_MENU);
1161 window->grab = input;
1162 }
1163
1164 EAPI Ecore_Wl2_Input *
ecore_wl2_window_popup_input_get(Ecore_Wl2_Window * window)1165 ecore_wl2_window_popup_input_get(Ecore_Wl2_Window *window)
1166 {
1167 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1168
1169 return window->grab;
1170 }
1171
1172 EAPI Ecore_Wl2_Display *
ecore_wl2_window_display_get(const Ecore_Wl2_Window * window)1173 ecore_wl2_window_display_get(const Ecore_Wl2_Window *window)
1174 {
1175 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1176 EINA_SAFETY_ON_NULL_RETURN_VAL(window->display, NULL);
1177
1178 if (window->display->recovering) return NULL;
1179
1180 return window->display;
1181 }
1182
1183 EAPI Eina_Bool
ecore_wl2_window_shell_surface_exists(Ecore_Wl2_Window * window)1184 ecore_wl2_window_shell_surface_exists(Ecore_Wl2_Window *window)
1185 {
1186 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1187 return !!window->zxdg_surface || !!window->xdg_surface;
1188 }
1189
1190 EAPI Eina_Bool
ecore_wl2_window_activated_get(const Ecore_Wl2_Window * window)1191 ecore_wl2_window_activated_get(const Ecore_Wl2_Window *window)
1192 {
1193 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1194 return window->req_config.focused;
1195 }
1196
1197 EAPI Ecore_Wl2_Output *
ecore_wl2_window_output_find(Ecore_Wl2_Window * window)1198 ecore_wl2_window_output_find(Ecore_Wl2_Window *window)
1199 {
1200 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1201
1202 return eina_list_data_get(window->outputs);
1203 }
1204
1205 EAPI void
ecore_wl2_window_buffer_transform_set(Ecore_Wl2_Window * window,int transform)1206 ecore_wl2_window_buffer_transform_set(Ecore_Wl2_Window *window, int transform)
1207 {
1208 EINA_SAFETY_ON_NULL_RETURN(window);
1209
1210 wl_surface_set_buffer_transform(window->surface, transform);
1211 }
1212
1213 EAPI void
ecore_wl2_window_wm_rotation_supported_set(Ecore_Wl2_Window * window,Eina_Bool enabled)1214 ecore_wl2_window_wm_rotation_supported_set(Ecore_Wl2_Window *window, Eina_Bool enabled)
1215 {
1216 EINA_SAFETY_ON_NULL_RETURN(window);
1217 window->wm_rot.supported = enabled;
1218 }
1219
1220 EAPI Eina_Bool
ecore_wl2_window_wm_rotation_supported_get(Ecore_Wl2_Window * window)1221 ecore_wl2_window_wm_rotation_supported_get(Ecore_Wl2_Window *window)
1222 {
1223 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1224 return window->wm_rot.supported;
1225 }
1226
1227 EAPI void
ecore_wl2_window_rotation_app_set(Ecore_Wl2_Window * window,Eina_Bool set)1228 ecore_wl2_window_rotation_app_set(Ecore_Wl2_Window *window, Eina_Bool set)
1229 {
1230 EINA_SAFETY_ON_NULL_RETURN(window);
1231 window->wm_rot.app_set = set;
1232 }
1233
1234 EAPI Eina_Bool
ecore_wl2_window_rotation_app_get(Ecore_Wl2_Window * window)1235 ecore_wl2_window_rotation_app_get(Ecore_Wl2_Window *window)
1236 {
1237 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1238 return window->wm_rot.app_set;
1239 }
1240
1241 EAPI void
ecore_wl2_window_preferred_rotation_set(Ecore_Wl2_Window * window,int rot)1242 ecore_wl2_window_preferred_rotation_set(Ecore_Wl2_Window *window, int rot)
1243 {
1244 EINA_SAFETY_ON_NULL_RETURN(window);
1245 window->wm_rot.preferred_rot = rot;
1246 }
1247
1248 EAPI int
ecore_wl2_window_preferred_rotation_get(Ecore_Wl2_Window * window)1249 ecore_wl2_window_preferred_rotation_get(Ecore_Wl2_Window *window)
1250 {
1251 EINA_SAFETY_ON_NULL_RETURN_VAL(window, 0);
1252 return window->wm_rot.preferred_rot;
1253 }
1254
1255 EAPI void
ecore_wl2_window_available_rotations_set(Ecore_Wl2_Window * window,const int * rots,unsigned int count)1256 ecore_wl2_window_available_rotations_set(Ecore_Wl2_Window *window, const int *rots, unsigned int count)
1257 {
1258 unsigned int i = 0;
1259 EINA_SAFETY_ON_NULL_RETURN(window);
1260
1261 if (window->wm_rot.available_rots)
1262 {
1263 free(window->wm_rot.available_rots);
1264 window->wm_rot.available_rots = NULL;
1265 }
1266 window->wm_rot.count = count;
1267
1268 if (count >= 1)
1269 {
1270 window->wm_rot.available_rots = calloc(count, sizeof(int));
1271 if (!window->wm_rot.available_rots) return;
1272
1273 for (; i < count; i++)
1274 window->wm_rot.available_rots[i] = ((int *)rots)[i];
1275 }
1276 }
1277
1278 EAPI Eina_Bool
ecore_wl2_window_available_rotations_get(Ecore_Wl2_Window * window,int ** rots,unsigned int * count)1279 ecore_wl2_window_available_rotations_get(Ecore_Wl2_Window *window, int **rots, unsigned int *count)
1280 {
1281 unsigned int i = 0;
1282 int *val = NULL;
1283
1284 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1285
1286 *rots = NULL;
1287 *count = window->wm_rot.count;
1288
1289 if (window->wm_rot.count >= 1)
1290 {
1291 val = calloc(window->wm_rot.count, sizeof(int));
1292 if (!val) return EINA_FALSE;
1293
1294 for (; i < window->wm_rot.count; i++)
1295 val[i] = ((int *)window->wm_rot.available_rots)[i];
1296
1297 *rots = val;
1298 return EINA_TRUE;
1299 }
1300
1301 return EINA_FALSE;
1302 }
1303
1304 EAPI void
ecore_wl2_window_rotation_change_prepare_send(Ecore_Wl2_Window * window,int rot,int w,int h,Eina_Bool resize)1305 ecore_wl2_window_rotation_change_prepare_send(Ecore_Wl2_Window *window, int rot, int w, int h, Eina_Bool resize)
1306 {
1307 Ecore_Wl2_Event_Window_Rotation_Change_Prepare *ev;
1308
1309 EINA_SAFETY_ON_NULL_RETURN(window);
1310
1311 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare));
1312 if (!ev) return;
1313
1314 ev->win = window;
1315 ev->rotation = rot;
1316 ev->w = w;
1317 ev->h = h;
1318 ev->resize = resize;
1319
1320 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE, ev, NULL, NULL);
1321 }
1322
1323 EAPI void
ecore_wl2_window_rotation_change_prepare_done_send(Ecore_Wl2_Window * window,int rot)1324 ecore_wl2_window_rotation_change_prepare_done_send(Ecore_Wl2_Window *window, int rot)
1325 {
1326 Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done *ev;
1327
1328 EINA_SAFETY_ON_NULL_RETURN(window);
1329
1330 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Prepare_Done));
1331 if (!ev) return;
1332
1333 ev->win = window;
1334 ev->rotation = rot;
1335 ev->w = 0;
1336 ev->h = 0;
1337 ev->resize = 0;
1338
1339 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_PREPARE_DONE,
1340 ev, NULL, NULL);
1341 }
1342
1343 EAPI void
ecore_wl2_window_rotation_change_request_send(Ecore_Wl2_Window * window,int rot)1344 ecore_wl2_window_rotation_change_request_send(Ecore_Wl2_Window *window, int rot)
1345 {
1346 Ecore_Wl2_Event_Window_Rotation_Change_Request *ev;
1347
1348 EINA_SAFETY_ON_NULL_RETURN(window);
1349
1350 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Request));
1351 if (!ev) return;
1352
1353 ev->win = window;
1354 ev->rotation = rot;
1355 ev->w = 0;
1356 ev->h = 0;
1357 ev->resize = 0;
1358
1359 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_REQUEST,
1360 ev, NULL, NULL);
1361 }
1362
1363 EAPI void
ecore_wl2_window_rotation_change_done_send(Ecore_Wl2_Window * window,int rot,int w,int h)1364 ecore_wl2_window_rotation_change_done_send(Ecore_Wl2_Window *window, int rot, int w, int h)
1365 {
1366 Ecore_Wl2_Event_Window_Rotation_Change_Done *ev;
1367
1368 EINA_SAFETY_ON_NULL_RETURN(window);
1369
1370 ev = calloc(1, sizeof(Ecore_Wl2_Event_Window_Rotation_Change_Done));
1371 if (!ev) return;
1372
1373 ev->win = window;
1374 ev->rotation = rot;
1375 ev->w = w;
1376 ev->h = h;
1377 ev->resize = 0;
1378
1379 ecore_event_add(ECORE_WL2_EVENT_WINDOW_ROTATION_CHANGE_DONE,
1380 ev, NULL, NULL);
1381 }
1382
1383 EAPI Eina_List *
ecore_wl2_window_aux_hints_supported_get(Ecore_Wl2_Window * win)1384 ecore_wl2_window_aux_hints_supported_get(Ecore_Wl2_Window *win)
1385 {
1386 Eina_List *res = NULL;
1387 Eina_List *ll;
1388 char *supported_hint = NULL;
1389 const char *hint = NULL;
1390
1391 if (!win) return NULL;
1392 if (!win->surface) return NULL;
1393
1394 EINA_LIST_FOREACH(win->supported_aux_hints, ll, supported_hint)
1395 {
1396 hint = eina_stringshare_add(supported_hint);
1397 res = eina_list_append(res, hint);
1398 }
1399 return res;
1400 }
1401
1402 EAPI void
ecore_wl2_window_aux_hint_add(Ecore_Wl2_Window * win,int id,const char * hint,const char * val)1403 ecore_wl2_window_aux_hint_add(Ecore_Wl2_Window *win, int id, const char *hint, const char *val)
1404 {
1405 if (!win) return;
1406 if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
1407
1408 efl_aux_hints_add_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, hint, val);
1409 ecore_wl2_display_flush(win->display);
1410 }
1411
1412 EAPI void
ecore_wl2_window_aux_hint_change(Ecore_Wl2_Window * win,int id,const char * val)1413 ecore_wl2_window_aux_hint_change(Ecore_Wl2_Window *win, int id, const char *val)
1414 {
1415 if (!win) return;
1416 if ((!win->surface) && (!win->display->wl.efl_aux_hints)) return;
1417
1418 efl_aux_hints_change_aux_hint(win->display->wl.efl_aux_hints, win->surface, id, val);
1419 ecore_wl2_display_flush(win->display);
1420 }
1421
1422 EAPI void
ecore_wl2_window_aux_hint_del(Ecore_Wl2_Window * win,int id)1423 ecore_wl2_window_aux_hint_del(Ecore_Wl2_Window *win, int id)
1424 {
1425 if (!win) return;
1426 if ((!win->surface) || (!win->display->wl.efl_aux_hints)) return;
1427
1428 efl_aux_hints_del_aux_hint(win->display->wl.efl_aux_hints, win->surface, id);
1429 ecore_wl2_display_flush(win->display);
1430 }
1431
1432 EAPI void
ecore_wl2_window_focus_skip_set(Ecore_Wl2_Window * window,Eina_Bool focus_skip)1433 ecore_wl2_window_focus_skip_set(Ecore_Wl2_Window *window, Eina_Bool focus_skip)
1434 {
1435 EINA_SAFETY_ON_NULL_RETURN(window);
1436 window->focus_skip = focus_skip;
1437 }
1438
1439 EAPI Eina_Bool
ecore_wl2_window_focus_skip_get(Ecore_Wl2_Window * window)1440 ecore_wl2_window_focus_skip_get(Ecore_Wl2_Window *window)
1441 {
1442 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1443 return window->focus_skip;
1444 }
1445
1446 EAPI void
ecore_wl2_window_role_set(Ecore_Wl2_Window * window,const char * role)1447 ecore_wl2_window_role_set(Ecore_Wl2_Window *window, const char *role)
1448 {
1449 EINA_SAFETY_ON_NULL_RETURN(window);
1450 eina_stringshare_replace(&window->role, role);
1451 }
1452
1453 EAPI const char *
ecore_wl2_window_role_get(Ecore_Wl2_Window * window)1454 ecore_wl2_window_role_get(Ecore_Wl2_Window *window)
1455 {
1456 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1457
1458 return window->role ? window->role : NULL;
1459 }
1460
1461 EAPI void
ecore_wl2_window_floating_mode_set(Ecore_Wl2_Window * window,Eina_Bool floating)1462 ecore_wl2_window_floating_mode_set(Ecore_Wl2_Window *window, Eina_Bool floating)
1463 {
1464 EINA_SAFETY_ON_NULL_RETURN(window);
1465 window->floating = floating;
1466 }
1467
1468 EAPI Eina_Bool
ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window * window)1469 ecore_wl2_window_floating_mode_get(Ecore_Wl2_Window *window)
1470 {
1471 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1472 return window->floating;
1473 }
1474
1475 EAPI void
ecore_wl2_window_aspect_set(Ecore_Wl2_Window * window,int w,int h,unsigned int aspect)1476 ecore_wl2_window_aspect_set(Ecore_Wl2_Window *window, int w, int h, unsigned int aspect)
1477 {
1478 EINA_SAFETY_ON_NULL_RETURN(window);
1479 EINA_SAFETY_ON_TRUE_RETURN(w < 1);
1480 EINA_SAFETY_ON_TRUE_RETURN(h < 1);
1481
1482 if ((window->aspect.aspect == aspect) && (window->aspect.w == w) &&
1483 (window->aspect.h == h))
1484 return;
1485
1486 window->aspect.w = w;
1487 window->aspect.h = h;
1488 window->aspect.aspect = aspect;
1489 window->aspect.set = 1;
1490 if (!window->display->wl.efl_hints) return;
1491 if (window->xdg_surface)
1492 efl_hints_set_aspect(window->display->wl.efl_hints,
1493 window->xdg_surface, w, h, aspect);
1494 ecore_wl2_display_flush(window->display);
1495 }
1496
1497 EAPI void
ecore_wl2_window_aspect_get(Ecore_Wl2_Window * window,int * w,int * h,unsigned int * aspect)1498 ecore_wl2_window_aspect_get(Ecore_Wl2_Window *window, int *w, int *h, unsigned int *aspect)
1499 {
1500 EINA_SAFETY_ON_NULL_RETURN(window);
1501
1502 if (w) *w = window->aspect.w;
1503 if (h) *h = window->aspect.h;
1504 if (aspect) *aspect = window->aspect.aspect;
1505 }
1506
1507 EAPI void
ecore_wl2_window_weight_set(Ecore_Wl2_Window * window,double w,double h)1508 ecore_wl2_window_weight_set(Ecore_Wl2_Window *window, double w, double h)
1509 {
1510 int ww, hh;
1511 EINA_SAFETY_ON_NULL_RETURN(window);
1512
1513 ww = lround(w * 100);
1514 hh = lround(h * 100);
1515
1516 if ((window->weight.w == ww) && (window->weight.h == hh))
1517 return;
1518
1519 window->weight.w = ww;
1520 window->weight.h = hh;
1521 window->weight.set = 1;
1522 if (!window->display->wl.efl_hints) return;
1523 if (window->xdg_surface)
1524 efl_hints_set_weight(window->display->wl.efl_hints,
1525 window->xdg_surface, ww, hh);
1526 ecore_wl2_display_flush(window->display);
1527 }
1528
1529 static void
_frame_cb(void * data,struct wl_callback * callback,uint32_t timestamp)1530 _frame_cb(void *data, struct wl_callback *callback, uint32_t timestamp)
1531 {
1532 Ecore_Wl2_Frame_Cb_Handle *cb;
1533 Ecore_Wl2_Window *window;
1534 Eina_Inlist *l;
1535
1536 window = data;
1537 window->commit_pending = EINA_FALSE;
1538 wl_callback_destroy(callback);
1539 window->callback = NULL;
1540 EINA_INLIST_FOREACH_SAFE(window->frame_callbacks, l, cb)
1541 cb->cb(window, timestamp, cb->data);
1542 }
1543
1544 static struct wl_callback_listener _frame_listener =
1545 {
1546 _frame_cb
1547 };
1548
1549 static void
_maximized_set(Ecore_Wl2_Window * window)1550 _maximized_set(Ecore_Wl2_Window *window)
1551 {
1552 EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
1553
1554 if (window->set_config.maximized)
1555 {
1556 window->saved = window->set_config.geometry;
1557 if (window->xdg_toplevel)
1558 xdg_toplevel_set_maximized(window->xdg_toplevel);
1559 if (window->zxdg_toplevel)
1560 zxdg_toplevel_v6_set_maximized(window->zxdg_toplevel);
1561 }
1562 else
1563 {
1564 if (window->xdg_toplevel)
1565 xdg_toplevel_unset_maximized(window->xdg_toplevel);
1566 if (window->zxdg_toplevel)
1567 zxdg_toplevel_v6_unset_maximized(window->zxdg_toplevel);
1568 }
1569 }
1570
1571 static void
_fullscreen_set(Ecore_Wl2_Window * window)1572 _fullscreen_set(Ecore_Wl2_Window *window)
1573 {
1574 EINA_SAFETY_ON_FALSE_RETURN(window->zxdg_toplevel || window->xdg_toplevel);
1575
1576 if (window->set_config.fullscreen)
1577 {
1578 window->saved = window->set_config.geometry;
1579 if (window->xdg_toplevel)
1580 xdg_toplevel_set_fullscreen(window->xdg_toplevel, NULL);
1581 if (window->zxdg_toplevel)
1582 zxdg_toplevel_v6_set_fullscreen(window->zxdg_toplevel, NULL);
1583 }
1584 else
1585 {
1586 if (window->xdg_toplevel)
1587 xdg_toplevel_unset_fullscreen(window->xdg_toplevel);
1588 if (window->zxdg_toplevel)
1589 zxdg_toplevel_v6_unset_fullscreen(window->zxdg_toplevel);
1590 }
1591 }
1592
1593 static struct wl_region *
_region_create(struct wl_compositor * comp,int x,int y,int w,int h)1594 _region_create(struct wl_compositor *comp, int x, int y, int w, int h)
1595 {
1596 struct wl_region *out;
1597
1598 out = wl_compositor_create_region(comp);
1599 if (!out)
1600 {
1601 ERR("Failed to create region");
1602 return NULL;
1603 }
1604
1605 wl_region_add(out, x, y, w, h);
1606
1607 return out;
1608 }
1609
1610 static void
_regions_set(Ecore_Wl2_Window * window)1611 _regions_set(Ecore_Wl2_Window *window)
1612 {
1613 struct wl_region *region = NULL;
1614
1615 if (window->pending.opaque)
1616 {
1617 if (window->opaque_set)
1618 {
1619 region = _region_create(window->display->wl.compositor,
1620 window->opaque.x, window->opaque.y,
1621 window->opaque.w, window->opaque.h);
1622 if (!region) return;
1623 }
1624 wl_surface_set_opaque_region(window->surface, region);
1625 }
1626
1627 if (!window->pending.input) goto out;
1628 if (window->type == ECORE_WL2_WINDOW_TYPE_DND) goto out;
1629
1630 if (!window->input_set)
1631 {
1632 wl_surface_set_input_region(window->surface, NULL);
1633 goto out;
1634 }
1635
1636 if (region && (window->opaque.x == window->input_rect.x) &&
1637 (window->opaque.y == window->input_rect.y) &&
1638 (window->opaque.w == window->input_rect.w) &&
1639 (window->opaque.h == window->input_rect.h))
1640 {
1641 wl_surface_set_input_region(window->surface, region);
1642 goto out;
1643 }
1644 if (region) wl_region_destroy(region);
1645
1646 region = _region_create(window->display->wl.compositor,
1647 window->input_rect.x, window->input_rect.y,
1648 window->input_rect.w, window->input_rect.h);
1649 if (!region) return;
1650 wl_surface_set_input_region(window->surface, region);
1651
1652 out:
1653 if (region) wl_region_destroy(region);
1654 }
1655
1656 EAPI void
ecore_wl2_window_commit(Ecore_Wl2_Window * window,Eina_Bool flush)1657 ecore_wl2_window_commit(Ecore_Wl2_Window *window, Eina_Bool flush)
1658 {
1659 EINA_SAFETY_ON_NULL_RETURN(window);
1660 EINA_SAFETY_ON_NULL_RETURN(window->surface);
1661
1662 if (window->commit_pending)
1663 {
1664 if (window->callback)
1665 wl_callback_destroy(window->callback);
1666 window->callback = NULL;
1667 /* The elm mouse cursor bits do some harmless but weird stuff that
1668 * can hit this, silence the warning for that case only. */
1669 if (window->type != ECORE_WL2_WINDOW_TYPE_NONE)
1670 WRN("Commit before previous commit processed");
1671 }
1672 if (!window->pending.configure)
1673 {
1674 if (window->has_buffer)
1675 window->commit_pending = EINA_TRUE;
1676 window->callback = wl_surface_frame(window->surface);
1677 wl_callback_add_listener(window->callback, &_frame_listener, window);
1678 /* Dispatch any state we've been saving along the way */
1679 if (window->pending.geom)
1680 {
1681 int gx, gy, gw, gh;
1682
1683 ecore_wl2_window_geometry_get(window, &gx, &gy, &gw, &gh);
1684 if (window->xdg_toplevel)
1685 xdg_surface_set_window_geometry(window->xdg_surface,
1686 gx, gy, gw, gh);
1687 if (window->zxdg_surface)
1688 zxdg_surface_v6_set_window_geometry(window->zxdg_surface,
1689 gx, gy, gw, gh);
1690 }
1691 if (window->pending.opaque || window->pending.input)
1692 _regions_set(window);
1693
1694 if (window->pending.maximized)
1695 _maximized_set(window);
1696
1697 if (window->pending.fullscreen)
1698 _fullscreen_set(window);
1699
1700 window->pending.geom = EINA_FALSE;
1701 window->pending.opaque = EINA_FALSE;
1702 window->pending.input = EINA_FALSE;
1703 window->pending.maximized = EINA_FALSE;
1704 window->pending.fullscreen = EINA_FALSE;
1705 }
1706
1707 if (window->req_config.serial != window->set_config.serial)
1708 {
1709 if (window->xdg_configure_ack)
1710 window->xdg_configure_ack(window->xdg_surface,
1711 window->req_config.serial);
1712 if (window->zxdg_configure_ack)
1713 window->zxdg_configure_ack(window->zxdg_surface,
1714 window->req_config.serial);
1715 window->set_config.serial = window->req_config.serial;
1716 }
1717 if (flush)
1718 {
1719 wl_surface_commit(window->surface);
1720 ecore_wl2_display_flush(window->display);
1721 }
1722
1723 if (!window->updating) return;
1724
1725 window->updating = EINA_FALSE;
1726 if (window->def_config.serial != window->set_config.serial)
1727 _ecore_wl2_window_configure_send(window);
1728 }
1729
1730 EAPI void
ecore_wl2_window_false_commit(Ecore_Wl2_Window * window)1731 ecore_wl2_window_false_commit(Ecore_Wl2_Window *window)
1732 {
1733 EINA_SAFETY_ON_NULL_RETURN(window);
1734 EINA_SAFETY_ON_NULL_RETURN(window->surface);
1735 EINA_SAFETY_ON_TRUE_RETURN(window->pending.configure);
1736 EINA_SAFETY_ON_TRUE_RETURN(window->commit_pending);
1737
1738 window->callback = wl_surface_frame(window->surface);
1739 wl_callback_add_listener(window->callback, &_frame_listener, window);
1740 wl_surface_commit(window->surface);
1741 ecore_wl2_display_flush(window->display);
1742 if (window->has_buffer)
1743 window->commit_pending = EINA_TRUE;
1744 }
1745
1746 EAPI Eina_Bool
ecore_wl2_window_pending_get(Ecore_Wl2_Window * window)1747 ecore_wl2_window_pending_get(Ecore_Wl2_Window *window)
1748 {
1749 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1750
1751 return window->commit_pending;
1752 }
1753
1754 EAPI Ecore_Wl2_Frame_Cb_Handle *
ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window * window,Ecore_Wl2_Frame_Cb cb,void * data)1755 ecore_wl2_window_frame_callback_add(Ecore_Wl2_Window *window, Ecore_Wl2_Frame_Cb cb, void *data)
1756 {
1757 Ecore_Wl2_Frame_Cb_Handle *callback;
1758
1759 EINA_SAFETY_ON_NULL_RETURN_VAL(window, NULL);
1760 EINA_SAFETY_ON_NULL_RETURN_VAL(cb, NULL);
1761
1762 callback = malloc(sizeof(*callback));
1763 EINA_SAFETY_ON_NULL_RETURN_VAL(callback, NULL);
1764 callback->cb = cb;
1765 callback->data = data;
1766 callback->win = window;
1767 window->frame_callbacks =
1768 eina_inlist_append(window->frame_callbacks, EINA_INLIST_GET(callback));
1769 return callback;
1770 }
1771
1772 EAPI void
ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle * handle)1773 ecore_wl2_window_frame_callback_del(Ecore_Wl2_Frame_Cb_Handle *handle)
1774 {
1775 EINA_SAFETY_ON_NULL_RETURN(handle);
1776
1777 handle->win->frame_callbacks =
1778 eina_inlist_remove(handle->win->frame_callbacks, EINA_INLIST_GET(handle));
1779 free(handle);
1780 }
1781
1782 EAPI void
ecore_wl2_window_buffer_attach(Ecore_Wl2_Window * win,void * buffer,int x,int y,Eina_Bool implicit)1783 ecore_wl2_window_buffer_attach(Ecore_Wl2_Window *win, void *buffer, int x, int y, Eina_Bool implicit)
1784 {
1785 EINA_SAFETY_ON_NULL_RETURN(win);
1786 EINA_SAFETY_ON_NULL_RETURN(win->surface);
1787
1788 /* FIXME: Haven't given any thought to x and y since we always use 0... */
1789 if (!implicit) wl_surface_attach(win->surface, buffer, x, y);
1790 win->buffer = buffer;
1791 if (!implicit && !buffer)
1792 win->has_buffer = EINA_FALSE;
1793 else
1794 win->has_buffer = EINA_TRUE;
1795 }
1796
1797 EAPI Eina_Bool
ecore_wl2_window_resizing_get(Ecore_Wl2_Window * window)1798 ecore_wl2_window_resizing_get(Ecore_Wl2_Window *window)
1799 {
1800 EINA_SAFETY_ON_NULL_RETURN_VAL(window, EINA_FALSE);
1801
1802 return window->req_config.resizing;
1803 }
1804
1805 EAPI void
ecore_wl2_window_update_begin(Ecore_Wl2_Window * window)1806 ecore_wl2_window_update_begin(Ecore_Wl2_Window *window)
1807 {
1808 EINA_SAFETY_ON_NULL_RETURN(window);
1809 EINA_SAFETY_ON_TRUE_RETURN(window->updating);
1810
1811 window->updating = EINA_TRUE;
1812 }
1813
1814 EAPI void
ecore_wl2_window_damage(Ecore_Wl2_Window * window,Eina_Rectangle * rects,unsigned int count)1815 ecore_wl2_window_damage(Ecore_Wl2_Window *window, Eina_Rectangle *rects, unsigned int count)
1816 {
1817 void (*damage)(struct wl_surface *, int32_t, int32_t, int32_t, int32_t);
1818 unsigned int k;
1819 int compositor_version;
1820
1821 EINA_SAFETY_ON_NULL_RETURN(window);
1822
1823 compositor_version = window->display->wl.compositor_version;
1824
1825 if (compositor_version >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)
1826 damage = wl_surface_damage_buffer;
1827 else
1828 damage = wl_surface_damage;
1829
1830 if ((rects) && (count > 0))
1831 for (k = 0; k < count; k++)
1832 damage(window->surface, rects[k].x, rects[k].y, rects[k].w, rects[k].h);
1833 else
1834 damage(window->surface, 0, 0, INT_MAX, INT_MAX);
1835 }
1836
1837 EAPI void
ecore_wl2_window_surface_flush(Ecore_Wl2_Window * window,Eina_Bool purge)1838 ecore_wl2_window_surface_flush(Ecore_Wl2_Window *window, Eina_Bool purge)
1839 {
1840 EINA_SAFETY_ON_NULL_RETURN(window);
1841
1842 if (!window->wl2_surface) return;
1843 ecore_wl2_surface_flush(window->wl2_surface, purge);
1844 }
1845
1846 EAPI Ecore_Wl2_Window_Type
ecore_wl2_window_type_get(Ecore_Wl2_Window * window)1847 ecore_wl2_window_type_get(Ecore_Wl2_Window *window)
1848 {
1849 EINA_SAFETY_ON_NULL_RETURN_VAL(window, ECORE_WL2_WINDOW_TYPE_NONE);
1850 return window->type;
1851 }
1852
1853 EAPI Ecore_Wl2_Window *
ecore_wl2_window_surface_find(struct wl_surface * surface)1854 ecore_wl2_window_surface_find(struct wl_surface *surface)
1855 {
1856 Ecore_Wl2_Display *ewd;
1857 Ecore_Wl2_Window *win;
1858
1859 EINA_SAFETY_ON_NULL_RETURN_VAL(surface, NULL);
1860
1861 ewd = ecore_wl2_connected_display_get(NULL);
1862 EINA_SAFETY_ON_NULL_RETURN_VAL(ewd, NULL);
1863
1864 win = ecore_wl2_display_window_find_by_surface(ewd, surface);
1865 return win;
1866 }
1867