9 #ifndef zakero_Yetani_h
10 #define zakero_Yetani_h
222 #include <linux/input-event-codes.h>
225 #include <wayland/wayland-client.h>
254 #define ZAKERO_YETANI__ERROR_DATA \
255 X(Error_None , 0 , "No Error" ) \
256 X(Error_Compositor_Was_Not_Found , 1 , "Could not find the Compositor object in the Global Repository." ) \
257 X(Error_Connection_Failed , 2 , "Failed to connect to the Wayland Server." ) \
258 X(Error_Cursor_Already_Exists , 3 , "A cursor with that name already exists." ) \
259 X(Error_Cursor_Does_Not_Exist , 4 , "No cursors exists with that name." ) \
260 X(Error_Cursor_Frame_Time_Too_Large , 5 , "The cursor time per frame is too large, must be <= Size_Max." ) \
261 X(Error_Cursor_Frame_Time_Too_Small , 6 , "The cursor time per frame is too small, must be greater than 0." ) \
262 X(Error_Cursor_Image_Data_Is_Empty , 7 , "The cursor image data can not be empty." ) \
263 X(Error_Cursor_Name_Is_Invalid , 8 , "The cursor name is invalid." ) \
264 X(Error_Cursor_Not_Attached , 9 , "The specified cursor is not attached/in-use." ) \
265 X(Error_Cursor_Size_Too_Small , 10 , "The cursor size, both width and height must be greater than 0." ) \
266 X(Error_Invalid_Display_Name , 11 , "An invalid dispaly name was given to the Wayland Server." ) \
267 X(Error_Minimum_Size_Greater_Than_Maximum_Size , 12 , "The minimum window size is larger than the maximum window size." ) \
268 X(Error_No_Output_Available , 13 , "No output devices are available." ) \
269 X(Error_Registry_Not_Available , 14 , "Unable to get the registery." ) \
270 X(Error_Server_Side_Decorations_Not_Available , 15 , "The Wayland Compositor does not support Server Side Decorations." ) \
271 X(Error_Shm_Was_Not_Found , 16 , "Could not find the Shm object in the Global Repository." ) \
272 X(Error_Wayland_Not_Available , 17 , "Could not find the Wayland Server." ) \
273 X(Error_Window_Initialization_Failed , 18 , "The window was not able to be initialized." ) \
274 X(Error_Window_Size_Too_Small , 19 , "The window size was too small." ) \
275 X(Error_Xdg_WM_Base_Was_Not_Found , 20 , "Could not find the XDG WM Base object the Global Repository." ) \
316 struct zxdg_decoration_manager_v1;
317 struct zxdg_toplevel_decoration_v1;
318 extern const struct wl_interface zxdg_decoration_manager_v1_interface;
319 extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
321 zxdg_decoration_manager_v1_set_user_data(
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1,
void *user_data)
323 wl_proxy_set_user_data((
struct wl_proxy *) zxdg_decoration_manager_v1, user_data);
326 zxdg_decoration_manager_v1_get_user_data(
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
328 return wl_proxy_get_user_data((
struct wl_proxy *) zxdg_decoration_manager_v1);
330 static inline uint32_t
331 zxdg_decoration_manager_v1_get_version(
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
333 return wl_proxy_get_version((
struct wl_proxy *) zxdg_decoration_manager_v1);
336 zxdg_decoration_manager_v1_destroy(
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1)
338 wl_proxy_marshal((
struct wl_proxy *) zxdg_decoration_manager_v1,
340 wl_proxy_destroy((
struct wl_proxy *) zxdg_decoration_manager_v1);
342 static inline struct zxdg_toplevel_decoration_v1 *
343 zxdg_decoration_manager_v1_get_toplevel_decoration(
struct zxdg_decoration_manager_v1 *zxdg_decoration_manager_v1,
struct xdg_toplevel *toplevel)
346 id = wl_proxy_marshal_constructor((
struct wl_proxy *) zxdg_decoration_manager_v1,
347 1, &zxdg_toplevel_decoration_v1_interface, NULL, toplevel);
348 return (
struct zxdg_toplevel_decoration_v1 *) id;
350 enum zxdg_toplevel_decoration_v1_error {
351 ZXDG_TOPLEVEL_DECORATION_V1_ERROR_UNCONFIGURED_BUFFER = 0,
352 ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ALREADY_CONSTRUCTED = 1,
353 ZXDG_TOPLEVEL_DECORATION_V1_ERROR_ORPHANED = 2,
355 enum zxdg_toplevel_decoration_v1_mode {
356 ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE = 1,
357 ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE = 2,
359 struct zxdg_toplevel_decoration_v1_listener {
360 void (*configure)(
void *data,
361 struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
365 zxdg_toplevel_decoration_v1_add_listener(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
366 const struct zxdg_toplevel_decoration_v1_listener *listener,
void *data)
368 return wl_proxy_add_listener((
struct wl_proxy *) zxdg_toplevel_decoration_v1,
369 (
void (**)(
void)) listener, data);
372 zxdg_toplevel_decoration_v1_set_user_data(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1,
void *user_data)
374 wl_proxy_set_user_data((
struct wl_proxy *) zxdg_toplevel_decoration_v1, user_data);
377 zxdg_toplevel_decoration_v1_get_user_data(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
379 return wl_proxy_get_user_data((
struct wl_proxy *) zxdg_toplevel_decoration_v1);
381 static inline uint32_t
382 zxdg_toplevel_decoration_v1_get_version(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
384 return wl_proxy_get_version((
struct wl_proxy *) zxdg_toplevel_decoration_v1);
387 zxdg_toplevel_decoration_v1_destroy(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
389 wl_proxy_marshal((
struct wl_proxy *) zxdg_toplevel_decoration_v1,
391 wl_proxy_destroy((
struct wl_proxy *) zxdg_toplevel_decoration_v1);
394 zxdg_toplevel_decoration_v1_set_mode(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1, uint32_t mode)
396 wl_proxy_marshal((
struct wl_proxy *) zxdg_toplevel_decoration_v1,
400 zxdg_toplevel_decoration_v1_unset_mode(
struct zxdg_toplevel_decoration_v1 *zxdg_toplevel_decoration_v1)
402 wl_proxy_marshal((
struct wl_proxy *) zxdg_toplevel_decoration_v1,
405 extern const struct wl_interface xdg_toplevel_interface;
406 extern const struct wl_interface zxdg_toplevel_decoration_v1_interface;
407 static const struct wl_interface *xdg_decoration_unstable_v1_types[] = {
409 &zxdg_toplevel_decoration_v1_interface,
410 &xdg_toplevel_interface,
412 static const struct wl_message zxdg_decoration_manager_v1_requests[] = {
413 {
"destroy",
"", xdg_decoration_unstable_v1_types + 0 },
414 {
"get_toplevel_decoration",
"no", xdg_decoration_unstable_v1_types + 1 },
416 const struct wl_interface zxdg_decoration_manager_v1_interface = {
417 "zxdg_decoration_manager_v1", 1,
418 2, zxdg_decoration_manager_v1_requests,
421 static const struct wl_message zxdg_toplevel_decoration_v1_requests[] = {
422 {
"destroy",
"", xdg_decoration_unstable_v1_types + 0 },
423 {
"set_mode",
"u", xdg_decoration_unstable_v1_types + 0 },
424 {
"unset_mode",
"", xdg_decoration_unstable_v1_types + 0 },
426 static const struct wl_message zxdg_toplevel_decoration_v1_events[] = {
427 {
"configure",
"u", xdg_decoration_unstable_v1_types + 0 },
429 const struct wl_interface zxdg_toplevel_decoration_v1_interface = {
430 "zxdg_toplevel_decoration_v1", 1,
431 3, zxdg_toplevel_decoration_v1_requests,
432 1, zxdg_toplevel_decoration_v1_events,
440 struct xdg_positioner;
444 extern const struct wl_interface xdg_wm_base_interface;
445 extern const struct wl_interface xdg_positioner_interface;
446 extern const struct wl_interface xdg_surface_interface;
447 extern const struct wl_interface xdg_toplevel_interface;
448 extern const struct wl_interface xdg_popup_interface;
449 enum xdg_wm_base_error {
450 XDG_WM_BASE_ERROR_ROLE = 0,
451 XDG_WM_BASE_ERROR_DEFUNCT_SURFACES = 1,
452 XDG_WM_BASE_ERROR_NOT_THE_TOPMOST_POPUP = 2,
453 XDG_WM_BASE_ERROR_INVALID_POPUP_PARENT = 3,
454 XDG_WM_BASE_ERROR_INVALID_SURFACE_STATE = 4,
455 XDG_WM_BASE_ERROR_INVALID_POSITIONER = 5,
457 struct xdg_wm_base_listener {
458 void (*ping)(
void *data,
459 struct xdg_wm_base *xdg_wm_base,
463 xdg_wm_base_add_listener(
struct xdg_wm_base *xdg_wm_base,
464 const struct xdg_wm_base_listener *listener,
void *data)
466 return wl_proxy_add_listener((
struct wl_proxy *) xdg_wm_base,
467 (
void (**)(
void)) listener, data);
470 xdg_wm_base_set_user_data(
struct xdg_wm_base *xdg_wm_base,
void *user_data)
472 wl_proxy_set_user_data((
struct wl_proxy *) xdg_wm_base, user_data);
475 xdg_wm_base_get_user_data(
struct xdg_wm_base *xdg_wm_base)
477 return wl_proxy_get_user_data((
struct wl_proxy *) xdg_wm_base);
479 static inline uint32_t
480 xdg_wm_base_get_version(
struct xdg_wm_base *xdg_wm_base)
482 return wl_proxy_get_version((
struct wl_proxy *) xdg_wm_base);
485 xdg_wm_base_destroy(
struct xdg_wm_base *xdg_wm_base)
487 wl_proxy_marshal((
struct wl_proxy *) xdg_wm_base,
489 wl_proxy_destroy((
struct wl_proxy *) xdg_wm_base);
491 static inline struct xdg_positioner *
492 xdg_wm_base_create_positioner(
struct xdg_wm_base *xdg_wm_base)
495 id = wl_proxy_marshal_constructor((
struct wl_proxy *) xdg_wm_base,
496 1, &xdg_positioner_interface, NULL);
497 return (
struct xdg_positioner *) id;
499 static inline struct xdg_surface *
500 xdg_wm_base_get_xdg_surface(
struct xdg_wm_base *xdg_wm_base,
struct wl_surface *surface)
503 id = wl_proxy_marshal_constructor((
struct wl_proxy *) xdg_wm_base,
504 2, &xdg_surface_interface, NULL, surface);
505 return (
struct xdg_surface *) id;
508 xdg_wm_base_pong(
struct xdg_wm_base *xdg_wm_base, uint32_t serial)
510 wl_proxy_marshal((
struct wl_proxy *) xdg_wm_base,
513 enum xdg_positioner_error {
514 XDG_POSITIONER_ERROR_INVALID_INPUT = 0,
516 enum xdg_positioner_anchor {
517 XDG_POSITIONER_ANCHOR_NONE = 0,
518 XDG_POSITIONER_ANCHOR_TOP = 1,
519 XDG_POSITIONER_ANCHOR_BOTTOM = 2,
520 XDG_POSITIONER_ANCHOR_LEFT = 3,
521 XDG_POSITIONER_ANCHOR_RIGHT = 4,
522 XDG_POSITIONER_ANCHOR_TOP_LEFT = 5,
523 XDG_POSITIONER_ANCHOR_BOTTOM_LEFT = 6,
524 XDG_POSITIONER_ANCHOR_TOP_RIGHT = 7,
525 XDG_POSITIONER_ANCHOR_BOTTOM_RIGHT = 8,
527 enum xdg_positioner_gravity {
528 XDG_POSITIONER_GRAVITY_NONE = 0,
529 XDG_POSITIONER_GRAVITY_TOP = 1,
530 XDG_POSITIONER_GRAVITY_BOTTOM = 2,
531 XDG_POSITIONER_GRAVITY_LEFT = 3,
532 XDG_POSITIONER_GRAVITY_RIGHT = 4,
533 XDG_POSITIONER_GRAVITY_TOP_LEFT = 5,
534 XDG_POSITIONER_GRAVITY_BOTTOM_LEFT = 6,
535 XDG_POSITIONER_GRAVITY_TOP_RIGHT = 7,
536 XDG_POSITIONER_GRAVITY_BOTTOM_RIGHT = 8,
538 enum xdg_positioner_constraint_adjustment {
539 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_NONE = 0,
540 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_X = 1,
541 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_SLIDE_Y = 2,
542 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_X = 4,
543 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_FLIP_Y = 8,
544 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_X = 16,
545 XDG_POSITIONER_CONSTRAINT_ADJUSTMENT_RESIZE_Y = 32,
548 xdg_positioner_set_user_data(
struct xdg_positioner *xdg_positioner,
void *user_data)
550 wl_proxy_set_user_data((
struct wl_proxy *) xdg_positioner, user_data);
553 xdg_positioner_get_user_data(
struct xdg_positioner *xdg_positioner)
555 return wl_proxy_get_user_data((
struct wl_proxy *) xdg_positioner);
557 static inline uint32_t
558 xdg_positioner_get_version(
struct xdg_positioner *xdg_positioner)
560 return wl_proxy_get_version((
struct wl_proxy *) xdg_positioner);
563 xdg_positioner_destroy(
struct xdg_positioner *xdg_positioner)
565 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
567 wl_proxy_destroy((
struct wl_proxy *) xdg_positioner);
570 xdg_positioner_set_size(
struct xdg_positioner *xdg_positioner, int32_t width, int32_t height)
572 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
576 xdg_positioner_set_anchor_rect(
struct xdg_positioner *xdg_positioner, int32_t x, int32_t y, int32_t width, int32_t height)
578 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
579 2, x, y, width, height);
582 xdg_positioner_set_anchor(
struct xdg_positioner *xdg_positioner, uint32_t anchor)
584 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
588 xdg_positioner_set_gravity(
struct xdg_positioner *xdg_positioner, uint32_t gravity)
590 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
594 xdg_positioner_set_constraint_adjustment(
struct xdg_positioner *xdg_positioner, uint32_t constraint_adjustment)
596 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
597 5, constraint_adjustment);
600 xdg_positioner_set_offset(
struct xdg_positioner *xdg_positioner, int32_t x, int32_t y)
602 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
606 xdg_positioner_set_reactive(
struct xdg_positioner *xdg_positioner)
608 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
612 xdg_positioner_set_parent_size(
struct xdg_positioner *xdg_positioner, int32_t parent_width, int32_t parent_height)
614 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
615 8, parent_width, parent_height);
618 xdg_positioner_set_parent_configure(
struct xdg_positioner *xdg_positioner, uint32_t serial)
620 wl_proxy_marshal((
struct wl_proxy *) xdg_positioner,
623 enum xdg_surface_error {
624 XDG_SURFACE_ERROR_NOT_CONSTRUCTED = 1,
625 XDG_SURFACE_ERROR_ALREADY_CONSTRUCTED = 2,
626 XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER = 3,
628 struct xdg_surface_listener {
629 void (*configure)(
void *data,
630 struct xdg_surface *xdg_surface,
634 xdg_surface_add_listener(
struct xdg_surface *xdg_surface,
635 const struct xdg_surface_listener *listener,
void *data)
637 return wl_proxy_add_listener((
struct wl_proxy *) xdg_surface,
638 (
void (**)(
void)) listener, data);
641 xdg_surface_set_user_data(
struct xdg_surface *xdg_surface,
void *user_data)
643 wl_proxy_set_user_data((
struct wl_proxy *) xdg_surface, user_data);
646 xdg_surface_get_user_data(
struct xdg_surface *xdg_surface)
648 return wl_proxy_get_user_data((
struct wl_proxy *) xdg_surface);
650 static inline uint32_t
651 xdg_surface_get_version(
struct xdg_surface *xdg_surface)
653 return wl_proxy_get_version((
struct wl_proxy *) xdg_surface);
656 xdg_surface_destroy(
struct xdg_surface *xdg_surface)
658 wl_proxy_marshal((
struct wl_proxy *) xdg_surface,
660 wl_proxy_destroy((
struct wl_proxy *) xdg_surface);
662 static inline struct xdg_toplevel *
663 xdg_surface_get_toplevel(
struct xdg_surface *xdg_surface)
666 id = wl_proxy_marshal_constructor((
struct wl_proxy *) xdg_surface,
667 1, &xdg_toplevel_interface, NULL);
668 return (
struct xdg_toplevel *) id;
670 static inline struct xdg_popup *
671 xdg_surface_get_popup(
struct xdg_surface *xdg_surface,
struct xdg_surface *parent,
struct xdg_positioner *positioner)
674 id = wl_proxy_marshal_constructor((
struct wl_proxy *) xdg_surface,
675 2, &xdg_popup_interface, NULL, parent, positioner);
676 return (
struct xdg_popup *) id;
679 xdg_surface_set_window_geometry(
struct xdg_surface *xdg_surface, int32_t x, int32_t y, int32_t width, int32_t height)
681 wl_proxy_marshal((
struct wl_proxy *) xdg_surface,
682 3, x, y, width, height);
685 xdg_surface_ack_configure(
struct xdg_surface *xdg_surface, uint32_t serial)
687 wl_proxy_marshal((
struct wl_proxy *) xdg_surface,
690 enum xdg_toplevel_resize_edge {
691 XDG_TOPLEVEL_RESIZE_EDGE_NONE = 0,
692 XDG_TOPLEVEL_RESIZE_EDGE_TOP = 1,
693 XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM = 2,
694 XDG_TOPLEVEL_RESIZE_EDGE_LEFT = 4,
695 XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT = 5,
696 XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT = 6,
697 XDG_TOPLEVEL_RESIZE_EDGE_RIGHT = 8,
698 XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT = 9,
699 XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT = 10,
701 enum xdg_toplevel_state {
702 XDG_TOPLEVEL_STATE_MAXIMIZED = 1,
703 XDG_TOPLEVEL_STATE_FULLSCREEN = 2,
704 XDG_TOPLEVEL_STATE_RESIZING = 3,
705 XDG_TOPLEVEL_STATE_ACTIVATED = 4,
706 XDG_TOPLEVEL_STATE_TILED_LEFT = 5,
707 XDG_TOPLEVEL_STATE_TILED_RIGHT = 6,
708 XDG_TOPLEVEL_STATE_TILED_TOP = 7,
709 XDG_TOPLEVEL_STATE_TILED_BOTTOM = 8,
711 struct xdg_toplevel_listener {
712 void (*configure)(
void *data,
713 struct xdg_toplevel *xdg_toplevel,
716 struct wl_array *states);
717 void (*close)(
void *data,
718 struct xdg_toplevel *xdg_toplevel);
721 xdg_toplevel_add_listener(
struct xdg_toplevel *xdg_toplevel,
722 const struct xdg_toplevel_listener *listener,
void *data)
724 return wl_proxy_add_listener((
struct wl_proxy *) xdg_toplevel,
725 (
void (**)(
void)) listener, data);
728 xdg_toplevel_set_user_data(
struct xdg_toplevel *xdg_toplevel,
void *user_data)
730 wl_proxy_set_user_data((
struct wl_proxy *) xdg_toplevel, user_data);
733 xdg_toplevel_get_user_data(
struct xdg_toplevel *xdg_toplevel)
735 return wl_proxy_get_user_data((
struct wl_proxy *) xdg_toplevel);
737 static inline uint32_t
738 xdg_toplevel_get_version(
struct xdg_toplevel *xdg_toplevel)
740 return wl_proxy_get_version((
struct wl_proxy *) xdg_toplevel);
743 xdg_toplevel_destroy(
struct xdg_toplevel *xdg_toplevel)
745 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
747 wl_proxy_destroy((
struct wl_proxy *) xdg_toplevel);
750 xdg_toplevel_set_parent(
struct xdg_toplevel *xdg_toplevel,
struct xdg_toplevel *parent)
752 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
756 xdg_toplevel_set_title(
struct xdg_toplevel *xdg_toplevel,
const char *title)
758 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
762 xdg_toplevel_set_app_id(
struct xdg_toplevel *xdg_toplevel,
const char *app_id)
764 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
768 xdg_toplevel_show_window_menu(
struct xdg_toplevel *xdg_toplevel,
struct wl_seat *seat, uint32_t serial, int32_t x, int32_t y)
770 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
771 4, seat, serial, x, y);
774 xdg_toplevel_move(
struct xdg_toplevel *xdg_toplevel,
struct wl_seat *seat, uint32_t serial)
776 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
780 xdg_toplevel_resize(
struct xdg_toplevel *xdg_toplevel,
struct wl_seat *seat, uint32_t serial, uint32_t edges)
782 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
783 6, seat, serial, edges);
786 xdg_toplevel_set_max_size(
struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
788 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
792 xdg_toplevel_set_min_size(
struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height)
794 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
798 xdg_toplevel_set_maximized(
struct xdg_toplevel *xdg_toplevel)
800 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
804 xdg_toplevel_unset_maximized(
struct xdg_toplevel *xdg_toplevel)
806 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
810 xdg_toplevel_set_fullscreen(
struct xdg_toplevel *xdg_toplevel,
struct wl_output *output)
812 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
816 xdg_toplevel_unset_fullscreen(
struct xdg_toplevel *xdg_toplevel)
818 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
822 xdg_toplevel_set_minimized(
struct xdg_toplevel *xdg_toplevel)
824 wl_proxy_marshal((
struct wl_proxy *) xdg_toplevel,
827 enum xdg_popup_error {
828 XDG_POPUP_ERROR_INVALID_GRAB = 0,
830 struct xdg_popup_listener {
831 void (*configure)(
void *data,
832 struct xdg_popup *xdg_popup,
837 void (*popup_done)(
void *data,
838 struct xdg_popup *xdg_popup);
839 void (*repositioned)(
void *data,
840 struct xdg_popup *xdg_popup,
844 xdg_popup_add_listener(
struct xdg_popup *xdg_popup,
845 const struct xdg_popup_listener *listener,
void *data)
847 return wl_proxy_add_listener((
struct wl_proxy *) xdg_popup,
848 (
void (**)(
void)) listener, data);
851 xdg_popup_set_user_data(
struct xdg_popup *xdg_popup,
void *user_data)
853 wl_proxy_set_user_data((
struct wl_proxy *) xdg_popup, user_data);
856 xdg_popup_get_user_data(
struct xdg_popup *xdg_popup)
858 return wl_proxy_get_user_data((
struct wl_proxy *) xdg_popup);
860 static inline uint32_t
861 xdg_popup_get_version(
struct xdg_popup *xdg_popup)
863 return wl_proxy_get_version((
struct wl_proxy *) xdg_popup);
866 xdg_popup_destroy(
struct xdg_popup *xdg_popup)
868 wl_proxy_marshal((
struct wl_proxy *) xdg_popup,
870 wl_proxy_destroy((
struct wl_proxy *) xdg_popup);
873 xdg_popup_grab(
struct xdg_popup *xdg_popup,
struct wl_seat *seat, uint32_t serial)
875 wl_proxy_marshal((
struct wl_proxy *) xdg_popup,
879 xdg_popup_reposition(
struct xdg_popup *xdg_popup,
struct xdg_positioner *positioner, uint32_t token)
881 wl_proxy_marshal((
struct wl_proxy *) xdg_popup,
882 2, positioner, token);
884 extern const struct wl_interface wl_output_interface;
885 extern const struct wl_interface wl_seat_interface;
886 extern const struct wl_interface wl_surface_interface;
887 extern const struct wl_interface xdg_popup_interface;
888 extern const struct wl_interface xdg_positioner_interface;
889 extern const struct wl_interface xdg_surface_interface;
890 extern const struct wl_interface xdg_toplevel_interface;
891 static const struct wl_interface *xdg_shell_types[] = {
896 &xdg_positioner_interface,
897 &xdg_surface_interface,
898 &wl_surface_interface,
899 &xdg_toplevel_interface,
900 &xdg_popup_interface,
901 &xdg_surface_interface,
902 &xdg_positioner_interface,
903 &xdg_toplevel_interface,
913 &wl_output_interface,
916 &xdg_positioner_interface,
919 static const struct wl_message xdg_wm_base_requests[] = {
920 {
"destroy",
"", xdg_shell_types + 0 },
921 {
"create_positioner",
"n", xdg_shell_types + 4 },
922 {
"get_xdg_surface",
"no", xdg_shell_types + 5 },
923 {
"pong",
"u", xdg_shell_types + 0 },
925 static const struct wl_message xdg_wm_base_events[] = {
926 {
"ping",
"u", xdg_shell_types + 0 },
928 const struct wl_interface xdg_wm_base_interface = {
930 4, xdg_wm_base_requests,
931 1, xdg_wm_base_events,
933 static const struct wl_message xdg_positioner_requests[] = {
934 {
"destroy",
"", xdg_shell_types + 0 },
935 {
"set_size",
"ii", xdg_shell_types + 0 },
936 {
"set_anchor_rect",
"iiii", xdg_shell_types + 0 },
937 {
"set_anchor",
"u", xdg_shell_types + 0 },
938 {
"set_gravity",
"u", xdg_shell_types + 0 },
939 {
"set_constraint_adjustment",
"u", xdg_shell_types + 0 },
940 {
"set_offset",
"ii", xdg_shell_types + 0 },
941 {
"set_reactive",
"3", xdg_shell_types + 0 },
942 {
"set_parent_size",
"3ii", xdg_shell_types + 0 },
943 {
"set_parent_configure",
"3u", xdg_shell_types + 0 },
945 const struct wl_interface xdg_positioner_interface = {
947 10, xdg_positioner_requests,
950 static const struct wl_message xdg_surface_requests[] = {
951 {
"destroy",
"", xdg_shell_types + 0 },
952 {
"get_toplevel",
"n", xdg_shell_types + 7 },
953 {
"get_popup",
"n?oo", xdg_shell_types + 8 },
954 {
"set_window_geometry",
"iiii", xdg_shell_types + 0 },
955 {
"ack_configure",
"u", xdg_shell_types + 0 },
957 static const struct wl_message xdg_surface_events[] = {
958 {
"configure",
"u", xdg_shell_types + 0 },
960 const struct wl_interface xdg_surface_interface = {
962 5, xdg_surface_requests,
963 1, xdg_surface_events,
965 static const struct wl_message xdg_toplevel_requests[] = {
966 {
"destroy",
"", xdg_shell_types + 0 },
967 {
"set_parent",
"?o", xdg_shell_types + 11 },
968 {
"set_title",
"s", xdg_shell_types + 0 },
969 {
"set_app_id",
"s", xdg_shell_types + 0 },
970 {
"show_window_menu",
"ouii", xdg_shell_types + 12 },
971 {
"move",
"ou", xdg_shell_types + 16 },
972 {
"resize",
"ouu", xdg_shell_types + 18 },
973 {
"set_max_size",
"ii", xdg_shell_types + 0 },
974 {
"set_min_size",
"ii", xdg_shell_types + 0 },
975 {
"set_maximized",
"", xdg_shell_types + 0 },
976 {
"unset_maximized",
"", xdg_shell_types + 0 },
977 {
"set_fullscreen",
"?o", xdg_shell_types + 21 },
978 {
"unset_fullscreen",
"", xdg_shell_types + 0 },
979 {
"set_minimized",
"", xdg_shell_types + 0 },
981 static const struct wl_message xdg_toplevel_events[] = {
982 {
"configure",
"iia", xdg_shell_types + 0 },
983 {
"close",
"", xdg_shell_types + 0 },
985 const struct wl_interface xdg_toplevel_interface = {
987 14, xdg_toplevel_requests,
988 2, xdg_toplevel_events,
990 static const struct wl_message xdg_popup_requests[] = {
991 {
"destroy",
"", xdg_shell_types + 0 },
992 {
"grab",
"ou", xdg_shell_types + 22 },
993 {
"reposition",
"3ou", xdg_shell_types + 24 },
995 static const struct wl_message xdg_popup_events[] = {
996 {
"configure",
"iiii", xdg_shell_types + 0 },
997 {
"popup_done",
"", xdg_shell_types + 0 },
998 {
"repositioned",
"3u", xdg_shell_types + 0 },
1000 const struct wl_interface xdg_popup_interface = {
1002 3, xdg_popup_requests,
1003 3, xdg_popup_events,
1019 #define X(name_, val_, mesg_) \
1020 static constexpr int name_ = val_;
1021 ZAKERO_YETANI__ERROR_DATA
1158 static
Yetani*
connect(const std::
string&, std::error_code&) noexcept;
1166 wl_shm_format format = WL_SHM_FORMAT_ARGB8888;
1167 int32_t hotspot_x = 0;
1168 int32_t hotspot_y = 0;
1169 std::chrono::milliseconds time_per_frame = std::chrono::milliseconds(0);
1189 std::string make =
"";
1190 std::string model =
"";
1195 int32_t physical_width_mm = 0;
1196 int32_t physical_height_mm = 0;
1197 int32_t subpixel = 0;
1198 int32_t refresh_mHz = 0;
1199 int32_t scale_factor = 0;
1200 int32_t transform = 0;
1202 float pixels_per_mm_horizontal = 0.0;
1203 float pixels_per_mm_vertical = 0.0;
1208 using OutputId = uint32_t;
1210 using LambdaOutputId = std::function<void(
const Yetani::OutputId)>;
1212 using VectorOutputId = std::vector<OutputId>;
1259 using VectorShmFormat = std::vector<wl_shm_format>;
1266 static std::
string shmFormatName(const wl_shm_format) noexcept;
1310 void setClass(
const std::string&) noexcept;
1311 void setTitle(
const std::string&) noexcept;
1337 uint32_t
time()
const noexcept;
1355 std::error_code
cursorUse(
const std::string&) noexcept;
1404 struct wl_buffer* wl_buffer;
1405 struct wl_surface* wl_surface;
1406 struct xdg_surface* xdg_surface;
1407 struct xdg_toplevel* xdg_toplevel;
1408 struct zxdg_toplevel_decoration_v1* xdg_decoration;
1410 wl_shm_format pixel_format;
1435 static constexpr uint32_t Size_Max = (uint32_t)std::numeric_limits<int32_t>::max();
1441 using VectorWlSurface = std::vector<struct wl_surface*>;
1446 void disconnect() noexcept;
1453 struct wl_surface* wl_surface =
nullptr;
1454 std::vector<::wl_buffer*> buffer_vector = {};
1455 wl_shm_format format = WL_SHM_FORMAT_ARGB8888;
1456 int64_t next_frame_time = 0;
1457 size_t buffer_index = 0;
1458 uint32_t time_per_frame = 0;
1461 int32_t hotspot_x = 0;
1462 int32_t hotspot_y = 0;
1465 using MapStringCursor = std::unordered_map<std::string, Yetani::Cursor>;
1467 MapStringCursor cursor_map;
1471 struct CursorSurface
1473 struct wl_pointer* wl_pointer;
1474 struct wl_surface* wl_surface;
1481 using MapCursorSurface = std::unordered_map<struct wl_surface*, Yetani::CursorSurface>;
1483 MapCursorSurface cursor_surface_map;
1488 mutable std::mutex cursor_mutex;
1489 struct wl_shm_pool* cursor_shm_pool;
1490 struct wl_pointer* cursor_pointer;
1494 void cursorAnimate() noexcept;
1495 std::error_code cursorCreateCursor(const std::
string&, const Yetani::CursorConfig&) noexcept;
1496 void cursorEnter(struct wl_pointer*, uint32_t, struct wl_surface*) noexcept;
1497 void cursorLeave(struct wl_surface*) noexcept;
1498 void cursorHide(struct wl_surface*) noexcept;
1499 void cursorShow(struct wl_surface*) noexcept;
1500 bool cursorIsHidden(struct wl_surface*) const noexcept;
1501 void cursorSetup() noexcept;
1502 void cursorTeardown() noexcept;
1503 std::error_code cursorAttach(const std::
string&, struct wl_surface*) noexcept;
1504 std::error_code cursorDetach(struct wl_surface*) noexcept;
1509 std::jthread event_loop;
1510 std::atomic<
bool> event_loop_is_running;
1514 void eventLoopStart() noexcept;
1515 static
void eventLoop(std::stop_token, Yetani*) noexcept;
1520 struct wl_compositor* compositor;
1521 struct wl_display* display;
1522 struct wl_registry* registry;
1524 Yetani::VectorShmFormat shm_format_vector;
1531 struct wl_keyboard* wl_keyboard =
nullptr;
1532 struct wl_pointer* wl_pointer =
nullptr;
1533 struct wl_touch* wl_touch =
nullptr;
1534 std::string name =
"";
1535 uint32_t version = 0;
1538 using MapSeat = std::map<struct wl_seat*, Seat>;
1539 using MapIdWlSeat = std::map<uint32_t, struct wl_seat*>;
1541 Yetani::MapSeat seat_map;
1542 Yetani::MapIdWlSeat id_to_seat;
1546 struct wl_seat* seat;
1550 void seatDestroy(
struct wl_seat*&) noexcept;
1555 struct KeyRepeatData
1557 std::chrono::time_point<std::chrono::steady_clock> trigger_time = {};
1558 uint32_t base_time = 0;
1561 using KeyRepeatMap = std::map<uint32_t, Yetani::KeyRepeatData>;
1565 struct KeyboardEvent
1572 using MapKeyboardEvent = std::unordered_map<struct wl_surface*, Yetani::KeyboardEvent>;
1578 struct wl_surface* wl_surface =
nullptr;
1579 Yetani::KeyboardEvent*
event =
nullptr;
1580 Yetani::MapKeyboardEvent event_map = {};
1581 Yetani::KeyModifier modifier = {};
1582 Yetani::KeyRepeatMap repeat_map = {};
1583 char* keymap =
nullptr;
1584 uint32_t keymap_size = 0;
1585 int32_t repeat_delay = 0;
1586 int32_t repeat_rate = 0;
1589 Yetani::Keyboard keyboard;
1593 static void keyboardDestroy(Yetani::Keyboard&) noexcept;
1594 static void keyboardRepeat(Yetani::Keyboard&) noexcept;
1595 static void keyboardRepeatAdd(Yetani::Keyboard&, uint32_t, uint32_t) noexcept;
1596 static void keyboardRepeatReleaseAll(Yetani::Keyboard&) noexcept;
1597 static void keyboardRepeatRemove(Yetani::Keyboard&, uint32_t) noexcept;
1620 using MapPointerEvent = std::unordered_map<struct wl_surface*, Yetani::PointerEvent>;
1627 Yetani* yetani =
nullptr;
1628 struct wl_surface* wl_surface =
nullptr;
1629 struct wl_pointer* wl_pointer =
nullptr;
1630 Yetani::PointerEvent*
event =
nullptr;
1631 Yetani::MapPointerEvent event_map = {};
1634 Yetani::PointMm point_mm = {};
1635 Yetani::PointPercent point_percent = {};
1636 Yetani::PointPixel point_pixel = {};
1639 Yetani::PointerAxis axis = {};
1642 Yetani::PointerButton button = {};
1643 uint32_t button_event_code = 0;
1644 bool button_is_pressed =
false;
1645 uint32_t button_time = {};
1648 struct wl_surface* enter_surface =
nullptr;
1649 Yetani::PointPixel enter_point = {};
1650 uint32_t enter_serial = 0;
1653 struct wl_surface* leave_surface =
nullptr;
1656 Yetani::PointPixel motion_point = {};
1659 Yetani::Pointer pointer;
1663 static void pointerClear(
struct Pointer&) noexcept;
1668 enum struct OutputState
1676 using VectorWlOutput = std::vector<struct wl_output*>;
1678 using MapWlOutputOutputState = std::unordered_map<struct wl_output*, Yetani::OutputState>;
1679 using MapOutputIdWlOutput = std::unordered_map<Yetani::OutputId, struct wl_output*>;
1680 using MapWlOutputOutputId = std::unordered_map<struct wl_output*, Yetani::OutputId>;
1681 using MapWlSurfaceVectorWlOutput = std::unordered_map<struct wl_surface*, Yetani::VectorWlOutput>;
1682 using MapWlOutputOutput = std::unordered_map<struct wl_output*, Output>;
1688 Yetani::MapWlSurfaceVectorWlOutput surface_output_map = {};
1689 Yetani::MapOutputIdWlOutput outputid_to_wloutput = {};
1690 Yetani::MapWlOutputOutput output_map = {};
1691 Yetani::MapWlOutputOutputId wloutput_to_outputid = {};
1692 mutable std::mutex mutex = {};
1695 Yetani::OutputData output_data;
1699 Yetani::LambdaOutputId on_output_add;
1700 Yetani::LambdaOutputId on_output_change;
1701 Yetani::LambdaOutputId on_output_remove;
1703 Yetani::MapWlOutputOutput output_changes_map;
1704 Yetani::MapWlOutputOutputState output_state_map;
1706 Yetani::VectorWlSurface output_notify_surface_vector;
1710 void convertPixel(
struct wl_surface*,
const int32_t,
const int32_t,
float&,
float&,
float&,
float&)
const noexcept;
1712 std::pair<float, float> convertPixelToMm(
const Yetani::Output&, int32_t, int32_t)
const noexcept;
1713 std::pair<float, float> convertPixelToPercent(
const Yetani::Output&, int32_t, int32_t)
const noexcept;
1714 std::pair<int32_t, int32_t> convertMmToPixel(
const Yetani::Output&,
float,
float)
const noexcept;
1715 std::pair<int32_t, int32_t> convertPercentToPixel(
const Yetani::Output&,
float,
float)
const noexcept;
1717 static void outputNotifySurface(Yetani*,
struct wl_output*,
struct wl_surface*) noexcept;
1726 MemoryPool* memory_pool =
nullptr;
1730 using MapBufferData = std::unordered_map<struct wl_buffer*, BufferData>;
1736 MapBufferData map = {};
1737 std::mutex mutex = {};
1744 static wl_buffer* bufferCreate(Yetani::SurfaceSize&, Yetani::Window::Memory*, Yetani::Buffer*) noexcept;
1745 static wl_buffer* bufferCreateAndRelease(Yetani*, Yetani::SurfaceSize&, Yetani::Window::Memory*) noexcept;
1746 static void bufferDestroy(
struct wl_buffer*&) noexcept;
1758 using MapSurfaceEvent = std::map<struct wl_surface*, Yetani::SurfaceEvent>;
1760 MapSurfaceEvent surface_event_map;
1764 enum struct SizeUnit
1772 struct SurfaceExtent
1774 Yetani::SizeUnit preferred_unit = {};
1775 Yetani::SizeMm preferred_mm = {};
1776 Yetani::SizePercent preferred_percent = {};
1777 Yetani::SizeMm size_mm = {};
1778 Yetani::SizePercent size_percent = {};
1779 Yetani::SizePixel size_pixel = {};
1780 Yetani::SizePixel size_pixel_max = {};
1781 Yetani::SizePixel size_pixel_min = {};
1784 using MapSurfaceExtent = std::unordered_map<struct wl_surface*, Yetani::SurfaceExtent>;
1786 MapSurfaceExtent surface_extent_map;
1787 std::mutex surface_extent_mutex;
1793 struct wl_callback* callback =
nullptr;
1794 struct wl_surface* wl_surface =
nullptr;
1795 std::atomic<wl_buffer*> buffer_next = {};
1797 uint32_t height = 0;
1798 uint32_t time_ms = 0;
1801 using MapSurfaceFrame = std::unordered_map<struct wl_surface*, Yetani::SurfaceFrame>;
1803 MapSurfaceFrame surface_frame_map;
1813 wl_shm_format pixel_format;
1814 uint8_t bytes_per_pixel;
1817 using MapSurfaceSize = std::unordered_map<struct wl_surface*, Yetani::SurfaceSize>;
1819 MapSurfaceSize surface_size_map;
1823 using MapSurfaceResizeMutex = std::unordered_map<struct wl_surface*, std::mutex>;
1825 MapSurfaceResizeMutex surface_resize_mutex_map;
1829 static void surfaceCalculateSize(Yetani*,
struct wl_surface*,
const Yetani::SizePixel&) noexcept;
1830 static struct wl_surface* surfaceCreate(Yetani*,
const wl_shm_format,
const Yetani::SizePixel&,
const bool, Yetani::Window::Memory&) noexcept;
1831 static void surfaceDestroy(Yetani*,
struct wl_surface*&) noexcept;
1839 struct wl_shm* wl_shm;
1840 struct wl_output* wl_output;
1841 std::string file_name;
1842 Yetani::SizeMm size_mm;
1843 Yetani::SizePercent size_percent;
1844 Yetani::SizePixel size_pixel;
1845 Yetani::SizeUnit size_unit;
1846 wl_shm_format pixel_format;
1847 std::error_code error;
1852 Yetani::Window*
windowCreate(
const Yetani::SizeUnit,
const Yetani::SizeMm&,
const Yetani::SizePercent&,
const Yetani::SizePixel&,
const wl_shm_format, std::error_code&) noexcept;
1853 void windowDataInit(Yetani::WindowData&) noexcept;
1854 void windowDataInitOutput(Yetani::WindowData&) noexcept;
1855 void windowInitMemory(Yetani::WindowData&, Yetani::Window::Memory&) noexcept;
1856 void windowInitOutput(Yetani::WindowData&,
struct wl_surface*) noexcept;
1857 void windowEraseMemory(Yetani::Window::Memory&) noexcept;
1858 void windowEraseOutput(
struct wl_surface*) noexcept;
1859 void windowEraseSurfaceExtent(
struct wl_surface*) noexcept;
1864 std::vector<Yetani::Window*> window_vector;
1865 std::mutex window_vector_mutex;
1869 void windowAdd(Yetani::Window*) noexcept;
1870 void windowRemove(Yetani::Window*) noexcept;
1875 enum XdgState : int32_t
1877 , Toplevel_Active = 1
1878 , Toplevel_Attach_Buffer = 2
1879 , Toplevel_Resizing = 3
1880 , Toplevel_Window_Fullscreen = 4
1881 , Toplevel_Window_Maximized = 5
1882 , Toplevel_Window_Normal = 6
1883 , Toplevel_Decoration = 7
1886 using VectorXdgStateChange = std::vector<int32_t>;
1887 using MapXdgStateChange = std::unordered_map<struct xdg_surface*, Yetani::VectorXdgStateChange>;
1889 Yetani::MapXdgStateChange xdg_state_change_map;
1890 std::mutex xdg_state_change_mutex;
1894 struct xdg_wm_base* xdg_wm_base;
1906 Yetani* yetani =
nullptr;
1907 struct wl_surface* wl_surface =
nullptr;
1910 using MapXdgSurface = std::unordered_map<struct wl_surface*, Yetani::XdgSurface>;
1912 Yetani::MapXdgSurface xdg_surface_map;
1916 struct xdg_surface* xdgSurfaceCreate(
struct wl_surface*) noexcept;
1917 void xdgSurfaceDestroy(
struct wl_surface*,
struct xdg_surface*&) noexcept;
1918 void xdgSurfaceSetExtent(
struct wl_surface*,
const Yetani::SizeUnit&,
const Yetani::SizeMm&,
const Yetani::SizePercent&,
const Yetani::SizePixel&) noexcept;
1925 Yetani::VectorXdgStateChange* state_change =
nullptr;
1928 bool is_active =
false;
1929 Yetani::XdgState window_state = XdgState::Unknown;
1931 Yetani::SizePixel previous_size = {};
1932 struct xdg_toplevel* xdg_toplevel =
nullptr;
1935 using MapXdgToplevel = std::unordered_map<struct xdg_surface*, Yetani::XdgToplevel>;
1937 MapXdgToplevel xdg_toplevel_map;
1941 struct xdg_toplevel* xdgToplevelCreate(
struct xdg_surface*) noexcept;
1942 void xdgToplevelDestroy(
struct xdg_surface*,
struct xdg_toplevel*&) noexcept;
1943 static void xdgToplevelSizeChange(Yetani*,
struct wl_surface*,
const Yetani::SizePixel&) noexcept;
1944 static void xdgToplevelSizeMinMaxChange(Yetani*,
struct xdg_toplevel*,
struct wl_surface*,
const Yetani::SizePixel&,
const Yetani::SizePixel&) noexcept;
1945 static void xdgToplevelWindowChange(Yetani*,
struct wl_surface*, Yetani::XdgToplevel&,
const Yetani::XdgState,
const Yetani::SizePixel&) noexcept;
1950 struct XdgDecoration
1952 Yetani::VectorXdgStateChange* state_change =
nullptr;
1955 bool is_present =
false;
1959 using MapXdgDecoration = std::unordered_map<struct xdg_surface*, Yetani::XdgDecoration>;
1961 MapXdgDecoration xdg_decoration_map;
1965 struct zxdg_decoration_manager_v1* decoration_manager;
1969 struct zxdg_toplevel_decoration_v1* xdgDecorationCreate(
struct xdg_surface*,
struct xdg_toplevel*) noexcept;
1970 void xdgDecorationDestroy(
struct xdg_surface*,
struct xdg_toplevel*,
struct zxdg_toplevel_decoration_v1*&) noexcept;
1971 static void xdgDecorationChange(Yetani::XdgDecoration&,
const uint32_t) noexcept;
1976 static struct wl_buffer_listener buffer_listener;
1977 static struct wl_callback_listener frame_callback_listener;
1978 static struct wl_keyboard_listener keyboard_listener;
1979 static struct wl_output_listener output_listener;
1980 static struct wl_pointer_listener pointer_listener;
1981 static struct wl_registry_listener registry_listener;
1982 static struct wl_seat_listener seat_listener;
1983 static struct wl_shm_listener shm_listener;
1984 static struct wl_surface_listener surface_listener;
1988 static void handlerBufferRelease(
void*,
struct wl_buffer*) noexcept;
1990 static void handlerKeyboardEnter(
void*,
struct wl_keyboard*, uint32_t,
struct wl_surface*,
struct wl_array*) noexcept;
1991 static void handlerKeyboardKey(
void*,
struct wl_keyboard*, uint32_t, uint32_t, uint32_t, uint32_t) noexcept;
1992 static void handlerKeyboardKeymap(
void*,
struct wl_keyboard*, uint32_t, int32_t, uint32_t) noexcept;
1993 static void handlerKeyboardLeave(
void*,
struct wl_keyboard*, uint32_t,
struct wl_surface*) noexcept;
1994 static void handlerKeyboardModifiers(
void*,
struct wl_keyboard*, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t) noexcept;
1995 static void handlerKeyboardRepeatInfo(
void*,
struct wl_keyboard*, int32_t, int32_t) noexcept;
1997 static void handlerOutputDone(
void*,
struct wl_output*) noexcept;
1998 static void handlerOutputGeometry(
void*,
struct wl_output*, int32_t, int32_t, int32_t, int32_t, int32_t,
const char*,
const char*, int32_t) noexcept;
1999 static void handlerOutputMode(
void*,
struct wl_output*, uint32_t, int32_t, int32_t, int32_t) noexcept;
2000 static void handlerOutputScale(
void*,
struct wl_output*, int32_t) noexcept;
2001 static void handlerPointerAxis(
void*,
struct wl_pointer*, uint32_t, uint32_t, wl_fixed_t) noexcept;
2002 static void handlerPointerAxisDiscrete(
void*,
struct wl_pointer*, uint32_t, int32_t) noexcept;
2003 static void handlerPointerAxisSource(
void*,
struct wl_pointer*, uint32_t) noexcept;
2004 static void handlerPointerAxisStop(
void*,
struct wl_pointer*, uint32_t, uint32_t) noexcept;
2005 static void handlerPointerButton(
void*,
struct wl_pointer*, uint32_t, uint32_t, uint32_t, uint32_t) noexcept;
2006 static void handlerPointerEnter(
void*,
struct wl_pointer*, uint32_t,
struct wl_surface*, wl_fixed_t, wl_fixed_t) noexcept;
2007 static void handlerPointerFrame(
void*,
struct wl_pointer*) noexcept;
2008 static void handlerPointerLeave(
void*,
struct wl_pointer*, uint32_t,
struct wl_surface*) noexcept;
2009 static void handlerPointerMotion(
void*,
struct wl_pointer*, uint32_t, wl_fixed_t, wl_fixed_t) noexcept;
2010 static void handlerRegistryGlobal(
void*,
struct wl_registry*, uint32_t,
const char*, uint32_t) noexcept;
2011 static void handlerRegistryRemove(
void*,
struct wl_registry*, uint32_t) noexcept;
2012 static void handlerSeatCapabilities(
void*,
struct wl_seat*, uint32_t) noexcept;
2013 static void handlerSeatName(
void*,
struct wl_seat*,
const char*) noexcept;
2014 static void handlerShmFormat(
void*,
struct wl_shm*, uint32_t) noexcept;
2015 static void handlerSurfaceEnter(
void*,
struct wl_surface*,
struct wl_output*) noexcept;
2016 static void handlerSurfaceLeave(
void*,
struct wl_surface*,
struct wl_output*) noexcept;
2017 static void handlerSwapBuffers(
void*,
struct wl_callback*, uint32_t) noexcept;
2024 static struct xdg_wm_base_listener xdg_wm_base_listener;
2025 static struct xdg_surface_listener xdg_surface_listener;
2026 static struct xdg_toplevel_listener xdg_toplevel_listener;
2030 static void handlerXdgSurfaceConfigure(
void*,
struct xdg_surface*, uint32_t) noexcept;
2031 static void handlerXdgToplevelClose(
void*,
struct xdg_toplevel*) noexcept;
2032 static void handlerXdgToplevelConfigure(
void*,
struct xdg_toplevel*, int32_t, int32_t,
struct wl_array*) noexcept;
2033 static void handlerXdgWmBasePing(
void*,
struct xdg_wm_base*, uint32_t) noexcept;
2038 static struct zxdg_toplevel_decoration_v1_listener xdg_toplevel_decoration_listener;
2042 static void handlerXdgToplevelDecorationConfigure(
void*,
struct zxdg_toplevel_decoration_v1*, uint32_t mode) noexcept;
2046 Yetani(
const Yetani&) =
delete;
2047 Yetani& operator=(
const Yetani&) =
delete;
2053 std::string
to_string(
const wl_shm_format) noexcept;
2054 std::string
to_string(
const std::error_code&) noexcept;
2055 std::string
to_string(
const Yetani::KeyModifier&) noexcept;
2057 std::string
to_string(
const Yetani::Output&) noexcept;
2068 #ifdef ZAKERO_YETANI_IMPLEMENTATION
2074 #ifdef ZAKERO__DOXYGEN_DEFINE_DOCS
2089 #define ZAKERO_YETANI_IMPLEMENTATION
2099 #define ZAKERO_YETANI_ENABLE_DEBUG
2109 #define ZAKERO_YETANI_ENABLE_SAFE_MODE
2111 #endif // ZAKERO__DOXYGEN_DEFINE_DOCS
2130 #ifdef ZAKERO_YETANI_ENABLE_DEBUG
2131 #define ZAKERO_YETANI__DEBUG_DISABLED false
2133 #define ZAKERO_YETANI__DEBUG_DISABLED true
2149 #ifndef ZAKERO_YETANI_ENABLE_DEBUG_STREAM
2150 #define ZAKERO_YETANI_ENABLE_DEBUG_STREAM std::cerr
2171 #define ZAKERO_YETANI__DEBUG \
2172 if(ZAKERO_YETANI__DEBUG_DISABLED) {} \
2173 else ZAKERO_YETANI_ENABLE_DEBUG_STREAM \
2175 << std::to_string(__LINE__) \
2177 << __PRETTY_FUNCTION__ \
2196 #define ZAKERO_YETANI__DEBUG_VAR(var_) \
2197 ZAKERO_YETANI__DEBUG \
2198 << #var_ << ": " << var_ \
2216 #define ZAKERO_YETANI__DEBUG_BOOL(var_) \
2217 ZAKERO_YETANI__DEBUG \
2218 << #var_ << ": " << std::boolalpha << var_ \
2231 #define ZAKERO_YETANI__ERROR(err_) std::error_code(err_, YetaniErrorCategory)
2250 #define ZAKERO_YETANI__SHM_FORMAT \
2251 X(WL_SHM_FORMAT_ARGB8888 , 4 , "32-bit ARGB format, [31:0] A:R:G:B 8:8:8:8 little endian" ) \
2252 X(WL_SHM_FORMAT_XRGB8888 , 4 , "32-bit RGB format, [31:0] x:R:G:B 8:8:8:8 little endian" ) \
2253 X(WL_SHM_FORMAT_C8 , 1 , "8-bit color index format, [7:0] C" ) \
2254 X(WL_SHM_FORMAT_RGB332 , 1 , "8-bit RGB format, [7:0] R:G:B 3:3:2" ) \
2255 X(WL_SHM_FORMAT_BGR233 , 1 , "8-bit BGR format, [7:0] B:G:R 2:3:3" ) \
2256 X(WL_SHM_FORMAT_XRGB4444 , 2 , "16-bit xRGB format, [15:0] x:R:G:B 4:4:4:4 little endian" ) \
2257 X(WL_SHM_FORMAT_XBGR4444 , 2 , "16-bit xBGR format, [15:0] x:B:G:R 4:4:4:4 little endian" ) \
2258 X(WL_SHM_FORMAT_RGBX4444 , 2 , "16-bit RGBx format, [15:0] R:G:B:x 4:4:4:4 little endian" ) \
2259 X(WL_SHM_FORMAT_BGRX4444 , 2 , "16-bit BGRx format, [15:0] B:G:R:x 4:4:4:4 little endian" ) \
2260 X(WL_SHM_FORMAT_ARGB4444 , 2 , "16-bit ARGB format, [15:0] A:R:G:B 4:4:4:4 little endian" ) \
2261 X(WL_SHM_FORMAT_ABGR4444 , 2 , "16-bit ABGR format, [15:0] A:B:G:R 4:4:4:4 little endian" ) \
2262 X(WL_SHM_FORMAT_RGBA4444 , 2 , "16-bit RBGA format, [15:0] R:G:B:A 4:4:4:4 little endian" ) \
2263 X(WL_SHM_FORMAT_BGRA4444 , 2 , "16-bit BGRA format, [15:0] B:G:R:A 4:4:4:4 little endian" ) \
2264 X(WL_SHM_FORMAT_XRGB1555 , 2 , "16-bit xRGB format, [15:0] x:R:G:B 1:5:5:5 little endian" ) \
2265 X(WL_SHM_FORMAT_XBGR1555 , 2 , "16-bit xBGR 1555 format, [15:0] x:B:G:R 1:5:5:5 little endian" ) \
2266 X(WL_SHM_FORMAT_RGBX5551 , 2 , "16-bit RGBx 5551 format, [15:0] R:G:B:x 5:5:5:1 little endian" ) \
2267 X(WL_SHM_FORMAT_BGRX5551 , 2 , "16-bit BGRx 5551 format, [15:0] B:G:R:x 5:5:5:1 little endian" ) \
2268 X(WL_SHM_FORMAT_ARGB1555 , 2 , "16-bit ARGB 1555 format, [15:0] A:R:G:B 1:5:5:5 little endian" ) \
2269 X(WL_SHM_FORMAT_ABGR1555 , 2 , "16-bit ABGR 1555 format, [15:0] A:B:G:R 1:5:5:5 little endian" ) \
2270 X(WL_SHM_FORMAT_RGBA5551 , 2 , "16-bit RGBA 5551 format, [15:0] R:G:B:A 5:5:5:1 little endian" ) \
2271 X(WL_SHM_FORMAT_BGRA5551 , 2 , "16-bit BGRA 5551 format, [15:0] B:G:R:A 5:5:5:1 little endian" ) \
2272 X(WL_SHM_FORMAT_RGB565 , 2 , "16-bit RGB 565 format, [15:0] R:G:B 5:6:5 little endian" ) \
2273 X(WL_SHM_FORMAT_BGR565 , 2 , "16-bit BGR 565 format, [15:0] B:G:R 5:6:5 little endian" ) \
2274 X(WL_SHM_FORMAT_RGB888 , 3 , "24-bit RGB format, [23:0] R:G:B little endian" ) \
2275 X(WL_SHM_FORMAT_BGR888 , 3 , "24-bit BGR format, [23:0] B:G:R little endian" ) \
2276 X(WL_SHM_FORMAT_XBGR8888 , 4 , "32-bit xBGR format, [31:0] x:B:G:R 8:8:8:8 little endian" ) \
2277 X(WL_SHM_FORMAT_RGBX8888 , 4 , "32-bit RGBx format, [31:0] R:G:B:x 8:8:8:8 little endian" ) \
2278 X(WL_SHM_FORMAT_BGRX8888 , 4 , "32-bit BGRx format, [31:0] B:G:R:x 8:8:8:8 little endian" ) \
2279 X(WL_SHM_FORMAT_ABGR8888 , 4 , "32-bit ABGR format, [31:0] A:B:G:R 8:8:8:8 little endian" ) \
2280 X(WL_SHM_FORMAT_RGBA8888 , 4 , "32-bit RGBA format, [31:0] R:G:B:A 8:8:8:8 little endian" ) \
2281 X(WL_SHM_FORMAT_BGRA8888 , 4 , "32-bit BGRA format, [31:0] B:G:R:A 8:8:8:8 little endian" ) \
2282 X(WL_SHM_FORMAT_XRGB2101010 , 4 , "32-bit xRGB format, [31:0] x:R:G:B 2:10:10:10 little endian" ) \
2283 X(WL_SHM_FORMAT_XBGR2101010 , 4 , "32-bit xBGR format, [31:0] x:B:G:R 2:10:10:10 little endian" ) \
2284 X(WL_SHM_FORMAT_RGBX1010102 , 4 , "32-bit RGBx format, [31:0] R:G:B:x 10:10:10:2 little endian" ) \
2285 X(WL_SHM_FORMAT_BGRX1010102 , 4 , "32-bit BGRx format, [31:0] B:G:R:x 10:10:10:2 little endian" ) \
2286 X(WL_SHM_FORMAT_ARGB2101010 , 4 , "32-bit ARGB format, [31:0] A:R:G:B 2:10:10:10 little endian" ) \
2287 X(WL_SHM_FORMAT_ABGR2101010 , 4 , "32-bit ABGR format, [31:0] A:B:G:R 2:10:10:10 little endian" ) \
2288 X(WL_SHM_FORMAT_RGBA1010102 , 4 , "32-bit RGBA format, [31:0] R:G:B:A 10:10:10:2 little endian" ) \
2289 X(WL_SHM_FORMAT_BGRA1010102 , 4 , "32-bit BGRA format, [31:0] B:G:R:A 10:10:10:2 little endian" ) \
2290 X(WL_SHM_FORMAT_YUYV , 4 , "packed YCbCr format, [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian" ) \
2291 X(WL_SHM_FORMAT_YVYU , 4 , "packed YCbCr format, [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian" ) \
2292 X(WL_SHM_FORMAT_UYVY , 4 , "packed YCbCr format, [31:0] Y1:Cr0:Y0:Cb0 8:8:8:8 little endian" ) \
2293 X(WL_SHM_FORMAT_VYUY , 4 , "packed YCbCr format, [31:0] Y1:Cb0:Y0:Cr0 8:8:8:8 little endian" ) \
2294 X(WL_SHM_FORMAT_AYUV , 4 , "packed AYCbCr format, [31:0] A:Y:Cb:Cr 8:8:8:8 little endian" ) \
2295 X(WL_SHM_FORMAT_NV12 , 8 , "2 plane YCbCr Cr:Cb format, 2x2 subsampled Cr:Cb plane" ) \
2296 X(WL_SHM_FORMAT_NV21 , 8 , "2 plane YCbCr Cb:Cr format, 2x2 subsampled Cb:Cr plane" ) \
2297 X(WL_SHM_FORMAT_NV16 , 8 , "2 plane YCbCr Cr:Cb format, 2x1 subsampled Cr:Cb plane" ) \
2298 X(WL_SHM_FORMAT_NV61 , 8 , "2 plane YCbCr Cb:Cr format, 2x1 subsampled Cb:Cr plane" ) \
2299 X(WL_SHM_FORMAT_YUV410 , 8 , "3 plane YCbCr format, 4x4 subsampled Cb (1) and Cr (2) planes" ) \
2300 X(WL_SHM_FORMAT_YVU410 , 8 , "3 plane YCbCr format, 4x4 subsampled Cr (1) and Cb (2) planes" ) \
2301 X(WL_SHM_FORMAT_YUV411 , 8 , "3 plane YCbCr format, 4x1 subsampled Cb (1) and Cr (2) planes" ) \
2302 X(WL_SHM_FORMAT_YVU411 , 8 , "3 plane YCbCr format, 4x1 subsampled Cr (1) and Cb (2) planes" ) \
2303 X(WL_SHM_FORMAT_YUV420 , 8 , "3 plane YCbCr format, 2x2 subsampled Cb (1) and Cr (2) planes" ) \
2304 X(WL_SHM_FORMAT_YVU420 , 8 , "3 plane YCbCr format, 2x2 subsampled Cr (1) and Cb (2) planes" ) \
2305 X(WL_SHM_FORMAT_YUV422 , 8 , "3 plane YCbCr format, 2x1 subsampled Cb (1) and Cr (2) planes" ) \
2306 X(WL_SHM_FORMAT_YVU422 , 8 , "3 plane YCbCr format, 2x1 subsampled Cr (1) and Cb (2) planes" ) \
2307 X(WL_SHM_FORMAT_YUV444 , 8 , "3 plane YCbCr format, non-subsampled Cb (1) and Cr (2) planes" ) \
2308 X(WL_SHM_FORMAT_YVU444 , 8 , "3 plane YCbCr format, non-subsampled Cr (1) and Cb (2) planes" ) \
2309 X(WL_SHM_FORMAT_R8 , 1 , "[7:0] R" ) \
2310 X(WL_SHM_FORMAT_R16 , 2 , "[15:0] R little endian" ) \
2311 X(WL_SHM_FORMAT_RG88 , 2 , "[15:0] R:G 8:8 little endian" ) \
2312 X(WL_SHM_FORMAT_GR88 , 2 , "[15:0] G:R 8:8 little endian" ) \
2313 X(WL_SHM_FORMAT_RG1616 , 4 , "[31:0] R:G 16:16 little endian" ) \
2314 X(WL_SHM_FORMAT_GR1616 , 4 , "[31:0] G:R 16:16 little endian" ) \
2315 X(WL_SHM_FORMAT_XRGB16161616F , 8 , "[63:0] x:R:G:B 16:16:16:16 little endian" ) \
2316 X(WL_SHM_FORMAT_XBGR16161616F , 8 , "[63:0] x:B:G:R 16:16:16:16 little endian" ) \
2317 X(WL_SHM_FORMAT_ARGB16161616F , 8 , "[63:0] A:R:G:B 16:16:16:16 little endian" ) \
2318 X(WL_SHM_FORMAT_ABGR16161616F , 8 , "[63:0] A:B:G:R 16:16:16:16 little endian" ) \
2319 X(WL_SHM_FORMAT_XYUV8888 , 4 , "[31:0] X:Y:Cb:Cr 8:8:8:8 little endian" ) \
2320 X(WL_SHM_FORMAT_VUY888 , 3 , "[23:0] Cr:Cb:Y 8:8:8 little endian" ) \
2321 X(WL_SHM_FORMAT_VUY101010 , 4 , "Y followed by U then V, 10:10:10. Non-linear modifier only" ) \
2322 X(WL_SHM_FORMAT_Y210 , 8 , "[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 10:6:10:6:10:6:10:6 little endian per 2 Y pixels" ) \
2323 X(WL_SHM_FORMAT_Y212 , 8 , "[63:0] Cr0:0:Y1:0:Cb0:0:Y0:0 12:4:12:4:12:4:12:4 little endian per 2 Y pixels" ) \
2324 X(WL_SHM_FORMAT_Y216 , 8 , "[63:0] Cr0:Y1:Cb0:Y0 16:16:16:16 little endian per 2 Y pixels" ) \
2325 X(WL_SHM_FORMAT_Y410 , 4 , "[31:0] A:Cr:Y:Cb 2:10:10:10 little endian" ) \
2326 X(WL_SHM_FORMAT_Y412 , 8 , "[63:0] A:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian" ) \
2327 X(WL_SHM_FORMAT_Y416 , 8 , "[63:0] A:Cr:Y:Cb 16:16:16:16 little endian" ) \
2328 X(WL_SHM_FORMAT_XVYU2101010 , 4 , "[31:0] X:Cr:Y:Cb 2:10:10:10 little endian" ) \
2329 X(WL_SHM_FORMAT_XVYU12_16161616 , 8 , "[63:0] X:0:Cr:0:Y:0:Cb:0 12:4:12:4:12:4:12:4 little endian" ) \
2330 X(WL_SHM_FORMAT_XVYU16161616 , 8 , "[63:0] X:Cr:Y:Cb 16:16:16:16 little endian" ) \
2331 X(WL_SHM_FORMAT_Y0L0 , 8 , "[63:0] A3:A2:Y3:0:Cr0:0:Y2:0:A1:A0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian" ) \
2332 X(WL_SHM_FORMAT_X0L0 , 8 , "[63:0] X3:X2:Y3:0:Cr0:0:Y2:0:X1:X0:Y1:0:Cb0:0:Y0:0 1:1:8:2:8:2:8:2:1:1:8:2:8:2:8:2 little endian" ) \
2333 X(WL_SHM_FORMAT_Y0L2 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2334 X(WL_SHM_FORMAT_X0L2 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2335 X(WL_SHM_FORMAT_YUV420_8BIT , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2336 X(WL_SHM_FORMAT_YUV420_10BIT , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2337 X(WL_SHM_FORMAT_XRGB8888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2338 X(WL_SHM_FORMAT_XBGR8888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2339 X(WL_SHM_FORMAT_RGBX8888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2340 X(WL_SHM_FORMAT_BGRX8888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2341 X(WL_SHM_FORMAT_RGB888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2342 X(WL_SHM_FORMAT_BGR888_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2343 X(WL_SHM_FORMAT_RGB565_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2344 X(WL_SHM_FORMAT_BGR565_A8 , 8 , "[63:0] X3:X2:Y3:Cr0:Y2:X1:X0:Y1:Cb0:Y0 1:1:10:10:10:1:1:10:10:10 little endian" ) \
2345 X(WL_SHM_FORMAT_NV24 , 0 , "[UNKNOWN SIZE] non-subsampled Cr:Cb plane" ) \
2346 X(WL_SHM_FORMAT_NV42 , 0 , "[UNKNOWN SIZE] non-subsampled Cb:Cr plane" ) \
2347 X(WL_SHM_FORMAT_P210 , 0 , "[UNKNOWN SIZE] 2x1 subsampled Cr:Cb plane, 10 bits per channel" ) \
2348 X(WL_SHM_FORMAT_P010 , 0 , "[UNKNOWN SIZE] 2x2 subsampled Cr:Cb plane, 10 bits per channel" ) \
2349 X(WL_SHM_FORMAT_P012 , 0 , "[UNKNOWN SIZE] 2x2 subsampled Cr:Cb plane, 12 bits per channel" ) \
2350 X(WL_SHM_FORMAT_P016 , 0 , "[UNKNOWN SIZE] 2x2 subsampled Cr:Cb plane, 16 bits per channel" ) \
2358 #define ZAKERO_YETANI__OUTPUT_SUBPIXEL \
2359 X(WL_OUTPUT_SUBPIXEL_UNKNOWN , "Unkown Geometry" ) \
2360 X(WL_OUTPUT_SUBPIXEL_NONE , "No Geometry" ) \
2361 X(WL_OUTPUT_SUBPIXEL_HORIZONTAL_RGB , "Horizontal RGB" ) \
2362 X(WL_OUTPUT_SUBPIXEL_HORIZONTAL_BGR , "Horizontal BGR" ) \
2363 X(WL_OUTPUT_SUBPIXEL_VERTICAL_RGB , "Vertical RGB" ) \
2364 X(WL_OUTPUT_SUBPIXEL_VERTICAL_BGR , "Vertical BGR" ) \
2372 #define ZAKERO_YETANI__OUTPUT_TRANSFORM \
2373 X(WL_OUTPUT_TRANSFORM_NORMAL , "No Transform" ) \
2374 X(WL_OUTPUT_TRANSFORM_90 , "90 degrees Counter-Clockwise" ) \
2375 X(WL_OUTPUT_TRANSFORM_180 , "180 degrees Counter-Clockwise" ) \
2376 X(WL_OUTPUT_TRANSFORM_270 , "270 degrees Counter-Clockwise" ) \
2377 X(WL_OUTPUT_TRANSFORM_FLIPPED , "180 degree flip around a vertical axis" ) \
2378 X(WL_OUTPUT_TRANSFORM_FLIPPED_90 , "Flig and rotate 90 degrees counter-clockwise" ) \
2379 X(WL_OUTPUT_TRANSFORM_FLIPPED_180 , "Flig and rotate 180 degrees counter-clockwise" ) \
2405 #define ZAKERO_YETANI__ARRAY_FOR_EACH(type_, pos_, array_) \
2406 for(type_ pos_ = (type_)(array_)->data \
2407 ; (const char*)pos_ < ((const char*)(array_)->data + (array_)->size) \
2571 class YetaniErrorCategory_
2572 :
public std::error_category
2575 constexpr YetaniErrorCategory_() noexcept
2579 const char* name()
const noexcept
override
2581 return "zakero.Yetani";
2584 std::string message(
int condition)
const override
2588 #define X(name_, val_, mesg_) \
2589 case val_: return mesg_;
2590 ZAKERO_YETANI__ERROR_DATA
2594 return "Unknown error condition";
2596 } YetaniErrorCategory;
2604 Yetani::LambdaKey LambdaKey_DoNothing = [](
const Yetani::Key&,
const Yetani::KeyModifier&) noexcept {};
2605 Yetani::LambdaAxis LambdaAxis_DoNothing = [](
const Yetani::PointerAxis&,
const Yetani::KeyModifier&) noexcept {};
2606 Yetani::LambdaButtonMm LambdaButtonMm_DoNothing = [](
const Yetani::PointerButton&,
const Yetani::PointMm&,
const Yetani::KeyModifier&) noexcept {};
2607 Yetani::LambdaButtonPercent LambdaButtonPercent_DoNothing = [](
const Yetani::PointerButton&,
const Yetani::PointPercent&,
const Yetani::KeyModifier&) noexcept {};
2608 Yetani::LambdaButtonPixel LambdaButtonPixel_DoNothing = [](
const Yetani::PointerButton&,
const Yetani::PointPixel&,
const Yetani::KeyModifier&) noexcept {};
2609 Yetani::LambdaPointMm LambdaPointMm_DoNothing = [](
const Yetani::PointMm&,
const Yetani::KeyModifier&) noexcept {};
2610 Yetani::LambdaPointPercent LambdaPointPercent_DoNothing = [](
const Yetani::PointPercent&,
const Yetani::KeyModifier&) noexcept {};
2611 Yetani::LambdaPointPixel LambdaPointPixel_DoNothing = [](
const Yetani::PointPixel&,
const Yetani::KeyModifier&) noexcept {};
2613 Yetani::LambdaOutputId LambdaOutputId_DoNothing = [](
const Yetani::OutputId) noexcept {};
2635 bool equalish(
const float a
2640 return (std::abs(a - b) < delta);
2656 inline size_t sizeInBytes(
const Yetani::SizePixel& size
2657 ,
const wl_shm_format format
2682 std::error_code validateMinMax(
const Type& min
2692 return ZAKERO_YETANI__ERROR(Yetani::Error_Window_Size_Too_Small);
2697 && (min.width > max.width)
2700 return ZAKERO_YETANI__ERROR(Yetani::Error_Minimum_Size_Greater_Than_Maximum_Size);
2705 && (min.height > max.height)
2708 return ZAKERO_YETANI__ERROR(Yetani::Error_Minimum_Size_Greater_Than_Maximum_Size);
2711 return ZAKERO_YETANI__ERROR(Yetani::Error_None);
3087 struct wl_buffer_listener Yetani::buffer_listener =
3088 { .release = &Yetani::handlerBufferRelease
3091 struct wl_callback_listener Yetani::frame_callback_listener =
3092 { .done = &Yetani::handlerSwapBuffers
3095 struct wl_keyboard_listener Yetani::keyboard_listener =
3096 { .keymap = &Yetani::handlerKeyboardKeymap
3097 , .enter = &Yetani::handlerKeyboardEnter
3098 , .leave = &Yetani::handlerKeyboardLeave
3099 , .key = &Yetani::handlerKeyboardKey
3100 , .modifiers = &Yetani::handlerKeyboardModifiers
3101 , .repeat_info = &Yetani::handlerKeyboardRepeatInfo
3104 struct wl_output_listener Yetani::output_listener =
3105 { .geometry = &Yetani::handlerOutputGeometry
3106 , .mode = &Yetani::handlerOutputMode
3107 , .done = &Yetani::handlerOutputDone
3108 , .scale = &Yetani::handlerOutputScale
3111 struct wl_pointer_listener Yetani::pointer_listener =
3112 { .enter = &Yetani::handlerPointerEnter
3113 , .leave = &Yetani::handlerPointerLeave
3114 , .motion = &Yetani::handlerPointerMotion
3115 , .button = &Yetani::handlerPointerButton
3116 , .axis = &Yetani::handlerPointerAxis
3117 , .frame = &Yetani::handlerPointerFrame
3118 , .axis_source = &Yetani::handlerPointerAxisSource
3119 , .axis_stop = &Yetani::handlerPointerAxisStop
3120 , .axis_discrete = &Yetani::handlerPointerAxisDiscrete
3123 struct wl_registry_listener Yetani::registry_listener =
3124 { .global = &Yetani::handlerRegistryGlobal
3125 , .global_remove = &Yetani::handlerRegistryRemove
3128 struct wl_seat_listener Yetani::seat_listener =
3129 { .capabilities = &Yetani::handlerSeatCapabilities
3130 , .name = &Yetani::handlerSeatName
3133 struct wl_shm_listener Yetani::shm_listener =
3134 { .format = &Yetani::handlerShmFormat
3137 struct wl_surface_listener Yetani::surface_listener =
3138 { .enter = &Yetani::handlerSurfaceEnter
3139 , .leave = &Yetani::handlerSurfaceLeave
3147 struct xdg_wm_base_listener Yetani::xdg_wm_base_listener =
3148 { .ping = &Yetani::handlerXdgWmBasePing
3151 struct xdg_surface_listener Yetani::xdg_surface_listener =
3152 { .configure = &Yetani::handlerXdgSurfaceConfigure
3155 struct xdg_toplevel_listener Yetani::xdg_toplevel_listener =
3156 { .configure = &Yetani::handlerXdgToplevelConfigure
3157 , .close = &Yetani::handlerXdgToplevelClose
3163 struct zxdg_toplevel_decoration_v1_listener Yetani::xdg_toplevel_decoration_listener =
3164 { .configure = &Yetani::handlerXdgToplevelDecorationConfigure
3176 Yetani::Yetani() noexcept
3178 , cursor_surface_map()
3179 , cursor_memory_pool(
3180 std::string(
"Zakero.Yetani.")
3184 , cursor_shm_pool(
nullptr)
3185 , cursor_pointer(
nullptr)
3187 , event_loop_is_running(
false)
3188 , compositor(
nullptr)
3192 , shm_format_vector()
3199 , on_output_add(LambdaOutputId_DoNothing)
3200 , on_output_change(LambdaOutputId_DoNothing)
3201 , on_output_remove(LambdaOutputId_DoNothing)
3202 , output_changes_map()
3203 , output_state_map()
3204 , output_notify_surface_vector()
3206 , surface_event_map()
3207 , surface_extent_map()
3208 , surface_extent_mutex()
3209 , surface_frame_map()
3210 , surface_size_map()
3211 , surface_resize_mutex_map()
3213 , window_vector_mutex()
3214 , xdg_state_change_map()
3215 , xdg_state_change_mutex()
3216 , xdg_wm_base(
nullptr)
3218 , xdg_toplevel_map()
3219 , xdg_decoration_map()
3220 , decoration_manager(
nullptr)
3236 if(event_loop_is_running || event_loop.joinable())
3238 event_loop.request_stop();
3272 std::error_code error;
3305 std::error_code error;
3374 , std::error_code& error
3379 const char* display_name =
nullptr;
3381 if(display.empty() ==
false)
3383 display_name = display.c_str();
3387 yetani->display = wl_display_connect(display_name);
3388 if(yetani->display ==
nullptr)
3392 const char* session = getenv(
"XDG_SESSION_TYPE");
3394 if(session !=
nullptr
3395 && strcasecmp(session,
"wayland") != 0
3398 error = ZAKERO_YETANI__ERROR(Error_Wayland_Not_Available);
3400 else if(display.empty())
3402 error = ZAKERO_YETANI__ERROR(Error_Connection_Failed);
3406 error = ZAKERO_YETANI__ERROR(Error_Invalid_Display_Name);
3413 yetani->registry = wl_display_get_registry(yetani->display);
3414 if(yetani->registry ==
nullptr)
3418 error = ZAKERO_YETANI__ERROR(Error_Registry_Not_Available);
3423 wl_registry_add_listener(yetani->registry, ®istry_listener, yetani);
3426 wl_display_dispatch(yetani->display);
3427 wl_display_roundtrip(yetani->display);
3430 if(yetani->compositor ==
nullptr)
3434 error = ZAKERO_YETANI__ERROR(Error_Compositor_Was_Not_Found);
3439 if(yetani->shm ==
nullptr)
3443 error = ZAKERO_YETANI__ERROR(Error_Shm_Was_Not_Found);
3448 if(yetani->xdg_wm_base ==
nullptr)
3452 error = ZAKERO_YETANI__ERROR(Error_Xdg_WM_Base_Was_Not_Found);
3457 yetani->cursorSetup();
3459 yetani->eventLoopStart();
3461 error = ZAKERO_YETANI__ERROR(Error_None);
3476 void Yetani::disconnect() noexcept
3480 if(decoration_manager !=
nullptr)
3482 zxdg_decoration_manager_v1_destroy(decoration_manager);
3483 decoration_manager =
nullptr;
3486 if(xdg_wm_base !=
nullptr)
3488 xdg_wm_base_destroy(xdg_wm_base);
3489 xdg_wm_base =
nullptr;
3494 wl_shm_destroy(shm);
3501 while(seat_map.empty() ==
false)
3503 auto iter = std::begin(seat_map);
3505 struct wl_seat* wl_seat = iter->first;
3507 seatDestroy(wl_seat);
3512 std::lock_guard<std::mutex> lock(output_data.mutex);
3514 for(
auto& iter : output_data.output_map)
3516 struct wl_output* wayland_output = iter.first;
3518 wl_output_destroy(wayland_output);
3521 output_changes_map.clear();
3522 output_state_map.clear();
3523 output_data.output_map.clear();
3524 output_data.wloutput_to_outputid.clear();
3525 output_data.outputid_to_wloutput.clear();
3528 if(registry !=
nullptr)
3530 wl_registry_destroy(registry);
3534 if(compositor !=
nullptr)
3536 wl_compositor_destroy(compositor);
3537 compositor =
nullptr;
3540 if(display !=
nullptr)
3542 wl_display_disconnect(display);
3684 void Yetani::cursorAnimate() noexcept
3688 std::lock_guard<std::mutex> lock(cursor_mutex);
3690 for(
auto& iter : cursor_map)
3692 Yetani::Cursor& cursor = iter.second;
3694 if(cursor.next_frame_time <= time_now)
3696 const int64_t time_over = time_now - cursor.next_frame_time;
3697 cursor.next_frame_time = time_now + cursor.time_per_frame - time_over;
3699 cursor.buffer_index = (cursor.buffer_index + 1) % cursor.buffer_vector.size();
3701 wl_surface_attach(cursor.wl_surface, cursor.buffer_vector[cursor.buffer_index], 0, 0);
3702 wl_surface_damage(cursor.wl_surface
3704 , cursor.width, cursor.height
3707 wl_surface_commit(cursor.wl_surface);
3759 return ZAKERO_YETANI__ERROR(Error_Cursor_Name_Is_Invalid);
3762 if(cursor_map.contains(name) ==
true)
3764 return ZAKERO_YETANI__ERROR(Error_Cursor_Already_Exists);
3767 if(config.size.width <= 0 || config.size.height <= 0)
3769 return ZAKERO_YETANI__ERROR(Error_Cursor_Size_Too_Small);
3772 if(config.image_data.empty())
3774 return ZAKERO_YETANI__ERROR(Error_Cursor_Image_Data_Is_Empty);
3776 else if(config.image_data.size() > 1)
3778 if(config.time_per_frame.count() <= 0)
3780 return ZAKERO_YETANI__ERROR(Error_Cursor_Frame_Time_Too_Small);
3783 if(config.time_per_frame.count() > Size_Max)
3785 return ZAKERO_YETANI__ERROR(Error_Cursor_Frame_Time_Too_Large);
3789 std::error_code error = cursorCreateCursor(name, config);
3805 std::error_code Yetani::cursorCreateCursor(
const std::string& cursor_name
3809 const uint8_t bytes_per_pixel = shmFormatBytesPerPixel(cursor_config.format);
3810 const size_t frame_count = cursor_config.image_data.size();
3812 Yetani::Cursor cursor =
3813 { .wl_surface = wl_compositor_create_surface(compositor)
3814 , .buffer_vector = { frame_count,
nullptr }
3815 , .format = cursor_config.format
3818 , .time_per_frame = uint32_t(cursor_config.time_per_frame.count())
3819 , .width = cursor_config.size.width
3820 , .height = cursor_config.size.height
3821 , .hotspot_x = cursor_config.hotspot_x
3822 , .hotspot_y = cursor_config.hotspot_y
3825 if(cursor.time_per_frame == 0)
3827 cursor.time_per_frame = Size_Max;
3830 const int stride = cursor.width * bytes_per_pixel;
3831 const size_t image_size = stride * cursor.height;
3833 for(
size_t i = 0; i < frame_count; i++)
3835 std::error_code error;
3837 off_t offset = cursor_memory_pool.alloc(image_size, error);
3844 struct wl_buffer* buffer = cursor.buffer_vector[i];
3845 cursor.buffer_vector[i] =
nullptr;
3847 off_t offset = (off_t)wl_buffer_get_user_data(buffer);
3848 wl_buffer_destroy(buffer);
3850 cursor_memory_pool.free(offset);
3856 uint32_t* p = (uint32_t*)cursor_memory_pool.addressOf(offset);
3857 memcpy(p, (uint8_t*)cursor_config.image_data[i], image_size);
3859 cursor.buffer_vector[i] = wl_shm_pool_create_buffer(cursor_shm_pool
3867 wl_buffer_set_user_data(cursor.buffer_vector[i], (
void*)offset);
3870 wl_surface_attach(cursor.wl_surface, cursor.buffer_vector[0], 0, 0);
3871 wl_surface_commit(cursor.wl_surface);
3873 std::lock_guard<std::mutex> lock(cursor_mutex);
3875 cursor_map[cursor_name] = cursor;
3877 return ZAKERO_YETANI__ERROR(Error_None);
3894 Yetani::Cursor cursor;
3897 std::lock_guard<std::mutex> lock(cursor_mutex);
3899 if(cursor_map.contains(name) ==
false)
3901 return ZAKERO_YETANI__ERROR(Error_Cursor_Does_Not_Exist);
3904 cursor = cursor_map[name];
3906 cursor_map.erase(name);
3909 auto iter = std::begin(cursor_surface_map);
3910 auto iter_end = std::end(cursor_surface_map);
3911 while(iter != iter_end)
3913 if(cursor.wl_surface == iter->second.wl_surface)
3915 iter = cursor_surface_map.erase(iter);
3923 if(cursor.wl_surface)
3925 wl_surface_destroy(cursor.wl_surface);
3926 cursor.wl_surface =
nullptr;
3929 for(wl_buffer* buffer : cursor.buffer_vector)
3931 off_t offset = (off_t)wl_buffer_get_user_data(buffer);
3932 wl_buffer_destroy(buffer);
3934 cursor_memory_pool.free(offset);
3937 return ZAKERO_YETANI__ERROR(Error_None);
3949 void Yetani::cursorEnter(wl_pointer* wl_pointer
3951 ,
struct wl_surface* wl_surface
3954 std::lock_guard<std::mutex> lock(cursor_mutex);
3956 cursor_pointer = wl_pointer;
3958 if(cursor_surface_map.contains(wl_surface) ==
false)
3963 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
3965 cursor_surface.wl_pointer = wl_pointer;
3966 cursor_surface.serial = serial;
3968 if(cursor_surface.is_visible)
3970 wl_pointer_set_cursor(cursor_surface.wl_pointer
3971 , cursor_surface.serial
3972 , cursor_surface.wl_surface
3973 , cursor_surface.hotspot_x
3974 , cursor_surface.hotspot_y
3979 wl_pointer_set_cursor(cursor_surface.wl_pointer
3980 , cursor_surface.serial
3998 void Yetani::cursorLeave(
struct wl_surface* wl_surface
4001 std::lock_guard<std::mutex> lock(cursor_mutex);
4003 cursor_pointer =
nullptr;
4005 if(cursor_surface_map.contains(wl_surface) ==
false)
4010 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
4012 cursor_surface.wl_pointer =
nullptr;
4013 cursor_surface.serial = 0;
4024 void Yetani::cursorHide(
struct wl_surface* wl_surface
4027 std::lock_guard<std::mutex> lock(cursor_mutex);
4029 if(cursor_surface_map.contains(wl_surface) ==
false)
4034 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
4036 cursor_surface.is_visible =
false;
4038 if(cursor_surface.wl_pointer !=
nullptr)
4040 wl_pointer_set_cursor(cursor_surface.wl_pointer
4041 , cursor_surface.serial
4057 void Yetani::cursorShow(
struct wl_surface* wl_surface
4060 std::lock_guard<std::mutex> lock(cursor_mutex);
4062 if(cursor_surface_map.contains(wl_surface) ==
false)
4067 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
4069 cursor_surface.is_visible =
true;
4071 if(cursor_surface.wl_pointer !=
nullptr)
4073 wl_pointer_set_cursor(cursor_surface.wl_pointer
4074 , cursor_surface.serial
4075 , cursor_surface.wl_surface
4076 , cursor_surface.hotspot_x
4077 , cursor_surface.hotspot_y
4093 bool Yetani::cursorIsHidden(
struct wl_surface* wl_surface
4096 std::lock_guard<std::mutex> lock(cursor_mutex);
4098 if(cursor_surface_map.contains(wl_surface) ==
false)
4103 const Yetani::CursorSurface& cursor_surface = cursor_surface_map.at(wl_surface);
4105 return !(cursor_surface.is_visible);
4116 void Yetani::cursorSetup() noexcept
4120 uint64_t bytes =
zakero::convert((uint64_t)4, zakero::Storage::Kilobyte, zakero::Storage::Byte);
4121 cursor_memory_pool.
init(bytes,
true, zakero::MemoryPool::Alignment::Bits_32);
4125 wl_shm_pool_resize(cursor_shm_pool, new_size);
4128 cursor_shm_pool = wl_shm_create_pool(shm, cursor_memory_pool.
fd(), cursor_memory_pool.
size());
4139 void Yetani::cursorTeardown() noexcept
4141 while(cursor_map.empty() ==
false)
4143 const auto& iter = cursor_map.begin();
4145 const std::string& name = iter->first;
4150 if(cursor_shm_pool !=
nullptr)
4152 wl_shm_pool_destroy(cursor_shm_pool);
4168 std::error_code Yetani::cursorAttach(
const std::string& cursor_name
4169 ,
struct wl_surface* wl_surface
4172 std::lock_guard<std::mutex> lock(cursor_mutex);
4174 if(cursor_map.contains(cursor_name) ==
false)
4176 return ZAKERO_YETANI__ERROR(Error_Cursor_Does_Not_Exist);
4179 if(cursor_surface_map.contains(wl_surface) ==
false)
4181 cursor_surface_map[wl_surface] =
4182 { .wl_pointer = cursor_pointer
4183 , .wl_surface = nullptr
4187 , .is_visible =
true
4191 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
4192 Yetani::Cursor& cursor = cursor_map[cursor_name];
4194 cursor_surface.wl_surface = cursor.wl_surface;
4195 cursor_surface.hotspot_x = cursor.hotspot_x;
4196 cursor_surface.hotspot_y = cursor.hotspot_y;
4198 if(cursor_surface.wl_pointer !=
nullptr)
4200 if(cursor_surface.is_visible)
4202 wl_pointer_set_cursor(cursor_surface.wl_pointer
4203 , cursor_surface.serial
4204 , cursor_surface.wl_surface
4205 , cursor_surface.hotspot_x
4206 , cursor_surface.hotspot_y
4211 wl_pointer_set_cursor(cursor_surface.wl_pointer
4212 , cursor_surface.serial
4220 return ZAKERO_YETANI__ERROR(Error_None);
4235 std::error_code Yetani::cursorDetach(
struct wl_surface* wl_surface
4238 std::lock_guard<std::mutex> lock(cursor_mutex);
4240 if(cursor_surface_map.contains(wl_surface) ==
false)
4242 return ZAKERO_YETANI__ERROR(Error_Cursor_Not_Attached);
4245 Yetani::CursorSurface& cursor_surface = cursor_surface_map[wl_surface];
4247 if(cursor_surface.wl_pointer !=
nullptr)
4249 wl_pointer_set_cursor(cursor_surface.wl_pointer
4250 , cursor_surface.serial
4257 cursor_surface_map.erase(wl_surface);
4259 return ZAKERO_YETANI__ERROR(Error_None);
4275 void Yetani::eventLoopStart() noexcept
4277 event_loop = std::jthread(&Yetani::eventLoop,
this);
4279 while(event_loop_is_running.load() ==
false)
4282 std::this_thread::sleep_for(std::chrono::nanoseconds(42));
4285 #ifdef ZAKERO_YETANI__ENABLE_THREAD_SCHEDULER
4286 int policy = SCHED_FIFO;
4287 int priority_min = sched_get_priority_min(policy);
4288 int priority_max = sched_get_priority_max(policy);
4291 { .sched_priority = (priority_min + priority_max) / 2
4294 pthread_setschedparam(event_loop.native_handle(), policy, &sched);
4326 void Yetani::eventLoop(std::stop_token thread_token
4330 struct pollfd fd_status =
4331 { .fd = wl_display_get_fd(yetani->display)
4332 , .events = POLLIN | POLLOUT
4336 yetani->event_loop_is_running.store(
true);
4339 while(thread_token.stop_requested() ==
false)
4341 poll(&fd_status, 1, 1);
4343 if(fd_status.revents & POLLIN)
4345 wl_display_dispatch(yetani->display);
4348 yetani->cursorAnimate();
4350 keyboardRepeat(yetani->keyboard);
4352 if(fd_status.revents & POLLOUT)
4354 wl_display_flush(yetani->display);
4357 #ifdef ZAKERO_YETANI__ENABLE_THREAD_SCHEDULER
4358 std::this_thread::yield();
4362 yetani->event_loop_is_running.store(
false);
4380 return shm_format_vector;
4400 #define X(value_, bytes_, desc_) \
4401 case value_: return bytes_;
4402 ZAKERO_YETANI__SHM_FORMAT
4425 #define X(value_, bytes_, desc_) \
4426 case value_: return desc_;
4427 ZAKERO_YETANI__SHM_FORMAT
4448 #define X(value_, bytes_, desc_) \
4449 case value_: return #value_;
4450 ZAKERO_YETANI__SHM_FORMAT
4503 struct wl_buffer* Yetani::bufferCreate(Yetani::SurfaceSize& surface_size
4505 , Yetani::Buffer* buffer
4508 off_t offset = window_memory->memory_pool.alloc(surface_size.in_bytes);
4510 struct wl_buffer* wl_buffer = wl_shm_pool_create_buffer(window_memory->wl_shm_pool
4512 , surface_size.width
4513 , surface_size.height
4514 , surface_size.stride
4515 , surface_size.pixel_format
4518 wl_buffer_set_user_data(wl_buffer, buffer);
4520 buffer->mutex.lock();
4522 buffer->map[wl_buffer] =
4523 { .memory_pool = &window_memory->memory_pool
4527 buffer->mutex.unlock();
4544 struct wl_buffer* Yetani::bufferCreateAndRelease(Yetani* yetani
4545 , Yetani::SurfaceSize& surface_size
4546 , Yetani::Window::Memory* window_memory
4549 struct wl_buffer* wl_buffer = bufferCreate(surface_size, window_memory, &yetani->buffer);
4551 wl_buffer_add_listener(wl_buffer
4552 , &Yetani::buffer_listener
4569 void Yetani::bufferDestroy(
struct wl_buffer*& wl_buffer
4572 Yetani::Buffer* buffer = (Yetani::Buffer*)wl_buffer_get_user_data(wl_buffer);
4574 wl_buffer_destroy(wl_buffer);
4576 buffer->mutex.lock();
4578 BufferData& buffer_data = buffer->map[wl_buffer];
4580 buffer_data.memory_pool->free(buffer_data.offset);
4582 buffer->map.erase(wl_buffer);
4584 buffer->mutex.unlock();
4586 wl_buffer =
nullptr;
4690 std::lock_guard<std::mutex> lock(output_data.mutex);
4692 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4694 ZAKERO_YETANI__DEBUG
4695 <<
"Invalid output_id: "
4696 << std::to_string(output_id)
4702 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4704 return output_data.output_map.at(wl_output);
4721 Yetani::VectorOutputId vector;
4723 std::lock_guard<std::mutex> lock(output_data.mutex);
4725 for(
const auto& iter : output_data.outputid_to_wloutput)
4727 vector.push_back(iter.first);
4748 switch(subpixel_format)
4750 #define X(value_, name_) \
4751 case value_: return name_;
4752 ZAKERO_YETANI__OUTPUT_SUBPIXEL
4775 #define X(value_, name_) \
4776 case value_: return name_;
4777 ZAKERO_YETANI__OUTPUT_TRANSFORM
4798 std::lock_guard<std::mutex> lock(output_data.mutex);
4800 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4802 return { point.time, 0, 0 };
4805 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4806 const Yetani::Output& output = output_data.output_map.at(wl_output);
4808 auto p = convertPixelToMm(output, point.
x, point.y);
4810 return { point.time, p.first, p.second };
4828 std::lock_guard<std::mutex> lock(output_data.mutex);
4830 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4832 return { point.time, 0, 0 };
4835 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4836 const Yetani::Output& output = output_data.output_map.at(wl_output);
4838 auto p = convertPixelToPercent(output, point.
x, point.y);
4840 return { point.time, p.first, p.second };
4858 std::lock_guard<std::mutex> lock(output_data.mutex);
4860 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4862 return { point.time, 0, 0 };
4865 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4866 const Yetani::Output& output = output_data.output_map.at(wl_output);
4868 auto p = convertMmToPixel(output, point.
x, point.y);
4870 return { point.time, p.first, p.second };
4888 std::lock_guard<std::mutex> lock(output_data.mutex);
4890 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4892 return { point.time, 0, 0 };
4895 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4896 const Yetani::Output& output = output_data.output_map.at(wl_output);
4898 auto p = convertPercentToPixel(output, point.
x, point.y);
4900 return { point.time, p.first, p.second };
4918 std::lock_guard<std::mutex> lock(output_data.mutex);
4920 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4925 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4926 const Yetani::Output& output = output_data.output_map.at(wl_output);
4928 auto p = convertPixelToMm(output, size.
width, size.height);
4930 return { p.first, p.second };
4948 std::lock_guard<std::mutex> lock(output_data.mutex);
4950 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4955 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4956 const Yetani::Output& output = output_data.output_map.at(wl_output);
4958 auto p = convertPixelToPercent(output, size.
width, size.height);
4960 return { p.first, p.second };
4977 std::lock_guard<std::mutex> lock(output_data.mutex);
4979 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
4984 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
4985 const Yetani::Output& output = output_data.output_map.at(wl_output);
4987 auto p = convertMmToPixel(output, size.
width, size.height);
4989 return { p.first, p.second };
5006 std::lock_guard<std::mutex> lock(output_data.mutex);
5008 if(output_data.outputid_to_wloutput.contains(output_id) ==
false)
5013 struct wl_output* wl_output = output_data.outputid_to_wloutput.at(output_id);
5014 const Yetani::Output& output = output_data.output_map.at(wl_output);
5016 auto p = convertPercentToPixel(output, size.
width, size.height);
5018 return { p.first, p.second };
5034 if(lambda ==
nullptr)
5036 on_output_add = LambdaOutputId_DoNothing;
5040 on_output_add = lambda;
5057 if(lambda ==
nullptr)
5059 on_output_change = LambdaOutputId_DoNothing;
5063 on_output_change = lambda;
5080 if(lambda ==
nullptr)
5082 on_output_remove = LambdaOutputId_DoNothing;
5086 on_output_remove = lambda;
5099 void Yetani::convertPixel(
struct wl_surface* wl_surface
5100 ,
const int32_t pixel_xw
5101 ,
const int32_t pixel_yh
5108 std::lock_guard<std::mutex> lock(output_data.mutex);
5110 const Yetani::VectorWlOutput& vector = output_data.surface_output_map.at(wl_surface);
5111 struct wl_output* wl_output = vector.front();
5112 const Yetani::Output& output = output_data.output_map.at(wl_output);
5114 auto mm = convertPixelToMm(output, pixel_xw, pixel_yh);
5118 auto pc = convertPixelToPercent(output, pixel_xw, pixel_yh);
5135 std::pair<float, float> Yetani::convertPixelToMm(
const Yetani::Output& output
5161 std::pair<float, float> Yetani::convertPixelToPercent(
const Yetani::Output& output
5167 { float(xw) / output.
width
5168 , float(yh) / output.
height
5184 std::pair<int32_t, int32_t> Yetani::convertMmToPixel(
const Yetani::Output& output
5193 { int32_t(xw * ratio_h)
5194 , int32_t(yh * ratio_v)
5210 std::pair<int32_t, int32_t> Yetani::convertPercentToPixel(
const Yetani::Output& output
5216 { int32_t(xw * output.
width)
5217 , int32_t(yh * output.
height)
5233 void Yetani::outputNotifySurface(Yetani* yetani
5234 ,
struct wl_output* wl_output
5235 ,
struct wl_surface* wl_surface
5238 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
5239 if(surface_extent.preferred_unit == Yetani::SizeUnit::Pixel)
5244 Yetani::OutputData& output_data = yetani->output_data;
5246 std::lock_guard<std::mutex> lock(output_data.mutex);
5248 Yetani::VectorWlOutput& output_vector = output_data.surface_output_map[wl_surface];
5250 struct wl_output* output_current = output_vector.front();
5252 if(output_current != wl_output)
5257 Yetani::Output& output = output_data.output_map.at(wl_output);
5258 Yetani::SizePixel new_size = surface_extent.size_pixel;
5260 if(surface_extent.preferred_unit == Yetani::SizeUnit::Millimeter)
5262 auto p = yetani->convertMmToPixel(output, surface_extent.size_mm.width, surface_extent.size_mm.height);
5263 new_size = { p.first, p.second };
5265 else if(surface_extent.preferred_unit == Yetani::SizeUnit::Percent)
5267 auto p = yetani->convertPercentToPixel(output, surface_extent.size_percent.width, surface_extent.size_percent.height);
5268 new_size = { p.first, p.second };
5271 if(new_size.width <= 0)
5276 if(new_size.height <= 0)
5278 new_size.height = 1;
5281 yetani->surface_resize_mutex_map[wl_surface].lock();
5283 surface_extent.size_pixel = new_size;
5284 surfaceCalculateSize(yetani, wl_surface, new_size);
5286 yetani->surface_resize_mutex_map[wl_surface].unlock();
5324 void Yetani::seatDestroy(
struct wl_seat*& wl_seat
5327 Yetani::Seat& seat = seat_map[wl_seat];
5329 if(seat.wl_keyboard !=
nullptr)
5331 wl_keyboard_release(seat.wl_keyboard);
5332 seat.wl_keyboard =
nullptr;
5335 if(seat.wl_pointer !=
nullptr)
5337 wl_pointer_release(seat.wl_pointer);
5338 seat.wl_pointer =
nullptr;
5341 if(seat.wl_touch !=
nullptr)
5343 wl_touch_release(seat.wl_touch);
5344 seat.wl_touch =
nullptr;
5347 seat_map.erase(wl_seat);
5349 wl_seat_release(wl_seat);
5432 return keyboard.repeat_delay;
5446 return 1000 / keyboard.repeat_rate;
5453 void Yetani::keyboardDestroy(Yetani::Keyboard& keyboard
5456 if(keyboard.keymap !=
nullptr)
5458 munmap(keyboard.keymap, keyboard.keymap_size);
5461 keyboard.wl_surface =
nullptr;
5462 keyboard.event =
nullptr;
5463 keyboard.modifier = { 0 };
5464 keyboard.repeat_rate = 0;
5465 keyboard.repeat_delay = {};
5466 keyboard.keymap =
nullptr;
5467 keyboard.keymap_size = 0;
5477 void Yetani::keyboardRepeat(Yetani::Keyboard& keyboard
5480 auto now = std::chrono::steady_clock::now();
5482 for(
auto& iter : keyboard.repeat_map)
5484 Yetani::KeyRepeatData& key_repeat = iter.second;
5486 if(now >= key_repeat.trigger_time)
5488 uint32_t key_code = iter.first;
5491 { .time = key_repeat.base_time
5493 , .state = Yetani::KeyState::Repeat
5496 keyboard.event->on_key(key, keyboard.modifier);
5498 key_repeat.trigger_time = now
5499 + std::chrono::milliseconds(keyboard.repeat_rate)
5500 - (now - key_repeat.trigger_time)
5502 key_repeat.base_time += keyboard.repeat_rate;
5515 void Yetani::keyboardRepeatAdd(Yetani::Keyboard& keyboard
5520 auto trigger_time = std::chrono::steady_clock::now()
5521 + std::chrono::milliseconds(keyboard.repeat_delay)
5524 keyboard.repeat_map[key_code] =
5525 { .trigger_time = trigger_time
5526 , .base_time = time + keyboard.repeat_delay
5537 void Yetani::keyboardRepeatReleaseAll(Yetani::Keyboard& keyboard
5540 while(keyboard.repeat_map.empty() ==
false)
5542 auto iter = keyboard.repeat_map.begin();
5544 uint32_t key_code = iter->first;
5549 , .state = Yetani::KeyState::Released
5552 keyboard.event->on_key(key, keyboard.modifier);
5554 keyboard.repeat_map.erase(iter);
5565 void Yetani::keyboardRepeatRemove(Yetani::Keyboard& keyboard
5569 keyboard.repeat_map.erase(key_code);
5590 void Yetani::pointerClear(Yetani::Pointer& pointer
5593 pointer.enter_surface =
nullptr;
5594 pointer.enter_point = { 0, 0, 0 };
5595 pointer.leave_surface =
nullptr;
5596 pointer.motion_point = { 0, 0, 0 };
5597 pointer.button_event_code = 0;
5598 pointer.button_is_pressed =
false;
5599 pointer.button_time = 0;
5600 pointer.axis.time = 0;
5602 pointer.axis.distance = 0;
5604 pointer.axis.steps = 0;
5647 void Yetani::surfaceCalculateSize(Yetani* yetani
5648 ,
struct wl_surface* wl_surface
5649 ,
const Yetani::SizePixel& size
5652 Yetani::SurfaceSize& surface_size = yetani->surface_size_map[wl_surface];
5653 surface_size.width = size.width;
5654 surface_size.height = size.height;
5655 surface_size.stride = size.width * surface_size.bytes_per_pixel;
5656 surface_size.in_bytes = surface_size.stride * surface_size.height;
5658 Yetani::SurfaceFrame& surface_frame = yetani->surface_frame_map[wl_surface];
5659 surface_frame.width = size.width;
5660 surface_frame.height = size.height;
5671 struct wl_surface* Yetani::surfaceCreate(Yetani* yetani
5672 ,
const wl_shm_format pixel_format
5673 ,
const Yetani::SizePixel& size
5674 ,
const bool attach_buffer
5675 , Yetani::Window::Memory& window_memory
5678 struct wl_surface* wl_surface = wl_compositor_create_surface(yetani->compositor);
5680 Yetani::SurfaceSize& surface_size = yetani->surface_size_map[wl_surface];
5681 surface_size.pixel_format = pixel_format;
5682 surface_size.bytes_per_pixel = shmFormatBytesPerPixel(pixel_format);
5684 Yetani::SurfaceFrame& surface_frame = yetani->surface_frame_map[wl_surface];
5685 surface_frame.callback =
nullptr;
5686 surface_frame.wl_surface = wl_surface;
5687 surface_frame.time_ms = 0;
5689 surfaceCalculateSize(yetani, wl_surface, size);
5691 surface_frame.buffer_next = bufferCreateAndRelease(yetani, surface_size, &window_memory);
5695 wl_surface_attach(surface_frame.wl_surface, surface_frame.buffer_next, 0, 0);
5697 surface_frame.callback = wl_surface_frame(wl_surface);
5699 wl_callback_add_listener(surface_frame.callback
5700 , &frame_callback_listener
5704 wl_surface_commit(wl_surface);
5708 bool event_keyboard =
true;
5711 yetani->keyboard.event_map[wl_surface] =
5712 { .on_enter = Lambda_DoNothing
5713 , .on_leave = Lambda_DoNothing
5714 , .on_key = LambdaKey_DoNothing
5719 bool event_pointer =
true;
5722 yetani->pointer.event_map[wl_surface] =
5723 { .on_axis = LambdaAxis_DoNothing
5724 , .on_axis_discrete = Lambda_DoNothing
5725 , .on_axis_source = Lambda_DoNothing
5726 , .on_axis_stop = Lambda_DoNothing
5727 , .on_button_mm = LambdaButtonMm_DoNothing
5728 , .on_button_percent = LambdaButtonPercent_DoNothing
5729 , .on_button_pixel = LambdaButtonPixel_DoNothing
5730 , .on_enter_mm = LambdaPointMm_DoNothing
5731 , .on_enter_percent = LambdaPointPercent_DoNothing
5732 , .on_enter_pixel = LambdaPointPixel_DoNothing
5733 , .on_leave = Lambda_DoNothing
5734 , .on_motion_mm = LambdaPointMm_DoNothing
5735 , .on_motion_percent = LambdaPointPercent_DoNothing
5736 , .on_motion_pixel = LambdaPointPixel_DoNothing
5740 yetani->surface_event_map[wl_surface] =
5741 { .on_size_mm_change = LambdaSizeMm_DoNothing
5742 , .on_size_percent_change = LambdaSizePercent_DoNothing
5743 , .on_size_pixel_change = LambdaSizePixel_DoNothing
5746 wl_surface_add_listener(wl_surface
5760 void Yetani::surfaceDestroy(Yetani* yetani
5761 ,
struct wl_surface*& wl_surface
5764 if(wl_surface ==
nullptr)
5769 if(yetani->surface_frame_map.contains(wl_surface))
5771 Yetani::SurfaceFrame& surface_frame = yetani->surface_frame_map[wl_surface];
5773 if(surface_frame.callback !=
nullptr)
5775 wl_callback_destroy(surface_frame.callback);
5776 surface_frame.callback =
nullptr;
5779 struct wl_buffer* wl_buffer =
nullptr;
5780 wl_buffer = surface_frame.buffer_next.exchange(
nullptr);
5782 if(wl_buffer !=
nullptr)
5784 bufferDestroy(wl_buffer);
5788 if(yetani->keyboard.event_map.contains(wl_surface))
5790 yetani->keyboard.event_map.erase(wl_surface);
5793 if(yetani->pointer.event_map.contains(wl_surface))
5795 yetani->pointer.event_map.erase(wl_surface);
5798 yetani->surface_size_map.erase(wl_surface);
5799 yetani->surface_frame_map.erase(wl_surface);
5800 yetani->surface_event_map.erase(wl_surface);
5802 yetani->cursorDetach(wl_surface);
5804 wl_surface_destroy(wl_surface);
5805 wl_surface =
nullptr;
5823 void Yetani::handlerBufferRelease(
void*
5824 ,
struct wl_buffer* wl_buffer
5827 Yetani::bufferDestroy(wl_buffer);
5836 void Yetani::handlerKeyboardEnter(
void* data
5837 ,
struct wl_keyboard*
5839 ,
struct wl_surface* wl_surface
5840 ,
struct wl_array* key_array
5843 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
5845 if(keyboard.wl_surface !=
nullptr)
5847 keyboardRepeatReleaseAll(keyboard);
5849 keyboard.event->on_leave();
5852 keyboard.wl_surface = wl_surface;
5854 if(keyboard.event_map.contains(wl_surface))
5856 keyboard.event = &(keyboard.event_map[wl_surface]);
5860 keyboard.event = &(keyboard.event_map[
nullptr]);
5863 keyboard.event->on_enter();
5865 if(key_array->size > 0)
5870 , .state = Yetani::KeyState::Pressed
5873 ZAKERO_YETANI__ARRAY_FOR_EACH(uint32_t*, key_iter, key_array)
5875 key.code = *key_iter;
5877 keyboard.event->on_key(key, keyboard.modifier);
5879 keyboardRepeatAdd(keyboard, key.code, 0);
5888 void Yetani::handlerKeyboardKey(
void* data
5889 ,
struct wl_keyboard*
5896 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
5901 , .state = (state == WL_KEYBOARD_KEY_STATE_PRESSED)
5902 ? Yetani::KeyState::Pressed
5903 : Yetani::KeyState::Released
5906 keyboard.event->on_key(key, keyboard.modifier);
5908 if(key.state == Yetani::KeyState::Pressed
5909 && keyboard.repeat_rate > 0
5912 keyboardRepeatAdd(keyboard, key_code, time);
5914 else if(key.state == Yetani::KeyState::Released)
5916 keyboardRepeatRemove(keyboard, key_code);
5924 void Yetani::handlerKeyboardKeymap(
void* data
5925 ,
struct wl_keyboard*
5931 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
5933 if(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
5935 if(keyboard.keymap !=
nullptr)
5937 munmap(keyboard.keymap
5938 , keyboard.keymap_size
5942 keyboard.keymap = (
char*)mmap(
nullptr
5945 , MAP_NORESERVE | MAP_PRIVATE
5949 keyboard.keymap_size = size;
5953 if(keyboard.keymap !=
nullptr)
5955 munmap(keyboard.keymap
5956 , keyboard.keymap_size
5959 keyboard.keymap =
nullptr;
5960 keyboard.keymap_size = 0;
5969 void Yetani::handlerKeyboardLeave(
void* data
5970 ,
struct wl_keyboard*
5972 ,
struct wl_surface* wl_surface
5975 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
5977 if(keyboard.wl_surface == wl_surface)
5979 keyboardRepeatReleaseAll(keyboard);
5981 keyboard.event->on_leave();
5983 keyboard.event = &(keyboard.event_map[
nullptr]);
5984 keyboard.wl_surface =
nullptr;
5992 void Yetani::handlerKeyboardModifiers(
void* data
5993 ,
struct wl_keyboard*
5995 , uint32_t mods_pressed
5996 , uint32_t mods_latched
5997 , uint32_t mods_locked
6001 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
6003 keyboard.modifier.pressed = mods_pressed;
6004 keyboard.modifier.latched = mods_latched;
6005 keyboard.modifier.locked = mods_locked;
6006 keyboard.modifier.group = group;
6013 void Yetani::handlerKeyboardRepeatInfo(
void* data
6014 ,
struct wl_keyboard*
6019 Yetani::Keyboard& keyboard = *((Yetani::Keyboard*)data);
6021 keyboard.repeat_delay = delay;
6022 keyboard.repeat_rate = 1000 / rate;
6031 void Yetani::handlerOutputDone(
void* data
6032 ,
struct wl_output* wl_output
6035 Yetani* yetani = (Yetani*)data;
6036 Yetani::Output& output = yetani->output_data.output_map[wl_output];
6037 Yetani::Output& changes = yetani->output_changes_map[wl_output];
6038 Yetani::OutputId output_id = yetani->output_data.wloutput_to_outputid[wl_output];
6068 output.pixels_per_mm_horizontal = output.width / float(output.physical_width_mm);
6069 output.pixels_per_mm_vertical = output.height / float(output.physical_height_mm);
6071 ZAKERO_YETANI__DEBUG <<
"\n" <<
to_string(output) <<
"\n";
6073 switch(yetani->output_state_map[wl_output])
6075 case Yetani::OutputState::Done:
6079 case Yetani::OutputState::Added:
6080 yetani->on_output_add(output_id);
6083 case Yetani::OutputState::Changed:
6084 yetani->on_output_change(output_id);
6086 for(
auto wl_surface : yetani->output_notify_surface_vector)
6088 outputNotifySurface(yetani, wl_output, wl_surface);
6094 yetani->output_state_map[wl_output] = Yetani::OutputState::Done;
6101 void Yetani::handlerOutputGeometry(
void* data
6102 ,
struct wl_output* wl_output
6105 , int32_t physical_width
6106 , int32_t physical_height
6113 Yetani* yetani = (Yetani*)data;
6114 Yetani::Output& output_changes = yetani->output_changes_map[wl_output];
6116 if(yetani->output_state_map[wl_output] != Yetani::OutputState::Added)
6118 yetani->output_state_map[wl_output] = Yetani::OutputState::Changed;
6121 output_changes.x = x;
6122 output_changes.y = y;
6123 output_changes.physical_width_mm = physical_width;
6124 output_changes.physical_height_mm = physical_height;
6125 output_changes.subpixel = subpixel;
6126 output_changes.make = std::string(make);
6127 output_changes.model = std::string(model);
6128 output_changes.transform = transform;
6135 void Yetani::handlerOutputMode(
void* data
6136 ,
struct wl_output* wl_output
6143 Yetani* yetani = (Yetani*)data;
6144 Yetani::Output& output_changes = yetani->output_changes_map[wl_output];
6146 if(yetani->output_state_map[wl_output] != Yetani::OutputState::Added)
6148 yetani->output_state_map[wl_output] = Yetani::OutputState::Changed;
6151 output_changes.flags = flags;
6152 output_changes.width = width;
6153 output_changes.height = height;
6154 output_changes.refresh_mHz = refresh;
6161 void Yetani::handlerOutputScale(
void* data
6162 ,
struct wl_output* wl_output
6166 Yetani* yetani = (Yetani*)data;
6167 Output& output_changes = yetani->output_changes_map[wl_output];
6169 if(yetani->output_state_map[wl_output] != Yetani::OutputState::Added)
6171 yetani->output_state_map[wl_output] = Yetani::OutputState::Changed;
6174 output_changes.scale_factor = factor;
6183 void Yetani::handlerPointerAxis(
void* data
6184 ,
struct wl_pointer*
6190 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6192 pointer.axis.time = time;
6193 pointer.axis.distance = (float)wl_fixed_to_double(value);
6195 if(axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL)
6197 pointer.axis.type = Yetani::PointerAxisType::Horizontal;
6199 else if(axis == WL_POINTER_AXIS_VERTICAL_SCROLL)
6201 pointer.axis.type = Yetani::PointerAxisType::Vertical;
6213 void Yetani::handlerPointerAxisDiscrete(
void* data
6214 ,
struct wl_pointer*
6219 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6221 pointer.axis.steps = discrete;
6228 void Yetani::handlerPointerAxisSource(
void* data
6229 ,
struct wl_pointer*
6230 , uint32_t axis_source
6233 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6237 case WL_POINTER_AXIS_SOURCE_WHEEL:
6238 pointer.axis.source = Yetani::PointerAxisSource::Wheel;
6241 case WL_POINTER_AXIS_SOURCE_FINGER:
6242 pointer.axis.source = Yetani::PointerAxisSource::Finger;
6245 case WL_POINTER_AXIS_SOURCE_CONTINUOUS:
6246 pointer.axis.source = Yetani::PointerAxisSource::Continuous;
6249 case WL_POINTER_AXIS_SOURCE_WHEEL_TILT:
6250 pointer.axis.source = Yetani::PointerAxisSource::Wheel_Tilt;
6262 void Yetani::handlerPointerAxisStop(
void*
6263 ,
struct wl_pointer*
6284 void Yetani::handlerPointerButton(
void* data
6285 ,
struct wl_pointer*
6292 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6294 pointer.button.code = button;
6295 pointer.button_time = time;
6297 if(state == WL_POINTER_BUTTON_STATE_RELEASED)
6301 else if(state == WL_POINTER_BUTTON_STATE_PRESSED)
6303 pointer.button.state = Yetani::PointerButtonState::Pressed;
6311 void Yetani::handlerPointerEnter(
void* data
6312 ,
struct wl_pointer*
6314 ,
struct wl_surface* wl_surface
6315 , wl_fixed_t surface_x
6316 , wl_fixed_t surface_y
6319 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6321 pointer.enter_serial = serial;
6322 pointer.enter_surface = wl_surface;
6324 pointer.enter_point =
6326 , .x = wl_fixed_to_int(surface_x)
6327 , .y = wl_fixed_to_int(surface_y)
6335 void Yetani::handlerPointerFrame(
void* data
6336 ,
struct wl_pointer* wl_pointer
6339 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6340 Yetani* yetani = pointer.yetani;
6342 if(pointer.enter_surface !=
nullptr)
6344 if(pointer.wl_surface !=
nullptr)
6346 yetani->cursorLeave(pointer.wl_surface);
6347 pointer.event_map[pointer.wl_surface].on_leave();
6350 yetani->cursorEnter(wl_pointer
6351 , pointer.enter_serial
6352 , pointer.enter_surface
6355 pointer.wl_surface = pointer.enter_surface;
6356 pointer.point_pixel = pointer.enter_point;
6358 if(pointer.event_map.contains(pointer.wl_surface))
6360 pointer.event = &(pointer.event_map[pointer.wl_surface]);
6364 pointer.event = &(pointer.event_map[
nullptr]);
6367 yetani->convertPixel(pointer.enter_surface
6368 , pointer.point_pixel.x , pointer.point_pixel.y
6369 , pointer.point_mm.x , pointer.point_mm.y
6370 , pointer.point_percent.x, pointer.point_percent.y
6373 pointer.event->on_enter_pixel(pointer.point_pixel
6374 , yetani->keyboard.modifier
6376 pointer.event->on_enter_mm(pointer.point_mm
6377 , yetani->keyboard.modifier
6379 pointer.event->on_enter_percent(pointer.point_percent
6380 , yetani->keyboard.modifier
6384 if((pointer.motion_point.time != 0)
6385 && (pointer.wl_surface !=
nullptr)
6388 pointer.point_pixel = pointer.motion_point;
6390 yetani->convertPixel(pointer.wl_surface
6391 , pointer.point_pixel.x , pointer.point_pixel.y
6392 , pointer.point_mm.x , pointer.point_mm.y
6393 , pointer.point_percent.x, pointer.point_percent.y
6395 pointer.point_mm.time = pointer.point_pixel.time;
6396 pointer.point_percent.time = pointer.point_pixel.time;
6398 pointer.event->on_motion_pixel(pointer.point_pixel
6399 , yetani->keyboard.modifier
6401 pointer.event->on_motion_mm(pointer.point_mm
6402 , yetani->keyboard.modifier
6404 pointer.event->on_motion_percent(pointer.point_percent
6405 , yetani->keyboard.modifier
6409 if((pointer.button_time != 0)
6410 && (pointer.wl_surface !=
nullptr)
6413 pointer.point_mm.time = pointer.button_time;
6414 pointer.point_percent.time = pointer.button_time;
6415 pointer.point_pixel.time = pointer.button_time;
6417 pointer.event->on_button_pixel(pointer.button
6418 , pointer.point_pixel
6419 , yetani->keyboard.modifier
6421 pointer.event->on_button_mm(pointer.button
6423 , yetani->keyboard.modifier
6425 pointer.event->on_button_percent(pointer.button
6426 , pointer.point_percent
6427 , yetani->keyboard.modifier
6431 if((pointer.axis.time != 0)
6432 && (pointer.wl_surface !=
nullptr)
6435 pointer.event->on_axis(pointer.axis
6436 , yetani->keyboard.modifier
6440 if((pointer.leave_surface !=
nullptr)
6441 && (pointer.leave_surface == pointer.wl_surface)
6444 yetani->cursorLeave(pointer.leave_surface);
6446 pointer.event->on_leave();
6448 pointer.event = &(pointer.event_map[
nullptr]);
6449 pointer.wl_surface =
nullptr;
6452 pointerClear(pointer);
6459 void Yetani::handlerPointerLeave(
void* data
6460 ,
struct wl_pointer*
6462 ,
struct wl_surface* wl_surface
6465 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6467 pointer.leave_surface = wl_surface;
6474 void Yetani::handlerPointerMotion(
void* data
6475 ,
struct wl_pointer*
6477 , wl_fixed_t surface_x
6478 , wl_fixed_t surface_y
6481 Yetani::Pointer& pointer = *((Yetani::Pointer*)data);
6483 pointer.motion_point =
6485 , .x = wl_fixed_to_int(surface_x)
6486 , .y = wl_fixed_to_int(surface_y)
6496 void Yetani::handlerRegistryGlobal(
void* data
6497 ,
struct wl_registry* registry
6499 ,
const char* interface
6503 Yetani* yetani = (Yetani*)data;
6505 std::string_view interface_name(interface);
6506 ZAKERO_YETANI__DEBUG_VAR(interface_name);
6508 if(interface_name == wl_compositor_interface.name)
6510 yetani->compositor = (
struct wl_compositor*)
6511 wl_registry_bind(registry
6513 , &wl_compositor_interface
6520 if(interface_name == wl_output_interface.name)
6522 struct wl_output* wl_output = (
struct wl_output*)wl_registry_bind(registry
6524 , &wl_output_interface
6528 yetani->output_data.wloutput_to_outputid[wl_output] = id;
6529 yetani->output_data.outputid_to_wloutput[id] = wl_output;
6530 yetani->output_data.output_map[wl_output] = {};
6531 yetani->output_changes_map[wl_output] = {};
6532 yetani->output_state_map[wl_output] = Yetani::OutputState::Added;
6534 wl_output_add_listener(wl_output
6535 , &Yetani::output_listener
6542 if(interface_name == wl_seat_interface.name)
6544 yetani->seat = (
struct wl_seat*)
6545 wl_registry_bind(registry
6547 , &wl_seat_interface
6551 yetani->id_to_seat[id] = yetani->seat;
6553 wl_seat_add_listener(yetani->seat
6554 , &yetani->seat_listener
6561 if(interface_name == wl_shm_interface.name)
6563 yetani->shm = (
struct wl_shm*)
6564 wl_registry_bind(registry
6570 wl_shm_add_listener(yetani->shm
6571 , &yetani->shm_listener
6578 if(interface_name == xdg_wm_base_interface.name)
6580 yetani->xdg_wm_base = (
struct xdg_wm_base*)
6581 wl_registry_bind(registry
6583 , &xdg_wm_base_interface
6587 xdg_wm_base_add_listener(yetani->xdg_wm_base
6588 , &yetani->xdg_wm_base_listener
6593 if(interface_name == zxdg_decoration_manager_v1_interface.name)
6595 yetani->decoration_manager = (
struct zxdg_decoration_manager_v1*)
6596 wl_registry_bind(registry
6598 , &zxdg_decoration_manager_v1_interface
6601 ZAKERO_YETANI__DEBUG <<
"--- Using UNSTABLE Decoration Manager ---\n";
6609 void Yetani::handlerRegistryRemove(
void* data
6610 ,
struct wl_registry*
6614 Yetani* yetani = (Yetani*)data;
6616 printf(
"Got a registry remove event for id %d\n",
id);
6620 std::lock_guard<std::mutex> lock(yetani->output_data.mutex);
6622 if(yetani->output_data.outputid_to_wloutput.contains(
id))
6624 struct wl_output* wl_output = yetani->output_data.outputid_to_wloutput[id];
6626 yetani->output_data.outputid_to_wloutput.erase(
id);
6627 yetani->output_data.wloutput_to_outputid.erase(wl_output);
6629 yetani->output_changes_map.erase(wl_output);
6630 yetani->output_state_map.erase(wl_output);
6632 yetani->on_output_remove(
id);
6633 yetani->output_data.output_map.erase(wl_output);
6641 if(yetani->id_to_seat.contains(
id))
6643 struct wl_seat* wl_seat = yetani->id_to_seat[id];
6645 yetani->seatDestroy(wl_seat);
6647 yetani->id_to_seat.erase(
id);
6662 void Yetani::handlerSeatCapabilities(
void* data
6663 ,
struct wl_seat* wl_seat
6664 , uint32_t capabilities
6667 ZAKERO_YETANI__DEBUG_VAR((uint64_t)wl_seat);
6669 Yetani* yetani = (Yetani*)data;
6670 Yetani::Seat& seat = yetani->seat_map[wl_seat];
6672 seat.version = wl_seat_get_version(wl_seat);
6674 if(capabilities & WL_SEAT_CAPABILITY_KEYBOARD)
6676 ZAKERO_YETANI__DEBUG <<
"-- Got a keyboard device --\n";
6678 yetani->keyboard.event_map[
nullptr] =
6679 { .on_enter = Lambda_DoNothing
6680 , .on_leave = Lambda_DoNothing
6681 , .on_key = LambdaKey_DoNothing
6684 yetani->keyboard.event = &(yetani->keyboard.event_map[
nullptr]);
6686 seat.wl_keyboard = wl_seat_get_keyboard(wl_seat);
6688 wl_keyboard_add_listener(seat.wl_keyboard
6689 , &Yetani::keyboard_listener
6694 if(capabilities & WL_SEAT_CAPABILITY_POINTER)
6696 ZAKERO_YETANI__DEBUG <<
"-- Got a pointer device --\n";
6698 yetani->pointer.yetani = yetani;
6700 yetani->pointer.event_map[
nullptr] =
6701 { .on_axis = LambdaAxis_DoNothing
6702 , .on_axis_discrete = Lambda_DoNothing
6703 , .on_axis_source = Lambda_DoNothing
6704 , .on_axis_stop = Lambda_DoNothing
6705 , .on_button_mm = LambdaButtonMm_DoNothing
6706 , .on_button_percent = LambdaButtonPercent_DoNothing
6707 , .on_button_pixel = LambdaButtonPixel_DoNothing
6708 , .on_enter_mm = LambdaPointMm_DoNothing
6709 , .on_enter_percent = LambdaPointPercent_DoNothing
6710 , .on_enter_pixel = LambdaPointPixel_DoNothing
6711 , .on_leave = Lambda_DoNothing
6712 , .on_motion_mm = LambdaPointMm_DoNothing
6713 , .on_motion_percent = LambdaPointPercent_DoNothing
6714 , .on_motion_pixel = LambdaPointPixel_DoNothing
6717 yetani->pointer.event = &(yetani->pointer.event_map[
nullptr]);
6719 seat.wl_pointer = wl_seat_get_pointer(wl_seat);
6721 wl_pointer_add_listener(seat.wl_pointer
6722 , &Yetani::pointer_listener
6727 if(capabilities & WL_SEAT_CAPABILITY_TOUCH)
6729 ZAKERO_YETANI__DEBUG <<
"-- Got a touch device --\n";
6730 seat.wl_touch = wl_seat_get_touch(wl_seat);
6743 void Yetani::handlerSeatName(
void* data
6744 ,
struct wl_seat* wl_seat
6748 ZAKERO_YETANI__DEBUG_VAR((uint64_t)wl_seat);
6749 ZAKERO_YETANI__DEBUG_VAR(name);
6751 Yetani* yetani = (Yetani*)data;
6753 yetani->seat_map[wl_seat].name = name;
6762 void Yetani::handlerShmFormat(
void* data
6767 Yetani* yetani = (Yetani*)data;
6769 wl_shm_format format = (wl_shm_format)value;
6776 yetani->shm_format_vector.push_back(format);
6785 void Yetani::handlerSurfaceEnter(
void* data
6786 ,
struct wl_surface* wl_surface
6787 ,
struct wl_output* wl_output
6795 Yetani* yetani = (Yetani*)data;
6796 Yetani::OutputData& output_data = yetani->output_data;
6798 output_data.mutex.lock();
6799 output_data.surface_output_map[wl_surface].push_back(wl_output);
6800 output_data.mutex.unlock();
6807 void Yetani::handlerSurfaceLeave(
void* data
6808 ,
struct wl_surface* wl_surface
6809 ,
struct wl_output* wl_output
6817 Yetani* yetani = (Yetani*)data;
6819 Yetani::OutputData& output_data = yetani->output_data;
6820 std::lock_guard<std::mutex> lock(output_data.mutex);
6822 Yetani::VectorWlOutput& output_vector = output_data.surface_output_map[wl_surface];
6825 struct wl_output* current_output = output_vector.front();
6831 if(current_output == output_vector.front())
6839 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
6841 if(surface_extent.preferred_unit == Yetani::SizeUnit::Pixel)
6849 current_output = output_vector.front();
6851 Yetani::Output& output = output_data.output_map.at(current_output);
6852 Yetani::SizePixel new_size;
6854 if(surface_extent.preferred_unit == Yetani::SizeUnit::Millimeter)
6856 auto p = yetani->convertMmToPixel(output
6857 , surface_extent.size_mm.width
6858 , surface_extent.size_mm.height
6861 new_size = { p.first, p.second };
6865 auto p = yetani->convertPercentToPixel(output
6866 , surface_extent.size_percent.width
6867 , surface_extent.size_percent.height
6870 new_size = { p.first, p.second };
6873 if(new_size.width <= 0)
6878 if(new_size.height <= 0)
6880 new_size.height = 1;
6883 if((new_size.width != surface_extent.size_pixel.width)
6884 && (new_size.height != surface_extent.size_pixel.height)
6887 yetani->surface_resize_mutex_map[wl_surface].lock();
6889 XdgSurface& surface = yetani->xdg_surface_map[wl_surface];
6891 surface_extent.size_pixel = new_size;
6892 surfaceCalculateSize(surface.yetani, surface.wl_surface, new_size);
6894 yetani->surface_resize_mutex_map[wl_surface].unlock();
6896 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
6897 event.on_size_pixel_change(surface_extent.size_pixel);
6907 void Yetani::handlerSwapBuffers(
void* data
6908 ,
struct wl_callback* callback
6912 Yetani::SurfaceFrame* surface_frame = (Yetani::SurfaceFrame*)data;
6914 wl_callback_destroy(callback);
6916 surface_frame->callback = wl_surface_frame(surface_frame->wl_surface);
6918 wl_callback_add_listener(surface_frame->callback
6919 , &frame_callback_listener
6923 struct wl_buffer* wl_buffer = surface_frame->buffer_next.exchange(
nullptr);
6924 if(wl_buffer !=
nullptr)
6926 surface_frame->time_ms = time_ms;
6928 wl_surface_attach(surface_frame->wl_surface, wl_buffer, 0, 0);
6930 wl_surface_damage(surface_frame->wl_surface
6932 , surface_frame->width, surface_frame->height
6936 wl_surface_commit(surface_frame->wl_surface);
6963 case Yetani::XdgState::Toplevel_Window_Fullscreen:
6964 return Yetani::WindowMode::Fullscreen;
6966 case Yetani::XdgState::Toplevel_Window_Maximized:
6967 return Yetani::WindowMode::Maximized;
6970 case Yetani::XdgState::Toplevel_Window_Normal:
6986 case Yetani::WindowMode::Fullscreen:
6987 return Yetani::XdgState::Toplevel_Window_Fullscreen;
6989 case Yetani::WindowMode::Maximized:
6990 return Yetani::XdgState::Toplevel_Window_Maximized;
6994 return Yetani::XdgState::Toplevel_Window_Normal;
7021 struct xdg_surface* Yetani::xdgSurfaceCreate(
struct wl_surface* wl_surface
7024 XdgSurface& surface = xdg_surface_map[wl_surface];
7026 surface.yetani =
this;
7027 surface.wl_surface = wl_surface;
7029 surface_extent_mutex.lock();
7031 Yetani::SurfaceExtent& surface_extent = surface_extent_map[wl_surface];
7033 surface_extent.preferred_unit = Yetani::SizeUnit::Pixel;
7034 surface_extent.preferred_mm = { 160, 90 };
7035 surface_extent.preferred_percent = { 0.32, 0.18 };
7036 surface_extent.size_mm = { 160, 90 };
7037 surface_extent.size_percent = { 0.32, 0.18 };
7038 surface_extent.size_pixel = { 800, 450 };
7039 surface_extent.size_pixel_max = { 0, 0 };
7040 surface_extent.size_pixel_min = { 0, 0 };
7042 surface_extent_mutex.unlock();
7044 output_notify_surface_vector.push_back(wl_surface);
7046 struct xdg_surface* xdg_surface = xdg_wm_base_get_xdg_surface(xdg_wm_base
7050 xdg_state_change_mutex.lock();
7052 xdg_state_change_map[xdg_surface] = {};
7054 xdg_state_change_mutex.unlock();
7056 xdg_surface_add_listener(xdg_surface
7057 , &xdg_surface_listener
7073 void Yetani::xdgSurfaceDestroy(
struct wl_surface* wl_surface
7074 ,
struct xdg_surface*& xdg_surface
7079 xdg_surface_destroy(xdg_surface);
7084 if(xdg_surface_map.contains(wl_surface))
7086 xdg_surface_map.erase(wl_surface);
7089 xdg_state_change_mutex.lock();
7091 if(xdg_state_change_map.contains(xdg_surface))
7093 xdg_state_change_map.erase(xdg_surface);
7096 xdg_state_change_mutex.unlock();
7098 surface_extent_mutex.lock();
7100 if(surface_extent_map.contains(wl_surface))
7102 surface_extent_map.erase(wl_surface);
7105 surface_extent_mutex.unlock();
7107 xdg_surface =
nullptr;
7114 void Yetani::xdgSurfaceSetExtent(
struct wl_surface* wl_surface
7115 ,
const Yetani::SizeUnit& size_unit
7116 ,
const Yetani::SizeMm& size_mm
7117 ,
const Yetani::SizePercent& size_percent
7118 ,
const Yetani::SizePixel& size_pixel
7121 Yetani::SurfaceExtent& surface_extent = surface_extent_map[wl_surface];
7123 surface_extent.preferred_unit = size_unit;
7124 surface_extent.preferred_mm = size_mm;
7125 surface_extent.preferred_percent = size_percent;
7126 surface_extent.size_mm = size_mm;
7127 surface_extent.size_percent = size_percent;
7128 surface_extent.size_pixel = size_pixel;
7129 surface_extent.size_pixel_max = { 0, 0 };
7130 surface_extent.size_pixel_min = { 0, 0 };
7174 struct xdg_toplevel* Yetani::xdgToplevelCreate(
struct xdg_surface* xdg_surface
7177 Yetani::XdgToplevel& toplevel = xdg_toplevel_map[xdg_surface];
7179 toplevel.close_request_lambda = Lambda_DoNothing;
7180 toplevel.state_change = &(xdg_state_change_map[xdg_surface]);
7181 toplevel.is_active =
false;
7182 toplevel.window_state = Yetani::XdgState::Toplevel_Window_Normal;
7183 toplevel.is_active_lambda = LambdaBool_DoNothing;
7184 toplevel.window_state_lambda = LambdaWindowMode_DoNothing;
7185 toplevel.previous_size = { 0, 0 };
7186 toplevel.xdg_toplevel =
nullptr;
7193 toplevel.state_change->push_back(Yetani::XdgState::Toplevel_Attach_Buffer);
7195 struct xdg_toplevel* xdg_toplevel =
nullptr;
7197 xdg_toplevel = xdg_surface_get_toplevel(xdg_surface);
7198 toplevel.xdg_toplevel = xdg_toplevel;
7200 xdg_toplevel_add_listener(xdg_toplevel
7201 , &xdg_toplevel_listener
7205 return xdg_toplevel;
7215 void Yetani::xdgToplevelDestroy(
struct xdg_surface* xdg_surface
7216 ,
struct xdg_toplevel*& xdg_toplevel
7219 if(xdg_toplevel !=
nullptr)
7221 xdg_toplevel_destroy(xdg_toplevel);
7224 if(xdg_toplevel_map.contains(xdg_surface))
7226 XdgToplevel& toplevel = xdg_toplevel_map[xdg_surface];
7228 toplevel.close_request_lambda =
nullptr;
7229 toplevel.state_change =
nullptr;
7230 toplevel.window_state = Yetani::XdgState::Unknown;
7231 toplevel.is_active =
false;
7232 toplevel.is_active_lambda =
nullptr;
7233 toplevel.window_state_lambda =
nullptr;
7235 xdg_toplevel_map.erase(xdg_surface);
7238 xdg_toplevel =
nullptr;
7251 void Yetani::xdgToplevelSizeChange(Yetani* yetani
7252 ,
struct wl_surface* wl_surface
7253 ,
const Yetani::SizePixel& size_pixel
7256 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
7257 Yetani::SizePixel new_size = surface_extent.size_pixel;
7259 if(((surface_extent.size_pixel_min.width == 0) || (size_pixel.width >= surface_extent.size_pixel_min.width))
7260 && ((surface_extent.size_pixel_max.width == 0) || (size_pixel.width <= surface_extent.size_pixel_max.width))
7263 new_size.width = size_pixel.width;
7266 if(((surface_extent.size_pixel_min.height == 0) || (size_pixel.height >= surface_extent.size_pixel_min.height))
7267 && ((surface_extent.size_pixel_max.height == 0) || (size_pixel.height <= surface_extent.size_pixel_max.height))
7270 new_size.height = size_pixel.height;
7273 if((new_size.width == surface_extent.size_pixel.width)
7274 && (new_size.height == surface_extent.size_pixel.height)
7281 Yetani::SizeMm size_mm;
7282 Yetani::SizePercent size_percent;
7283 yetani->convertPixel(wl_surface
7284 , size_pixel.width , size_pixel.height
7285 , size_mm.width , size_mm.height
7286 , size_percent.width, size_percent.height
7289 yetani->surface_resize_mutex_map[wl_surface].lock();
7291 surface_extent.size_pixel = new_size;
7292 surfaceCalculateSize(yetani, wl_surface, new_size);
7294 yetani->surface_resize_mutex_map[wl_surface].unlock();
7296 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
7297 event.on_size_pixel_change(surface_extent.size_pixel);
7298 event.on_size_mm_change(surface_extent.size_mm);
7299 event.on_size_percent_change(surface_extent.size_percent);
7306 void Yetani::xdgToplevelSizeMinMaxChange(Yetani* yetani
7307 ,
struct xdg_toplevel* xdg_toplevel
7308 ,
struct wl_surface* wl_surface
7309 ,
const Yetani::SizePixel& size_pixel_min
7310 ,
const Yetani::SizePixel& size_pixel_max
7313 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
7315 Yetani::SizePixel size_pixel = surface_extent.size_pixel;
7316 bool need_to_resize =
false;
7318 if(size_pixel_max.width > 0
7319 && size_pixel_max.width < surface_extent.size_pixel.width
7322 need_to_resize =
true;
7323 size_pixel.width = size_pixel_max.width;
7326 if(size_pixel_max.height > 0
7327 && size_pixel_max.height < surface_extent.size_pixel.height
7330 need_to_resize =
true;
7331 size_pixel.height = size_pixel_max.height;
7334 if(size_pixel_min.width > 0
7335 && size_pixel_min.width > surface_extent.size_pixel.width
7338 need_to_resize =
true;
7339 size_pixel.width = size_pixel_min.width;
7342 if(size_pixel_min.height > 0
7343 && size_pixel_min.height > surface_extent.size_pixel.height
7346 need_to_resize =
true;
7347 size_pixel.height = size_pixel_min.height;
7352 xdg_toplevel_set_max_size(xdg_toplevel, 0, 0);
7353 xdg_toplevel_set_min_size(xdg_toplevel, 0, 0);
7355 yetani->surface_resize_mutex_map[wl_surface].lock();
7357 surface_extent.size_pixel = size_pixel;
7358 surfaceCalculateSize(yetani, wl_surface, size_pixel);
7360 yetani->surface_resize_mutex_map[wl_surface].unlock();
7363 xdg_toplevel_set_min_size(xdg_toplevel
7364 , size_pixel_min.width
7365 , size_pixel_min.height
7368 xdg_toplevel_set_max_size(xdg_toplevel
7369 , size_pixel_max.width
7370 , size_pixel_max.height
7373 surface_extent.size_pixel_min = size_pixel_min;
7374 surface_extent.size_pixel_max = size_pixel_max;
7381 void Yetani::xdgToplevelWindowChange(Yetani* yetani
7382 ,
struct wl_surface* wl_surface
7383 , Yetani::XdgToplevel& toplevel
7384 ,
const Yetani::XdgState window_state
7385 ,
const Yetani::SizePixel& size_pixel
7388 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
7389 Yetani::SizePixel new_size(1, 1);
7391 toplevel.window_state = window_state;
7393 if((toplevel.window_state == Yetani::XdgState::Toplevel_Window_Fullscreen)
7394 || (toplevel.window_state == Yetani::XdgState::Toplevel_Window_Maximized)
7397 if(toplevel.previous_size.width == 0)
7399 xdg_toplevel_set_max_size(toplevel.xdg_toplevel, 0, 0);
7400 xdg_toplevel_set_min_size(toplevel.xdg_toplevel, 0, 0);
7402 toplevel.previous_size = surface_extent.size_pixel;
7405 if((size_pixel.width != 0)
7406 && (size_pixel.height != 0)
7409 new_size = size_pixel;
7412 else if(toplevel.window_state == Yetani::XdgState::Toplevel_Window_Normal)
7414 xdg_toplevel_set_max_size(toplevel.xdg_toplevel
7415 , surface_extent.size_pixel_max.width
7416 , surface_extent.size_pixel_max.height
7419 xdg_toplevel_set_min_size(toplevel.xdg_toplevel
7420 , surface_extent.size_pixel_min.width
7421 , surface_extent.size_pixel_min.height
7424 new_size = toplevel.previous_size;
7425 toplevel.previous_size.width = 0;
7428 if(new_size == surface_extent.size_pixel)
7434 Yetani::SizeMm size_mm;
7435 Yetani::SizePercent size_percent;
7436 yetani->convertPixel(wl_surface
7437 , size_pixel.width , size_pixel.height
7438 , size_mm.width , size_mm.height
7439 , size_percent.width, size_percent.height
7442 yetani->surface_resize_mutex_map[wl_surface].lock();
7444 surface_extent.size_mm = size_mm;
7445 surface_extent.size_percent = size_percent;
7446 surface_extent.size_pixel = new_size;
7447 surfaceCalculateSize(yetani, wl_surface, new_size);
7449 yetani->surface_resize_mutex_map[wl_surface].unlock();
7451 toplevel.window_state_lambda(Yetani::toWindowMode(toplevel.window_state));
7453 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
7454 event.on_size_pixel_change(surface_extent.size_pixel);
7455 event.on_size_mm_change(surface_extent.size_mm);
7456 event.on_size_percent_change(surface_extent.size_percent);
7485 struct zxdg_toplevel_decoration_v1* Yetani::xdgDecorationCreate(
struct xdg_surface* xdg_surface
7486 ,
struct xdg_toplevel* xdg_toplevel
7489 if(decoration_manager ==
nullptr)
7500 zxdg_toplevel_decoration_v1* xdg_decoration =
7501 zxdg_decoration_manager_v1_get_toplevel_decoration(decoration_manager
7505 Yetani::XdgDecoration& decoration = xdg_decoration_map[xdg_surface];
7506 decoration.state_change = &(xdg_state_change_map[xdg_surface]);
7507 decoration.lambda = LambdaWindowDecorations_DoNothing;
7508 decoration.state = 0;
7509 decoration.is_present =
false;
7511 zxdg_toplevel_decoration_v1_add_listener(xdg_decoration
7512 , &xdg_toplevel_decoration_listener
7516 return xdg_decoration;
7525 void Yetani::xdgDecorationDestroy(
struct xdg_surface* xdg_surface
7526 ,
struct xdg_toplevel*
7527 ,
struct zxdg_toplevel_decoration_v1*& xdg_decoration
7530 zxdg_toplevel_decoration_v1_destroy(xdg_decoration);
7532 if(xdg_decoration_map.contains(xdg_surface))
7534 Yetani::XdgDecoration& decoration = xdg_decoration_map[xdg_surface];
7535 decoration.state_change =
nullptr;
7536 decoration.lambda =
nullptr;
7537 decoration.state = 0;
7538 decoration.is_present =
false;
7540 xdg_decoration_map.erase(xdg_surface);
7543 xdg_decoration =
nullptr;
7552 void Yetani::xdgDecorationChange(Yetani::XdgDecoration& decoration
7553 ,
const uint32_t decoration_state
7556 if(decoration_state == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE)
7558 if(decoration.state != decoration_state)
7560 decoration.state = decoration_state;
7561 decoration.is_present =
false;
7568 else if(decoration_state == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE)
7570 if(decoration.state != decoration_state)
7572 decoration.state = decoration_state;
7573 decoration.is_present =
true;
7577 decoration.is_present = !decoration.is_present;
7580 if(decoration.is_present ==
true)
7583 Yetani::WindowDecorations::Server_Side
7611 void Yetani::handlerXdgSurfaceConfigure(
void* data
7612 , xdg_surface* xdg_surface
7616 Yetani::XdgSurface& surface = *((Yetani::XdgSurface*)data);
7617 Yetani* yetani = surface.yetani;
7619 xdg_surface_ack_configure(xdg_surface, serial);
7621 VectorXdgStateChange& state_change = yetani->xdg_state_change_map[xdg_surface];
7623 if(state_change.empty())
7628 auto iter = std::begin(state_change);
7629 auto iter_end = std::end(state_change);
7631 while(iter != iter_end)
7635 case Yetani::XdgState::Toplevel_Active:
7637 Yetani::XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
7640 bool is_active = bool(*iter);
7641 if(toplevel.is_active != is_active)
7643 toplevel.is_active = is_active;
7645 toplevel.is_active_lambda(is_active);
7649 case Yetani::XdgState::Toplevel_Attach_Buffer:
7651 struct wl_surface* wl_surface = surface.wl_surface;
7653 SurfaceFrame& surface_frame =
7654 yetani->surface_frame_map[wl_surface];
7656 wl_surface_attach(surface_frame.wl_surface
7657 , surface_frame.buffer_next
7661 surface_frame.callback = wl_surface_frame(surface_frame.wl_surface);
7663 wl_callback_add_listener(surface_frame.callback
7664 , &frame_callback_listener
7668 wl_surface_commit(surface_frame.wl_surface);
7671 case Yetani::XdgState::Toplevel_Window_Normal:
7672 case Yetani::XdgState::Toplevel_Window_Maximized:
7673 case Yetani::XdgState::Toplevel_Window_Fullscreen:
7675 struct wl_surface* wl_surface = surface.wl_surface;
7677 Yetani::XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
7679 Yetani::XdgState window_state = XdgState(*iter);
7681 Yetani::SizePixel size_pixel;
7684 size_pixel.width = *iter;
7687 size_pixel.height = *iter;
7689 if(toplevel.window_state != window_state)
7691 xdgToplevelWindowChange(yetani
7700 case Yetani::XdgState::Toplevel_Resizing:
7702 struct wl_surface* wl_surface = surface.wl_surface;
7704 Yetani::SizePixel size_pixel;
7707 size_pixel.width = *iter;
7710 size_pixel.height = *iter;
7712 if(size_pixel.width > 0
7713 && size_pixel.height > 0
7716 xdgToplevelSizeChange(yetani
7723 case Yetani::XdgState::Toplevel_Decoration:
7726 uint32_t decoration_state = *iter;
7728 Yetani::XdgDecoration& decoration = yetani->xdg_decoration_map[xdg_surface];
7730 xdgDecorationChange(decoration, decoration_state);
7737 state_change.clear();
7746 void Yetani::handlerXdgToplevelClose(
void* data
7747 ,
struct xdg_toplevel*
7750 Yetani::XdgToplevel* toplevel = (Yetani::XdgToplevel*)data;
7752 toplevel->close_request_lambda();
7759 void Yetani::handlerXdgToplevelConfigure(
void* data
7760 ,
struct xdg_toplevel*
7763 ,
struct wl_array* state_array
7766 Yetani::XdgToplevel* toplevel = (Yetani::XdgToplevel*)data;
7768 Yetani::XdgState window_state = Yetani::XdgState::Toplevel_Window_Normal;
7769 int32_t is_active = 0;
7771 ZAKERO_YETANI__ARRAY_FOR_EACH(xdg_toplevel_state*, state_iter, state_array)
7773 xdg_toplevel_state state = *state_iter;
7777 case XDG_TOPLEVEL_STATE_MAXIMIZED:
7778 window_state = Yetani::XdgState::Toplevel_Window_Maximized;
7780 case XDG_TOPLEVEL_STATE_FULLSCREEN:
7781 window_state = Yetani::XdgState::Toplevel_Window_Fullscreen;
7783 case XDG_TOPLEVEL_STATE_RESIZING:
7784 toplevel->state_change->push_back(Yetani::XdgState::Toplevel_Resizing);
7785 toplevel->state_change->push_back(width);
7786 toplevel->state_change->push_back(height);
7788 case XDG_TOPLEVEL_STATE_ACTIVATED:
7791 case XDG_TOPLEVEL_STATE_TILED_LEFT:
7793 case XDG_TOPLEVEL_STATE_TILED_RIGHT:
7795 case XDG_TOPLEVEL_STATE_TILED_TOP:
7797 case XDG_TOPLEVEL_STATE_TILED_BOTTOM:
7804 toplevel->state_change->push_back(window_state);
7805 toplevel->state_change->push_back(width);
7806 toplevel->state_change->push_back(height);
7808 toplevel->state_change->push_back(Yetani::XdgState::Toplevel_Active);
7809 toplevel->state_change->push_back(is_active);
7818 void Yetani::handlerXdgWmBasePing(
void*
7819 ,
struct xdg_wm_base* xdg_wm_base
7823 xdg_wm_base_pong(xdg_wm_base, serial);
7832 void Yetani::handlerXdgToplevelDecorationConfigure(
void* data
7833 ,
struct zxdg_toplevel_decoration_v1*
7837 Yetani::XdgDecoration* deco = (Yetani::XdgDecoration*)data;
7839 deco->state_change->push_back(Yetani::XdgState::Toplevel_Decoration);
7840 deco->state_change->push_back(mode);
8007 , std::error_code& error
8010 return windowCreate(Yetani::SizeUnit::Millimeter
8014 , SHM_FORMAT_DEFAULT
8033 ,
const wl_shm_format format
8036 std::error_code error;
8038 return windowCreate(Yetani::SizeUnit::Millimeter
8064 ,
const wl_shm_format format
8065 , std::error_code& error
8068 return windowCreate(Yetani::SizeUnit::Millimeter
8092 , std::error_code& error
8095 return windowCreate(Yetani::SizeUnit::Percent
8099 , SHM_FORMAT_DEFAULT
8118 ,
const wl_shm_format format
8121 std::error_code error;
8123 return windowCreate(Yetani::SizeUnit::Percent
8149 ,
const wl_shm_format format
8150 , std::error_code& error
8153 return windowCreate(Yetani::SizeUnit::Percent
8177 , std::error_code& error
8180 return windowCreate(Yetani::SizeUnit::Pixel
8184 , SHM_FORMAT_DEFAULT
8203 ,
const wl_shm_format format
8206 std::error_code error;
8208 return windowCreate(Yetani::SizeUnit::Pixel
8234 ,
const wl_shm_format format
8235 , std::error_code& error
8238 return windowCreate(Yetani::SizeUnit::Pixel
8259 ,
const wl_shm_format pixel_format
8260 , std::error_code& error
8263 if((size_unit == Yetani::SizeUnit::Millimeter)
8264 && (size_mm.width <= 0 || size_mm.height <= 0)
8267 error = ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
8272 if((size_unit == Yetani::SizeUnit::Percent)
8273 && (size_percent.width <= 0 || size_percent.height <= 0)
8276 error = ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
8281 if((size_unit == Yetani::SizeUnit::Pixel)
8282 && (size_pixel.width <= 0 || size_pixel.height <= 0)
8285 error = ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
8290 const std::string file_name =
"Zakero.Yetani."
8294 struct WindowData window_data =
8297 , .wl_output = nullptr
8298 , .file_name = file_name
8299 , .size_mm = size_mm
8300 , .size_percent = size_percent
8301 , .size_pixel = size_pixel
8302 , .size_unit = size_unit
8303 , .pixel_format = pixel_format
8304 , .error = ZAKERO_YETANI__ERROR(Error_None)
8307 windowDataInit(window_data);
8309 if(window_data.error)
8311 error = window_data.error;
8316 Yetani::Window* window =
new Window(&window_data);
8318 if(window_data.error)
8323 ZAKERO_YETANI__DEBUG <<
to_string(window_data.error) <<
"\n";
8325 error = ZAKERO_YETANI__ERROR(Error_Window_Initialization_Failed);
8330 error = ZAKERO_YETANI__ERROR(Error_None);
8339 void Yetani::windowDataInit(Yetani::WindowData& window_data
8342 windowDataInitOutput(window_data);
8344 if(window_data.error)
8349 window_data.size_pixel.width = std::max(1, window_data.size_pixel.width);
8350 window_data.size_pixel.height = std::max(1, window_data.size_pixel.height);
8352 window_data.error = ZAKERO_YETANI__ERROR(Error_None);
8359 void Yetani::windowDataInitOutput(Yetani::WindowData& window_data
8362 std::lock_guard<std::mutex> lock(output_data.mutex);
8364 if(output_data.output_map.empty())
8366 window_data.error = ZAKERO_YETANI__ERROR(Error_No_Output_Available);
8371 const auto& iter = output_data.output_map.begin();
8373 window_data.wl_output = iter->first;
8374 Yetani::Output& output = iter->second;
8376 if(window_data.size_unit == Yetani::SizeUnit::Millimeter)
8378 auto px = convertMmToPixel(output
8379 , window_data.size_mm.width
8380 , window_data.size_mm.height
8383 auto pc = convertPixelToPercent(output
8388 window_data.size_mm = window_data.size_mm;
8389 window_data.size_percent = { pc.first, pc.second };
8390 window_data.size_pixel = { px.first, px.second };
8392 else if(window_data.size_unit == Yetani::SizeUnit::Percent)
8394 auto px = convertPercentToPixel(output
8395 , window_data.size_percent.width
8396 , window_data.size_percent.height
8399 auto mm = convertPixelToMm(output
8404 window_data.size_mm = { mm.first, mm.second };
8405 window_data.size_percent = window_data.size_percent;
8406 window_data.size_pixel = { px.first, px.second };
8408 else if(window_data.size_unit == Yetani::SizeUnit::Pixel)
8410 auto mm = convertPixelToMm(output
8411 , window_data.size_pixel.width
8412 , window_data.size_pixel.height
8415 auto pc = convertPixelToPercent(output
8416 , window_data.size_pixel.width
8417 , window_data.size_pixel.height
8420 window_data.size_mm = { mm.first, mm.second };
8421 window_data.size_percent = { pc.first, pc.second };
8422 window_data.size_pixel = window_data.size_pixel;
8425 window_data.error = ZAKERO_YETANI__ERROR(Error_None);
8432 void Yetani::windowInitMemory(Yetani::WindowData& window_data
8433 , Yetani::Window::Memory& window_memory
8436 size_t size_in_bytes = sizeInBytes(window_data.size_pixel
8437 , window_data.pixel_format
8440 window_data.error = window_memory.memory_pool.init(size_in_bytes
8442 , zakero::MemoryPool::Alignment::Bits_32
8445 if(window_data.error)
8450 window_memory.wl_shm_pool = wl_shm_create_pool(window_data.wl_shm
8451 , window_memory.memory_pool.fd()
8452 , window_memory.memory_pool.size()
8455 window_memory.memory_pool.sizeOnChange([&](
size_t new_size)
8457 wl_shm_pool_resize(window_memory.wl_shm_pool, new_size);
8460 window_data.error = ZAKERO_YETANI__ERROR(Error_None);
8467 void Yetani::windowInitOutput(Yetani::WindowData& window_data
8468 ,
struct wl_surface* wl_surface
8471 std::lock_guard<std::mutex> lock(output_data.mutex);
8473 output_data.surface_output_map[wl_surface].push_back(window_data.wl_output);
8480 void Yetani::windowEraseMemory(Yetani::Window::Memory& window_memory
8483 if(window_memory.wl_shm_pool)
8485 wl_shm_pool_destroy(window_memory.wl_shm_pool);
8486 window_memory.wl_shm_pool =
nullptr;
8494 void Yetani::windowEraseOutput(
struct wl_surface* wl_surface
8497 std::lock_guard<std::mutex> lock(output_data.mutex);
8499 if(output_data.surface_output_map.contains(wl_surface))
8501 output_data.surface_output_map.erase(wl_surface);
8509 void Yetani::windowEraseSurfaceExtent(
struct wl_surface* wl_surface
8512 std::lock_guard<std::mutex> lock(surface_extent_mutex);
8514 if(surface_extent_map.contains(wl_surface))
8516 surface_extent_map.erase(wl_surface);
8524 void Yetani::windowAdd(Yetani::Window* window
8527 std::lock_guard<std::mutex> lock(window_vector_mutex);
8529 window_vector.push_back(window);
8536 void Yetani::windowRemove(Yetani::Window* window
8539 std::lock_guard<std::mutex> lock(window_vector_mutex);
8744 : yetani {((Yetani::WindowData*)ptr)->yetani}
8745 , wl_buffer {
nullptr}
8746 , wl_surface {
nullptr}
8747 , xdg_surface {
nullptr}
8748 , xdg_toplevel {
nullptr}
8749 , xdg_decoration {
nullptr}
8750 , window_memory {
nullptr, ((Yetani::WindowData*)ptr)->file_name}
8751 , pixel_format {((Yetani::WindowData*)ptr)->pixel_format}
8753 Yetani::WindowData& window_data = *((Yetani::WindowData*)ptr);
8755 yetani->windowInitMemory(window_data, window_memory);
8756 if(window_data.error)
8761 wl_surface = yetani->surfaceCreate(yetani
8763 , window_data.size_pixel
8768 xdg_surface = yetani->xdgSurfaceCreate(wl_surface);
8770 yetani->xdgSurfaceSetExtent(wl_surface
8771 , window_data.size_unit
8772 , window_data.size_mm
8773 , window_data.size_percent
8774 , window_data.size_pixel
8777 xdg_toplevel = yetani->xdgToplevelCreate(xdg_surface);
8779 xdg_decoration = yetani->xdgDecorationCreate(xdg_surface, xdg_toplevel);
8781 wl_surface_commit(wl_surface);
8783 yetani->windowInitOutput(window_data, wl_surface);
8784 if(window_data.error)
8789 yetani->windowAdd(
this);
8798 yetani->windowRemove(
this);
8800 if(xdg_decoration !=
nullptr)
8802 yetani->xdgDecorationDestroy(xdg_surface, xdg_toplevel, xdg_decoration);
8805 if(xdg_toplevel !=
nullptr)
8807 yetani->xdgToplevelDestroy(xdg_surface, xdg_toplevel);
8810 if(xdg_surface !=
nullptr)
8812 yetani->xdgSurfaceDestroy(wl_surface, xdg_surface);
8815 if(wl_surface !=
nullptr)
8817 yetani->windowEraseOutput(wl_surface);
8818 yetani->surfaceDestroy(yetani, wl_surface);
8819 yetani->windowEraseSurfaceExtent(wl_surface);
8822 yetani->windowEraseMemory(window_memory);
8846 return yetani->cursorDetach(wl_surface);
8849 return yetani->cursorAttach(name, wl_surface);
8860 yetani->cursorHide(wl_surface);
8871 yetani->cursorShow(wl_surface);
8896 xdg_toplevel_set_app_id(xdg_toplevel, class_name.c_str());
8909 xdg_toplevel_set_title(xdg_toplevel, title.c_str());
8935 if(yetani->decoration_manager ==
nullptr)
8937 return ZAKERO_YETANI__ERROR(Error_Server_Side_Decorations_Not_Available);
8940 uint32_t decoration_state = decorations == Yetani::WindowDecorations::Server_Side
8941 ? ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE
8942 : ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE
8945 zxdg_toplevel_decoration_v1_set_mode(xdg_decoration
8949 return ZAKERO_YETANI__ERROR(Error_None);
8962 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
8981 XdgState window_state = Yetani::toXdgState(window_mode);
8983 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
8985 if(toplevel.window_state == window_state)
9005 XdgState window_state = Yetani::toXdgState(window_mode);
9007 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
9009 if(toplevel.window_state == window_state)
9016 case WindowMode::Fullscreen:
9017 xdg_toplevel_set_fullscreen(xdg_toplevel,
nullptr);
9020 case WindowMode::Maximized:
9021 xdg_toplevel_set_maximized(xdg_toplevel);
9025 xdg_toplevel_unset_fullscreen(xdg_toplevel);
9026 xdg_toplevel_unset_maximized(xdg_toplevel);
9051 if(size.width <= 0 || size.height <= 0)
9053 return ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
9058 if(size_pixel.
width <= 0)
9060 size_pixel.
width = 1;
9063 if(size_pixel.
height <= 0)
9068 yetani->surface_resize_mutex_map[wl_surface].lock();
9070 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
9072 surface_extent.preferred_unit = Yetani::SizeUnit::Millimeter;
9073 surface_extent.preferred_mm = size;
9074 surface_extent.size_pixel = size_pixel;
9076 surfaceCalculateSize(yetani, wl_surface, size_pixel);
9078 yetani->surface_resize_mutex_map[wl_surface].unlock();
9080 return ZAKERO_YETANI__ERROR(Error_None);
9103 if(size.width <= 0 || size.height <= 0)
9105 return ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
9110 if(size_pixel.
width <= 0)
9112 size_pixel.
width = 1;
9115 if(size_pixel.
height <= 0)
9120 yetani->surface_resize_mutex_map[wl_surface].lock();
9122 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
9124 surface_extent.preferred_unit = Yetani::SizeUnit::Percent;
9125 surface_extent.preferred_percent = size;
9126 surface_extent.size_pixel = size_pixel;
9128 surfaceCalculateSize(yetani, wl_surface, size_pixel);
9130 yetani->surface_resize_mutex_map[wl_surface].unlock();
9132 return ZAKERO_YETANI__ERROR(Error_None);
9155 if(size.width <= 0 || size.height <= 0)
9157 return ZAKERO_YETANI__ERROR(Error_Window_Size_Too_Small);
9160 yetani->surface_resize_mutex_map[wl_surface].lock();
9162 Yetani::SurfaceExtent& surface_extent = yetani->surface_extent_map[wl_surface];
9164 surface_extent.preferred_unit = Yetani::SizeUnit::Pixel;
9165 surface_extent.size_pixel = size;
9167 surfaceCalculateSize(yetani, wl_surface, size);
9169 yetani->surface_resize_mutex_map[wl_surface].unlock();
9171 return ZAKERO_YETANI__ERROR(Error_None);
9190 std::error_code error = validateMinMax<Yetani::SizeMm>(size_min, size_max);
9200 Yetani::OutputData& output_data = yetani->output_data;
9202 std::lock_guard<std::mutex> lock(output_data.mutex);
9204 Yetani::VectorWlOutput& vector = output_data.surface_output_map[wl_surface];
9205 struct wl_output* wl_output = vector.front();
9208 auto min = yetani->convertMmToPixel(
output, size_min.
width, size_min.height);
9209 size_pixel_min = { min.first, min.second };
9211 auto max = yetani->convertMmToPixel(
output, size_max.
width, size_max.height);
9212 size_pixel_max = { max.first, max.second };
9215 yetani->xdgToplevelSizeMinMaxChange(yetani
9222 return ZAKERO_YETANI__ERROR(Error_None);
9241 std::error_code error = validateMinMax<Yetani::SizePercent>(size_min, size_max);
9251 Yetani::OutputData& output_data = yetani->output_data;
9253 std::lock_guard<std::mutex> lock(output_data.mutex);
9255 Yetani::VectorWlOutput& vector = output_data.surface_output_map[wl_surface];
9256 struct wl_output* wl_output = vector.front();
9259 auto min = yetani->convertPercentToPixel(
output, size_min.
width, size_min.height);
9260 size_pixel_min = { min.first, min.second };
9262 auto max = yetani->convertPercentToPixel(
output, size_max.
width, size_max.height);
9263 size_pixel_max = { max.first, max.second };
9266 yetani->xdgToplevelSizeMinMaxChange(yetani
9273 return ZAKERO_YETANI__ERROR(Error_None);
9292 std::error_code error = validateMinMax<Yetani::SizePixel>(size_min, size_max);
9298 yetani->xdgToplevelSizeMinMaxChange(yetani
9305 return ZAKERO_YETANI__ERROR(Error_None);
9351 if(wl_buffer !=
nullptr)
9353 bufferDestroy(wl_buffer);
9356 Yetani::SurfaceSize& surface_size = yetani->surface_size_map[wl_surface];
9358 yetani->surface_resize_mutex_map[wl_surface].lock();
9360 wl_buffer = bufferCreateAndRelease(yetani
9365 yetani->surface_resize_mutex_map[wl_surface].unlock();
9367 image = window_memory.memory_pool.addressOf(
9368 yetani->buffer.map[wl_buffer].offset
9371 size = { surface_size.width, surface_size.height };
9373 return ZAKERO_YETANI__ERROR(Error_None);
9385 if(wl_buffer ==
nullptr)
9397 Yetani::SurfaceFrame& surface_frame = yetani->surface_frame_map[wl_surface];
9399 wl_buffer = surface_frame.buffer_next.exchange(wl_buffer);
9417 Yetani::SurfaceFrame& surface_frame = yetani->surface_frame_map[wl_surface];
9419 return surface_frame.time_ms;
9435 return yetani->shmFormatBytesPerPixel(pixel_format);
9448 xdg_toplevel_set_minimized(xdg_toplevel);
9464 const Yetani::OutputData& output_data = yetani->output_data;
9466 std::lock_guard<std::mutex> lock(output_data.mutex);
9468 struct wl_output* wl_output = output_data.surface_output_map.at(wl_surface).front();
9471 auto p = yetani->convertPixelToMm(
output, point.
x, point.y);
9473 return { point.time, p.first, p.second };
9487 const Yetani::OutputData& output_data = yetani->output_data;
9489 std::lock_guard<std::mutex> lock(output_data.mutex);
9491 struct wl_output* wl_output = output_data.surface_output_map.at(wl_surface).front();
9494 auto p = yetani->convertPixelToPercent(
output, point.
x, point.y);
9496 return { point.time, p.first, p.second };
9510 Yetani::OutputData& output_data = yetani->output_data;
9512 std::lock_guard<std::mutex> lock(output_data.mutex);
9514 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9517 auto p = yetani->convertMmToPixel(
output, point.
x, point.y);
9519 return { point.time, p.first, p.second };
9533 Yetani::OutputData& output_data = yetani->output_data;
9535 std::lock_guard<std::mutex> lock(output_data.mutex);
9537 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9540 auto p = yetani->convertPercentToPixel(
output, point.
x, point.y);
9542 return { point.time, p.first, p.second };
9556 Yetani::OutputData& output_data = yetani->output_data;
9558 std::lock_guard<std::mutex> lock(output_data.mutex);
9560 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9563 auto p = yetani->convertPixelToMm(
output, size.
width, size.height);
9565 return { p.first, p.second };
9579 Yetani::OutputData& output_data = yetani->output_data;
9581 std::lock_guard<std::mutex> lock(output_data.mutex);
9583 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9586 auto p = yetani->convertPixelToPercent(
output, size.
width, size.height);
9588 return { p.first, p.second };
9602 Yetani::OutputData& output_data = yetani->output_data;
9604 std::lock_guard<std::mutex> lock(output_data.mutex);
9606 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9609 auto p = yetani->convertMmToPixel(
output, size.
width, size.height);
9611 return { p.first, p.second };
9625 Yetani::OutputData& output_data = yetani->output_data;
9627 std::lock_guard<std::mutex> lock(output_data.mutex);
9629 struct wl_output* wl_output = output_data.surface_output_map[wl_surface].front();
9632 auto p = yetani->convertPercentToPixel(
output, size.
width, size.height);
9634 return { p.first, p.second };
9654 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
9656 if(lambda ==
nullptr)
9658 toplevel.close_request_lambda = Lambda_DoNothing;
9662 toplevel.close_request_lambda = lambda;
9679 XdgDecoration& decoration = yetani->xdg_decoration_map[xdg_surface];
9681 if(lambda ==
nullptr)
9683 decoration.lambda = LambdaWindowDecorations_DoNothing;
9687 decoration.lambda = lambda;
9708 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
9710 if(lambda ==
nullptr)
9712 toplevel.is_active_lambda = LambdaBool_DoNothing;
9716 toplevel.is_active_lambda = lambda;
9729 if(yetani->keyboard.event_map.contains(wl_surface) ==
false)
9734 Yetani::KeyboardEvent&
event = yetani->keyboard.event_map[wl_surface];
9736 if(lambda ==
nullptr)
9738 event.on_enter = Lambda_DoNothing;
9742 event.on_enter = lambda;
9755 if(yetani->keyboard.event_map.contains(wl_surface) ==
false)
9760 Yetani::KeyboardEvent&
event = yetani->keyboard.event_map[wl_surface];
9762 if(lambda ==
nullptr)
9764 event.on_leave = Lambda_DoNothing;
9768 event.on_leave = lambda;
9783 if(yetani->keyboard.event_map.contains(wl_surface) ==
false)
9788 Yetani::KeyboardEvent&
event = yetani->keyboard.event_map[wl_surface];
9790 if(lambda ==
nullptr)
9792 event.on_key = LambdaKey_DoNothing;
9796 event.on_key = lambda;
9810 XdgToplevel& toplevel = yetani->xdg_toplevel_map[xdg_surface];
9812 if(lambda ==
nullptr)
9814 toplevel.window_state_lambda = LambdaWindowMode_DoNothing;
9818 toplevel.window_state_lambda = lambda;
9839 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
9841 if(lambda ==
nullptr)
9843 event.on_size_mm_change = LambdaSizeMm_DoNothing;
9847 event.on_size_mm_change = lambda;
9868 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
9870 if(lambda ==
nullptr)
9872 event.on_size_percent_change = LambdaSizePercent_DoNothing;
9876 event.on_size_percent_change = lambda;
9897 Yetani::SurfaceEvent&
event = yetani->surface_event_map[wl_surface];
9899 if(lambda ==
nullptr)
9901 event.on_size_pixel_change = LambdaSizePixel_DoNothing;
9905 event.on_size_pixel_change = lambda;
9920 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
9925 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
9927 if(lambda ==
nullptr)
9929 event.on_button_mm = LambdaButtonMm_DoNothing;
9933 event.on_button_mm = lambda;
9948 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
9953 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
9955 if(lambda ==
nullptr)
9957 event.on_button_percent = LambdaButtonPercent_DoNothing;
9961 event.on_button_percent = lambda;
9976 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
9981 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
9983 if(lambda ==
nullptr)
9985 event.on_button_pixel = LambdaButtonPixel_DoNothing;
9989 event.on_button_pixel = lambda;
10007 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10012 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10014 if(lambda ==
nullptr)
10016 event.on_enter_mm = LambdaPointMm_DoNothing;
10020 event.on_enter_mm = lambda;
10038 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10043 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10045 if(lambda ==
nullptr)
10047 event.on_enter_percent = LambdaPointPercent_DoNothing;
10051 event.on_enter_percent = lambda;
10069 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10074 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10076 if(lambda ==
nullptr)
10078 event.on_enter_pixel = LambdaPointPixel_DoNothing;
10082 event.on_enter_pixel = lambda;
10097 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10102 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10104 if(lambda ==
nullptr)
10106 event.on_leave = Lambda_DoNothing;
10110 event.on_leave = lambda;
10125 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10130 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10132 if(lambda ==
nullptr)
10134 event.on_motion_mm = LambdaPointMm_DoNothing;
10138 event.on_motion_mm = lambda;
10153 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10158 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10160 if(lambda ==
nullptr)
10162 event.on_motion_percent = LambdaPointPercent_DoNothing;
10166 event.on_motion_percent = lambda;
10181 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10186 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10188 if(lambda ==
nullptr)
10190 event.on_motion_pixel = LambdaPointPixel_DoNothing;
10194 event.on_motion_pixel = lambda;
10208 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10213 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10215 if(lambda ==
nullptr)
10217 event.on_axis = LambdaAxis_DoNothing;
10221 event.on_axis = lambda;
10235 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10240 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10242 if(lambda ==
nullptr)
10244 event.on_axis_source = Lambda_DoNothing;
10248 event.on_axis_source = lambda;
10262 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10267 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10269 if(lambda ==
nullptr)
10271 event.on_axis_stop = Lambda_DoNothing;
10275 event.on_axis_stop = lambda;
10289 if(yetani->pointer.event_map.contains(wl_surface) ==
false)
10294 Yetani::PointerEvent&
event = yetani->pointer.event_map[wl_surface];
10296 if(lambda ==
nullptr)
10298 event.on_axis_discrete = Lambda_DoNothing;
10302 event.on_axis_discrete = lambda;
10338 auto mod_to_str = [](std::string& s, uint32_t m)
10341 std::string delim =
"";
10345 s += delim +
"\"Shift\"";
10351 s += delim +
"\"CapsLock\"";
10357 s += delim +
"\"Control\"";
10363 s += delim +
"\"Alt\"";
10369 s += delim +
"\"Meta\"";
10375 std::string str =
"{ \"pressed\": ";
10376 mod_to_str(str, key_modifier.pressed);
10378 str +=
", \"latched\": ";
10379 mod_to_str(str, key_modifier.latched);
10381 str +=
", \"locked\": ";
10382 mod_to_str(str, key_modifier.locked);
10402 case Yetani::KeyState::Pressed:
return "Pressed";
10403 case Yetani::KeyState::Released:
return "Released";
10404 case Yetani::KeyState::Repeat:
return "Repeat";
10405 default:
return "";
10420 return "{\tx: " + std::to_string(
output.
x)
10421 +
"\n,\ty: " + std::to_string(
output.
y)
10453 case Yetani::PointerAxisSource::Continuous:
return "Continuous";
10454 case Yetani::PointerAxisSource::Finger:
return "Finger";
10455 case Yetani::PointerAxisSource::Wheel:
return "Wheel";
10456 case Yetani::PointerAxisSource::Wheel_Tilt:
return "Wheel Tilt";
10458 default:
return "";
10475 case Yetani::PointerAxisType::Horizontal:
return "Horizontal";
10476 case Yetani::PointerAxisType::Vertical:
return "Vertical";
10478 default:
return "";
10493 switch(button_state)
10495 case Yetani::PointerButtonState::Pressed:
return "Pressed";
10497 default:
return "";
10512 switch(window_mode)
10514 case Yetani::WindowMode::Fullscreen:
return "Fullscreen";
10515 case Yetani::WindowMode::Maximized:
return "Maximized";
10517 default:
return "";
10539 return equalish(lhs.x, rhs.x, 0.001)
10540 && equalish(lhs.y, rhs.y, 0.001)
10562 return equalish(lhs.x, rhs.x, 0.00001)
10563 && equalish(lhs.y, rhs.y, 0.00001)
10582 return (lhs.x == rhs.x) && (lhs.y == rhs.y);
10601 return equalish(lhs.width, rhs.width, 0.001)
10602 && equalish(lhs.height, rhs.height, 0.001)
10622 return equalish(lhs.width, rhs.width, 0.00001)
10623 && equalish(lhs.height, rhs.height, 0.00001)
10640 return (lhs.width == rhs.width) && (lhs.height == rhs.height);
10647 #endif // ZAKERO_YETANI_IMPLEMENTATION
10651 #endif // zakero_Yetani_h