diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c deleted file mode 100644 index a1cecaf10..000000000 --- a/src/bin/e_comp_wl.c +++ /dev/null @@ -1,2909 +0,0 @@ -#include "e.h" -#include "e_comp_wl.h" -#include - -#define e_pixmap_parent_window_set(X, Y) e_pixmap_parent_window_set(X, (Ecore_Window)(uintptr_t)Y) - -/* compositor function prototypes */ -static void _seat_send_updated_caps(struct wl_seat *seat); -static void _move_resources(struct wl_list *dest, struct wl_list *src); -static void _move_resources_for_client(struct wl_list *dest, struct wl_list *src, struct wl_client *client); - -static struct wl_resource *_find_resource_for_surface(struct wl_list *list, struct wl_resource *surface); - -static void _default_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y); -static void _default_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y); -static void _default_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp, uint32_t button, uint32_t state_w); - -static void _default_grab_touch_down(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy); -static void _default_grab_touch_up(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id); -static void _default_grab_touch_motion(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy); - -static void _data_offer_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type); -static void _data_offer_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd); -static void _data_offer_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); - -static void _destroy_data_offer(struct wl_resource *resource); -static void _destroy_offer_data_source(struct wl_listener *listener, void *data EINA_UNUSED); - -static void _create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id); -static void _get_data_device(struct wl_client *client, struct wl_resource *manager_resource EINA_UNUSED, uint32_t id, struct wl_resource *seat_resource); - -static void _current_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static void _bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id); - -static void _default_grab_key(struct wl_keyboard_grab *grab, uint32_t timestamp, uint32_t key, uint32_t state); -static void _default_grab_modifiers(struct wl_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group); - -static void _data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource EINA_UNUSED, struct wl_resource *icon_resource, uint32_t serial EINA_UNUSED); -static void _data_device_set_selection(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *source_resource, uint32_t serial); -static void _destroy_data_device_icon(struct wl_listener *listener, void *data EINA_UNUSED); - -static void _destroy_selection_data_source(struct wl_listener *listener, void *data EINA_UNUSED); -static void _data_source_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *type); -static void _data_source_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); -static void _destroy_data_source(struct wl_resource *resource); -static void _destroy_data_device_source(struct wl_listener *listener, void *data EINA_UNUSED); -static void _data_device_end_drag_grab(struct wl_seat *seat); - -static void _drag_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp EINA_UNUSED, uint32_t button, uint32_t state_w); -static void _drag_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y); - -static void _destroy_drag_focus(struct wl_listener *listener, void *data EINA_UNUSED); -static void _drag_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y); - -static void _client_source_accept(struct wl_data_source *source, uint32_t timestamp EINA_UNUSED, const char *mime_type); -static void _client_source_send(struct wl_data_source *source, const char *mime_type, int32_t fd); -static void _client_source_cancel(struct wl_data_source *source); - -static void _e_comp_wl_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id); -static Eina_Bool _e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED); -static Eina_Bool _e_comp_wl_cb_idle(void *data EINA_UNUSED); -static Eina_Bool _e_comp_wl_cb_module_idle(void *data EINA_UNUSED); - -/* compositor interface prototypes */ -static void _e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id); -static void _e_comp_wl_cb_surface_destroy(struct wl_resource *resource); -static void _e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id); -static void _e_comp_wl_cb_region_destroy(struct wl_resource *resource); - -/* input function prototypes */ -static Eina_Bool _e_comp_wl_input_init(void); -static void _e_comp_wl_input_shutdown(void); -static void _e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id); -static void _e_comp_wl_input_cb_unbind(struct wl_resource *resource); -static struct xkb_keymap *_e_comp_wl_input_keymap_get(void); -static int _e_comp_wl_input_keymap_fd_get(off_t size); -static E_Wayland_Keyboard_Info *_e_comp_wl_input_keyboard_info_get(struct xkb_keymap *keymap); - -/* input interface prototypes */ -static void _e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id); -static void _e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id); -static void _e_comp_wl_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id); - -/* pointer function prototypes */ -static void _e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static void _e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -static void _e_comp_wl_pointer_unmap(E_Wayland_Surface *ews); - -/* pointer interface prototypes */ -static void _e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y); -static void _e_comp_wl_pointer_cb_release(struct wl_client *client, struct wl_resource *resource); - -/* keyboard interface prototypes */ -static void _e_comp_wl_keyboard_cb_release(struct wl_client *client, struct wl_resource *resource); - -/* touch interface prototypes */ -static void _e_comp_wl_touch_cb_release(struct wl_client *client, struct wl_resource *resource); - -/* region interface prototypes */ -static void _e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); -static void _e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h); -static void _e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h); - -/* surface function prototypes */ -static void _e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static void _e_comp_wl_surface_cb_frame_destroy(struct wl_resource *resource); -static void _e_comp_wl_surface_buffer_reference(E_Wayland_Buffer_Reference *ref, E_Wayland_Buffer *buffer); -static void _e_comp_wl_surface_buffer_reference_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static E_Wayland_Buffer *_e_comp_wl_surface_buffer_resource(struct wl_resource *resource); -static void _e_comp_wl_surface_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); - -/* surface interface prototypes */ -static void _e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); -static void _e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int x, int y); -static void _e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h); -static void _e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, unsigned int callback); -static void _e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource); -static void _e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource); -static void _e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); -static void _e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int transform EINA_UNUSED); -static void _e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int scale EINA_UNUSED); - -/* local wayland interfaces */ -static const struct wl_compositor_interface _e_compositor_interface = -{ - _e_comp_wl_cb_surface_create, - _e_comp_wl_cb_region_create -}; - -static const struct wl_seat_interface _e_input_interface = -{ - _e_comp_wl_input_cb_pointer_get, - _e_comp_wl_input_cb_keyboard_get, - _e_comp_wl_input_cb_touch_get, -}; - -static const struct wl_pointer_interface _e_pointer_interface = -{ - _e_comp_wl_pointer_cb_cursor_set, - _e_comp_wl_pointer_cb_release -}; - -static const struct wl_keyboard_interface _e_keyboard_interface = -{ - _e_comp_wl_keyboard_cb_release -}; - -static const struct wl_touch_interface _e_touch_interface = -{ - _e_comp_wl_touch_cb_release -}; - -static const struct wl_region_interface _e_region_interface = -{ - _e_comp_wl_region_cb_destroy, - _e_comp_wl_region_cb_add, - _e_comp_wl_region_cb_subtract -}; - -static const struct wl_surface_interface _e_surface_interface = -{ - _e_comp_wl_surface_cb_destroy, - _e_comp_wl_surface_cb_attach, - _e_comp_wl_surface_cb_damage, - _e_comp_wl_surface_cb_frame, - _e_comp_wl_surface_cb_opaque_region_set, - _e_comp_wl_surface_cb_input_region_set, - _e_comp_wl_surface_cb_commit, - _e_comp_wl_surface_cb_buffer_transform_set, - _e_comp_wl_surface_cb_buffer_scale_set -}; - -static const struct wl_pointer_grab_interface _e_pointer_grab_interface = -{ - _default_grab_focus, - _default_grab_motion, - _default_grab_button -}; - -static const struct wl_keyboard_grab_interface _e_default_keyboard_grab_interface = -{ - _default_grab_key, - _default_grab_modifiers, -}; - -static const struct wl_data_offer_interface _e_data_offer_interface = -{ - _data_offer_accept, - _data_offer_receive, - _data_offer_destroy, -}; - -static const struct wl_data_device_manager_interface _e_manager_interface = -{ - _create_data_source, - _get_data_device -}; - -static const struct wl_data_device_interface _e_data_device_interface = -{ - _data_device_start_drag, - _data_device_set_selection, -}; - -static const struct wl_touch_grab_interface _e_default_touch_grab_interface = -{ - _default_grab_touch_down, - _default_grab_touch_up, - _default_grab_touch_motion -}; - -static struct wl_data_source_interface _e_data_source_interface = -{ - _data_source_offer, - _data_source_destroy -}; - -static const struct wl_pointer_grab_interface _e_drag_grab_interface = -{ - _drag_grab_focus, - _drag_grab_motion, - _drag_grab_button, -}; - -/* local variables */ -static Ecore_Idler *_module_idler = NULL; -#ifdef HAVE_WAYLAND_EGL -static Eina_Bool black_listed = EINA_FALSE; -#endif - -/* external variables */ -EAPI E_Wayland_Compositor *_e_wl_comp; - -/* external functions */ -EAPI Eina_Bool -e_comp_wl_init(void) -{ - int fd = 0; - char buf[PATH_MAX]; - - if (_e_wl_comp) return EINA_TRUE; - - /* try to allocate space for a new compositor */ - if (!(_e_wl_comp = E_NEW(E_Wayland_Compositor, 1))) - return EINA_FALSE; - - /* try to create a wayland display */ - snprintf(buf, sizeof(buf), "%s/wayland-0", e_ipc_socket); - e_env_set("WAYLAND_DISPLAY", buf); - if ((!(_e_wl_comp->wl.display = wl_display_create())) || - wl_display_add_socket(_e_wl_comp->wl.display, buf)) - { - ERR("Could not create a Wayland Display: %m"); - goto err; - } - - /* init compositor signals */ - wl_signal_init(&_e_wl_comp->signals.destroy); - wl_signal_init(&_e_wl_comp->signals.activate); - wl_signal_init(&_e_wl_comp->signals.kill); - wl_signal_init(&_e_wl_comp->signals.seat); - - /* try to add compositor to the displays globals */ - if (!wl_global_create(_e_wl_comp->wl.display, &wl_compositor_interface, 3, - _e_wl_comp, _e_comp_wl_cb_bind)) - { - ERR("Could not add compositor to globals: %m"); - goto err; - } - - /* init data device manager */ - wl_data_device_manager_init(_e_wl_comp->wl.display); - - /* try to init shm mechanism */ - if (wl_display_init_shm(_e_wl_comp->wl.display) < 0) - ERR("Could not initialize SHM: %m"); - -#ifdef HAVE_WAYLAND_EGL - /* try to get the egl display - * - * NB: This is interesting....if we try to eglGetDisplay and pass in the - * wayland display, then EGL fails due to XCB not owning the event queue. - * If we pass it a NULL, it inits just fine */ - _e_wl_comp->egl.display = eglGetDisplay(NULL); - if (_e_wl_comp->egl.display == EGL_NO_DISPLAY) - ERR("Could not get EGL display: %m"); - else - { - EGLint major, minor; - const char *vendor; - - /* FIXME: HACK: - * - * Frenchie reports major icky crash with Binary Nvidia Driver and - * calling eglTerminate. Let's hack around that.... */ - vendor = - (const char *)eglQueryString(_e_wl_comp->egl.display, EGL_VENDOR); - if ((vendor) && (!strcmp(vendor, "NVIDIA Corporation"))) - black_listed = EINA_TRUE; - if (black_listed) - { - ERR("Black listed driver [%s]. Not a supported configuration.", vendor); - goto err; - } - - /* try to initialize egl */ - if (!eglInitialize(_e_wl_comp->egl.display, &major, &minor)) - { - ERR("Could not initialize EGL: %m"); - eglTerminate(_e_wl_comp->egl.display); - } - else - { - EGLint n; - EGLint attribs[] = - { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 1, EGL_GREEN_SIZE, 1, EGL_BLUE_SIZE, 1, - EGL_ALPHA_SIZE, 1, EGL_RENDERABLE_TYPE, - EGL_OPENGL_ES2_BIT, EGL_NONE - }; - - if ((!eglChooseConfig(_e_wl_comp->egl.display, attribs, - &_e_wl_comp->egl.config, 1, &n) || (n == 0))) - { - ERR("Could not choose EGL config: %m"); - eglTerminate(_e_wl_comp->egl.display); - } - } - } -#endif - - /* try to initialize input */ - if (!_e_comp_wl_input_init()) - { - ERR("Could not initialize input: %m"); - goto err; - } - -#ifndef HAVE_WAYLAND_ONLY - /* setup keymap_change event handler */ - _e_wl_comp->kbd_handler = - ecore_event_handler_add(ECORE_X_EVENT_XKB_STATE_NOTIFY, - e_comp_wl_cb_keymap_changed, NULL); -#endif - - /* get the displays event loop */ - _e_wl_comp->wl.loop = wl_display_get_event_loop(_e_wl_comp->wl.display); - - /* get the event loop's file descriptor so we can listen on it */ - fd = wl_event_loop_get_fd(_e_wl_comp->wl.loop); - - /* add the fd to E's main loop */ - _e_wl_comp->fd_handler = - ecore_main_fd_handler_add(fd, ECORE_FD_READ, - _e_comp_wl_cb_read, NULL, NULL, NULL); - - /* add an idler for flushing clients */ - _e_wl_comp->idler = ecore_idle_enterer_add(_e_comp_wl_cb_idle, NULL); - - /* TODO: event handlers ?? */ - - wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0); - - /* add an idler for deferred shell module loading */ - _module_idler = ecore_idler_add(_e_comp_wl_cb_module_idle, NULL); - - /* return success */ - return EINA_TRUE; - -err: - e_env_set("WAYLAND_DISPLAY", ""); - /* remove kbd handler */ - if (_e_wl_comp->kbd_handler) - ecore_event_handler_del(_e_wl_comp->kbd_handler); - - /* remove the module idler */ - if (_module_idler) ecore_idler_del(_module_idler); - -#ifdef HAVE_WAYLAND_EGL - /* unbind wayland display */ - if (_e_wl_comp->egl.bound) - _e_wl_comp->egl.unbind_display(_e_wl_comp->egl.display, _e_wl_comp->wl.display); - - /* terminate the egl display */ - if (!black_listed) - { - if ((_e_wl_comp->egl.display)) - eglTerminate(_e_wl_comp->egl.display); - - eglReleaseThread(); - } -#endif - - /* if we have a display, destroy it */ - if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display); - - /* free the compositor */ - E_FREE(_e_wl_comp); - - /* return failure */ - return EINA_FALSE; -} - -EINTERN void -e_comp_wl_shutdown(void) -{ - E_Module *mod = NULL; - - if (_e_wl_comp) - { - /* remove the idler */ - if (_e_wl_comp->idler) ecore_idler_del(_e_wl_comp->idler); - - /* remove the fd handler */ - if (_e_wl_comp->fd_handler) - ecore_main_fd_handler_del(_e_wl_comp->fd_handler); - - /* shutdown input */ - _e_comp_wl_input_shutdown(); - -#ifdef HAVE_WAYLAND_EGL - /* unbind wayland display */ - if (_e_wl_comp->egl.bound) - _e_wl_comp->egl.unbind_display(_e_wl_comp->egl.display, _e_wl_comp->wl.display); - - /* terminate the egl display */ - if (_e_wl_comp->egl.display) eglTerminate(_e_wl_comp->egl.display); - - eglReleaseThread(); -#endif - - /* if we have a display, destroy it */ - if (_e_wl_comp->wl.display) wl_display_destroy(_e_wl_comp->wl.display); - - /* free the compositor */ - E_FREE(_e_wl_comp); - } - - /* disable the loaded shell module */ - /* TODO: we should have a config variable somewhere to store which - * shell we want to unload (tablet, mobile, etc) */ - if ((mod = e_module_find("wl_desktop_shell"))) - e_module_disable(mod); -} - -#ifdef HAVE_WAYLAND_ONLY -EAPI int -e_comp_wl_input_read(int fd EINA_UNUSED, unsigned int mask EINA_UNUSED, void *data) -{ - E_Wayland_Compositor *wl_comp = data; - - wl_event_loop_dispatch(wl_comp->wl.loop, 0); - return 1; -} -#endif - -EAPI void -wl_seat_init(struct wl_seat *seat) -{ - memset(seat, 0, sizeof *seat); - - wl_signal_init(&seat->destroy_signal); - - seat->selection_data_source = NULL; - wl_list_init(&seat->base_resource_list); - wl_signal_init(&seat->selection_signal); - wl_list_init(&seat->drag_resource_list); - wl_signal_init(&seat->drag_icon_signal); -} - -EAPI void -wl_seat_release(struct wl_seat *seat) -{ - /* if (seat->pointer) */ - /* { */ - /* if (seat->pointer->focus) */ - /* wl_list_remove(&seat->pointer->focus_listener.link); */ - /* } */ - - /* if (seat->keyboard) */ - /* { */ - /* if (seat->keyboard->focus) */ - /* wl_list_remove(&seat->keyboard->focus_listener.link); */ - /* } */ - - /* if (seat->touch) */ - /* { */ - /* if (seat->touch->focus) */ - /* wl_list_remove(&seat->touch->focus_listener.link); */ - /* } */ - - wl_signal_emit(&seat->destroy_signal, seat); -} - -EAPI void -wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer) -{ - if (pointer && (seat->pointer || pointer->seat)) return; /* XXX: error? */ - if (!pointer && !seat->pointer) return; - - seat->pointer = pointer; - if (pointer) pointer->seat = seat; - - _seat_send_updated_caps(seat); -} - -EAPI void -wl_seat_set_keyboard(struct wl_seat *seat, struct wl_keyboard *keyboard) -{ - if (keyboard && (seat->keyboard || keyboard->seat)) return; /* XXX: error? */ - if (!keyboard && !seat->keyboard) return; - - seat->keyboard = keyboard; - if (keyboard) keyboard->seat = seat; - - _seat_send_updated_caps(seat); -} - -EAPI void -wl_seat_set_touch(struct wl_seat *seat, struct wl_touch *touch) -{ - if (touch && (seat->touch || touch->seat)) return; /* XXX: error? */ - if (!touch && !seat->touch) return; - - seat->touch = touch; - if (touch) touch->seat = seat; - - _seat_send_updated_caps(seat); -} - -EAPI void -wl_pointer_init(struct wl_pointer *pointer) -{ - memset(pointer, 0, sizeof *pointer); - wl_list_init(&pointer->resource_list); - wl_list_init(&pointer->focus_resource_list); - pointer->default_grab.interface = &_e_pointer_grab_interface; - pointer->default_grab.pointer = pointer; - pointer->grab = &pointer->default_grab; - wl_signal_init(&pointer->focus_signal); - - pointer->x = wl_fixed_from_int(100); - pointer->y = wl_fixed_from_int(100); -} - -EAPI void -wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_resource *surface, wl_fixed_t sx, wl_fixed_t sy) -{ - struct wl_keyboard *kbd = pointer->seat->keyboard; - struct wl_resource *res; - struct wl_list *lst; - uint32_t serial; - - lst = &pointer->focus_resource_list; - if ((!wl_list_empty(lst)) && (pointer->focus != surface)) - { - serial = wl_display_next_serial(_e_wl_comp->wl.display); - wl_resource_for_each(res, lst) - wl_pointer_send_leave(res, serial, pointer->focus); - - _move_resources(&pointer->resource_list, lst); - } - - if ((_find_resource_for_surface(&pointer->resource_list, surface)) && - (pointer->focus != surface)) - { - struct wl_client *client; - - client = wl_resource_get_client(surface); - _move_resources_for_client(lst, &pointer->resource_list, client); - - wl_resource_for_each(res, lst) - wl_pointer_send_enter(res, serial, surface, sx, sy); - - pointer->focus_serial = serial; - } - - if ((kbd) && (surface) && (kbd->focus != pointer->focus)) - { - struct wl_client *client; - - client = wl_resource_get_client(surface); - - wl_resource_for_each(res, &kbd->resource_list) - { - if (wl_resource_get_client(res) == client) - wl_keyboard_send_modifiers(res, serial, - kbd->modifiers.mods_depressed, - kbd->modifiers.mods_latched, - kbd->modifiers.mods_locked, - kbd->modifiers.group); - } - } - - pointer->focus = surface; - pointer->default_grab.focus = surface; - wl_signal_emit(&pointer->focus_signal, pointer); -} - -EAPI void -wl_pointer_start_grab(struct wl_pointer *pointer, struct wl_pointer_grab *grab) -{ - const struct wl_pointer_grab_interface *interface; - - pointer->grab = grab; - interface = pointer->grab->interface; - grab->pointer = pointer; - - if (pointer->current) - interface->focus(pointer->grab, pointer->current, - pointer->current_x, pointer->current_y); -} - -EAPI void -wl_pointer_end_grab(struct wl_pointer *pointer) -{ - const struct wl_pointer_grab_interface *interface; - - pointer->grab = &pointer->default_grab; - interface = pointer->grab->interface; - interface->focus(pointer->grab, pointer->current, - pointer->current_x, pointer->current_y); -} - -EAPI void -wl_keyboard_init(struct wl_keyboard *keyboard) -{ - memset(keyboard, 0, sizeof *keyboard); - wl_list_init(&keyboard->resource_list); - wl_array_init(&keyboard->keys); - wl_list_init(&keyboard->focus_resource_list); - keyboard->default_grab.interface = &_e_default_keyboard_grab_interface; - keyboard->default_grab.keyboard = keyboard; - keyboard->grab = &keyboard->default_grab; - wl_signal_init(&keyboard->focus_signal); -} - -EAPI void -wl_keyboard_set_focus(struct wl_keyboard *keyboard, struct wl_resource *surface) -{ - struct wl_resource *res; - struct wl_list *lst; - uint32_t serial; - - lst = &keyboard->focus_resource_list; - - if ((!wl_list_empty(lst)) && (keyboard->focus != surface)) - { - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - wl_resource_for_each(res, lst) - wl_keyboard_send_leave(res, serial, keyboard->focus); - - _move_resources(&keyboard->resource_list, lst); - } - - if ((_find_resource_for_surface(&keyboard->resource_list, surface)) && - (keyboard->focus != surface)) - { - struct wl_client *client; - - client = wl_resource_get_client(surface); - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - _move_resources_for_client(lst, &keyboard->resource_list, client); - - wl_resource_for_each(res, lst) - { - wl_keyboard_send_modifiers(res, serial, - keyboard->modifiers.mods_depressed, - keyboard->modifiers.mods_latched, - keyboard->modifiers.mods_locked, - keyboard->modifiers.group); - wl_keyboard_send_enter(res, serial, surface, &keyboard->keys); - } - - keyboard->focus_serial = serial; - } - - keyboard->focus = surface; - wl_signal_emit(&keyboard->focus_signal, keyboard); -} - -EAPI void -wl_keyboard_start_grab(struct wl_keyboard *device, struct wl_keyboard_grab *grab) -{ - device->grab = grab; - grab->keyboard = device; -} - -EAPI void -wl_keyboard_end_grab(struct wl_keyboard *keyboard) -{ - keyboard->grab = &keyboard->default_grab; -} - -EAPI void -wl_touch_init(struct wl_touch *touch) -{ - memset(touch, 0, sizeof *touch); - wl_list_init(&touch->resource_list); - wl_list_init(&touch->focus_resource_list); - touch->default_grab.interface = &_e_default_touch_grab_interface; - touch->default_grab.touch = touch; - touch->grab = &touch->default_grab; - wl_signal_init(&touch->focus_signal); -} - -EAPI void -wl_touch_start_grab(struct wl_touch *device, struct wl_touch_grab *grab) -{ - device->grab = grab; - grab->touch = device; -} - -EAPI void -wl_touch_end_grab(struct wl_touch *touch) -{ - touch->grab = &touch->default_grab; -} - -EAPI void -wl_data_device_set_keyboard_focus(struct wl_seat *seat) -{ - struct wl_resource *data_device, *focus, *offer; - struct wl_data_source *source; - - if (!seat->keyboard) return; - - focus = seat->keyboard->focus; - if (!focus) return; - - data_device = - wl_resource_find_for_client(&seat->drag_resource_list, - wl_resource_get_client(focus)); - if (!data_device) return; - - source = seat->selection_data_source; - if (source) - { - offer = wl_data_source_send_offer(source, data_device); - wl_data_device_send_selection(data_device, offer); - } -} - -EAPI int -wl_data_device_manager_init(struct wl_display *display) -{ - if (!wl_global_create(display, &wl_data_device_manager_interface, 1, - NULL, _bind_manager)) - return -1; - return 0; -} - -EAPI struct wl_resource * -wl_data_source_send_offer(struct wl_data_source *source, struct wl_resource *target) -{ - struct wl_data_offer *offer; - char **p; - - offer = malloc(sizeof *offer); - if (offer == NULL) return NULL; - - offer->resource = - wl_resource_create(wl_resource_get_client(target), - &wl_data_offer_interface, 1, 0); - if (!offer->resource) - { - free(offer); - return NULL; - } - - wl_resource_set_implementation(offer->resource, &_e_data_offer_interface, - offer, _destroy_data_offer); - - offer->source = source; - offer->source_destroy_listener.notify = _destroy_offer_data_source; - wl_signal_add(&source->destroy_signal, - &offer->source_destroy_listener); - - wl_data_device_send_data_offer(target, offer->resource); - - wl_array_for_each(p, &source->mime_types) - wl_data_offer_send_offer(offer->resource, *p); - - return offer->resource; -} - -EAPI void -wl_seat_set_selection(struct wl_seat *seat, struct wl_data_source *source, uint32_t serial) -{ - struct wl_resource *data_device, *offer; - struct wl_resource *focus = NULL; - - if (seat->selection_data_source && - seat->selection_serial - serial < UINT32_MAX / 2) - return; - - if (seat->selection_data_source) - { - seat->selection_data_source->cancel(seat->selection_data_source); - wl_list_remove(&seat->selection_data_source_listener.link); - seat->selection_data_source = NULL; - } - - seat->selection_data_source = source; - seat->selection_serial = serial; - if (seat->keyboard) - focus = seat->keyboard->focus; - if (focus) - { - data_device = - wl_resource_find_for_client(&seat->drag_resource_list, - wl_resource_get_client(focus)); - if (data_device && source) - { - offer = wl_data_source_send_offer(seat->selection_data_source, - data_device); - wl_data_device_send_selection(data_device, offer); - } - else if (data_device) - { - wl_data_device_send_selection(data_device, NULL); - } - } - - wl_signal_emit(&seat->selection_signal, seat); - if (source) - { - seat->selection_data_source_listener.notify = - _destroy_selection_data_source; - wl_signal_add(&source->destroy_signal, - &seat->selection_data_source_listener); - } -} - -EAPI unsigned int -e_comp_wl_time_get(void) -{ - struct timeval tm; - - gettimeofday(&tm, NULL); - return (tm.tv_sec * 1000 + tm.tv_usec / 1000); -} - -EAPI void -e_comp_wl_mouse_button(struct wl_resource *resource, uint32_t serial, uint32_t timestamp, uint32_t button, uint32_t state_w) -{ - switch (button) - { - case BTN_LEFT: - case BTN_MIDDLE: - case BTN_RIGHT: - wl_pointer_send_button(resource, serial, timestamp, - button, state_w); - break; - case 4: - if (state_w) - wl_pointer_send_axis(resource, timestamp, - WL_POINTER_AXIS_VERTICAL_SCROLL, - -wl_fixed_from_int(1)); - break; - case 5: - if (state_w) - wl_pointer_send_axis(resource, timestamp, - WL_POINTER_AXIS_VERTICAL_SCROLL, - wl_fixed_from_int(1)); - break; - case 6: - if (state_w) - wl_pointer_send_axis(resource, timestamp, - WL_POINTER_AXIS_HORIZONTAL_SCROLL, - -wl_fixed_from_int(1)); - break; - case 7: - if (state_w) - wl_pointer_send_axis(resource, timestamp, - WL_POINTER_AXIS_HORIZONTAL_SCROLL, - wl_fixed_from_int(1)); - break; - } -} - -EAPI void -e_comp_wl_input_modifiers_update(unsigned int serial) -{ - struct wl_keyboard *kbd; - struct wl_keyboard_grab *grab; - unsigned int pressed = 0, latched = 0, locked = 0, group = 0; - Eina_Bool changed = EINA_FALSE; - - /* check for valid keyboard */ - if (!(kbd = _e_wl_comp->input->wl.seat.keyboard)) - return; - - /* try to get the current keyboard's grab interface. - * Fallback to the default grab */ - if (!(grab = kbd->grab)) grab = &kbd->default_grab; - - pressed = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, - XKB_STATE_DEPRESSED); - latched = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, - XKB_STATE_LATCHED); - locked = xkb_state_serialize_mods(_e_wl_comp->input->xkb.state, - XKB_STATE_LOCKED); - group = xkb_state_serialize_group(_e_wl_comp->input->xkb.state, - XKB_STATE_EFFECTIVE); - - if ((pressed != kbd->modifiers.mods_depressed) || - (latched != kbd->modifiers.mods_latched) || - (locked != kbd->modifiers.mods_locked) || - (group != kbd->modifiers.group)) - changed = EINA_TRUE; - - kbd->modifiers.mods_depressed = pressed; - kbd->modifiers.mods_latched = latched; - kbd->modifiers.mods_locked = locked; - kbd->modifiers.group = group; - - /* TODO: update leds ? */ - - if (changed) - grab->interface->modifiers(grab, serial, - kbd->modifiers.mods_depressed, - kbd->modifiers.mods_latched, - kbd->modifiers.mods_locked, - kbd->modifiers.group); -} - -/* local functions */ -static void -_seat_send_updated_caps(struct wl_seat *seat) -{ - struct wl_resource *res; - enum wl_seat_capability caps = 0; - - if (seat->pointer) - caps |= WL_SEAT_CAPABILITY_POINTER; - if (seat->keyboard) - caps |= WL_SEAT_CAPABILITY_KEYBOARD; - if (seat->touch) - caps |= WL_SEAT_CAPABILITY_TOUCH; - - wl_resource_for_each(res, &seat->base_resource_list) - wl_seat_send_capabilities(res, caps); -} - -static void -_move_resources(struct wl_list *dest, struct wl_list *src) -{ - wl_list_insert_list(dest, src); - wl_list_init(src); -} - -static void -_move_resources_for_client(struct wl_list *dest, struct wl_list *src, struct wl_client *client) -{ - struct wl_resource *res, *tmp; - - wl_resource_for_each_safe(res, tmp, src) - { - if (wl_resource_get_client(res) == client) - { - wl_list_remove(wl_resource_get_link(res)); - wl_list_insert(dest, wl_resource_get_link(res)); - } - } -} - -static struct wl_resource * -_find_resource_for_surface(struct wl_list *list, struct wl_resource *surface) -{ - if (!surface) return NULL; - - return wl_resource_find_for_client(list, wl_resource_get_client(surface)); -} - -static void -_default_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y) -{ - struct wl_pointer *pointer = grab->pointer; - - if (pointer->button_count > 0) return; - - wl_pointer_set_focus(pointer, surface, x, y); -} - -static void -_default_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y) -{ - struct wl_list *lst; - struct wl_resource *res; - - lst = &grab->pointer->focus_resource_list; - wl_resource_for_each(res, lst) - wl_pointer_send_motion(res, timestamp, x, y); -} - -static void -_default_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp, uint32_t button, uint32_t state_w) -{ - struct wl_pointer *pointer = grab->pointer; - struct wl_list *lst; - struct wl_resource *res; - - lst = &pointer->focus_resource_list; - if (!wl_list_empty(lst)) - { - uint32_t serial; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - wl_resource_for_each(res, lst) - e_comp_wl_mouse_button(res, serial, timestamp, button, state_w); - } -} - -static void -_default_grab_touch_down(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy) -{ - struct wl_resource *res; - struct wl_list *lst; - struct wl_touch *touch = grab->touch; - - lst = &touch->focus_resource_list; - if (!wl_list_empty(lst) && (touch->focus)) - { - uint32_t serial; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - wl_resource_for_each(res, lst) - wl_touch_send_down(res, serial, timestamp, - touch->focus, touch_id, sx, sy); - } -} - -static void -_default_grab_touch_up(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id) -{ - struct wl_resource *res; - struct wl_list *lst; - struct wl_touch *touch = grab->touch; - - lst = &touch->focus_resource_list; - if (!wl_list_empty(lst) && (touch->focus)) - { - uint32_t serial; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - wl_resource_for_each(res, lst) - wl_touch_send_up(res, serial, timestamp, touch_id); - } -} - -static void -_default_grab_touch_motion(struct wl_touch_grab *grab, uint32_t timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy) -{ - struct wl_resource *res; - struct wl_list *lst; - struct wl_touch *touch = grab->touch; - - lst = &touch->focus_resource_list; - wl_resource_for_each(res, lst) - wl_touch_send_motion(res, timestamp, touch_id, sx, sy); -} - -static void -_data_offer_accept(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial, const char *mime_type) -{ - struct wl_data_offer *offer; - - offer = wl_resource_get_user_data(resource); - - if (offer->source) - offer->source->accept(offer->source, serial, mime_type); -} - -static void -_data_offer_receive(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *mime_type, int32_t fd) -{ - struct wl_data_offer *offer; - - offer = wl_resource_get_user_data(resource); - - if (offer->source) - offer->source->send(offer->source, mime_type, fd); - else - close(fd); -} - -static void -_data_offer_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_destroy_data_offer(struct wl_resource *resource) -{ - struct wl_data_offer *offer; - - offer = wl_resource_get_user_data(resource); - - if (offer->source) - wl_list_remove(&offer->source_destroy_listener.link); - free(offer); -} - -static void -_destroy_offer_data_source(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_data_offer *offer; - - offer = container_of(listener, struct wl_data_offer, - source_destroy_listener); - offer->source = NULL; -} - -static void -_create_data_source(struct wl_client *client, struct wl_resource *resource, uint32_t id) -{ - struct wl_data_source *source; - - source = malloc(sizeof *source); - if (source == NULL) - { - wl_resource_post_no_memory(resource); - return; - } - - wl_signal_init(&source->destroy_signal); - source->accept = _client_source_accept; - source->send = _client_source_send; - source->cancel = _client_source_cancel; - - wl_array_init(&source->mime_types); - - source->resource = - wl_resource_create(client, &wl_data_source_interface, 1, id); - - wl_resource_set_implementation(source->resource, - &_e_data_source_interface, source, - _destroy_data_source); -} - -static void -_unbind_data_device(struct wl_resource *resource) -{ - wl_list_remove(wl_resource_get_link(resource)); -} - -static void -_get_data_device(struct wl_client *client, struct wl_resource *manager_resource, uint32_t id, struct wl_resource *seat_resource) -{ - struct wl_seat *seat; - struct wl_resource *resource; - - seat = wl_resource_get_user_data(seat_resource); - - resource = - wl_resource_create(client, &wl_data_device_interface, 1, id); - if (!resource) - { - wl_resource_post_no_memory(manager_resource); - return; - } - - wl_list_insert(&seat->drag_resource_list, wl_resource_get_link(resource)); - - wl_resource_set_implementation(resource, &_e_data_device_interface, seat, - _unbind_data_device); - -} - -static void -_current_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_pointer *pointer = - container_of(listener, struct wl_pointer, current_listener); - pointer->current = NULL; -} - -static void -_bind_manager(struct wl_client *client, void *data EINA_UNUSED, uint32_t version EINA_UNUSED, uint32_t id) -{ - struct wl_resource *res; - - res = wl_resource_create(client, &wl_data_device_manager_interface, 1, id); - if (!res) - { - wl_client_post_no_memory(client); - return; - } - - wl_resource_set_implementation(res, &_e_manager_interface, NULL, NULL); -} - -static void -_default_grab_key(struct wl_keyboard_grab *grab, uint32_t timestamp, uint32_t key, uint32_t state) -{ - struct wl_keyboard *keyboard = grab->keyboard; - struct wl_resource *res; - struct wl_list *lst; - - lst = &keyboard->focus_resource_list; - if (!wl_list_empty(lst)) - { - uint32_t serial; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - wl_resource_for_each(res, lst) - wl_keyboard_send_key(res, serial, timestamp, key - 8, state); - } -} - -static void -_default_grab_modifiers(struct wl_keyboard_grab *grab, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -{ - struct wl_keyboard *keyboard = grab->keyboard; - struct wl_pointer *pointer = keyboard->seat->pointer; - struct wl_resource *res; - struct wl_list *lst; - - lst = &keyboard->focus_resource_list; - wl_resource_for_each(res, lst) - wl_keyboard_send_modifiers(res, serial, mods_depressed, mods_latched, - mods_locked, group); - - if (pointer && pointer->focus && pointer->focus != keyboard->focus) - { - struct wl_client *client; - - lst = &keyboard->resource_list; - client = wl_resource_get_client(pointer->focus); - wl_resource_for_each(res, lst) - { - if (wl_resource_get_client(res) == client) - wl_keyboard_send_modifiers(res, serial, mods_depressed, - mods_latched, mods_locked, group); - } - } -} - -static void -_data_device_start_drag(struct wl_client *client, struct wl_resource *resource, struct wl_resource *source_resource, struct wl_resource *origin_resource, struct wl_resource *icon_resource, uint32_t serial EINA_UNUSED) -{ - struct wl_seat *seat; - - seat = wl_resource_get_user_data(resource); - - if ((seat->pointer->button_count == 0) || - (seat->pointer->grab_serial != serial) || - (seat->pointer->focus != wl_resource_get_user_data(origin_resource))) - return; - - seat->drag_grab.interface = &_e_drag_grab_interface; - seat->drag_client = client; - seat->drag_data_source = NULL; - - if (source_resource) - { - struct wl_data_source *source; - - source = wl_resource_get_user_data(source_resource); - seat->drag_data_source = source; - seat->drag_data_source_listener.notify = - _destroy_data_device_source; - wl_signal_add(&source->destroy_signal, - &seat->drag_data_source_listener); - } - - if (icon_resource) - { - E_Wayland_Surface *icon; - - icon = wl_resource_get_user_data(icon_resource); - - seat->drag_surface = icon->wl.surface; - seat->drag_icon_listener.notify = _destroy_data_device_icon; - wl_signal_add(&icon->wl.destroy_signal, - &seat->drag_icon_listener); - /* wl_signal_emit(&seat->drag_icon_signal, icon_resource); */ - } - - wl_pointer_set_focus(seat->pointer, NULL, - wl_fixed_from_int(0), wl_fixed_from_int(0)); - wl_pointer_start_grab(seat->pointer, &seat->drag_grab); -} - -static void -_data_device_set_selection(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *source_resource, uint32_t serial) -{ - struct wl_data_source *source; - struct wl_seat *seat; - - if (!(seat = wl_resource_get_user_data(resource))) return; - source = wl_resource_get_user_data(source_resource); - - wl_seat_set_selection(seat, source, serial); -} - -static void -_destroy_data_device_icon(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_seat *seat = - container_of(listener, struct wl_seat, drag_icon_listener); - - seat->drag_surface = NULL; -} - -static void -_destroy_selection_data_source(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_seat *seat = - container_of(listener, struct wl_seat, selection_data_source_listener); - struct wl_resource *data_device; - struct wl_resource *focus = NULL; - - seat->selection_data_source = NULL; - - if (seat->keyboard) - focus = seat->keyboard->focus; - - if (focus) - { - data_device = - wl_resource_find_for_client(&seat->drag_resource_list, - wl_resource_get_client(focus)); - if (data_device) - wl_data_device_send_selection(data_device, NULL); - } - - wl_signal_emit(&seat->selection_signal, seat); -} - -static void -_destroy_data_device_source(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_seat *seat = - container_of(listener, struct wl_seat, drag_data_source_listener); - _data_device_end_drag_grab(seat); -} - -static void -_data_source_offer(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *type) -{ - struct wl_data_source *source; - char **p; - - source = wl_resource_get_user_data(resource); - p = wl_array_add(&source->mime_types, sizeof *p); - if (p) *p = strdup(type); - - if (!p || !*p) wl_resource_post_no_memory(resource); -} - -static void -_data_source_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_destroy_data_source(struct wl_resource *resource) -{ - struct wl_data_source *source; - char **p; - - source = wl_resource_get_user_data(resource); - - wl_signal_emit(&source->destroy_signal, source); - - wl_array_for_each(p, &source->mime_types) - free(*p); - - wl_array_release(&source->mime_types); - - source->resource = NULL; -} - -static void -_data_device_end_drag_grab(struct wl_seat *seat) -{ - if (seat->drag_surface) - { - seat->drag_surface = NULL; - wl_signal_emit(&seat->drag_icon_signal, NULL); - wl_list_remove(&seat->drag_icon_listener.link); - } - - _drag_grab_focus(&seat->drag_grab, NULL, - wl_fixed_from_int(0), wl_fixed_from_int(0)); - wl_pointer_end_grab(seat->pointer); - seat->drag_data_source = NULL; - seat->drag_client = NULL; -} - -static void -_drag_grab_button(struct wl_pointer_grab *grab, uint32_t timestamp EINA_UNUSED, uint32_t button, uint32_t state_w) -{ - struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab); - enum wl_pointer_button_state state = state_w; - - if (seat->drag_focus_resource && - seat->pointer->grab_button == button && - state == WL_POINTER_BUTTON_STATE_RELEASED) - wl_data_device_send_drop(seat->drag_focus_resource); - - if (seat->pointer->button_count == 0 && - state == WL_POINTER_BUTTON_STATE_RELEASED) - { - if (seat->drag_data_source) - wl_list_remove(&seat->drag_data_source_listener.link); - - _data_device_end_drag_grab(seat); - } -} - -static void -_drag_grab_motion(struct wl_pointer_grab *grab, uint32_t timestamp, wl_fixed_t x, wl_fixed_t y) -{ - struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab); - - if (seat->drag_focus_resource) - wl_data_device_send_motion(seat->drag_focus_resource, - timestamp, x, y); -} - -static void -_destroy_drag_focus(struct wl_listener *listener, void *data EINA_UNUSED) -{ - struct wl_seat *seat = - container_of(listener, struct wl_seat, drag_focus_listener); - - seat->drag_focus_resource = NULL; -} - -static void -_drag_grab_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y) -{ - struct wl_seat *seat = container_of(grab, struct wl_seat, drag_grab); - struct wl_resource *resource, *offer = NULL; - struct wl_display *display; - uint32_t serial; - E_Wayland_Surface *ews; - - if (seat->drag_focus_resource) - { - wl_data_device_send_leave(seat->drag_focus_resource); - wl_list_remove(&seat->drag_focus_listener.link); - seat->drag_focus_resource = NULL; - seat->drag_focus = NULL; - } - - if (!surface) return; - - if (!seat->drag_data_source && - wl_resource_get_client(surface) != seat->drag_client) - return; - - resource = - wl_resource_find_for_client(&seat->drag_resource_list, - wl_resource_get_client(surface)); - if (!resource) return; - - display = wl_client_get_display(wl_resource_get_client(resource)); - serial = wl_display_next_serial(display); - - if (seat->drag_data_source) - offer = wl_data_source_send_offer(seat->drag_data_source, - resource); - - wl_data_device_send_enter(resource, serial, surface, x, y, offer); - - ews = wl_resource_get_user_data(surface); - - seat->drag_focus = surface; - seat->drag_focus_listener.notify = _destroy_drag_focus; - wl_signal_add(&ews->wl.destroy_signal, &seat->drag_focus_listener); - seat->drag_focus_resource = resource; - grab->focus = surface; -} - -static void -_client_source_accept(struct wl_data_source *source, uint32_t timestamp EINA_UNUSED, const char *mime_type) -{ - wl_data_source_send_target(source->resource, mime_type); -} - -static void -_client_source_send(struct wl_data_source *source, const char *mime_type, int32_t fd) -{ - wl_data_source_send_send(source->resource, mime_type, fd); - close(fd); -} - -static void -_client_source_cancel(struct wl_data_source *source) -{ - wl_data_source_send_cancelled(source->resource); -} - -static void -_e_comp_wl_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id) -{ - E_Wayland_Compositor *comp; - struct wl_resource *res; - - if (!(comp = data)) return; - - res = - wl_resource_create(client, &wl_compositor_interface, MIN(version, 3), id); - if (res) - wl_resource_set_implementation(res, &_e_compositor_interface, comp, NULL); -} - -static Eina_Bool -_e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdl EINA_UNUSED) -{ - /* flush any events before we sleep */ - wl_display_flush_clients(_e_wl_comp->wl.display); - wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0); - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_e_comp_wl_cb_idle(void *data EINA_UNUSED) -{ - if ((_e_wl_comp) && (_e_wl_comp->wl.display)) - { - /* flush any clients before we idle */ - wl_display_flush_clients(_e_wl_comp->wl.display); - } - - return ECORE_CALLBACK_RENEW; -} - -static Eina_Bool -_e_comp_wl_cb_module_idle(void *data EINA_UNUSED) -{ - E_Module *mod = NULL; - - /* if we are still in the process of loading modules, then we will wait */ - if (e_module_loading_get()) return ECORE_CALLBACK_RENEW; - - /* try to find the shell module, and create it if not found - * - * TODO: we should have a config variable somewhere to store which - * shell we want to load (tablet, mobile, etc) */ - if (!(mod = e_module_find("wl_desktop_shell"))) - mod = e_module_new("wl_desktop_shell"); - - /* if we have the module now, load it */ - if (mod) - { - e_module_enable(mod); - _module_idler = NULL; - - /* flush any pending events - * - * NB: This advertises out any globals so it needs to be deferred - * until after the shell has been loaded */ - wl_event_loop_dispatch(_e_wl_comp->wl.loop, 0); - - return ECORE_CALLBACK_CANCEL; - } - - return ECORE_CALLBACK_RENEW; -} - -EAPI Eina_Bool -e_comp_wl_cb_keymap_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED) -{ - struct xkb_keymap *keymap; - - /* try to fetch the keymap */ - if (!(keymap = _e_comp_wl_input_keymap_get())) - return ECORE_CALLBACK_PASS_ON; - - /* destroy keyboard */ - if (_e_wl_comp->input->xkb.info) - { - /* if we have a keymap, unreference it */ - if (_e_wl_comp->input->xkb.info->keymap) - xkb_map_unref(_e_wl_comp->input->xkb.info->keymap); - - /* if we have a keymap mmap'd area, unmap it */ - if (_e_wl_comp->input->xkb.info->area) - munmap(_e_wl_comp->input->xkb.info->area, - _e_wl_comp->input->xkb.info->size); - - /* if we created an fd for keyboard input, close it */ - if (_e_wl_comp->input->xkb.info->fd) - close(_e_wl_comp->input->xkb.info->fd); - - /* free the allocated keyboard info structure */ - E_FREE(_e_wl_comp->input->xkb.info); - } - - /* unreference the xkb state we created */ - if (_e_wl_comp->input->xkb.state) - xkb_state_unref(_e_wl_comp->input->xkb.state); - - /* unreference the xkb context we created */ - if (_e_wl_comp->xkb.context) - xkb_context_unref(_e_wl_comp->xkb.context); - - /* create the xkb context */ - _e_wl_comp->xkb.context = xkb_context_new(0); - - /* try to fetch the keymap */ -// if ((keymap = _e_comp_wl_input_keymap_get())) - { - /* try to create new keyboard info */ - _e_wl_comp->input->xkb.info = - _e_comp_wl_input_keyboard_info_get(keymap); - - /* create new xkb state */ - _e_wl_comp->input->xkb.state = xkb_state_new(keymap); - - /* unreference the keymap */ - xkb_map_unref(keymap); - } - - /* check for valid keyboard */ - if (!_e_wl_comp->input->wl.keyboard_resource) - return ECORE_CALLBACK_PASS_ON; - - /* send the current keymap to the keyboard object */ - wl_keyboard_send_keymap(_e_wl_comp->input->wl.keyboard_resource, - WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - _e_wl_comp->input->xkb.info->fd, - _e_wl_comp->input->xkb.info->size); - - return ECORE_CALLBACK_PASS_ON; -} - -/* compositor interface functions */ -static void -_e_comp_wl_cb_surface_create(struct wl_client *client, struct wl_resource *resource, unsigned int id) -{ - E_Wayland_Surface *ews = NULL; - uint64_t wid; - pid_t pid; - - /* try to allocate space for a new surface */ - if (!(ews = E_NEW(E_Wayland_Surface, 1))) - { - wl_resource_post_no_memory(resource); - return; - } - - ews->wl.client = client; - wl_client_get_credentials(client, &pid, NULL, NULL); - wid = e_comp_wl_id_get(pid, id); - ews->pixmap = e_pixmap_find(E_PIXMAP_TYPE_WL, wid); - if (!ews->pixmap) - ews->pixmap = e_pixmap_new(E_PIXMAP_TYPE_WL, wid); - e_pixmap_parent_window_set(ews->pixmap, ews); - e_pixmap_usable_set(ews->pixmap, 1); - /* initialize the destroy signal */ - wl_signal_init(&ews->wl.destroy_signal); - - /* initialize the link */ - wl_list_init(&ews->wl.link); - - /* initialize the lists of frames */ - wl_list_init(&ews->wl.frames); - wl_list_init(&ews->pending.frames); - - ews->wl.surface = NULL; - - /* set destroy function for pending buffers */ - ews->pending.buffer_destroy.notify = - _e_comp_wl_surface_cb_pending_buffer_destroy; - - /* initialize regions */ - pixman_region32_init(&ews->region.opaque); - pixman_region32_init(&ews->region.damage); - pixman_region32_init(&ews->region.clip); - pixman_region32_init_rect(&ews->region.input, INT32_MIN, INT32_MIN, - UINT32_MAX, UINT32_MAX); - - /* initialize pending regions */ - pixman_region32_init(&ews->pending.opaque); - pixman_region32_init(&ews->pending.damage); - pixman_region32_init_rect(&ews->pending.input, INT32_MIN, INT32_MIN, - UINT32_MAX, UINT32_MAX); - - ews->wl.surface = - wl_resource_create(client, &wl_surface_interface, - wl_resource_get_version(resource), id); - wl_resource_set_implementation(ews->wl.surface, &_e_surface_interface, - ews, _e_comp_wl_cb_surface_destroy); - - /* add this surface to the list of surfaces */ - _e_wl_comp->surfaces = eina_inlist_append(_e_wl_comp->surfaces, EINA_INLIST_GET(ews)); -} - -static void -_e_comp_wl_cb_surface_destroy(struct wl_resource *resource) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Surface_Frame_Callback *cb = NULL, *ncb = NULL; - struct wl_pointer *pointer; - Eina_Inlist *l; - E_Wayland_Buffer *buffer; - - /* try to get the surface from this resource */ - if (!(ews = wl_resource_get_user_data(resource))) - return; - - pointer = &_e_wl_comp->input->wl.pointer; - if (pointer->focus == resource) - { - wl_pointer_set_focus(pointer, NULL, - wl_fixed_from_int(0), wl_fixed_from_int(0)); - - _e_wl_comp->input->pointer.surface = NULL; - } - - /* if this surface is mapped, unmap it */ - if (ews->mapped) - { - if (ews->unmap) ews->unmap(ews); - } - if (ews->buffer_reference.buffer) - ews->buffer_reference.buffer->ews = NULL; - if (ews->pending.buffer) - ews->pending.buffer->ews = NULL; - - /* loop any pending surface frame callbacks and destroy them */ - wl_list_for_each_safe(cb, ncb, &ews->pending.frames, wl.link) - wl_resource_destroy(cb->wl.resource); - - /* clear any pending regions */ - pixman_region32_fini(&ews->pending.damage); - pixman_region32_fini(&ews->pending.opaque); - pixman_region32_fini(&ews->pending.input); - - /* remove the pending buffer from the list */ - if (ews->pending.buffer) - wl_list_remove(&ews->pending.buffer_destroy.link); - - /* dereference any existing buffers */ - _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, NULL); - - /* clear any active regions */ - pixman_region32_fini(&ews->region.damage); - pixman_region32_fini(&ews->region.opaque); - pixman_region32_fini(&ews->region.input); - pixman_region32_fini(&ews->region.clip); - - /* loop any active surface frame callbacks and destroy them */ - wl_list_for_each_safe(cb, ncb, &ews->wl.frames, wl.link) - wl_resource_destroy(cb->wl.resource); - - EINA_INLIST_FOREACH_SAFE(ews->buffers, l, buffer) - { - buffer->ews = NULL; - ews->buffers = eina_inlist_remove(ews->buffers, EINA_INLIST_GET(buffer)); - } - if (e_comp_get(NULL)->pointer->pixmap == ews->pixmap) - { - e_pointer_image_set(e_comp_get(NULL)->pointer, NULL, 0, 0, 0, 0); - } - e_pixmap_parent_window_set(ews->pixmap, NULL); - e_pixmap_free(ews->pixmap); - - /* remove this surface from the compositor's list of surfaces */ - _e_wl_comp->surfaces = eina_inlist_remove(_e_wl_comp->surfaces, EINA_INLIST_GET(ews)); - - /* free the allocated surface structure */ - free(ews); -} - -static void -_e_comp_wl_cb_region_create(struct wl_client *client, struct wl_resource *resource, unsigned int id) -{ - E_Wayland_Region *ewr = NULL; - - /* try to allocate space for a new region */ - if (!(ewr = E_NEW_RAW(E_Wayland_Region, 1))) - { - wl_resource_post_no_memory(resource); - return; - } - - pixman_region32_init(&ewr->region); - - ewr->wl.resource = - wl_resource_create(client, &wl_region_interface, - wl_resource_get_version(resource), id); - wl_resource_set_implementation(ewr->wl.resource, &_e_region_interface, ewr, - _e_comp_wl_cb_region_destroy); -} - -static void -_e_comp_wl_cb_region_destroy(struct wl_resource *resource) -{ - E_Wayland_Region *ewr = NULL; - - /* try to get the region from this resource */ - if (!(ewr = wl_resource_get_user_data(resource))) - return; - - /* tell pixman we are finished with this region */ - pixman_region32_fini(&ewr->region); - - /* free the allocated region structure */ - E_FREE(ewr); -} - -/* input functions */ -static Eina_Bool -_e_comp_wl_input_init(void) -{ - struct xkb_keymap *keymap; - - /* try to allocate space for a new compositor */ - if (!(_e_wl_comp->input = E_NEW(E_Wayland_Input, 1))) - return EINA_FALSE; - - /* initialize the seat */ - wl_seat_init(&_e_wl_comp->input->wl.seat); - - /* try to add this input to the diplay's list of globals */ - if (!wl_global_create(_e_wl_comp->wl.display, &wl_seat_interface, 2, - _e_wl_comp->input, _e_comp_wl_input_cb_bind)) - { - ERR("Could not add Input to Wayland Display Globals: %m"); - goto err; - } - - _e_wl_comp->input->pointer.surface = NULL; - _e_wl_comp->input->pointer.surface_destroy.notify = - _e_comp_wl_pointer_cb_destroy; - _e_wl_comp->input->pointer.hot.x = 16; - _e_wl_comp->input->pointer.hot.y = 16; - - /* initialize wayland pointer */ - wl_pointer_init(&_e_wl_comp->input->wl.pointer); - - /* tell the seat about this pointer */ - wl_seat_set_pointer(&_e_wl_comp->input->wl.seat, - &_e_wl_comp->input->wl.pointer); - - /* set flag to indicate we have a pointer */ - _e_wl_comp->input->has_pointer = EINA_TRUE; - - /* create the xkb context */ - _e_wl_comp->xkb.context = xkb_context_new(0); - - /* try to fetch the keymap */ - if ((keymap = _e_comp_wl_input_keymap_get())) - { - /* try to create new keyboard info */ - _e_wl_comp->input->xkb.info = - _e_comp_wl_input_keyboard_info_get(keymap); - - /* create new xkb state */ - _e_wl_comp->input->xkb.state = xkb_state_new(keymap); - - /* unreference the keymap */ - xkb_map_unref(keymap); - } - - /* initialize the keyboard */ - wl_keyboard_init(&_e_wl_comp->input->wl.keyboard); - - /* tell the seat about this keyboard */ - wl_seat_set_keyboard(&_e_wl_comp->input->wl.seat, - &_e_wl_comp->input->wl.keyboard); - - /* set flag to indicate we have a keyboard */ - _e_wl_comp->input->has_keyboard = EINA_TRUE; - - wl_list_init(&_e_wl_comp->input->wl.link); - - /* append this input to the list */ - _e_wl_comp->seats = eina_list_append(_e_wl_comp->seats, _e_wl_comp->input); - - /* emit a signal saying that input has been initialized */ - wl_signal_emit(&_e_wl_comp->signals.seat, _e_wl_comp->input); - - /* return success */ - return EINA_TRUE; - -err: - /* release the wl_seat */ - wl_seat_release(&_e_wl_comp->input->wl.seat); - - /* free the allocated input structure */ - E_FREE(_e_wl_comp->input); - - /* return failure */ - return EINA_FALSE; -} - -static void -_e_comp_wl_input_shutdown(void) -{ - /* safety check */ - if (!_e_wl_comp->input) return; - - /* destroy keyboard */ - if (_e_wl_comp->input->xkb.info) - { - /* if we have a keymap, unreference it */ - if (_e_wl_comp->input->xkb.info->keymap) - xkb_map_unref(_e_wl_comp->input->xkb.info->keymap); - - /* if we have a keymap mmap'd area, unmap it */ - if (_e_wl_comp->input->xkb.info->area) - munmap(_e_wl_comp->input->xkb.info->area, - _e_wl_comp->input->xkb.info->size); - - /* if we created an fd for keyboard input, close it */ - if (_e_wl_comp->input->xkb.info->fd) - close(_e_wl_comp->input->xkb.info->fd); - - /* free the allocated keyboard info structure */ - E_FREE(_e_wl_comp->input->xkb.info); - } - - /* unreference the xkb state we created */ - if (_e_wl_comp->input->xkb.state) - xkb_state_unref(_e_wl_comp->input->xkb.state); - - /* unreference the xkb context we created */ - if (_e_wl_comp->xkb.context) - xkb_context_unref(_e_wl_comp->xkb.context); - - /* TODO: destroy pointer surface - * - * NB: Currently, we do not create one */ - - wl_list_remove(&_e_wl_comp->input->wl.link); - - /* release the seat */ - wl_seat_release(&_e_wl_comp->input->wl.seat); - - /* free the allocated input structure */ - E_FREE(_e_wl_comp->input); -} - -static void -_e_comp_wl_input_cb_bind(struct wl_client *client, void *data, unsigned int version, unsigned int id) -{ - struct wl_seat *seat = NULL; - struct wl_resource *resource = NULL; - enum wl_seat_capability caps = 0; - - /* try to cast data to our seat */ - if (!(seat = data)) return; - - /* add the seat object to the client */ - resource = - wl_resource_create(client, &wl_seat_interface, MIN(version, 2), id); - - wl_list_insert(&seat->base_resource_list, wl_resource_get_link(resource)); - - wl_resource_set_implementation(resource, &_e_input_interface, data, - _e_comp_wl_input_cb_unbind); - - /* set capabilities based on seat */ - if (seat->pointer) caps |= WL_SEAT_CAPABILITY_POINTER; - if (seat->keyboard) caps |= WL_SEAT_CAPABILITY_KEYBOARD; - if (seat->touch) caps |= WL_SEAT_CAPABILITY_TOUCH; - - /* inform the resource about the seat capabilities */ - wl_seat_send_capabilities(resource, caps); -} - -static void -_e_comp_wl_input_cb_unbind(struct wl_resource *resource) -{ - /* remove the link */ - wl_list_remove(wl_resource_get_link(resource)); -} - -static struct xkb_keymap * -_e_comp_wl_input_keymap_get(void) -{ - E_Config_XKB_Layout *kbd_layout; - struct xkb_keymap *keymap; - struct xkb_rule_names names; - - memset(&names, 0, sizeof(names)); - - if ((kbd_layout = e_xkb_layout_get())) - { - names.model = strdup(kbd_layout->model); - names.layout = strdup(kbd_layout->name); - } - -#ifndef HAVE_WAYLAND_ONLY - /* if we are running under X11, try to get the xkb rule names atom */ - if (getenv("DISPLAY")) - { - Ecore_X_Atom rules = 0; - Ecore_X_Window root = 0; - int len = 0; - unsigned char *data; - - /* TODO: FIXME: NB: - * - * The below commented out code is for using the "already" configured - * E xkb settings in the wayland clients. The only Major problem with - * that is: That the E_Config_XKB_Layout does not define a - * 'RULES' which we need .... - * - */ - - root = ecore_x_window_root_first_get(); - rules = ecore_x_atom_get("_XKB_RULES_NAMES"); - ecore_x_window_prop_property_get(root, rules, ECORE_X_ATOM_STRING, - 1024, &data, &len); - - if ((data) && (len > 0)) - { - names.rules = (char*)data; - data += strlen((const char *)data) + 1; - if (!names.model) - names.model = strdup((const char *)data); - data += strlen((const char *)data) + 1; - if (!names.layout) - names.layout = strdup((const char *)data); - } - } -#endif - - printf("Keymap\n"); - printf("\tRules: %s\n", names.rules); - printf("\tModel: %s\n", names.model); - printf("\tLayout: %s\n", names.layout); - - keymap = xkb_map_new_from_names(_e_wl_comp->xkb.context, &names, 0); - - free((char *)names.rules); - free((char *)names.model); - free((char *)names.layout); - - return keymap; -} - -static int -_e_comp_wl_input_keymap_fd_get(off_t size) -{ - char tmp[PATH_MAX]; - const char *path; - int fd = 0; - long flags; - - if (!(path = getenv("XDG_RUNTIME_DIR"))) - return -1; - - strcpy(tmp, path); - strcat(tmp, "/e-wl-keymap-XXXXXX"); - - if ((fd = mkstemp(tmp)) < 0) - return -1; - - /* TODO: really should error check the returns here */ - - flags = fcntl(fd, F_GETFD); - fcntl(fd, F_SETFD, flags | FD_CLOEXEC); - - if (ftruncate(fd, size) < 0) - { - close(fd); - return -1; - } - - unlink(tmp); - return fd; -} - -static E_Wayland_Keyboard_Info * -_e_comp_wl_input_keyboard_info_get(struct xkb_keymap *keymap) -{ - E_Wayland_Keyboard_Info *info = NULL; - char *tmp; - - /* try to allocate space for the keyboard info structure */ - if (!(info = E_NEW(E_Wayland_Keyboard_Info, 1))) - return NULL; - - if (!(info->keymap = xkb_map_ref(keymap))) - { - E_FREE(info); - return NULL; - } - - /* init modifiers */ - info->mod_shift = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_SHIFT); - info->mod_caps = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CAPS); - info->mod_ctrl = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_CTRL); - info->mod_alt = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_ALT); - info->mod_super = xkb_map_mod_get_index(keymap, XKB_MOD_NAME_LOGO); - - /* try to get a string of this keymap */ - if (!(tmp = xkb_map_get_as_string(keymap))) - { - printf("Could not get keymap as string\n"); - E_FREE(info); - return NULL; - } - - info->size = strlen(tmp) + 1; - - /* try to create an fd we can listen on for input */ - info->fd = _e_comp_wl_input_keymap_fd_get(info->size); - if (info->fd < 0) - { - printf("Could not create keymap fd\n"); - E_FREE(info); - return NULL; - } - - info->area = - mmap(NULL, info->size, PROT_READ | PROT_WRITE, MAP_SHARED, info->fd, 0); - - /* TODO: error check mmap */ - - if ((info->area) && (tmp)) - { - strcpy(info->area, tmp); - free(tmp); - } - - return info; -} - -/* input interface functions */ -static void -_e_comp_wl_input_cb_pointer_get(struct wl_client *client, struct wl_resource *resource, unsigned int id) -{ - E_Wayland_Input *input = NULL; - struct wl_resource *ptr = NULL; - - /* try to cast the resource data to our input structure */ - if (!(input = wl_resource_get_user_data(resource))) - return; - - /* check that input has a pointer */ - if (!input->has_pointer) return; - - /* add a pointer object to the client */ - ptr = wl_resource_create(client, &wl_pointer_interface, - wl_resource_get_version(resource), id); - wl_list_insert(&input->wl.seat.pointer->resource_list, - wl_resource_get_link(ptr)); - wl_resource_set_implementation(ptr, &_e_pointer_interface, - input, _e_comp_wl_input_cb_unbind); - - /* if the pointer has a focused surface, set it */ - if ((input->wl.seat.pointer->focus) && - (wl_resource_get_client(input->wl.seat.pointer->focus) == client)) - { - /* tell pointer which surface is focused */ - wl_list_remove(wl_resource_get_link(ptr)); - wl_list_insert(&input->wl.seat.pointer->focus_resource_list, - wl_resource_get_link(ptr)); - - wl_pointer_send_enter(ptr, input->wl.seat.pointer->focus_serial, - input->wl.seat.pointer->focus, - input->wl.seat.pointer->x, - input->wl.seat.pointer->y); - } -} - -static void -_e_comp_wl_input_cb_keyboard_get(struct wl_client *client, struct wl_resource *resource, unsigned int id) -{ - E_Wayland_Input *input = NULL; - struct wl_resource *kbd = NULL; - - /* try to cast the resource data to our input structure */ - if (!(input = wl_resource_get_user_data(resource))) - return; - - /* check that input has a keyboard */ - if (!input->has_keyboard) return; - - /* add a keyboard object to the client */ - kbd = wl_resource_create(client, &wl_keyboard_interface, - wl_resource_get_version(resource), id); - wl_list_insert(&input->wl.seat.keyboard->resource_list, - wl_resource_get_link(kbd)); - wl_resource_set_implementation(kbd, &_e_keyboard_interface, input, - _e_comp_wl_input_cb_unbind); - - /* send the current keymap to the keyboard object */ - wl_keyboard_send_keymap(kbd, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, - input->xkb.info->fd, input->xkb.info->size); - - if (((input->wl.seat.keyboard) && (input->wl.seat.keyboard->focus) && - (wl_resource_get_client(input->wl.seat.keyboard->focus) == client)) || - ((input->wl.seat.pointer) && (input->wl.seat.pointer->focus) && - (wl_resource_get_client(input->wl.seat.pointer->focus) == client))) - { - wl_keyboard_send_modifiers(kbd, input->wl.seat.keyboard->focus_serial, - input->wl.seat.keyboard->modifiers.mods_depressed, - input->wl.seat.keyboard->modifiers.mods_latched, - input->wl.seat.keyboard->modifiers.mods_locked, - input->wl.seat.keyboard->modifiers.group); - } - - /* test if keyboard has a focused client */ - if ((input->wl.seat.keyboard->focus) && - (wl_resource_get_client(input->wl.seat.keyboard->focus) == client)) - { - wl_list_remove(wl_resource_get_link(kbd)); - wl_list_insert(&input->wl.seat.keyboard->focus_resource_list, - wl_resource_get_link(kbd)); - wl_keyboard_send_enter(kbd, input->wl.seat.keyboard->focus_serial, - input->wl.seat.keyboard->focus, - &input->wl.seat.keyboard->keys); - - if (input->wl.seat.keyboard->focus_resource_list.prev == - wl_resource_get_link(kbd)) - { - /* update the keyboard focus in the data device */ - wl_data_device_set_keyboard_focus(&input->wl.seat); - } - } - - input->wl.keyboard_resource = kbd; -} - -static void -_e_comp_wl_input_cb_touch_get(struct wl_client *client, struct wl_resource *resource, unsigned int id) -{ - E_Wayland_Input *input = NULL; - struct wl_resource *tch = NULL; - - /* try to cast the resource data to our input structure */ - if (!(input = wl_resource_get_user_data(resource))) - return; - - /* check that input has a touch */ - if (!input->has_touch) return; - - /* add a touch object to the client */ - tch = wl_resource_create(client, &wl_touch_interface, - wl_resource_get_version(resource), id); - if ((input->wl.seat.touch->focus) && - (wl_resource_get_client(input->wl.seat.touch->focus) == client)) - { - wl_list_insert(&input->wl.seat.touch->resource_list, - wl_resource_get_link(tch)); - } - else - wl_list_insert(&input->wl.seat.touch->focus_resource_list, - wl_resource_get_link(tch)); - - wl_resource_set_implementation(tch, &_e_touch_interface, input, - _e_comp_wl_input_cb_unbind); -} - -/* pointer functions */ -static void -_e_comp_wl_pointer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Input *input = NULL; - - /* try to get the input from this listener */ - if (!(input = container_of(listener, E_Wayland_Input, pointer.surface_destroy))) - return; - - input->pointer.surface = NULL; -} - -static void -_e_comp_wl_pointer_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Wayland_Input *input = NULL; - E_Wayland_Surface *focus = NULL; - - /* safety check */ - if (!ews) return; - - /* see if this surface has 'input' */ - if (!(input = ews->input)) return; - - input->pointer.hot.x -= x; - input->pointer.hot.y -= y; - - /* configure the surface geometry */ - ews->geometry.x = x; - ews->geometry.y = y; - ews->geometry.w = w; - ews->geometry.h = h; - ews->geometry.changed = EINA_TRUE; - - /* tell pixman we are finished with this region */ - pixman_region32_fini(&ews->pending.input); - - /* reinitalize the pending input region */ - pixman_region32_init(&ews->pending.input); - - /* do we have a focused surface ? */ - if (!input->wl.seat.pointer->focus) return; - - focus = wl_resource_get_user_data(input->wl.seat.pointer->focus); - if (!focus) return; - /* NB: Ideally, I wanted to use the e_pointer methods here so that - * the cursor would match the E theme, however Wayland currently - * provides NO Method to get the cursor name :( so we are stuck - * using the pixels from their cursor surface */ - - /* is it mapped ? */ - if ((!focus->mapped) || (!focus->ec)) return; - e_pixmap_dirty(ews->pixmap); - e_pointer_image_set(focus->ec->comp->pointer, ews->pixmap, w, h, input->pointer.hot.x, input->pointer.hot.y); -} - -static void -_e_comp_wl_pointer_unmap(E_Wayland_Surface *ews) -{ - E_Wayland_Input *input = NULL; - - /* safety check */ - if (!ews) return; - - if (!(input = ews->input)) return; - - wl_list_remove(&input->pointer.surface_destroy.link); - - if (input->pointer.surface) - input->pointer.surface->configure = NULL; - - input->pointer.surface = NULL; -} - -/* pointer interface functions */ -static void -_e_comp_wl_pointer_cb_cursor_set(struct wl_client *client, struct wl_resource *resource, unsigned int serial, struct wl_resource *surface_resource, int x, int y) -{ - E_Wayland_Input *input = NULL; - E_Wayland_Surface *ews = NULL; - - /* try to cast the resource data to our input structure */ - if (!(input = wl_resource_get_user_data(resource))) - return; - - /* if we were passed in a surface, try to cast it to our structure */ - if (surface_resource) ews = wl_resource_get_user_data(surface_resource); - - /* if this input has no pointer, get out */ - if (!input->has_pointer) return; - - /* if the input has no current focus, get out */ - if (!input->wl.seat.pointer->focus) - { - /* if we have an existing pointer surface, unmap it */ - if (input->pointer.surface) - { - /* call the unmap function */ - if (input->pointer.surface->unmap) - input->pointer.surface->unmap(input->pointer.surface); - } - - input->pointer.surface = NULL; - - return; - } - - if (wl_resource_get_client(input->wl.seat.pointer->focus) != client) return; - if ((input->wl.seat.pointer->focus_serial - serial) > (UINT32_MAX / 2)) - return; - - /* is the passed in surface the same as our pointer surface ? */ - if ((ews) && (ews != input->pointer.surface)) - { - if (ews->configure) - { - wl_resource_post_error(ews->wl.surface, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Surface already configured"); - return; - } - } - - /* if we have an existing pointer surface, unmap it */ - if (input->pointer.surface) - { - /* call the unmap function */ - if (input->pointer.surface->unmap) - input->pointer.surface->unmap(input->pointer.surface); - } - - input->pointer.surface = ews; - - /* if we don't have a pointer surface, we are done here */ - if (!ews) - { - e_pointer_hide(e_comp_get(NULL)->pointer); - return; - } - - /* set the destroy listener */ - wl_signal_add(&ews->wl.destroy_signal, - &input->pointer.surface_destroy); - - /* set some properties on this surface */ - ews->unmap = _e_comp_wl_pointer_unmap; - ews->configure = _e_comp_wl_pointer_configure; - ews->input = input; - - /* update input structure with new values */ - input->pointer.hot.x = x; - input->pointer.hot.y = y; - - if (&ews->buffer_reference) - { - E_Wayland_Buffer *buf; - - if ((buf = ews->buffer_reference.buffer)) - { - Evas_Coord bw = 0, bh = 0; - - bw = buf->w; - bh = buf->h; - - /* configure the pointer surface */ - _e_comp_wl_pointer_configure(ews, 0, 0, bw, bh); - } - } -} - -static void -_e_comp_wl_pointer_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -/* keyboard interface functions */ -static void -_e_comp_wl_keyboard_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -/* touch interface functions */ -static void -_e_comp_wl_touch_cb_release(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -/* region interface functions */ -static void -_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h) -{ - E_Wayland_Region *ewr = NULL; - - /* try to cast the resource data to our region structure */ - if (!(ewr = wl_resource_get_user_data(resource))) return; - - /* tell pixman to union this region with any previous one */ - pixman_region32_union_rect(&ewr->region, &ewr->region, x, y, w, h); -} - -static void -_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h) -{ - E_Wayland_Region *ewr = NULL; - pixman_region32_t region; - - /* try to cast the resource data to our region structure */ - if (!(ewr = wl_resource_get_user_data(resource))) return; - - /* ask pixman to create a new temporary rect */ - pixman_region32_init_rect(®ion, x, y, w, h); - - /* ask pixman to subtract this temp rect from the existing region */ - pixman_region32_subtract(&ewr->region, &ewr->region, ®ion); - - /* tell pixman we are finished with the temporary rect */ - pixman_region32_fini(®ion); -} - -/* surface functions */ -static void -_e_comp_wl_surface_cb_pending_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Surface *ews = NULL; - - /* try to get the surface from this listener */ - if (!(ews = container_of(listener, E_Wayland_Surface, - pending.buffer_destroy))) - return; - - /* set surface pending buffer to null */ - ews->pending.buffer = NULL; -} - -static void -_e_comp_wl_surface_cb_frame_destroy(struct wl_resource *resource) -{ - E_Wayland_Surface_Frame_Callback *cb = NULL; - - /* try to cast the resource data to our surface frame callback structure */ - if (!(cb = wl_resource_get_user_data(resource))) return; - - wl_list_remove(&cb->wl.link); - - /* free the allocated callback structure */ - E_FREE(cb); -} - -static void -_e_comp_wl_surface_buffer_reference(E_Wayland_Buffer_Reference *ref, E_Wayland_Buffer *buffer) -{ - if ((ref->buffer) && (buffer != ref->buffer)) - { - ref->buffer->busy_count--; - if (ref->buffer->busy_count == 0) - wl_resource_queue_event(ref->buffer->wl.resource, WL_BUFFER_RELEASE); - wl_list_remove(&ref->destroy_listener.link); - } - - if ((buffer) && (buffer != ref->buffer)) - { - buffer->busy_count++; - wl_signal_add(&buffer->wl.destroy_signal, &ref->destroy_listener); - } - - //INF("CURRENT BUFFER SWAP: %p->%p", ref->buffer, buffer); - ref->buffer = buffer; - ref->destroy_listener.notify = - _e_comp_wl_surface_buffer_reference_cb_destroy; -} - -static void -_e_comp_wl_surface_buffer_reference_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Buffer_Reference *ref; - - /* try to get the surface from this listener */ - ref = container_of(listener, E_Wayland_Buffer_Reference, destroy_listener); - if (!ref) return; - - /* set referenced buffer to null */ - ref->buffer = NULL; -} - -static E_Wayland_Buffer * -_e_comp_wl_surface_buffer_resource(struct wl_resource *resource) -{ - E_Wayland_Buffer *buffer; - struct wl_listener *listener; - - listener = - wl_resource_get_destroy_listener(resource, - _e_comp_wl_surface_buffer_cb_destroy); - if (listener) - buffer = container_of(listener, E_Wayland_Buffer, wl.destroy_listener); - else - { - buffer = E_NEW_RAW(E_Wayland_Buffer, 1); - memset(buffer, 0, sizeof(*buffer)); - buffer->wl.resource = resource; - wl_signal_init(&buffer->wl.destroy_signal); - buffer->wl.destroy_listener.notify = - _e_comp_wl_surface_buffer_cb_destroy; - wl_resource_add_destroy_listener(resource, - &buffer->wl.destroy_listener); - } - - return buffer; -} - -static void -_e_comp_wl_surface_buffer_cb_destroy(struct wl_listener *listener, void *data) -{ - E_Wayland_Buffer *buffer; - - buffer = container_of(listener, E_Wayland_Buffer, wl.destroy_listener); - - wl_signal_emit(&buffer->wl.destroy_signal, buffer); - if (buffer->ews) - { - if (buffer->ews->ec && buffer->ews->pixmap && (e_pixmap_resource_get(buffer->ews->pixmap) == data) && - evas_object_visible_get(buffer->ews->ec->frame)) - { - //INF("DESTROYED CURRENT BUFFER: %s", e_pixmap_dirty_get(buffer->ews->pixmap) ? "DIRTY" : "CLEAN"); - e_pixmap_usable_set(buffer->ews->pixmap, 0); - if (!e_pixmap_image_exists(buffer->ews->pixmap)) - { - e_pixmap_image_refresh(buffer->ews->pixmap); - } - - e_pixmap_image_clear(buffer->ews->pixmap, 0); - e_comp_object_damage(buffer->ews->ec->frame, 0, 0, buffer->ews->ec->client.w, buffer->ews->ec->client.h); - e_comp_object_render(buffer->ews->ec->frame); - e_comp_object_render_update_del(buffer->ews->ec->frame); - } - buffer->ews->buffers = eina_inlist_remove(buffer->ews->buffers, EINA_INLIST_GET(buffer)); - } - E_FREE(buffer); -} - -/* surface interface functionss */ -static void -_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int x, int y) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Buffer *buffer = NULL; - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - - if (buffer_resource) - { - buffer = _e_comp_wl_surface_buffer_resource(buffer_resource); - if (ews->ec && (!ews->buffer_reference.buffer)) - { - e_pixmap_usable_set(ews->pixmap, 1); - } - } - - /* reference any existing buffers */ - _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, buffer); - if (buffer) - { - if (!buffer->ews) - ews->buffers = eina_inlist_append(ews->buffers, EINA_INLIST_GET(buffer)); - buffer->ews = ews; - } - //INF("ATTACHED NEW BUFFER"); - e_pixmap_dirty(ews->pixmap); - //if (ews->ec) - //e_comp_object_damage(ews->ec->frame, 0, 0, ews->ec->client.w, ews->ec->client.h); - - - /* if we are setting a null buffer, then unmap the surface */ - if (!buffer) - { - if (ews->mapped) - { - if (ews->unmap) ews->unmap(ews); - } - } - - /* if we already have a pending buffer, remove the listener */ - if (ews->pending.buffer) - wl_list_remove(&ews->pending.buffer_destroy.link); - - /* set some pending values */ - ews->pending.x = x; - ews->pending.y = y; - ews->pending.buffer = buffer; -// if (buffer) - ews->pending.new_buffer = EINA_TRUE; - - /* if we were given a buffer, initialize the destroy signal */ - if (buffer) - wl_signal_add(&buffer->wl.destroy_signal, &ews->pending.buffer_destroy); -} - -static void -_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int x, int y, int w, int h) -{ - E_Wayland_Surface *ews = NULL; - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - e_pixmap_image_clear(ews->pixmap, 1); - - /* tell pixman to add this damage to pending */ - pixman_region32_union_rect(&ews->pending.damage, &ews->pending.damage, - x, y, w, h); -} - -static void -_e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, unsigned int callback) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Surface_Frame_Callback *cb = NULL; - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - - /* try to allocate space for a new frame callback */ - if (!(cb = E_NEW(E_Wayland_Surface_Frame_Callback, 1))) - { - wl_resource_post_no_memory(resource); - return; - } - - cb->wl.resource = - wl_resource_create(client, &wl_callback_interface, 1, callback); - wl_resource_set_implementation(cb->wl.resource, NULL, cb, - _e_comp_wl_surface_cb_frame_destroy); - - /* add this callback to the surface list of pending frames */ - wl_list_insert(ews->pending.frames.prev, &cb->wl.link); -} - -static void -_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) -{ - E_Wayland_Surface *ews = NULL; - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - - if (region_resource) - { - E_Wayland_Region *ewr = NULL; - - /* copy this region to the pending opaque region */ - if ((ewr = wl_resource_get_user_data(region_resource))) - pixman_region32_copy(&ews->pending.opaque, &ewr->region); - } - else - { - /* tell pixman we are finished with this region */ - pixman_region32_fini(&ews->pending.opaque); - - /* reinitalize the pending opaque region */ - pixman_region32_init(&ews->pending.opaque); - } -} - -static void -_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource) -{ - E_Wayland_Surface *ews = NULL; - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - - if (region_resource) - { - E_Wayland_Region *ewr = NULL; - - /* copy this region to the pending input region */ - if ((ewr = wl_resource_get_user_data(region_resource))) - pixman_region32_copy(&ews->pending.input, &ewr->region); - } - else - { - /* tell pixman we are finished with this region */ - pixman_region32_fini(&ews->pending.input); - - /* reinitalize the pending input region */ - pixman_region32_init_rect(&ews->pending.input, INT32_MIN, INT32_MIN, - UINT32_MAX, UINT32_MAX); - } -} - -static void -_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Wayland_Surface *ews = NULL; - Evas_Coord bw = 0, bh = 0; - pixman_region32_t opaque; - pixman_box32_t *rects; - int n = 0; - - /* FIXME */ - - /* try to cast the resource data to our surface structure */ - if (!(ews = wl_resource_get_user_data(resource))) return; - - /* if we have a pending buffer or a new pending buffer, attach it */ - if ((ews->pending.buffer) || (ews->pending.new_buffer)) - { - /* reference the pending buffer */ - _e_comp_wl_surface_buffer_reference(&ews->buffer_reference, - ews->pending.buffer); - - /* if the pending buffer is NULL, unmap the surface */ - if (!ews->pending.buffer) - { - if (ews->mapped) - { - if (ews->unmap) ews->unmap(ews); - } - } - } - e_pixmap_dirty(ews->pixmap); - e_pixmap_refresh(ews->pixmap); - e_pixmap_size_get(ews->pixmap, &bw, &bh); - - /* if we have a new pending buffer, call configure */ - if ((ews->configure) && (ews->pending.new_buffer)) -// ews->configure(ews, ews->pending.x, ews->pending.y, bw, bh); - ews->configure(ews, ews->geometry.x, ews->geometry.y, bw, bh); - - if (ews->pending.buffer) - wl_list_remove(&ews->pending.buffer_destroy.link); - - /* set some pending values */ - ews->pending.buffer = NULL; - ews->pending.x = 0; - ews->pending.y = 0; - ews->pending.new_buffer = EINA_FALSE; - - /* set surface damage */ - pixman_region32_union(&ews->region.damage, &ews->region.damage, - &ews->pending.damage); - pixman_region32_intersect_rect(&ews->region.damage, &ews->region.damage, - 0, 0, ews->geometry.w, ews->geometry.h); - - /* empty any pending damage */ - pixman_region32_fini(&ews->pending.damage); - pixman_region32_init(&ews->pending.damage); - - /* get the extent of the damage region */ - if (ews->ec) - { - rects = pixman_region32_rectangles(&ews->region.damage, &n); - while (n--) - { - pixman_box32_t *r; - - r = &rects[n]; - - /* send damages to the image */ - e_comp_object_damage(ews->ec->frame, r->x1, r->y1, r->x2, r->y2); - } - } - - /* tell pixman we are finished with this region */ - /* pixman_region32_fini(&ews->region.damage); */ - - /* reinitalize the damage region */ - /* pixman_region32_init(&ews->region.damage); */ - - /* calculate new opaque region */ - pixman_region32_init_rect(&opaque, 0, 0, ews->geometry.w, ews->geometry.h); - pixman_region32_intersect(&opaque, &opaque, &ews->pending.opaque); - - /* if new opaque region is not equal to the current one, then update */ - if (!pixman_region32_equal(&opaque, &ews->region.opaque)) - { - pixman_region32_copy(&ews->region.opaque, &opaque); - ews->geometry.changed = EINA_TRUE; - } - - /* tell pixman we are done with this temporary region */ - pixman_region32_fini(&opaque); - - /* clear any existing input region */ - pixman_region32_fini(&ews->region.input); - - /* initialize a new input region */ - pixman_region32_init_rect(&ews->region.input, 0, 0, - ews->geometry.w, ews->geometry.h); - - /* put pending input region into new input region */ - pixman_region32_intersect(&ews->region.input, &ews->region.input, - &ews->pending.input); - - /* check for valid input region */ -// if (pixman_region32_not_empty(&ews->region.input)) - { - /* get the extent of the input region */ - rects = pixman_region32_extents(&ews->region.input); - - /* update the smart object's input region */ - if (ews->ec) - e_comp_object_input_area_set(ews->ec->frame, rects->x1, rects->y1, - rects->x2, rects->y2); - } - - /* put any pending frame callbacks into active list */ - wl_list_insert_list(&ews->wl.frames, &ews->pending.frames); - - /* clear list of pending frame callbacks */ - wl_list_init(&ews->pending.frames); - - ews->updates = 1; - - _e_wl_comp->surfaces = eina_inlist_promote(_e_wl_comp->surfaces, EINA_INLIST_GET(ews)); - - /* TODO: schedule repaint ?? */ -} - -static void -_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int transform EINA_UNUSED) -{ - -} - -static void -_e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int scale EINA_UNUSED) -{ - -} diff --git a/src/bin/e_comp_wl.h b/src/bin/e_comp_wl.h deleted file mode 100644 index e60a7dc72..000000000 --- a/src/bin/e_comp_wl.h +++ /dev/null @@ -1,640 +0,0 @@ -#ifdef E_TYPEDEFS - -#else -# ifndef E_COMP_WL_H -# define E_COMP_WL_H - -# define WL_HIDE_DEPRECATED -# include - -/* NB: Turn off shadow warnings for Wayland includes */ -# pragma GCC diagnostic ignored "-Wshadow" -# include -# pragma GCC diagnostic pop - -# include - -/* headers for terminal support */ -# include -# include - -# ifdef __linux__ -# include -# else -# define BTN_LEFT 0x110 -# define BTN_RIGHT 0x111 -# define BTN_MIDDLE 0x112 -# define BTN_SIDE 0x113 -# define BTN_EXTRA 0x114 -# define BTN_FORWARD 0x115 -# define BTN_BACK 0x116 -# endif - -# ifdef HAVE_WAYLAND_EGL -# include -# include -# endif - -# define container_of(ptr, type, member) ({ \ - const __typeof__(((type *)0)->member) *__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type,member));}) - -typedef enum _E_Wayland_Shell_Surface_Type E_Wayland_Shell_Surface_Type; - -typedef struct _E_Wayland_Region E_Wayland_Region; -typedef struct _E_Wayland_Surface E_Wayland_Surface; -typedef struct _E_Wayland_Surface_Frame_Callback E_Wayland_Surface_Frame_Callback; -typedef struct _E_Wayland_Shell_Surface E_Wayland_Shell_Surface; -typedef struct _E_Wayland_Shell_Interface E_Wayland_Shell_Interface; -typedef struct _E_Wayland_Shell_Grab E_Wayland_Shell_Grab; -typedef struct _E_Wayland_Keyboard_Info E_Wayland_Keyboard_Info; -typedef struct _E_Wayland_Input E_Wayland_Input; -typedef struct _E_Wayland_Compositor E_Wayland_Compositor; -typedef struct _E_Wayland_Output E_Wayland_Output; -typedef struct _E_Wayland_Output_Mode E_Wayland_Output_Mode; -typedef struct _E_Wayland_Terminal E_Wayland_Terminal; -typedef struct _E_Wayland_Plane E_Wayland_Plane; -typedef struct _E_Wayland_Buffer E_Wayland_Buffer; -typedef struct _E_Wayland_Buffer_Reference E_Wayland_Buffer_Reference; - -/* - * NB: All of these structs and interfaces were recently removed from - * wayland so for now, reimplement them here - */ -struct wl_seat; -struct wl_pointer; -struct wl_keyboard; -struct wl_touch; - -struct wl_pointer_grab; -struct wl_pointer_grab_interface -{ - void (*focus)(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y); - void (*motion)(struct wl_pointer_grab *grab, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y); - void (*button)(struct wl_pointer_grab *grab, unsigned int timestamp, unsigned int button, unsigned int state); -}; -struct wl_pointer_grab -{ - const struct wl_pointer_grab_interface *interface; - struct wl_pointer *pointer; - struct wl_resource *focus; - wl_fixed_t x, y; - unsigned int edges; -}; - -struct wl_keyboard_grab; -struct wl_keyboard_grab_interface -{ - void (*key)(struct wl_keyboard_grab *grab, unsigned int timestamp, unsigned int key, unsigned int state); - void (*modifiers)(struct wl_keyboard_grab *grab, unsigned int serial, unsigned int mods_depressed, unsigned int mods_latched, unsigned int mods_locked, unsigned int group); -}; -struct wl_keyboard_grab -{ - const struct wl_keyboard_grab_interface *interface; - struct wl_keyboard *keyboard; - struct wl_resource *focus; - unsigned int key; -}; - -struct wl_touch_grab; -struct wl_touch_grab_interface -{ - void (*down)(struct wl_touch_grab *grab, unsigned int timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy); - void (*up)(struct wl_touch_grab *grab, unsigned int timestamp, int touch_id); - void (*motion)(struct wl_touch_grab *grab, unsigned int timestamp, int touch_id, wl_fixed_t sx, wl_fixed_t sy); -}; -struct wl_touch_grab -{ - const struct wl_touch_grab_interface *interface; - struct wl_touch *touch; - struct wl_resource *focus; -}; - -struct wl_pointer -{ - struct wl_seat *seat; - - struct wl_list resource_list; - struct wl_list focus_resource_list; - struct wl_resource *focus; - unsigned int focus_serial; - struct wl_signal focus_signal; - - struct wl_pointer_grab *grab; - struct wl_pointer_grab default_grab; - wl_fixed_t grab_x, grab_y; - unsigned int grab_button; - unsigned int grab_serial; - unsigned int grab_time; - - wl_fixed_t x, y; - struct wl_resource *current; - struct wl_listener current_listener; - wl_fixed_t current_x, current_y; - - unsigned int button_count; -}; - -struct wl_keyboard -{ - struct wl_seat *seat; - - struct wl_list resource_list; - struct wl_list focus_resource_list; - struct wl_resource *focus; - unsigned int focus_serial; - struct wl_signal focus_signal; - - struct wl_keyboard_grab *grab; - struct wl_keyboard_grab default_grab; - unsigned int grab_key; - unsigned int grab_serial; - unsigned int grab_time; - - struct wl_array keys; - - struct - { - unsigned int mods_depressed; - unsigned int mods_latched; - unsigned int mods_locked; - unsigned int group; - } modifiers; -}; - -struct wl_touch -{ - struct wl_seat *seat; - - struct wl_list resource_list; - struct wl_list focus_resource_list; - struct wl_resource *focus; - unsigned int focus_serial; - struct wl_signal focus_signal; - - struct wl_touch_grab *grab; - struct wl_touch_grab default_grab; - wl_fixed_t grab_x, grab_y; - unsigned int grab_serial; - unsigned int grab_time; -}; - -struct wl_data_offer -{ - struct wl_resource *resource; - struct wl_data_source *source; - struct wl_listener source_destroy_listener; -}; - -struct wl_data_source -{ - struct wl_resource *resource; - struct wl_array mime_types; - struct wl_signal destroy_signal; - - void (*accept)(struct wl_data_source *source, - uint32_t serial, const char *mime_type); - void (*send)(struct wl_data_source *source, - const char *mime_type, int32_t fd); - void (*cancel)(struct wl_data_source *source); -}; - -struct wl_seat -{ - struct wl_list base_resource_list; - struct wl_signal destroy_signal; - - struct wl_pointer *pointer; - struct wl_keyboard *keyboard; - struct wl_touch *touch; - - unsigned int selection_serial; - struct wl_data_source *selection_data_source; - struct wl_listener selection_data_source_listener; - struct wl_signal selection_signal; - - struct wl_list drag_resource_list; - struct wl_client *drag_client; - struct wl_data_source *drag_data_source; - struct wl_listener drag_data_source_listener; - struct wl_resource *drag_focus; - struct wl_resource *drag_focus_resource; - struct wl_listener drag_focus_listener; - struct wl_pointer_grab drag_grab; - struct wl_resource *drag_surface; - struct wl_listener drag_icon_listener; - struct wl_signal drag_icon_signal; -}; - -enum _E_Wayland_Shell_Surface_Type -{ - E_WAYLAND_SHELL_SURFACE_TYPE_NONE, - E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL, - E_WAYLAND_SHELL_SURFACE_TYPE_TRANSIENT, - E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN, - E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED, - E_WAYLAND_SHELL_SURFACE_TYPE_POPUP -}; - -struct _E_Wayland_Region -{ - struct - { - struct wl_resource *resource; - } wl; - - pixman_region32_t region; -}; - -struct _E_Wayland_Surface_Frame_Callback -{ - struct - { - struct wl_resource *resource; - struct wl_list link; - } wl; -}; - -struct _E_Wayland_Buffer -{ - EINA_INLIST; - struct - { - struct wl_resource *resource; - struct wl_signal destroy_signal; - struct wl_listener destroy_listener; - union - { - struct wl_shm_buffer *shm_buffer; - void *legacy_buffer; - }; - } wl; - - int w, h; - unsigned int busy_count; - E_Wayland_Surface *ews; -}; - -struct _E_Wayland_Buffer_Reference -{ - E_Wayland_Buffer *buffer; - struct wl_listener destroy_listener; -}; - -struct _E_Wayland_Surface -{ - EINA_INLIST; - Ecore_Window id; - struct - { - struct wl_client *client; - struct wl_resource *surface; - struct wl_signal destroy_signal; - struct wl_list link, frames; - } wl; - - struct - { - E_Wayland_Buffer *buffer; - struct wl_listener buffer_destroy; - struct wl_list frames; - Evas_Coord x, y; - Eina_Bool new_buffer : 1; - pixman_region32_t damage, opaque, input; - } pending; - - E_Wayland_Buffer_Reference buffer_reference; - - struct - { - Evas_Coord x, y; - Evas_Coord w, h; - Eina_Bool changed : 1; - } geometry; - - struct - { - pixman_region32_t opaque, input; - pixman_region32_t damage, clip; - } region; - - E_Client *ec; - E_Pixmap *pixmap; - Eina_Inlist *buffers; - - E_Wayland_Shell_Surface *shell_surface; - Eina_Bool mapped : 1; - Eina_Bool updates : 1; //surface has render updates - - E_Wayland_Input *input; - - void (*map) (E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); - void (*unmap) (E_Wayland_Surface *ews); - void (*configure) (E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -}; - -struct _E_Wayland_Shell_Surface -{ - struct - { - struct wl_resource *resource; - struct wl_listener surface_destroy; - struct wl_signal destroy_signal; - struct wl_list link; - } wl; - - struct - { - Evas_Coord x, y; - Evas_Coord w, h; - Eina_Bool valid : 1; - } saved; - - struct - { - struct wl_pointer_grab grab; - struct wl_seat *seat; - struct wl_listener parent_destroy; - int x, y; - Eina_Bool up : 1; - unsigned int serial; - } popup; - - struct - { - Evas_Coord x, y; - unsigned int flags; - } transient; - - E_Wayland_Surface *surface, *parent; - E_Wayland_Shell_Surface_Type type, next_type; - - Eina_Stringshare *title, *clas; - - Eina_Bool active : 1; - - void *shell; - void *ping_timer; -}; - -struct _E_Wayland_Shell_Interface -{ - void *shell; - - E_Wayland_Shell_Surface *(*shell_surface_create) (void *shell, E_Wayland_Surface *ews, const void *client); - void (*toplevel_set) (E_Wayland_Shell_Surface *ewss); - void (*transient_set) (E_Wayland_Shell_Surface *ewss, E_Wayland_Surface *ews, int x, int y, unsigned int flags); - void (*fullscreen_set) (E_Wayland_Shell_Surface *ewss, unsigned int method, unsigned int framerate, void *output); - void (*popup_set) (E_Wayland_Shell_Surface *ewss, E_Wayland_Surface *ews, void *seat, unsigned int serial, int x, int y, unsigned int flags); - void (*maximized_set) (E_Wayland_Shell_Surface *ewss, unsigned int edges); - int (*move) (E_Wayland_Shell_Surface *ewss, void *seat); - int (*resize) (E_Wayland_Shell_Surface *ewss, void *seat, unsigned int edges); -}; - -struct _E_Wayland_Shell_Grab -{ - struct wl_pointer_grab grab; - Evas_Coord x, y, w, h; - unsigned int edges; - - E_Wayland_Shell_Surface *shell_surface; - struct wl_listener shell_surface_destroy; -}; - -struct _E_Wayland_Keyboard_Info -{ - struct xkb_keymap *keymap; - int fd; - size_t size; - char *area; - xkb_mod_index_t mod_shift, mod_caps, mod_ctrl, mod_alt, mod_super; -}; - -struct _E_Wayland_Input -{ - struct - { - struct wl_seat seat; - struct wl_pointer pointer; - struct wl_keyboard keyboard; - struct wl_resource *keyboard_resource; - struct wl_list link; - } wl; - - struct - { - E_Wayland_Keyboard_Info *info; - struct xkb_state *state; - } xkb; - - struct - { - E_Wayland_Surface *surface; - struct wl_listener surface_destroy; - struct - { - Evas_Coord x, y; - } hot; - } pointer; - - Eina_Bool has_pointer : 1; - Eina_Bool has_keyboard : 1; - Eina_Bool has_touch : 1; -}; - -struct _E_Wayland_Compositor -{ - struct - { - struct wl_display *display; - struct wl_event_loop *loop; - } wl; - - struct - { - struct wl_signal destroy; - struct wl_signal activate; - struct wl_signal kill; - struct wl_signal seat; - } signals; - - struct - { - struct xkb_rule_names names; - struct xkb_context *context; - } xkb; - -#ifdef HAVE_WAYLAND_EGL - struct - { - EGLDisplay display; - EGLContext context; - EGLConfig config; - PFNEGLBINDWAYLANDDISPLAYWL bind_display; - PFNEGLUNBINDWAYLANDDISPLAYWL unbind_display; - Eina_Bool bound : 1; - } egl; -#endif - - E_Wayland_Shell_Interface shell_interface; - -#ifdef HAVE_WAYLAND_ONLY - Eina_Bool focus : 1; - - unsigned int output_pool; -#endif - - Ecore_Event_Handler *kbd_handler; - Ecore_Fd_Handler *fd_handler; - Ecore_Idler *idler; - - E_Wayland_Input *input; - - Eina_Inlist *surfaces; - Eina_List *seats; - - void (*ping_cb) (E_Wayland_Surface *ews, unsigned int serial); -}; - -struct _E_Wayland_Output -{ - unsigned int id; - - void *render_state; - - struct - { - struct wl_list link; - struct wl_list resources; - struct wl_global *global; - } wl; - - E_Wayland_Compositor *compositor; - - struct - { - Evas_Coord x, y, w, h; - Evas_Coord mm_w, mm_h; - } geometry; - - pixman_region32_t region, prev_damage; - - Eina_Bool repaint_needed : 1; - Eina_Bool repaint_scheduled : 1; - - Eina_Bool dirty : 1; - - struct - { - struct wl_signal sig; - unsigned int timestamp; - } frame; - - char *make, *model; - unsigned int subpixel, transform; - - struct - { - E_Wayland_Output_Mode *current; - E_Wayland_Output_Mode *origin; - struct wl_list list; - } mode; - - void (*repaint) (E_Wayland_Output *output, pixman_region32_t *damage); - void (*destroy) (E_Wayland_Output *output); - int (*switch_mode) (E_Wayland_Output *output, E_Wayland_Output_Mode *mode); - - /* TODO: add backlight support */ -}; - -struct _E_Wayland_Output_Mode -{ - struct - { - struct wl_list link; - } wl; - - unsigned int flags; - Evas_Coord w, h; - unsigned int refresh; -}; - -struct _E_Wayland_Terminal -{ - E_Wayland_Compositor *compositor; - - int fd, kbd_mode; - - struct termios attributes; - - struct - { - struct wl_event_source *input; - struct wl_event_source *vt; - } wl; - - struct - { - void (*func) (E_Wayland_Compositor *compositor, int event); - int current, starting; - Eina_Bool exists : 1; - } vt; -}; - -struct _E_Wayland_Plane -{ - pixman_region32_t damage, clip; - Evas_Coord x, y; - struct wl_list link; -}; - -/* external variables */ -extern EAPI E_Wayland_Compositor *_e_wl_comp; - -EAPI Eina_Bool e_comp_wl_init(void); -EINTERN void e_comp_wl_shutdown(void); - -#ifdef HAVE_WAYLAND_ONLY -EAPI int e_comp_wl_input_read(int fd EINA_UNUSED, unsigned int mask EINA_UNUSED, void *data); -#endif - -EAPI void wl_seat_init(struct wl_seat *seat); -EAPI void wl_seat_release(struct wl_seat *seat); - -EAPI void wl_seat_set_pointer(struct wl_seat *seat, struct wl_pointer *pointer); -EAPI void wl_seat_set_keyboard(struct wl_seat *seat, struct wl_keyboard *keyboard); -EAPI void wl_seat_set_touch(struct wl_seat *seat, struct wl_touch *touch); - -EAPI void wl_pointer_init(struct wl_pointer *pointer); -EAPI void wl_pointer_set_focus(struct wl_pointer *pointer, struct wl_resource *surface, wl_fixed_t sx, wl_fixed_t sy); -EAPI void wl_pointer_start_grab(struct wl_pointer *pointer, struct wl_pointer_grab *grab); -EAPI void wl_pointer_end_grab(struct wl_pointer *pointer); - -EAPI void wl_keyboard_init(struct wl_keyboard *keyboard); -EAPI void wl_keyboard_set_focus(struct wl_keyboard *keyboard, struct wl_resource *surface); -EAPI void wl_keyboard_start_grab(struct wl_keyboard *device, struct wl_keyboard_grab *grab); -EAPI void wl_keyboard_end_grab(struct wl_keyboard *keyboard); - -EAPI void wl_touch_init(struct wl_touch *touch); -EAPI void wl_touch_start_grab(struct wl_touch *device, struct wl_touch_grab *grab); -EAPI void wl_touch_end_grab(struct wl_touch *touch); - -EAPI void wl_data_device_set_keyboard_focus(struct wl_seat *seat); -EAPI int wl_data_device_manager_init(struct wl_display *display); -EAPI struct wl_resource *wl_data_source_send_offer(struct wl_data_source *source, struct wl_resource *target); -EAPI void wl_seat_set_selection(struct wl_seat *seat, struct wl_data_source *source, uint32_t serial); - -EAPI unsigned int e_comp_wl_time_get(void); -EAPI void e_comp_wl_input_modifiers_update(unsigned int serial); - -EAPI void e_comp_wl_mouse_button(struct wl_resource *resource, uint32_t serial, uint32_t timestamp, uint32_t button, uint32_t state_w); -EAPI Eina_Bool e_comp_wl_cb_keymap_changed(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED); - -static inline uint64_t -e_comp_wl_id_get(uint32_t client, uint32_t surface) -{ - return ((uint64_t)surface << 32) + (uint64_t)client; -} - -# endif -#endif diff --git a/src/bin/e_surface.c b/src/bin/e_surface.c deleted file mode 100644 index 7e13f4141..000000000 --- a/src/bin/e_surface.c +++ /dev/null @@ -1,438 +0,0 @@ -#include "e.h" -//#include "e_comp_wl.h" -#include "e_surface.h" - -/* local structures */ -typedef struct _E_Smart_Data E_Smart_Data; -struct _E_Smart_Data -{ - /* canvas */ - Evas *evas; - - /* object geometry */ - Evas_Coord x, y, w, h; - - /* input geometry */ - struct - { - Evas_Coord x, y, w, h; - } input; - - /* main image object where we draw pixels to */ - Evas_Object *o_img; - - /* input rectangle */ - Evas_Object *o_input; - - double mouse_down_time; -}; - -/* smart function prototypes */ -static void _e_smart_add(Evas_Object *obj); -static void _e_smart_del(Evas_Object *obj); -static void _e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y); -static void _e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h); -static void _e_smart_show(Evas_Object *obj); -static void _e_smart_hide(Evas_Object *obj); -static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip); -static void _e_smart_clip_unset(Evas_Object *obj); - -/* local function prototypes */ -static void _e_surface_cb_focus_in(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED); -static void _e_surface_cb_focus_out(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED); -static void _e_surface_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_surface_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_surface_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_surface_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_surface_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event); -static void _e_surface_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event); -static void _e_surface_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_surface_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); - -EAPI Evas_Object * -e_surface_add(Evas *evas) -{ - /* Evas_Object *obj = NULL; */ - /* E_Smart_Data *sd = NULL; */ - - static Evas_Smart *smart = NULL; - static const Evas_Smart_Class sc = - { - "smart_surface", EVAS_SMART_CLASS_VERSION, - _e_smart_add, _e_smart_del, _e_smart_move, _e_smart_resize, - _e_smart_show, _e_smart_hide, NULL, - _e_smart_clip_set, _e_smart_clip_unset, - NULL, NULL, NULL, NULL, NULL, NULL, NULL - }; - - /* create the smart class */ - if (!smart) - if (!(smart = evas_smart_class_new(&sc))) - return NULL; - - /* create new smart object */ - /* obj = evas_object_smart_add(evas, smart); */ - - /* get the smart data and set reference to the surface */ - /* if ((sd = evas_object_smart_data_get(obj))) */ - /* sd->ews = ews; */ - - /* return newly created smart object */ - return evas_object_smart_add(evas, smart); -} - -EAPI void -e_surface_input_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - sd->input.x = x; - sd->input.y = y; - sd->input.w = w; - sd->input.h = h; - - if ((w >= 0) && (h >= 0)) - { - if (sd->o_img) evas_object_pass_events_set(sd->o_img, EINA_TRUE); - } - else - if (sd->o_img) evas_object_pass_events_set(sd->o_img, EINA_FALSE); - - /* update input rectangle geometry */ - if (sd->o_input) - { - evas_object_move(sd->o_input, x, y); - evas_object_resize(sd->o_input, w, h); - } -} - -EAPI void -e_surface_damage_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* update the image damaged area */ - if (sd->o_img) - evas_object_image_data_update_add(sd->o_img, x, y, w, h); -} - -EAPI void -e_surface_image_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h, void *pixels) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* update the image damaged area */ - if (sd->o_img) - { - evas_object_image_size_set(sd->o_img, w, h); - evas_object_image_data_copy_set(sd->o_img, pixels); - } -} - -EAPI void -e_surface_border_input_set(Evas_Object *obj, E_Client *ec) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - //e_client_input_object_set(bd, sd->o_input); -} - -/* smart functions */ -static void -_e_smart_add(Evas_Object *obj) -{ - E_Smart_Data *sd = NULL; - - /* try to allocate space for the smart data structure */ - if (!(sd = E_NEW(E_Smart_Data, 1))) return; - - /* get a reference to the canvas */ - sd->evas = evas_object_evas_get(obj); - evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, - _e_surface_cb_focus_in, obj); - evas_event_callback_add(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, - _e_surface_cb_focus_out, obj); - - /* create the base input rectangle */ - sd->o_input = evas_object_rectangle_add(sd->evas); - evas_object_color_set(sd->o_input, 0, 0, 0, 0); - evas_object_propagate_events_set(sd->o_input, EINA_FALSE); - evas_object_repeat_events_set(sd->o_input, EINA_FALSE); - - /* we have to set focus to the input object first, or else Evas will - * never report any key events (up/down) to us */ - evas_object_focus_set(sd->o_input, EINA_TRUE); - - /* add the event callbacks we need to listen for */ - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_IN, - _e_surface_cb_mouse_in, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_OUT, - _e_surface_cb_mouse_out, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_MOVE, - _e_surface_cb_mouse_move, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_DOWN, - _e_surface_cb_mouse_down, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_UP, - _e_surface_cb_mouse_up, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_MOUSE_WHEEL, - _e_surface_cb_mouse_wheel, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_KEY_DOWN, - _e_surface_cb_key_down, obj); - evas_object_event_callback_add(sd->o_input, EVAS_CALLBACK_KEY_UP, - _e_surface_cb_key_up, obj); - evas_object_smart_member_add(sd->o_input, obj); - - /* create the image object */ - sd->o_img = evas_object_image_filled_add(sd->evas); - evas_object_image_content_hint_set(sd->o_img, EVAS_IMAGE_CONTENT_HINT_DYNAMIC); - evas_object_image_scale_hint_set(sd->o_img, EVAS_IMAGE_SCALE_HINT_DYNAMIC); - evas_object_image_smooth_scale_set(sd->o_img, EINA_FALSE); - evas_object_image_alpha_set(sd->o_img, EINA_TRUE); - evas_object_pass_events_set(sd->o_img, EINA_FALSE); - evas_object_propagate_events_set(sd->o_img, EINA_FALSE); - evas_object_smart_member_add(sd->o_img, obj); - - /* set the objects smart data */ - evas_object_smart_data_set(obj, sd); -} - -static void -_e_smart_del(Evas_Object *obj) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* delete the image object */ - if (sd->o_img) evas_object_del(sd->o_img); - - /* delete the input rectangle */ - if (sd->o_input) - { - /* delete the callbacks */ - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_IN, - _e_surface_cb_mouse_in); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_OUT, - _e_surface_cb_mouse_out); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_MOVE, - _e_surface_cb_mouse_move); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_DOWN, - _e_surface_cb_mouse_down); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_UP, - _e_surface_cb_mouse_up); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_MOUSE_WHEEL, - _e_surface_cb_mouse_wheel); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_KEY_DOWN, - _e_surface_cb_key_down); - evas_object_event_callback_del(sd->o_input, EVAS_CALLBACK_KEY_UP, - _e_surface_cb_key_up); - - evas_object_del(sd->o_input); - } - - /* delete the event callbacks */ - evas_event_callback_del(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_IN, - _e_surface_cb_focus_in); - evas_event_callback_del(sd->evas, EVAS_CALLBACK_CANVAS_FOCUS_OUT, - _e_surface_cb_focus_out); - - /* free the allocated smart data structure */ - E_FREE(sd); - - /* set the objects smart data */ - evas_object_smart_data_set(obj, NULL); -} - -static void -_e_smart_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - if ((sd->x == x) && (sd->y == y)) return; - - sd->x = x; - sd->y = y; - - /* move the input rectangle */ - if (sd->o_input) - evas_object_move(sd->o_input, sd->input.x, sd->input.y); - - /* move the image object */ - if (sd->o_img) evas_object_move(sd->o_img, x, y); -} - -static void -_e_smart_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - if ((sd->w == w) && (sd->h == h)) return; - - sd->w = w; - sd->h = h; - - /* resize the input rectangle */ - if (sd->o_input) - evas_object_resize(sd->o_input, sd->input.w, sd->input.h); - - /* resize the image object */ - if (sd->o_img) evas_object_resize(sd->o_img, w, h); -} - -static void -_e_smart_show(Evas_Object *obj) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* show the input rectangle */ - if (sd->o_input) evas_object_show(sd->o_input); - - /* show the image object */ - if (sd->o_img) evas_object_show(sd->o_img); -} - -static void -_e_smart_hide(Evas_Object *obj) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* hide the input rectangle */ - if (sd->o_input) evas_object_hide(sd->o_input); - - /* hide the image object */ - if (sd->o_img) evas_object_hide(sd->o_img); -} - -static void -_e_smart_clip_set(Evas_Object *obj, Evas_Object *clip) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* TODO: Hmmm, set clip on the input rectangle ?? */ - - /* set the clip on the image object */ - if (sd->o_img) evas_object_clip_set(sd->o_img, clip); -} - -static void -_e_smart_clip_unset(Evas_Object *obj) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(obj))) return; - - /* TODO: Hmmm, unset clip on the input rectangle ?? */ - - /* unset the image object clip */ - if (sd->o_img) evas_object_clip_unset(sd->o_img); -} - -/* local functions */ -static void -_e_surface_cb_focus_in(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED) -{ - evas_object_smart_callback_call(data, "focus_in", NULL); -} - -static void -_e_surface_cb_focus_out(void *data, Evas *evas EINA_UNUSED, void *event EINA_UNUSED) -{ - evas_object_smart_callback_call(data, "focus_out", NULL); -} - -static void -_e_surface_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "mouse_in", event); -} - -static void -_e_surface_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "mouse_out", event); -} - -static void -_e_surface_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "mouse_move", event); -} - -static void -_e_surface_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Smart_Data *sd = NULL; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(data))) return; - - /* grab the loop time for this mouse down event - * - * NB: we use this for comparison in the mouse_up callback due to - * some e_border grab shenanigans. Basically, this lets us ignore the - * spurious mouse_up that we get from e_border grabs */ - sd->mouse_down_time = ecore_loop_time_get(); - evas_object_smart_callback_call(data, "mouse_down", event); -} - -static void -_e_surface_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Smart_Data *sd = NULL; - double timestamp; - - /* try to get the objects smart data */ - if (!(sd = evas_object_smart_data_get(data))) return; - - timestamp = ecore_loop_time_get(); - if (fabs(timestamp - sd->mouse_down_time) <= 0.010) return; - - evas_object_smart_callback_call(data, "mouse_up", event); -} - -static void -_e_surface_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "mouse_wheel", event); -} - -static void -_e_surface_cb_key_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "key_down", event); -} - -static void -_e_surface_cb_key_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - evas_object_smart_callback_call(data, "key_up", event); -} diff --git a/src/bin/e_surface.h b/src/bin/e_surface.h deleted file mode 100644 index 9bf822338..000000000 --- a/src/bin/e_surface.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifdef E_TYPEDEFS -#else -# ifndef E_SURFACE_H -# define E_SURFACE_H - -EAPI Evas_Object *e_surface_add(Evas *evas); -EAPI void e_surface_input_set(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -EAPI void e_surface_damage_add(Evas_Object *obj, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -EAPI void e_surface_image_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h, void *pixels); -EAPI void e_surface_border_input_set(Evas_Object *obj, E_Client *ec); - -# endif -#endif diff --git a/src/modules/wl_desktop_shell/e-desktop-shell.xml b/src/modules/wl_desktop_shell/e-desktop-shell.xml deleted file mode 100644 index 50c343c04..000000000 --- a/src/modules/wl_desktop_shell/e-desktop-shell.xml +++ /dev/null @@ -1,90 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - Tell the server, that enough desktop elements have been drawn - to make the desktop look ready for use. During start-up, the - server can wait for this request with a black screen before - starting to fade in the desktop, for instance. If the client - parts of a desktop take a long time to initialize, we avoid - showing temporary garbage. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/wl_desktop_shell/e_desktop_shell_protocol.c b/src/modules/wl_desktop_shell/e_desktop_shell_protocol.c deleted file mode 100644 index bd7b6a886..000000000 --- a/src/modules/wl_desktop_shell/e_desktop_shell_protocol.c +++ /dev/null @@ -1,61 +0,0 @@ -#include -#include -#include "wayland-util.h" - -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_surface_interface; -extern const struct wl_interface wl_output_interface; - -static const struct wl_interface *types[] = { - NULL, - &wl_output_interface, - &wl_surface_interface, - &wl_output_interface, - &wl_surface_interface, - &wl_surface_interface, - &wl_surface_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - &wl_surface_interface, - &wl_output_interface, -}; - -static const struct wl_message e_desktop_shell_requests[] = { - { "set_background", "oo", types + 1 }, - { "set_panel", "oo", types + 3 }, - { "set_lock_surface", "o", types + 5 }, - { "unlock", "", types + 0 }, - { "set_grab_surface", "o", types + 6 }, - { "desktop_ready", "2", types + 0 }, -}; - -static const struct wl_message e_desktop_shell_events[] = { - { "configure", "2uoii", types + 7 }, - { "prepare_lock_surface", "2", types + 0 }, - { "grab_cursor", "2u", types + 0 }, -}; - -WL_EXPORT const struct wl_interface e_desktop_shell_interface = { - "e_desktop_shell", 2, - 6, e_desktop_shell_requests, - 3, e_desktop_shell_events, -}; - -static const struct wl_message screensaver_requests[] = { - { "set_surface", "oo", types + 11 }, -}; - -WL_EXPORT const struct wl_interface screensaver_interface = { - "screensaver", 1, - 1, screensaver_requests, - 0, NULL, -}; - diff --git a/src/modules/wl_desktop_shell/e_desktop_shell_protocol.h b/src/modules/wl_desktop_shell/e_desktop_shell_protocol.h deleted file mode 100644 index 662df8a4d..000000000 --- a/src/modules/wl_desktop_shell/e_desktop_shell_protocol.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef DESKTOP_SERVER_PROTOCOL_H -#define DESKTOP_SERVER_PROTOCOL_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "wayland-util.h" - -struct wl_client; -struct wl_resource; - -/* struct e_desktop_shell; */ -/* struct screensaver; */ - -extern const struct wl_interface e_desktop_shell_interface; -extern const struct wl_interface screensaver_interface; - -#ifndef E_DESKTOP_SHELL_CURSOR_ENUM -#define E_DESKTOP_SHELL_CURSOR_ENUM -enum e_desktop_shell_cursor { - E_DESKTOP_SHELL_CURSOR_NONE = 0, - E_DESKTOP_SHELL_CURSOR_RESIZE_TOP = 1, - E_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM = 2, - E_DESKTOP_SHELL_CURSOR_ARROW = 3, - E_DESKTOP_SHELL_CURSOR_RESIZE_LEFT = 4, - E_DESKTOP_SHELL_CURSOR_RESIZE_TOP_LEFT = 5, - E_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM_LEFT = 6, - E_DESKTOP_SHELL_CURSOR_MOVE = 7, - E_DESKTOP_SHELL_CURSOR_RESIZE_RIGHT = 8, - E_DESKTOP_SHELL_CURSOR_RESIZE_TOP_RIGHT = 9, - E_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM_RIGHT = 10, - E_DESKTOP_SHELL_CURSOR_BUSY = 11, -}; -#endif /* E_DESKTOP_SHELL_CURSOR_ENUM */ - -struct e_desktop_shell_interface { - /** - * set_background - (none) - * @output: (none) - * @surface: (none) - */ - void (*set_background)(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *output, - struct wl_resource *surface); - /** - * set_panel - (none) - * @output: (none) - * @surface: (none) - */ - void (*set_panel)(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *output, - struct wl_resource *surface); - /** - * set_lock_surface - (none) - * @surface: (none) - */ - void (*set_lock_surface)(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *surface); - /** - * unlock - (none) - */ - void (*unlock)(struct wl_client *client, - struct wl_resource *resource); - /** - * set_grab_surface - (none) - * @surface: (none) - */ - void (*set_grab_surface)(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *surface); - - /** - * desktop_ready - desktop is ready to be shown - * - * Tell the server, that enough desktop elements have been drawn - * to make the desktop look ready for use. During start-up, the - * server can wait for this request with a black screen before - * starting to fade in the desktop, for instance. If the client - * parts of a desktop take a long time to initialize, we avoid - * showing temporary garbage. - * @since: 2 - */ - void (*desktop_ready)(struct wl_client *client, - struct wl_resource *resource); -}; - -#define E_DESKTOP_SHELL_CONFIGURE 0 -#define E_DESKTOP_SHELL_PREPARE_LOCK_SURFACE 1 -#define E_DESKTOP_SHELL_GRAB_CURSOR 2 - -static inline void -e_desktop_shell_send_configure(struct wl_resource *resource_, uint32_t edges, struct wl_resource *surface, int32_t width, int32_t height) -{ - wl_resource_post_event(resource_, E_DESKTOP_SHELL_CONFIGURE, edges, surface, width, height); -} - -static inline void -e_desktop_shell_send_prepare_lock_surface(struct wl_resource *resource_) -{ - wl_resource_post_event(resource_, E_DESKTOP_SHELL_PREPARE_LOCK_SURFACE); -} - -static inline void -e_desktop_shell_send_grab_cursor(struct wl_resource *resource_, uint32_t cursor) -{ - wl_resource_post_event(resource_, E_DESKTOP_SHELL_GRAB_CURSOR, cursor); -} - -struct screensaver_interface { - /** - * set_surface - (none) - * @surface: (none) - * @output: (none) - */ - void (*set_surface)(struct wl_client *client, - struct wl_resource *resource, - struct wl_resource *surface, - struct wl_resource *output); -}; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c deleted file mode 100644 index e98a11067..000000000 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ /dev/null @@ -1,2354 +0,0 @@ -#include "e.h" -#include "e_comp_wl.h" -#include "e_surface.h" -#include "e_mod_main.h" -#include "e_desktop_shell_protocol.h" - -/* shell function prototypes */ -static void _e_wl_shell_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static void _e_wl_shell_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id); -static void _e_wl_shell_cb_bind_desktop(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id); -static void _e_wl_shell_cb_ping(E_Wayland_Surface *ews, unsigned int serial); -static void _e_wl_shell_cb_pointer_focus(struct wl_listener *listener EINA_UNUSED, void *data); - -static void _e_wl_shell_grab_start(E_Wayland_Shell_Grab *grab, E_Wayland_Shell_Surface *ewss, struct wl_pointer *pointer, const struct wl_pointer_grab_interface *interface, enum e_desktop_shell_cursor cursor); -static void _e_wl_shell_grab_end(E_Wayland_Shell_Grab *ewsg); -static void _e_wl_shell_grab_cb_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED); - -/* shell interface prototypes */ -static void _e_wl_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *surface_resource); - -/* desktop shell function prototypes */ -static void _e_wl_desktop_shell_cb_unbind(struct wl_resource *resource); - -/* desktop shell interface prototypes */ -static void _e_wl_desktop_shell_cb_background_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED); -static void _e_wl_desktop_shell_cb_panel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED); -static void _e_wl_desktop_shell_cb_lock_surface_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED); -static void _e_wl_desktop_shell_cb_unlock(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED); -static void _e_wl_desktop_shell_cb_shell_grab_surface_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *surface_resource); -static void _e_wl_desktop_shell_cb_ready(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED); - -/* shell surface function prototypes */ -static E_Wayland_Shell_Surface *_e_wl_shell_shell_surface_create(void *shell, E_Wayland_Surface *ews, const void *client EINA_UNUSED); -static void _e_wl_shell_shell_surface_create_toplevel(E_Wayland_Surface *ews); -static void _e_wl_shell_shell_surface_create_popup(E_Wayland_Surface *ews); -static void _e_wl_shell_shell_surface_destroy(struct wl_resource *resource); -static void _e_wl_shell_shell_surface_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -static void _e_wl_shell_shell_surface_map(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h); -static void _e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews); -static void _e_wl_shell_shell_surface_type_set(E_Wayland_Shell_Surface *ewss); -static void _e_wl_shell_shell_surface_type_reset(E_Wayland_Shell_Surface *ewss); -static void _e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED); -static int _e_wl_shell_shell_surface_cb_ping_timeout(void *data); - -static void _e_wl_shell_render_post(void *data, Evas *e EINA_UNUSED, void *event EINA_UNUSED); -static void _e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_key_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event); -static void _e_wl_shell_shell_surface_cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED); -static Eina_Bool _e_wl_shell_shell_surface_cb_client_prop(void *data, int type, void *event); -static void _e_wl_shell_shell_surface_cb_ec_hook_focus_set(void *data, E_Client *ec); -static void _e_wl_shell_shell_surface_cb_ec_hook_focus_unset(void *data, E_Client *ec); -static void _e_wl_shell_shell_surface_cb_ec_hook_move_end(void *data, E_Client *ec); -static void _e_wl_shell_shell_surface_cb_ec_hook_resize_update(void *data, E_Client *ec); -static void _e_wl_shell_shell_surface_cb_ec_hook_resize_end(void *data, E_Client *ec); -static void _e_wl_shell_surface_cb_smart_client_resize(void *data, Evas_Object *obj, void *event_info); - -static void _e_wl_shell_mouse_down_helper(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button *ev, Eina_Bool move); - -/* shell surface interface prototypes */ -static void _e_wl_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial); -static void _e_wl_shell_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial); -static void _e_wl_shell_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial, unsigned int edges); -static void _e_wl_shell_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource); -static void _e_wl_shell_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource, int x, int y, unsigned int flags); -static void _e_wl_shell_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int method EINA_UNUSED, unsigned int framerate EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED); -static void _e_wl_shell_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial, struct wl_resource *parent_resource, int x, int y, unsigned int flags EINA_UNUSED); -static void _e_wl_shell_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED); -static void _e_wl_shell_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title); -static void _e_wl_shell_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *clas); - -/* shell move_grab interface prototypes */ -static void _e_wl_shell_move_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_move_grab_cb_motion(struct wl_pointer_grab *grab, unsigned int timestamp EINA_UNUSED, wl_fixed_t x, wl_fixed_t y); -static void _e_wl_shell_move_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp EINA_UNUSED, unsigned int button EINA_UNUSED, unsigned int state); - -/* shell resize_grab interface prototypes */ -static void _e_wl_shell_resize_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_resize_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_resize_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp EINA_UNUSED, unsigned int button EINA_UNUSED, unsigned int state); - -/* shell popup_grab interface prototypes */ -static void _e_wl_shell_popup_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y); -static void _e_wl_shell_popup_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_popup_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp, unsigned int button, unsigned int state); - -/* shell popup function prototypes */ -static void _e_wl_shell_popup_grab_end(struct wl_pointer *pointer); - -/* shell busy_grab interface prototypes */ -static void _e_wl_shell_busy_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_busy_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED); -static void _e_wl_shell_busy_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp EINA_UNUSED, unsigned int button, unsigned int state); - -/* local wayland interfaces */ -static const struct wl_shell_interface _e_shell_interface = -{ - _e_wl_shell_cb_shell_surface_get -}; - -static const struct e_desktop_shell_interface _e_desktop_shell_interface = -{ - _e_wl_desktop_shell_cb_background_set, - _e_wl_desktop_shell_cb_panel_set, - _e_wl_desktop_shell_cb_lock_surface_set, - _e_wl_desktop_shell_cb_unlock, - _e_wl_desktop_shell_cb_shell_grab_surface_set, - _e_wl_desktop_shell_cb_ready -}; - -static const struct wl_shell_surface_interface _e_shell_surface_interface = -{ - _e_wl_shell_shell_surface_cb_pong, - _e_wl_shell_shell_surface_cb_move, - _e_wl_shell_shell_surface_cb_resize, - _e_wl_shell_shell_surface_cb_toplevel_set, - _e_wl_shell_shell_surface_cb_transient_set, - _e_wl_shell_shell_surface_cb_fullscreen_set, - _e_wl_shell_shell_surface_cb_popup_set, - _e_wl_shell_shell_surface_cb_maximized_set, - _e_wl_shell_shell_surface_cb_title_set, - _e_wl_shell_shell_surface_cb_class_set -}; - -static const struct wl_pointer_grab_interface _e_move_grab_interface = -{ - _e_wl_shell_move_grab_cb_focus, - _e_wl_shell_move_grab_cb_motion, - _e_wl_shell_move_grab_cb_button, -}; - -static const struct wl_pointer_grab_interface _e_resize_grab_interface = -{ - _e_wl_shell_resize_grab_cb_focus, - _e_wl_shell_resize_grab_cb_motion, - _e_wl_shell_resize_grab_cb_button, -}; - -static const struct wl_pointer_grab_interface _e_popup_grab_interface = -{ - _e_wl_shell_popup_grab_cb_focus, - _e_wl_shell_popup_grab_cb_motion, - _e_wl_shell_popup_grab_cb_button, -}; - -static const struct wl_pointer_grab_interface _e_busy_grab_interface = -{ - _e_wl_shell_busy_grab_cb_focus, - _e_wl_shell_busy_grab_cb_motion, - _e_wl_shell_busy_grab_cb_button, -}; - -/* local variables */ - -static Eina_List *ec_hooks = NULL; -static Ecore_Event_Handler *prop_handler = NULL; - -/* external variables */ - -EAPI E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" }; - -EAPI void * -e_modapi_init(E_Module *m) -{ - E_Wayland_Desktop_Shell *shell = NULL; - struct wl_global *gshell = NULL; - E_Wayland_Input *input = NULL; - const Eina_List *l = NULL; - E_Comp *comp; - - /* test for valid compositor */ - if (!_e_wl_comp) return NULL; - - /* try to allocate space for the shell structure */ - if (!(shell = E_NEW(E_Wayland_Desktop_Shell, 1))) - return NULL; - - /* tell the shell what compositor to use */ - shell->compositor = _e_wl_comp; - - /* setup shell destroy callback */ - shell->wl.destroy_listener.notify = _e_wl_shell_cb_destroy; - wl_signal_add(&_e_wl_comp->signals.destroy, &shell->wl.destroy_listener); - - /* setup compositor ping callback */ - _e_wl_comp->ping_cb = _e_wl_shell_cb_ping; - - /* setup compositor shell interface functions */ - _e_wl_comp->shell_interface.shell = shell; - _e_wl_comp->shell_interface.shell_surface_create = - _e_wl_shell_shell_surface_create; - - /* try to add this shell to the display's global list */ - if (!(gshell = - wl_global_create(_e_wl_comp->wl.display, &wl_shell_interface, - 1, shell, _e_wl_shell_cb_bind))) - goto err; - - /* try to add the desktop shell interface to the display's global list */ - if (!wl_global_create(_e_wl_comp->wl.display, &e_desktop_shell_interface, - 2, shell, _e_wl_shell_cb_bind_desktop)) - goto err; - - /* for each input, we need to create a pointer focus listener */ - EINA_LIST_FOREACH(_e_wl_comp->seats, l, input) - { - struct wl_listener *lst; - - /* skip this input if it has no pointer */ - if (!input->has_pointer) continue; - - /* allocate space for the listener */ - lst = malloc(sizeof(*lst)); - - /* set the listener callback function */ - lst->notify = _e_wl_shell_cb_pointer_focus; - - /* add this listener to the pointer focus signal */ - wl_signal_add(&input->wl.seat.pointer->focus_signal, lst); - } - - ec_hooks = eina_list_append(ec_hooks, - e_client_hook_add(E_CLIENT_HOOK_FOCUS_SET, - _e_wl_shell_shell_surface_cb_ec_hook_focus_set, NULL)); - ec_hooks = eina_list_append(ec_hooks, - e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET, - _e_wl_shell_shell_surface_cb_ec_hook_focus_unset, NULL)); - - ec_hooks = eina_list_append(ec_hooks, - e_client_hook_add(E_CLIENT_HOOK_MOVE_END, - _e_wl_shell_shell_surface_cb_ec_hook_move_end, NULL)); - ec_hooks = eina_list_append(ec_hooks, - e_client_hook_add(E_CLIENT_HOOK_RESIZE_END, - _e_wl_shell_shell_surface_cb_ec_hook_resize_end, NULL)); - ec_hooks = eina_list_append(ec_hooks, - e_client_hook_add(E_CLIENT_HOOK_RESIZE_UPDATE, - _e_wl_shell_shell_surface_cb_ec_hook_resize_update, NULL)); - - prop_handler = ecore_event_handler_add(E_EVENT_CLIENT_PROPERTY, _e_wl_shell_shell_surface_cb_client_prop, NULL); - EINA_LIST_FOREACH(e_comp_list(), l, comp) - evas_event_callback_add(comp->evas, EVAS_CALLBACK_RENDER_POST, - _e_wl_shell_render_post, NULL); - - return m; - -err: - /* remove previously added shell global */ - if (gshell) wl_global_destroy(gshell); - - /* reset compositor shell interface */ - _e_wl_comp->shell_interface.shell = NULL; - - /* free the allocated shell structure */ - E_FREE(shell); - - return NULL; -} - -EAPI int -e_modapi_shutdown(E_Module *m EINA_UNUSED) -{ - const Eina_List *l; - E_Comp *comp; - - E_FREE_LIST(ec_hooks, e_client_hook_del); - E_FREE_FUNC(prop_handler, ecore_event_handler_del); - EINA_LIST_FOREACH(e_comp_list(), l, comp) - evas_event_callback_del_full(comp->evas, EVAS_CALLBACK_RENDER_POST, - _e_wl_shell_render_post, NULL); - /* nothing to do here as shell will get the destroy callback from - * the compositor and we can cleanup there */ - return 1; -} - -/* shell functions */ -static void -_e_wl_shell_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Desktop_Shell *shell = NULL; - - /* try to get the shell from the listener */ - shell = - container_of(listener, E_Wayland_Desktop_Shell, wl.destroy_listener); - - /* free the allocated shell structure */ - E_FREE(shell); -} - -static void -_e_wl_shell_cb_bind(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id) -{ - E_Wayland_Desktop_Shell *shell = NULL; - struct wl_resource *res = NULL; - - /* try to cast data to our shell */ - if (!(shell = data)) return; - - /* try to add the shell to the client */ - res = wl_resource_create(client, &wl_shell_interface, 1, id); - if (res) - { - struct wl_resource *dres = NULL; - - wl_resource_set_implementation(res, &_e_shell_interface, shell, NULL); - - dres = wl_resource_create(client, &e_desktop_shell_interface, -1, 0); - if (dres) - { - wl_resource_set_implementation(dres, &_e_desktop_shell_interface, - shell, _e_wl_desktop_shell_cb_unbind); - - shell->wl.resource = dres; - } - } -} - -static void -_e_wl_shell_cb_bind_desktop(struct wl_client *client, void *data, unsigned int version EINA_UNUSED, unsigned int id) -{ - E_Wayland_Desktop_Shell *shell = NULL; - struct wl_resource *res = NULL; - - /* try to cast data to our shell */ - if (!(shell = data)) return; - - /* try to add the shell to the client */ - res = wl_resource_create(client, &e_desktop_shell_interface, 2, id); - if (res) - { - wl_resource_set_implementation(res, &_e_desktop_shell_interface, - shell, _e_wl_desktop_shell_cb_unbind); - shell->wl.resource = res; - } -} - -static void -_e_wl_shell_cb_ping(E_Wayland_Surface *ews, unsigned int serial) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Desktop_Shell *shell = NULL; - - if (!ews) return; - - /* try to cast to our shell surface */ - if (!(ewss = ews->shell_surface)) return; - - shell = (E_Wayland_Desktop_Shell *)ewss->shell; - - if ((ewss->surface) && (ewss->surface == shell->grab_surface)) - return; - - /* if we do not have a ping timer yet, create one */ - if (!ewss->ping_timer) - { - E_Wayland_Ping_Timer *tmr = NULL; - - /* try to allocate space for a new ping timer */ - if (!(tmr = E_NEW(E_Wayland_Ping_Timer, 1))) - return; - - tmr->serial = serial; - - /* add a timer to the event loop */ - tmr->source = - wl_event_loop_add_timer(_e_wl_comp->wl.loop, - _e_wl_shell_shell_surface_cb_ping_timeout, - ewss); - - /* update timer source interval */ - wl_event_source_timer_update(tmr->source, - e_config->ping_clients_interval * (1000 / 8)); - - ewss->ping_timer = tmr; - - /* send the ping to the shell surface */ - wl_shell_surface_send_ping(ewss->wl.resource, serial); - } -} - -static void -_e_wl_shell_cb_pointer_focus(struct wl_listener *listener EINA_UNUSED, void *data) -{ - struct wl_pointer *ptr; - E_Wayland_Surface *ews = NULL; - - if (!(ptr = data)) return; - - if (!ptr->focus) return; - - /* try to cast the current pointer focus to a wayland surface */ - if (!(ews = wl_resource_get_user_data(ptr->focus))) - return; - - /* if this surface has a shell_surface and it is not active, then we - * should set the busy cursor on it */ - if ((ews->mapped) && (ews->shell_surface) && (!ews->shell_surface->active)) - { - E_Wayland_Desktop_Shell *shell; - - /* set busy cursor */ - shell = ews->shell_surface->shell; - e_desktop_shell_send_grab_cursor(shell->wl.resource, - E_DESKTOP_SHELL_CURSOR_BUSY); - } - else - { - unsigned int serial = 0; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - /* ping the surface */ - _e_wl_shell_cb_ping(ews, serial); - } -} - -static void -_e_wl_shell_grab_start(E_Wayland_Shell_Grab *grab, E_Wayland_Shell_Surface *ewss, struct wl_pointer *pointer, const struct wl_pointer_grab_interface *interface, enum e_desktop_shell_cursor cursor) -{ - E_Wayland_Desktop_Shell *shell; - - /* safety check */ - if ((!grab) || (!ewss)) return; - - shell = (E_Wayland_Desktop_Shell *)ewss->shell; - - /* end any popup grabs */ - _e_wl_shell_popup_grab_end(pointer); - - /* setup grab properties */ - grab->grab.interface = interface; - grab->shell_surface = ewss; - grab->shell_surface_destroy.notify = _e_wl_shell_grab_cb_surface_destroy; - - /* add a listener in case this surface gets destroyed */ - wl_signal_add(&ewss->wl.destroy_signal, &grab->shell_surface_destroy); - - /* start the pointer grab */ - wl_pointer_start_grab(pointer, &grab->grab); - - /* set cursor */ - if (shell) - e_desktop_shell_send_grab_cursor(shell->wl.resource, cursor); - - /* tell the pointer which surface is focused */ - wl_pointer_set_focus(pointer, ewss->surface->wl.surface, 0, 0); -} - -static void -_e_wl_shell_grab_end(E_Wayland_Shell_Grab *ewsg) -{ - /* safety */ - if (!ewsg) return; - - /* remove the destroy listener */ - if (ewsg->shell_surface) - wl_list_remove(&ewsg->shell_surface_destroy.link); - - /* end the grab */ - wl_pointer_end_grab(ewsg->grab.pointer); -} - -static void -_e_wl_shell_grab_cb_surface_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Shell_Grab *ewsg = NULL; - - /* try to get the grab from the listener */ - ewsg = container_of(listener, E_Wayland_Shell_Grab, shell_surface_destroy); - if (!ewsg) return; - - /* set the grab surface to null */ - ewsg->shell_surface = NULL; -} - -/* shell interface functions */ -static void -_e_wl_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource, unsigned int id, struct wl_resource *surface_resource) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Desktop_Shell *shell = NULL; - - /* try to cast the surface resource to our structure */ - if (!(ews = wl_resource_get_user_data(surface_resource))) - return; - - shell = wl_resource_get_user_data(resource); - - /* check if this surface already has a shell surface */ - if ((ews->configure) && - (ews->configure == _e_wl_shell_shell_surface_configure)) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Shell surface already requested for surface"); - return; - } - - /* try to create a shell surface for this surface */ - if (!(ewss = _e_wl_shell_shell_surface_create(shell, ews, NULL))) - { - wl_resource_post_no_memory(surface_resource); - return; - } - - ewss->wl.resource = - wl_resource_create(client, &wl_shell_surface_interface, 1, id); - wl_resource_set_implementation(ewss->wl.resource, - &_e_shell_surface_interface, ewss, - _e_wl_shell_shell_surface_destroy); -} - -/* desktop shell functions */ -static void -_e_wl_desktop_shell_cb_unbind(struct wl_resource *resource) -{ - E_Wayland_Desktop_Shell *shell = NULL; - - shell = wl_resource_get_user_data(resource); - shell->wl.resource = NULL; -} - -/* desktop shell interface functions */ -static void -_e_wl_desktop_shell_cb_background_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED) -{ - -} - -static void -_e_wl_desktop_shell_cb_panel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED) -{ - -} - -static void -_e_wl_desktop_shell_cb_lock_surface_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, struct wl_resource *surface_resource EINA_UNUSED) -{ - -} - -static void -_e_wl_desktop_shell_cb_unlock(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED) -{ - -} - -static void -_e_wl_desktop_shell_cb_shell_grab_surface_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *surface_resource) -{ - E_Wayland_Desktop_Shell *shell = NULL; - - /* try to get the shell */ - if (!(shell = wl_resource_get_user_data(resource))) - return; - - shell->grab_surface = wl_resource_get_user_data(surface_resource); -} - -static void -_e_wl_desktop_shell_cb_ready(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED) -{ - -} - -/* shell surface functions */ -static E_Wayland_Shell_Surface * -_e_wl_shell_shell_surface_create(void *shell, E_Wayland_Surface *ews, const void *client EINA_UNUSED) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - if (!ews) return NULL; - - /* try to allocate space for our shell surface structure */ - if (!(ewss = E_NEW(E_Wayland_Shell_Surface, 1))) - return NULL; - - /* set some function pointers on the surface */ - ews->configure = _e_wl_shell_shell_surface_configure; - ews->map = _e_wl_shell_shell_surface_map; - ews->unmap = _e_wl_shell_shell_surface_unmap; - - /* set some properties on the shell surface */ - ewss->shell = (E_Wayland_Desktop_Shell *)shell; - ewss->surface = ews; - ews->shell_surface = ewss; - - /* setup shell surface destroy */ - wl_signal_init(&ewss->wl.destroy_signal); - ewss->wl.surface_destroy.notify = _e_wl_shell_shell_surface_cb_destroy; - wl_signal_add(&ews->wl.destroy_signal, &ewss->wl.surface_destroy); - - /* wl_list_init(&ewss->wl.surface_destroy.link); */ - - wl_list_init(&ewss->wl.link); - - /* set some defaults on this shell surface */ - ewss->active = EINA_TRUE; - ewss->type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE; - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE; - - return ewss; -} - -static void -_e_wl_shell_shell_surface_create_toplevel(E_Wayland_Surface *ews) -{ - E_Comp *comp; - - /* get the current container */ - comp = e_util_comp_current_get(); - - /* create the e client for this surface */ - ews->ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ews->pixmap)); - if (!ews->ec) - ews->ec = e_client_new(comp, ews->pixmap, 1, 0); - e_pixmap_ref(ews->pixmap); - ews->ec->argb = 1; - ews->ec->no_shape_cut = 1; // specify no input shape cutting for this client - ews->ec->borderless = !ews->ec->internal; - ews->ec->lock_border = 1; - ews->ec->border.changed = ews->ec->changes.border = !ews->ec->borderless; - ews->ec->comp_data = (E_Comp_Client_Data*)ews; - ews->ec->icccm.title = eina_stringshare_ref(ews->shell_surface->title); - ews->ec->icccm.class = eina_stringshare_ref(ews->shell_surface->clas); - ews->ec->changes.icon = !!ews->ec->icccm.class; - EC_CHANGED(ews->ec); - - /* hook object callbacks */ - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, - _e_wl_shell_shell_surface_cb_mouse_out, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, - _e_wl_shell_shell_surface_cb_mouse_move, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_UP, - _e_wl_shell_shell_surface_cb_mouse_up, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_DOWN, - _e_wl_shell_shell_surface_cb_mouse_down, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, - _e_wl_shell_shell_surface_cb_mouse_wheel, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_KEY_UP, - _e_wl_shell_shell_surface_cb_key_up, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_KEY_DOWN, - _e_wl_shell_shell_surface_cb_key_down, ews); - evas_object_smart_callback_add(ews->ec->frame, "client_resize", - _e_wl_shell_surface_cb_smart_client_resize, ews); - - ews->ec->client.w = ews->geometry.w; - ews->ec->client.h = ews->geometry.h; - - ews->ec->visible = 1; - evas_object_show(ews->ec->frame); - - evas_object_geometry_set(ews->ec->frame, ews->geometry.x, ews->geometry.y, - ews->geometry.w, ews->geometry.h); - - ews->mapped = EINA_TRUE; -} - -static void -_e_wl_shell_shell_surface_create_popup(E_Wayland_Surface *ews) -{ - E_Wayland_Shell_Surface *ewss = NULL; - struct wl_seat *seat; - //char opts[PATH_MAX]; - E_Comp *comp; - - /* try to get the shell surface */ - if (!(ewss = ews->shell_surface)) return; - /* get the current comp */ - if (ewss->parent) - comp = ewss->parent->ec->comp; - else - comp = e_util_comp_current_get(); - - /* create the e client for this surface */ - ews->ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ews->pixmap)); - if (!ews->ec) - ews->ec = e_client_new(comp, ews->pixmap, 1, 1); - e_pixmap_ref(ews->pixmap); - ews->ec->argb = 1; - ews->ec->no_shape_cut = 1; // specify no input shape cutting for this client - ews->ec->borderless = !ews->ec->internal; - ews->ec->lock_border = 1; - ews->ec->border.changed = ews->ec->changes.border = !ews->ec->borderless; - ews->ec->comp_data = (E_Comp_Client_Data*)ews; - ews->ec->icccm.title = eina_stringshare_ref(ewss->title); - ews->ec->icccm.class = eina_stringshare_ref(ewss->clas); - ews->ec->changes.icon = !!ews->ec->icccm.class; - EC_CHANGED(ews->ec); - - /* hook object callbacks */ - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, - _e_wl_shell_shell_surface_cb_mouse_out, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, - _e_wl_shell_shell_surface_cb_mouse_move, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_UP, - _e_wl_shell_shell_surface_cb_mouse_up, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_DOWN, - _e_wl_shell_shell_surface_cb_mouse_down, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, - _e_wl_shell_shell_surface_cb_mouse_wheel, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_KEY_UP, - _e_wl_shell_shell_surface_cb_key_up, ews); - evas_object_event_callback_add(ews->ec->frame, EVAS_CALLBACK_KEY_DOWN, - _e_wl_shell_shell_surface_cb_key_down, ews); - evas_object_smart_callback_add(ews->ec->frame, "client_resize", - _e_wl_shell_surface_cb_smart_client_resize, ews); - - ews->ec->client.w = ews->geometry.w; - ews->ec->client.h = ews->geometry.h; - - ews->ec->visible = 1; - evas_object_show(ews->ec->frame); - - evas_object_geometry_set(ews->ec->frame, ews->geometry.x, ews->geometry.y, - ews->geometry.w, ews->geometry.h); - - - ews->mapped = EINA_TRUE; - - /* set popup properties */ - ewss->popup.grab.interface = &_e_popup_grab_interface; - ewss->popup.up = EINA_FALSE; - - if (ewss->parent) - { - /* TODO */ - /* ewss->popup.parent_destroy.notify = ; */ - - /* add a signal callback to be raised when the parent gets destroyed */ - /* wl_signal_add(&ewss->parent->wl.surface.resource.destroy_signal, */ - /* &ewss->popup.parent_destroy); */ - } - - seat = ewss->popup.seat; - if (seat->pointer->grab_serial == ewss->popup.serial) - wl_pointer_start_grab(seat->pointer, &ewss->popup.grab); - else - wl_shell_surface_send_popup_done(ewss->wl.resource); -} - -static void -_e_wl_shell_shell_surface_destroy(struct wl_resource *resource) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Ping_Timer *tmr = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* if we have a popup grab, end it */ - if (ewss->popup.grab.pointer) - wl_pointer_end_grab(ewss->popup.grab.pointer); - -// wl_list_remove(&ewss->wl.surface_destroy.link); -// if (ewss->surface) ewss->surface->configure = NULL; - - /* try to cast the ping timer */ - if ((tmr = (E_Wayland_Ping_Timer *)ewss->ping_timer)) - { - if (tmr->source) wl_event_source_remove(tmr->source); - - /* free the allocated space for ping timer */ - E_FREE(tmr); - ewss->ping_timer = NULL; - } - - wl_list_remove(&ewss->wl.link); - - /* try to free our allocated structure */ - /* E_FREE(ewss); */ -} - -static void -_e_wl_shell_shell_surface_configure(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Wayland_Shell_Surface *ewss = NULL; - Eina_Bool changed_type = EINA_FALSE; - - ewss = ews->shell_surface; - - /* FIXME */ - /* if ((!ews->mapped) && */ - /* (!wl_list_empty(&ewss->popup.grab_link)) */ - /* { */ - - /* } */ - - if (w == 0) return; - - /* if ((ews->configure == _e_wl_shell_shell_surface_configure)) */ - /* { */ - /* if (!(ewss = ews->shell_surface)) return; */ - /* } */ - /* else */ - /* return; */ - - /* handle shell_surface type change */ - if ((ewss->next_type != E_WAYLAND_SHELL_SURFACE_TYPE_NONE) && - (ewss->type != ewss->next_type)) - { - /* set the shell surface type */ - _e_wl_shell_shell_surface_type_set(ewss); - - changed_type = EINA_TRUE; - } - - /* if this surface is not mapped yet, then we need to map it */ - if (!ews->mapped) - { - /* if the surface has a map function, call that. Else we use a - * default one for this shell */ - if (ews->map) ews->map(ews, x, y, w, h); - else _e_wl_shell_shell_surface_map(ews, x, y, w, h); - } - else if ((changed_type) || (x != 0) || (y != 0) || - (ews->geometry.w != w) || (ews->geometry.h != h)) - { - if (ews->ec && e_client_util_resizing_get(ews->ec)) return; - ews->geometry.w = w; - ews->geometry.h = h; - ews->geometry.changed = EINA_TRUE; - if (ews->ec) - { - if ((ews->geometry.x != x) || (ews->geometry.y != y)) - { - ews->ec->client.x = ews->geometry.x = x; - ews->ec->client.y = ews->geometry.y = y; - e_comp_object_frame_xy_adjust(ews->ec->frame, x, y, &ews->ec->x, &ews->ec->y); - ews->ec->changes.pos = 1; - } - ews->ec->client.w = w; - ews->ec->client.h = h; - e_comp_object_frame_wh_adjust(ews->ec->frame, w, h, &ews->ec->w, &ews->ec->h); - ews->ec->changes.size = 1; - EC_CHANGED(ews->ec); - } - } -} - -static void -_e_wl_shell_shell_surface_map(E_Wayland_Surface *ews, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - /* safety check */ - if (!ews) return; - - /* update surface geometry */ - ews->geometry.w = w; - ews->geometry.h = h; - ews->geometry.changed = EINA_TRUE; - - /* starting position */ - switch (ews->shell_surface->type) - { - case E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL: - ews->geometry.x = x; - ews->geometry.y = y; - ews->geometry.changed = EINA_TRUE; - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN: - /* center */ - /* map fullscreen */ - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED: - /* maximize */ - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_POPUP: - ews->geometry.x = x; - ews->geometry.y = y; - ews->geometry.changed = EINA_TRUE; - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_NONE: - ews->geometry.x += x; - ews->geometry.y += y; - ews->geometry.changed = EINA_TRUE; - break; - default: - break; - } - - /* stacking */ - - /* activate */ - switch (ews->shell_surface->type) - { - case E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL: - _e_wl_shell_shell_surface_create_toplevel(ews); - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_POPUP: - _e_wl_shell_shell_surface_create_popup(ews); - break; - default: return; - } - if (ews->ec && ews->ec->icccm.title) - e_comp_object_frame_title_set(ews->ec->frame, ews->ec->icccm.title); -} - -static void -_e_wl_shell_shell_surface_unmap(E_Wayland_Surface *ews) -{ - Eina_List *l = NULL; - E_Wayland_Input *input; - - if (!ews) return; - - EINA_LIST_FOREACH(_e_wl_comp->seats, l, input) - { - if ((input->wl.seat.keyboard) && - (input->wl.seat.keyboard->focus == ews->wl.surface)) - wl_keyboard_set_focus(input->wl.seat.keyboard, NULL); - if ((input->wl.seat.pointer) && - (input->wl.seat.pointer->focus == ews->wl.surface)) - wl_pointer_set_focus(input->wl.seat.pointer, NULL, 0, 0); - } - - if (ews->ec) - { - //evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_OUT, - //_e_wl_shell_shell_surface_cb_mouse_out, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_MOVE, - _e_wl_shell_shell_surface_cb_mouse_move, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_UP, - _e_wl_shell_shell_surface_cb_mouse_up, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_DOWN, - _e_wl_shell_shell_surface_cb_mouse_down, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, - _e_wl_shell_shell_surface_cb_mouse_wheel, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_KEY_UP, - _e_wl_shell_shell_surface_cb_key_up, ews); - evas_object_event_callback_del_full(ews->ec->frame, EVAS_CALLBACK_KEY_DOWN, - _e_wl_shell_shell_surface_cb_key_down, ews); - evas_object_smart_callback_del_full(ews->ec->frame, "client_resize", - _e_wl_shell_surface_cb_smart_client_resize, ews); - - - if (evas_object_visible_get(ews->ec->frame)) - { - /* surface probably has render updates pending: - * - check ourselves before we wreck ourselves - * - copy image - * - re-render - */ - e_pixmap_image_clear(ews->pixmap, 0); - e_pixmap_dirty(ews->pixmap); - if (e_pixmap_refresh(ews->pixmap)) - { - e_comp_object_damage(ews->ec->frame, 0, 0, ews->ec->w, ews->ec->h); - e_comp_object_dirty(ews->ec->frame); - e_comp_object_render(ews->ec->frame); - } - e_comp_object_render_update_del(ews->ec->frame); - evas_object_pass_events_set(ews->ec->frame, 1); - evas_object_hide(ews->ec->frame); - } - e_object_del(E_OBJECT(ews->ec)); - } - - ews->mapped = EINA_FALSE; -} - -static void -_e_wl_shell_shell_surface_type_set(E_Wayland_Shell_Surface *ewss) -{ - /* safety check */ - if (!ewss) return; - - /* reset the shell surface type */ - _e_wl_shell_shell_surface_type_reset(ewss); - - ewss->type = ewss->next_type; - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE; - - switch (ewss->type) - { - case E_WAYLAND_SHELL_SURFACE_TYPE_TRANSIENT: - ewss->surface->geometry.x = - ewss->parent->geometry.x + ewss->transient.x; - ewss->surface->geometry.y = - ewss->parent->geometry.y + ewss->transient.y; - break; - /* record the current geometry so we can restore it */ - case E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN: - case E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED: - ewss->saved.x = ewss->surface->geometry.x; - ewss->saved.y = ewss->surface->geometry.y; - ewss->saved.w = ewss->surface->geometry.w; - ewss->saved.h = ewss->surface->geometry.h; - ewss->saved.valid = EINA_TRUE; - break; - default: - break; - } -} - -static void -_e_wl_shell_shell_surface_type_reset(E_Wayland_Shell_Surface *ewss) -{ - /* safety check */ - if (!ewss) return; - - switch (ewss->type) - { - case E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN: - /* unfullscreen the client */ - if (ewss->surface->ec) - e_client_unfullscreen(ewss->surface->ec); - - /* restore the saved geometry */ - ewss->surface->geometry.x = ewss->saved.x; - ewss->surface->geometry.y = ewss->saved.y; - ewss->surface->geometry.w = ewss->saved.w; - ewss->surface->geometry.h = ewss->saved.h; - ewss->surface->geometry.changed = EINA_TRUE; - break; - case E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED: - /* unmaximize the client */ - if (ewss->surface->ec) - e_client_unmaximize(ewss->surface->ec, - (e_config->maximize_policy & E_MAXIMIZE_TYPE) | - E_MAXIMIZE_BOTH); - - /* restore the saved geometry */ - ewss->surface->geometry.x = ewss->saved.x; - ewss->surface->geometry.y = ewss->saved.y; - ewss->surface->geometry.w = ewss->saved.w; - ewss->surface->geometry.h = ewss->saved.h; - ewss->surface->geometry.changed = EINA_TRUE; - break; - default: - break; - } - - /* reset the current type to none */ - ewss->type = E_WAYLAND_SHELL_SURFACE_TYPE_NONE; -} - -static void -_e_wl_shell_shell_surface_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* try to get the shell surface from the listener */ - ewss = container_of(listener, E_Wayland_Shell_Surface, wl.surface_destroy); - if (!ewss) return; - - if (ewss->wl.resource) - wl_resource_destroy(ewss->wl.resource); - else - { - E_Wayland_Ping_Timer *tmr = NULL; - - wl_signal_emit(&ewss->wl.destroy_signal, ewss); - - /* TODO: FIXME: Popup->grab_link */ - - wl_list_remove(&ewss->wl.surface_destroy.link); - ewss->surface->configure = NULL; - - /* destroy the ping timer */ - if ((tmr = (E_Wayland_Ping_Timer *)ewss->ping_timer)) - { - if (tmr->source) wl_event_source_remove(tmr->source); - E_FREE(tmr); - ewss->ping_timer = NULL; - } - - wl_list_remove(&ewss->wl.link); - eina_stringshare_del(ewss->clas); - eina_stringshare_del(ewss->title); - free(ewss); - } -} - -static int -_e_wl_shell_shell_surface_cb_ping_timeout(void *data) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Shell_Grab *grab = NULL; - - /* try to cast to our shell surface structure */ - if (!(ewss = data)) return 1; - - ewss->active = EINA_FALSE; - - /* this can be NULL if there's a long enough timeout */ - if (!ewss->surface->input) return 1; - - /* TODO: this should loop inputs */ - - /* try to allocate space for our grab structure */ - if (!(grab = E_NEW(E_Wayland_Shell_Grab, 1))) return 1; - - /* set grab properties */ - grab->x = _e_wl_comp->input->wl.seat.pointer->grab_x; - grab->y = _e_wl_comp->input->wl.seat.pointer->grab_y; - - /* set busy cursor */ - _e_wl_shell_grab_start(grab, ewss, _e_wl_comp->input->wl.seat.pointer, - &_e_busy_grab_interface, E_DESKTOP_SHELL_CURSOR_BUSY); - - return 1; -} - -static void -_e_wl_shell_render_post(void *data EINA_UNUSED, Evas *e EINA_UNUSED, void *event EINA_UNUSED) -{ - E_Wayland_Surface *ews; - unsigned int secs; - E_Wayland_Surface_Frame_Callback *cb = NULL, *ncb = NULL; - - /* grab the current server time */ - secs = e_comp_wl_time_get(); - - EINA_INLIST_FOREACH(_e_wl_comp->surfaces, ews) - { - if (!ews->updates) break; - /* for each frame callback in the surface, signal it is done */ - wl_list_for_each_safe(cb, ncb, &ews->wl.frames, wl.link) - { - wl_callback_send_done(cb->wl.resource, secs); - wl_resource_destroy(cb->wl.resource); - } - ews->updates = 0; - } -} - -static void -_e_wl_shell_shell_surface_cb_mouse_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Wayland_Surface *ews = NULL; - Evas_Event_Mouse_Out *ev = event; - struct wl_pointer *ptr = NULL; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; - if (e_object_is_del(E_OBJECT(ews->ec))) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - ptr->x = wl_fixed_from_int(ev->output.x - ews->ec->client.x); - ptr->y = wl_fixed_from_int(ev->output.y - ews->ec->client.y); - - ptr->current_x = ptr->x; - ptr->current_y = ptr->y; - ptr->grab->x = ptr->x; - ptr->grab->y = ptr->y; - - /* send this mouse movement to wayland */ - ptr->grab->interface->motion(ptr->grab, ev->timestamp, - ptr->grab->x, ptr->grab->y); - } -} - -static void -_e_wl_shell_shell_surface_cb_mouse_move(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Wayland_Surface *ews = NULL; - Evas_Event_Mouse_Move *ev = event; - struct wl_pointer *ptr = NULL; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - ptr->x = wl_fixed_from_int(ev->cur.output.x - ews->ec->client.x); - ptr->y = wl_fixed_from_int(ev->cur.output.y - ews->ec->client.y); - - ptr->current_x = ptr->x; - ptr->current_y = ptr->y; - ptr->grab->x = ptr->x; - ptr->grab->y = ptr->y; - - /* send this mouse movement to wayland */ - ptr->grab->interface->motion(ptr->grab, ev->timestamp, - ptr->grab->x, ptr->grab->y); - } -} - -static void -_e_wl_shell_shell_surface_cb_mouse_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; - Evas_Event_Mouse_Up *ev = event; - int btn = 0; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - if (ev->button == 1) - btn = ev->button + BTN_LEFT - 1; // BTN_LEFT - else if (ev->button == 2) - btn = BTN_MIDDLE; - else if (ev->button == 3) - btn = BTN_RIGHT; - - if (ptr->button_count > 0) ptr->button_count--; - - ptr->grab->interface->button(ptr->grab, ev->timestamp, btn, - WL_POINTER_BUTTON_STATE_RELEASED); - - if (ptr->button_count == 1) - ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); - } -} - -static void -_e_wl_shell_shell_surface_cb_mouse_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; - Evas_Event_Mouse_Down *ev; - int btn = 0; - - ev = event; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - unsigned int serial = 0; - - if (ev->button == 1) - btn = ev->button + BTN_LEFT - 1; // BTN_LEFT - else if (ev->button == 2) - btn = BTN_MIDDLE; - else if (ev->button == 3) - btn = BTN_RIGHT; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - /* if the compositor has a ping callback, call it on this surface */ - if (_e_wl_comp->ping_cb) _e_wl_comp->ping_cb(ews, serial); - - /* update some pointer properties */ - if (ptr->button_count == 0) - { - ptr->x = wl_fixed_from_int(ev->output.x - ews->ec->client.x); - ptr->y = wl_fixed_from_int(ev->output.y - ews->ec->client.y); - ptr->grab_x = ptr->x; - ptr->grab_y = ptr->y; - ptr->grab_button = btn; - ptr->grab_time = ev->timestamp; - } - - ptr->button_count++; - - /* send this button press to the pointer */ - ptr->grab->interface->button(ptr->grab, ev->timestamp, btn, - WL_POINTER_BUTTON_STATE_PRESSED); - - if (ptr->button_count == 1) - ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); - } -} - -static void -_e_wl_shell_shell_surface_cb_mouse_wheel(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; - Evas_Event_Mouse_Wheel *ev; - int btn = 0; - - ev = event; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - if (ews->ec->cur_mouse_action || ews->ec->border_menu) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - unsigned int serial = 0; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - /* if the compositor has a ping callback, call it on this surface */ - if (_e_wl_comp->ping_cb) _e_wl_comp->ping_cb(ews, serial); - - switch (ev->direction) - { - case 0: - if (ev->z == -1) btn = 4; - else if (ev->z == 1) btn = 5; - break; - case 1: - if (ev->z == -1) btn = 6; - else if (ev->z == 1) btn = 7; - break; - } - - /* send this wheel event to the pointer as a button press */ - ptr->grab->interface->button(ptr->grab, ev->timestamp, btn, - WL_POINTER_BUTTON_STATE_PRESSED); - } -} - -static void -_e_wl_shell_shell_surface_cb_key_up(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event) -{ - Evas_Event_Key_Up *ev; - E_Wayland_Surface *ews = NULL; - struct wl_keyboard *kbd; - struct wl_keyboard_grab *grab; - unsigned int key = 0, *end, *k; - unsigned int serial = 0; - - ev = event; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - - /* try to get a reference to the input's keyboard */ - if (!(kbd = _e_wl_comp->input->wl.seat.keyboard)) return; - - /* does this keyboard have a focused surface ? */ - if (!kbd->focus) return; - - /* is the focused surface actually This surface ? */ - if (kbd->focus != ews->wl.surface) return; - -#ifndef HAVE_WAYLAND_ONLY - if (_e_wl_comp->kbd_handler) - /* get the keycode for this key from X, since we're definitely in X here */ - key = ecore_x_keysym_keycode_get(ev->key) - 8; - else -#endif - { - xkb_keysym_t sym; - - sym = xkb_keysym_from_name(ev->key, 0); - if (!sym) - sym = xkb_keysym_from_name(ev->key, XKB_KEYSYM_CASE_INSENSITIVE); - key = sym - 8; - } - end = ((unsigned int *)kbd->keys.data + (kbd->keys.size / sizeof(*k))); - for (k = kbd->keys.data; k < end; k++) - if ((*k == key)) *k = *--end; - - kbd->keys.size = (const char *)end - (const char *)kbd->keys.data; - - /* try to get the current keyboard's grab interface. - * Fallback to the default grab */ - if (!(grab = kbd->grab)) grab = &kbd->default_grab; - - /* if we have a grab, send this key to it */ - if (grab) - { - /* send keycode from evdev */ - grab->interface->key(grab, - ev->timestamp, - ev->keycode ? ev->keycode : key, - WL_KEYBOARD_KEY_STATE_RELEASED); - } - - /* update xkb key state */ - xkb_state_update_key(_e_wl_comp->input->xkb.state, key + 8, XKB_KEY_UP); - - /* update keyboard modifiers */ - serial = wl_display_get_serial(_e_wl_comp->wl.display); - e_comp_wl_input_modifiers_update(serial); -} - -static void -_e_wl_shell_shell_surface_cb_key_down(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED) -{ - Evas_Event_Key_Down *ev; - E_Wayland_Surface *ews = NULL; - struct wl_keyboard *kbd; - struct wl_keyboard_grab *grab; - unsigned int serial = 0, key = 0; - unsigned int *end, *k; - - ev = event; - - /* try to cast data to our surface structure */ - if (!(ews = data)) return; - - /* try to get a reference to the input's keyboard */ - if (!(kbd = _e_wl_comp->input->wl.seat.keyboard)) return; - - /* does this keyboard have a focused surface ? */ - if (!kbd->focus) return; - - /* is the focused surface actually This surface ? */ - if (kbd->focus != ews->wl.surface) return; - - serial = wl_display_next_serial(_e_wl_comp->wl.display); - - /* if the compositor has a ping callback, call it on this surface */ - if (_e_wl_comp->ping_cb) _e_wl_comp->ping_cb(ews, serial); - -#ifndef HAVE_WAYLAND_ONLY - if (_e_wl_comp->kbd_handler) - /* get the keycode for this key from X, since we're definitely in X here */ - key = ecore_x_keysym_keycode_get(ev->key) - 8; - else -#endif - { - xkb_keysym_t sym; - - sym = xkb_keysym_from_name(ev->key, 0); - if (!sym) - sym = xkb_keysym_from_name(ev->key, XKB_KEYSYM_CASE_INSENSITIVE); - key = sym - 8; - } - /* update the keyboards grab properties */ - kbd->grab_key = key; - kbd->grab_time = ev->timestamp; - - end = ((unsigned int *)kbd->keys.data + (kbd->keys.size / sizeof(*k))); - for (k = kbd->keys.data; k < end; k++) - { - /* ignore server generated key repeats */ - if ((*k == key)) return; - } - - kbd->keys.size = (const char *)end - (const char *)kbd->keys.data; - k = wl_array_add(&kbd->keys, sizeof(*k)); - *k = key; - - /* try to get the current keyboard's grab interface. - * Fallback to the default grab */ - if (!(grab = kbd->grab)) grab = &kbd->default_grab; - - /* if we have a grab, send this key to it */ - if (grab) - { - /* send keycode from evdev */ - grab->interface->key(grab, - ev->timestamp, - ev->keycode ? ev->keycode : key, - WL_KEYBOARD_KEY_STATE_PRESSED); - } - - /* update xkb key state */ - xkb_state_update_key(_e_wl_comp->input->xkb.state, key + 8, XKB_KEY_DOWN); - - /* update keyboard modifiers */ - serial = wl_display_get_serial(_e_wl_comp->wl.display); - e_comp_wl_input_modifiers_update(serial); -} - -static Eina_Bool -_e_wl_shell_shell_surface_cb_client_prop(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) -{ - E_Event_Client_Property *ev = event; - - if (e_pixmap_type_get(ev->ec->pixmap) != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW; - if (!(ev->property & E_CLIENT_PROPERTY_ICON)) return ECORE_CALLBACK_RENEW; - if (ev->ec->desktop) - { - if (!ev->ec->exe_inst) - e_exec_phony(ev->ec); - } - return ECORE_CALLBACK_RENEW; -} - -static void -_e_wl_shell_shell_surface_cb_ec_hook_focus_unset(void *data EINA_UNUSED, E_Client *ec) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Input *input = NULL; - Eina_List *l = NULL; - - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return; - /* try to cast data to our surface structure */ - if (!(ews = (E_Wayland_Surface*)ec->comp_data)) return; - - /* if this surface is not visible, get out */ - if (!ews->mapped) return; - - /* loop the list of inputs */ - EINA_LIST_FOREACH(_e_wl_comp->seats, l, input) - { - /* set keyboard focus */ - wl_keyboard_set_focus(input->wl.seat.keyboard, NULL); - - /* end any keyboard grabs */ - wl_keyboard_end_grab(input->wl.seat.keyboard); - } -} - -static void -_e_wl_shell_shell_surface_cb_ec_hook_focus_set(void *data EINA_UNUSED, E_Client *ec) -{ - E_Wayland_Surface *ews = NULL; - E_Wayland_Input *input = NULL; - struct wl_pointer *ptr = NULL; - Eina_List *l = NULL; - - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return; - /* try to cast data to our surface structure */ - if (!(ews = (E_Wayland_Surface*)ec->comp_data)) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - /* if the mouse entered this surface & it is not the current surface */ - if (ews->wl.surface != ptr->current) - { - const struct wl_pointer_grab_interface *grab; - - /* set this surface as the current */ - grab = ptr->grab->interface; - ptr->current = ews->wl.surface; - - /* send a pointer focus event */ - grab->focus(ptr->grab, ews->wl.surface, - ptr->current_x, ptr->current_y); - } - } - /* loop the list of inputs */ - EINA_LIST_FOREACH(_e_wl_comp->seats, l, input) - { - /* set keyboard focus */ - wl_keyboard_set_focus(input->wl.seat.keyboard, ews->wl.surface); - - /* update the keyboard focus in the data device */ - wl_data_device_set_keyboard_focus(&input->wl.seat); - } -} - -static void -_e_wl_shell_shell_surface_cb_ec_hook_move_end(void *data EINA_UNUSED, E_Client *ec) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; - -return; - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return; - /* try to cast data to our surface structure */ - if (!(ews = (E_Wayland_Surface*)ec->comp_data)) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - /* do we have a valid pointer grab ? */ - if (!ptr->grab) return; - - /* is this grab the 'move' interface ? */ - if (ptr->grab->interface != &_e_move_grab_interface) - return; - - /* does this shell have a valid shell surface ? */ - if (!ews->shell_surface) return; - - /* is the shell surface the same one in the grab ? */ - if ((ptr->current) && (ptr->current != ews->wl.surface)) return; - - /* send this button press to the pointer */ - ptr->grab->interface->button(ptr->grab, - ptr->grab_time, - ptr->grab_button, - WL_POINTER_BUTTON_STATE_RELEASED); - } -} - -static void -_e_wl_shell_shell_surface_cb_ec_hook_resize_end(void *data EINA_UNUSED, E_Client *ec) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; -return; - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return; - /* try to cast data to our surface structure */ - if (!(ews = (E_Wayland_Surface*)ec->comp_data)) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - /* do we have a valid pointer grab ? */ - if (!ptr->grab) return; - - /* is this grab the 'move' interface ? */ - if (ptr->grab->interface != &_e_resize_grab_interface) - return; - - /* does this shell have a valid shell surface ? */ - if (!ews->shell_surface) return; - - /* is the shell surface the same one in the grab ? */ - if ((ptr->current) && (ptr->current != ews->wl.surface)) return; - - ptr->button_count--; - - /* send this button press to the pointer */ - ptr->grab->interface->button(ptr->grab, - ptr->grab_time, - ptr->grab_button, - WL_POINTER_BUTTON_STATE_RELEASED); - - if (ptr->button_count == 1) - ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); - } -} - -static void -_e_wl_shell_shell_surface_cb_ec_hook_resize_update(void *data EINA_UNUSED, E_Client *ec) -{ - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; -return; - if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return; - /* try to cast data to our surface structure */ - if (!(ews = (E_Wayland_Surface*)ec->comp_data)) return; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - Evas_Coord w = 0, h = 0; - - if (!ptr->grab) return; - - if (ptr->grab->interface != &_e_resize_grab_interface) - return; - - if (!ews->shell_surface) return; - - if ((ptr->current) && (ptr->current != ews->wl.surface)) return; - - /* send this button press to the pointer */ - ptr->grab->interface->button(ptr->grab, - ptr->grab_time, - ptr->grab_button, - WL_POINTER_BUTTON_STATE_RELEASED); - w = ec->client.w; - h = ec->client.h; - - wl_shell_surface_send_configure(ews->shell_surface->wl.resource, - ptr->grab->edges, w, h); - } -} - -static void -_e_wl_shell_surface_cb_smart_client_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) -{ - E_Wayland_Shell_Grab *grab = NULL; - E_Wayland_Surface *ews = NULL; - struct wl_pointer *ptr = NULL; - - /* try to cast data to our surface structure */ - ews = data; - - /* try to get the pointer from this input */ - if ((ptr = _e_wl_comp->input->wl.seat.pointer)) - { - Evas_Coord w = 0, h = 0; - - if (!(grab = (E_Wayland_Shell_Grab *)ptr->grab)) return; - - w = ews->ec->client.w; - h = ews->ec->client.h; - - wl_shell_surface_send_configure(ews->shell_surface->wl.resource, - grab->edges, w, h); - } -} - -/* shell surface interface functions */ -static void -_e_wl_shell_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int serial) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Ping_Timer *tmr = NULL; - Eina_Bool responsive = EINA_FALSE; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* try to cast the ping timer */ - if (!(tmr = (E_Wayland_Ping_Timer *)ewss->ping_timer)) - return; - - if (tmr->serial != serial) return; - - responsive = ewss->active; - ewss->active = EINA_TRUE; - - if (!responsive) - { - E_Wayland_Shell_Grab *grab = NULL; - - grab = (E_Wayland_Shell_Grab *)_e_wl_comp->input->wl.seat.pointer->grab; - if ((grab->grab.interface == &_e_busy_grab_interface) && - (grab->shell_surface == ewss)) - { - _e_wl_shell_grab_end(grab); - free(grab); - } - } - - if (tmr->source) wl_event_source_remove(tmr->source); - - /* free the allocated space for ping timer */ - E_FREE(tmr); - ewss->ping_timer = NULL; -} - -static void -_e_wl_shell_mouse_down_helper(E_Client *ec, int button, Evas_Point *output, E_Binding_Event_Mouse_Button *ev, Eina_Bool move) -{ - if ((button >= 1) && (button <= 3)) - { - ec->mouse.last_down[button - 1].mx = output->x; - ec->mouse.last_down[button - 1].my = output->y; - ec->mouse.last_down[button - 1].x = ec->x; - ec->mouse.last_down[button - 1].y = ec->y; - ec->mouse.last_down[button - 1].w = ec->w; - ec->mouse.last_down[button - 1].h = ec->h; - } - else - { - ec->moveinfo.down.x = ec->x; - ec->moveinfo.down.y = ec->y; - ec->moveinfo.down.w = ec->w; - ec->moveinfo.down.h = ec->h; - } - ec->mouse.current.mx = output->x; - ec->mouse.current.my = output->y; - - if (move) - { - /* tell E to start moving the client */ - e_client_act_move_begin(ec, ev); - - /* we have to get a reference to the window_move action here, or else - * when e_client stops the move we will never get notified */ - ec->cur_mouse_action = e_action_find("window_move"); - if (ec->cur_mouse_action) - e_object_ref(E_OBJECT(ec->cur_mouse_action)); - } - else - { - /* tell E to start resizing the client */ - e_client_act_resize_begin(ec, ev); - - /* we have to get a reference to the window_resize action here, - * or else when e_client stops the resize we will never get notified */ - ec->cur_mouse_action = e_action_find("window_resize"); - if (ec->cur_mouse_action) - e_object_ref(E_OBJECT(ec->cur_mouse_action)); - } - - e_focus_event_mouse_down(ec); - - if ((button >= 1) && (button <= 3)) - { - ec->mouse.last_down[button - 1].mx = output->x; - ec->mouse.last_down[button - 1].my = output->y; - ec->mouse.last_down[button - 1].x = ec->x; - ec->mouse.last_down[button - 1].y = ec->y; - ec->mouse.last_down[button - 1].w = ec->w; - ec->mouse.last_down[button - 1].h = ec->h; - } - else - { - ec->moveinfo.down.x = ec->x; - ec->moveinfo.down.y = ec->y; - ec->moveinfo.down.w = ec->w; - ec->moveinfo.down.h = ec->h; - } - ec->mouse.current.mx = output->x; - ec->mouse.current.my = output->y; -} - -static void -_e_wl_shell_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial) -{ - E_Wayland_Input *input = NULL; - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Shell_Grab *grab = NULL; - E_Binding_Event_Mouse_Button ev; - struct wl_pointer *ptr = NULL; - - /* try to cast the seat resource to our input structure */ - if (!(input = wl_resource_get_user_data(seat_resource))) - return; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* if the shell surface is fullscreen, get out */ - if (ewss->type == E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN) return; - - /* check for valid move setup */ - if ((input->wl.seat.pointer->button_count == 0) || - (input->wl.seat.pointer->grab_serial != serial) || - (input->wl.seat.pointer->focus != ewss->surface->wl.surface)) - return; - - /* try to allocate space for our grab structure */ - if (!(grab = E_NEW(E_Wayland_Shell_Grab, 1))) return; - - /* try to get the pointer from this input */ - ptr = _e_wl_comp->input->wl.seat.pointer; - - /* set grab properties */ - grab->x = ptr->grab_x; - grab->y = ptr->grab_y; - - /* start the movement grab */ - _e_wl_shell_grab_start(grab, ewss, input->wl.seat.pointer, - &_e_move_grab_interface, - E_DESKTOP_SHELL_CURSOR_MOVE); - - /* set button property of the binding event */ - if (grab->grab.pointer->grab_button == BTN_LEFT) - ev.button = 1; - else if (grab->grab.pointer->grab_button == BTN_MIDDLE) - ev.button = 2; - else if (grab->grab.pointer->grab_button == BTN_RIGHT) - ev.button = 3; - else - ev.button = 0; - - /* set the clicked location in the binding event - * the ptr coords are relative to the client, so adjust them to be canvas - */ - e_comp_object_frame_xy_unadjust(ewss->surface->ec->frame, - wl_fixed_to_int(ptr->x) + ewss->surface->ec->client.x, - wl_fixed_to_int(ptr->y) + ewss->surface->ec->client.y, &ev.canvas.x, &ev.canvas.y); - - /* call our helper function to initiate a move */ - _e_wl_shell_mouse_down_helper(ewss->surface->ec, ev.button, - &(Evas_Point){ev.canvas.x, ev.canvas.y}, - &ev, EINA_TRUE); -} - -static void -_e_wl_shell_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial, unsigned int edges) -{ - E_Wayland_Input *input = NULL; - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Shell_Grab *grab = NULL; - E_Binding_Event_Mouse_Button ev; - struct wl_pointer *ptr = NULL; - - /* try to cast the seat resource to our input structure */ - if (!(input = wl_resource_get_user_data(seat_resource))) - return; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* if the shell surface is fullscreen or maximized, get out */ - if ((ewss->type == E_WAYLAND_SHELL_SURFACE_TYPE_FULLSCREEN) || - (ewss->type == E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED)) - return; - - /* check for valid move setup */ - if ((input->wl.seat.pointer->button_count == 0) || - (input->wl.seat.pointer->grab_serial != serial) || - (input->wl.seat.pointer->focus != ewss->surface->wl.surface)) - return; - - if ((edges == 0) || (edges > 15) || - ((edges & 3) == 3) || ((edges & 12) == 12)) - return; - - /* try to allocate space for our grab structure */ - if (!(grab = E_NEW(E_Wayland_Shell_Grab, 1))) return; - - /* try to get the pointer from this input */ - ptr = _e_wl_comp->input->wl.seat.pointer; - - /* set grab properties */ - grab->edges = edges; - grab->grab.edges = edges; - grab->w = ewss->surface->geometry.w; - grab->h = ewss->surface->geometry.h; - - /* start the resize grab */ - _e_wl_shell_grab_start(grab, ewss, input->wl.seat.pointer, - &_e_resize_grab_interface, edges); - - if (grab->grab.pointer->grab_button == BTN_LEFT) - ev.button = 1; - else if (grab->grab.pointer->grab_button == BTN_MIDDLE) - ev.button = 2; - else if (grab->grab.pointer->grab_button == BTN_RIGHT) - ev.button = 3; - else - ev.button = 0; - - /* set the clicked location in the binding event - * the ptr coords are relative to the client, so adjust them to be canvas - */ - e_comp_object_frame_xy_unadjust(ewss->surface->ec->frame, - wl_fixed_to_int(ptr->x) + ewss->surface->ec->client.x, - wl_fixed_to_int(ptr->y) + ewss->surface->ec->client.y, &ev.canvas.x, &ev.canvas.y); - - /* call our helper function to initiate a resize */ - _e_wl_shell_mouse_down_helper(ewss->surface->ec, ev.button, - &(Evas_Point){ev.canvas.x, ev.canvas.y}, - &ev, EINA_FALSE); -} - -static void -_e_wl_shell_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* set next surface type */ - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL; -} - -static void -_e_wl_shell_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource, int x, int y, unsigned int flags) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Surface *ews = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - ews = wl_resource_get_user_data(parent_resource); - - ewss->parent = ews; - ewss->transient.x = x; - ewss->transient.y = y; - ewss->transient.flags = flags; - - /* set next surface type */ - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_TRANSIENT; -} - -static void -_e_wl_shell_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, unsigned int method EINA_UNUSED, unsigned int framerate EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* NB FIXME: Disable fullscreen support for right now. - * - * Appears to be some recent issue with e_client... - * - * Needs looking into */ - return; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* set next surface type */ - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_TOPLEVEL; - - /* check for valid client */ - if (ewss->surface->ec) - { - /* tell E to fullscreen this window */ - e_client_fullscreen(ewss->surface->ec, E_FULLSCREEN_RESIZE); - - /* send configure message to the shell surface to inform of new size */ - wl_shell_surface_send_configure(ewss->wl.resource, 0, - ewss->surface->ec->w, - ewss->surface->ec->h); - } -} - -static void -_e_wl_shell_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource, unsigned int serial, struct wl_resource *parent_resource, int x, int y, unsigned int flags EINA_UNUSED) -{ - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Input *input = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* cast the seat resource to our input structure */ - input = wl_resource_get_user_data(seat_resource); - - /* set surface type */ - ewss->type = E_WAYLAND_SHELL_SURFACE_TYPE_POPUP; - - /* set surface popup properties */ - ewss->parent = wl_resource_get_user_data(parent_resource); - ewss->popup.seat = &input->wl.seat; - ewss->popup.serial = serial; - ewss->popup.x = x; - ewss->popup.y = y; -} - -static void -_e_wl_shell_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - /* set next surface type */ - ewss->next_type = E_WAYLAND_SHELL_SURFACE_TYPE_MAXIMIZED; - - /* check for valid client */ - if (ewss->surface->ec) - { - unsigned int edges = 0; - - edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); - - /* tell E to maximize this window */ - e_client_maximize(ewss->surface->ec, - (e_config->maximize_policy & E_MAXIMIZE_TYPE) | - E_MAXIMIZE_BOTH); - - /* send configure message to the shell surface to inform of new size */ - wl_shell_surface_send_configure(ewss->wl.resource, edges, - ewss->surface->ec->w, - ewss->surface->ec->h); - } -} - -static void -_e_wl_shell_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - eina_stringshare_replace(&ewss->title, title); - if (!ewss->surface->ec) return; - eina_stringshare_refplace(&ewss->surface->ec->icccm.title, ewss->title); - e_comp_object_frame_title_set(ewss->surface->ec->frame, title); -} - -static void -_e_wl_shell_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *clas) -{ - E_Wayland_Shell_Surface *ewss = NULL; - - /* try to cast the resource to our shell surface */ - if (!(ewss = wl_resource_get_user_data(resource))) - return; - - eina_stringshare_replace(&ewss->clas, clas); - if (!ewss->surface->ec) return; - eina_stringshare_refplace(&ewss->surface->ec->icccm.class, ewss->clas); - ewss->surface->ec->changes.icon = 1; - EC_CHANGED(ewss->surface->ec); -} - -/* shell move_grab interface functions */ -static void -_e_wl_shell_move_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - struct wl_pointer *ptr; - - /* safety */ - if (!grab) return; - - ptr = grab->pointer; - ptr->current = surface; -} - -static void -_e_wl_shell_move_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - /* FIXME: This needs to become a no-op as the actual surface movement - * is handled by e_client now */ -} - -static void -_e_wl_shell_move_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp, unsigned int button, unsigned int state) -{ - E_Wayland_Shell_Grab *ewsg = NULL; - struct wl_pointer *ptr; - - /* safety */ - if (!grab) return; - - /* try to get the shell grab from the pointer grab */ - if (!(ewsg = container_of(grab, E_Wayland_Shell_Grab, grab))) - return; - - /* try to get the pointer */ - if (!(ptr = grab->pointer)) return; - - if (state == WL_POINTER_BUTTON_STATE_RELEASED) - { - if (ptr->button_count > 0) ptr->button_count--; - } - else - ptr->button_count++; - - if (ptr->button_count == 1) - ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); - - /* test if we are done with the grab */ - if ((ptr->button_count == 0) && - (state == WL_POINTER_BUTTON_STATE_RELEASED)) - { - struct wl_list *lst; - struct wl_resource *res; - - /* end the grab */ - _e_wl_shell_grab_end(ewsg); - free(grab); - - lst = &ptr->focus_resource_list; - if (!wl_list_empty(lst)) - { - wl_resource_for_each(res, lst) - e_comp_wl_mouse_button(res, ptr->grab_serial, timestamp, button, state); - } - } -} - -/* shell resize_grab interface functions */ -static void -_e_wl_shell_resize_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - struct wl_pointer *ptr; - - /* safety */ - if (!grab) return; - - ptr = grab->pointer; - ptr->current = surface; -} - -static void -_e_wl_shell_resize_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - /* FIXME: This needs to become a no-op as the actual surface resize - * is handled by e_client now */ -} - -static void -_e_wl_shell_resize_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp, unsigned int button, unsigned int state) -{ - E_Wayland_Shell_Grab *ewsg = NULL; - struct wl_pointer *ptr; - - /* safety */ - if (!grab) return; - - /* try to get the shell grab from the pointer grab */ - if (!(ewsg = container_of(grab, E_Wayland_Shell_Grab, grab))) - return; - - /* try to get the pointer */ - if (!(ptr = grab->pointer)) return; - - if (state == WL_POINTER_BUTTON_STATE_RELEASED) - { - if (ptr->button_count > 0) ptr->button_count--; - } - else - ptr->button_count++; - - if (ptr->button_count == 1) - ptr->grab_serial = wl_display_get_serial(_e_wl_comp->wl.display); - - /* test if we are done with the grab */ - if ((ptr->button_count == 0) && - (state == WL_POINTER_BUTTON_STATE_RELEASED)) - { - struct wl_list *lst; - struct wl_resource *res; - - /* end the grab */ - _e_wl_shell_grab_end(ewsg); - free(grab); - - lst = &ptr->focus_resource_list; - if (!wl_list_empty(lst)) - { - wl_resource_for_each(res, lst) - e_comp_wl_mouse_button(res, ptr->grab_serial, timestamp, button, state); - } - } -} - -/* shell popup_grab interface prototypes */ -static void -_e_wl_shell_popup_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x, wl_fixed_t y) -{ - E_Wayland_Shell_Surface *ewss; - struct wl_pointer *ptr; - struct wl_client *client; - - /* try to get the pointer */ - if (!(ptr = grab->pointer)) return; - - /* try to get the surface from the pointer grab */ - ewss = container_of(grab, E_Wayland_Shell_Surface, popup.grab); - if (!ewss) return; - - client = wl_resource_get_client(ewss->surface->wl.surface); - - if ((surface) && (wl_resource_get_client(surface) == client)) - { - wl_pointer_set_focus(ptr, surface, x, y); - grab->focus = surface; - } - else - { - wl_pointer_set_focus(ptr, NULL, 0, 0); - grab->focus = NULL; - } -} - -static void -_e_wl_shell_popup_grab_cb_motion(struct wl_pointer_grab *grab, unsigned int timestamp, wl_fixed_t x, wl_fixed_t y) -{ - struct wl_resource *res; - - wl_resource_for_each(res, &grab->pointer->focus_resource_list) - wl_pointer_send_motion(res, timestamp, x, y); -} - -static void -_e_wl_shell_popup_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp, unsigned int button, unsigned int state) -{ - E_Wayland_Shell_Surface *ewss = NULL; - struct wl_resource *res; - struct wl_list *lst; - - /* try to get the shell surface */ - ewss = container_of(grab, E_Wayland_Shell_Surface, popup.grab); - if (!ewss) return; - - lst = &grab->pointer->focus_resource_list; - if (!wl_list_empty(lst)) - { - uint32_t serial; - - serial = wl_display_get_serial(_e_wl_comp->wl.display); - - wl_resource_for_each(res, lst) - wl_pointer_send_button(res, serial, timestamp, button, state); - } - else if ((state = WL_POINTER_BUTTON_STATE_RELEASED) && - ((ewss->popup.up) || - (timestamp - ewss->popup.seat->pointer->grab_time > 500))) - { - /* end the popup grab */ - _e_wl_shell_popup_grab_end(grab->pointer); - } - - if (state == WL_POINTER_BUTTON_STATE_RELEASED) - ewss->popup.up = EINA_TRUE; -} - -/* shell popup functions */ -static void -_e_wl_shell_popup_grab_end(struct wl_pointer *pointer) -{ - E_Wayland_Shell_Surface *ewss = NULL; - struct wl_pointer_grab *grab; - - grab = pointer->grab; - - /* try to get the shell surface from this grab */ - ewss = container_of(grab, E_Wayland_Shell_Surface, popup.grab); - if (!ewss) return; - - if (pointer->grab->interface == &_e_popup_grab_interface) - { - wl_shell_surface_send_popup_done(ewss->wl.resource); - wl_pointer_end_grab(grab->pointer); - ewss->popup.grab.pointer = NULL; - } -} - -/* shell busy_grab interface functions */ -static void -_e_wl_shell_busy_grab_cb_focus(struct wl_pointer_grab *grab, struct wl_resource *surface, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - E_Wayland_Shell_Grab *ewsg = NULL; - - /* try to cast the pointer grab to our structure */ - if (!(ewsg = (E_Wayland_Shell_Grab *)grab)) return; - - /* if the grab's focus is not this surface, then end the grab */ - if ((!ewsg->shell_surface) || - (ewsg->shell_surface->surface->wl.surface != surface)) - { - /* end the grab */ - _e_wl_shell_grab_end(ewsg); - free(grab); - } -} - -static void -_e_wl_shell_busy_grab_cb_motion(struct wl_pointer_grab *grab EINA_UNUSED, unsigned int timestamp EINA_UNUSED, wl_fixed_t x EINA_UNUSED, wl_fixed_t y EINA_UNUSED) -{ - /* no-op */ -} - -static void -_e_wl_shell_busy_grab_cb_button(struct wl_pointer_grab *grab, unsigned int timestamp EINA_UNUSED, unsigned int button, unsigned int state) -{ - E_Wayland_Shell_Grab *ewsg = NULL; - E_Wayland_Shell_Surface *ewss = NULL; - E_Wayland_Input *input = NULL; - - /* try to cast the pointer grab to our structure */ - if (!(ewsg = (E_Wayland_Shell_Grab *)grab)) return; - - /* try to get the current shell surface */ - if (!(ewss = ewsg->shell_surface)) return; - /* if (!(ews = (E_Wayland_Surface *)ewsg->grab.pointer->current)) return; */ - - /* try to cast the pointer seat to our input structure */ - if (!(input = (E_Wayland_Input *)ewsg->grab.pointer->seat)) - return; - - if ((ewss) && (button == 1) && (state)) - { - E_Wayland_Shell_Grab *mgrab = NULL; - - /* try to allocate space for our grab structure */ - if (!(mgrab = E_NEW(E_Wayland_Shell_Grab, 1))) return; - - /* set grab properties */ - mgrab->x = input->wl.seat.pointer->grab_x; - mgrab->y = input->wl.seat.pointer->grab_y; - - /* start the movement grab */ - _e_wl_shell_grab_start(mgrab, ewss, input->wl.seat.pointer, - &_e_busy_grab_interface, - E_DESKTOP_SHELL_CURSOR_MOVE); - } -} diff --git a/src/modules/wl_desktop_shell/e_mod_main.h b/src/modules/wl_desktop_shell/e_mod_main.h deleted file mode 100644 index 29dc63e64..000000000 --- a/src/modules/wl_desktop_shell/e_mod_main.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef E_MOD_MAIN_H -# define E_MOD_MAIN_H - -# define SLOGFNS 1 - -# ifdef SLOGFNS -# include -# define SLOGFN(fl, ln, fn) printf("-E-SHELL: %25s: %5i - %s\n", fl, ln, fn); -# else -# define SLOGFN(fl, ln, fn) -# endif - -typedef struct _E_Wayland_Desktop_Shell E_Wayland_Desktop_Shell; -typedef struct _E_Wayland_Ping_Timer E_Wayland_Ping_Timer; - -struct _E_Wayland_Desktop_Shell -{ - E_Wayland_Compositor *compositor; - E_Wayland_Surface *grab_surface; - - struct - { - struct wl_resource *resource; - struct wl_listener destroy_listener; - } wl; -}; - -struct _E_Wayland_Ping_Timer -{ - struct wl_event_source *source; - unsigned int serial; -}; - -EAPI extern E_Module_Api e_modapi; - -EAPI void *e_modapi_init(E_Module *m); -EAPI int e_modapi_shutdown(E_Module *m); - -#endif