discomfitor pushed a commit to branch master. http://git.enlightenment.org/core/enlightenment.git/commit/?id=ad3d0bd8c54336bda05f214b1e741e49d770cae4
commit ad3d0bd8c54336bda05f214b1e741e49d770cae4 Author: Mike Blumenkrantz <[email protected]> Date: Mon Oct 10 11:30:52 2016 -0400 split wl_desktop_shell into separate files per shell this should make it easier to selectively disable shells, and it will definitely simplify future shell additions --- src/modules/Makefile_wl_desktop_shell.mk | 9 +- src/modules/wl_desktop_shell/e_mod_main.c | 1521 +------------------- src/modules/wl_desktop_shell/e_mod_main.h | 27 +- src/modules/wl_desktop_shell/wl_shell.c | 523 +++++++ .../wl_desktop_shell/{e_mod_main.c => xdg5.c} | 723 +--------- 5 files changed, 620 insertions(+), 2183 deletions(-) diff --git a/src/modules/Makefile_wl_desktop_shell.mk b/src/modules/Makefile_wl_desktop_shell.mk index 9665a75..83b0d5a 100644 --- a/src/modules/Makefile_wl_desktop_shell.mk +++ b/src/modules/Makefile_wl_desktop_shell.mk @@ -22,9 +22,12 @@ src_modules_wl_desktop_shell_module_la_LIBADD = $(MOD_LIBS) @WAYLAND_LIBS@ src_modules_wl_desktop_shell_module_la_LDFLAGS = $(MOD_LDFLAGS) src_modules_wl_desktop_shell_module_la_SOURCES = \ - src/modules/wl_desktop_shell/e_mod_main.c \ - src/modules/wl_desktop_shell/e_mod_main.h \ - src/modules/wl_desktop_shell/e_mod_input_panel.c +src/modules/wl_desktop_shell/e_mod_main.c \ +src/modules/wl_desktop_shell/e_mod_main.h \ +src/modules/wl_desktop_shell/e_mod_input_panel.c \ +src/modules/wl_desktop_shell/wl_shell.c \ +src/modules/wl_desktop_shell/xdg5.c + nodist_src_modules_wl_desktop_shell_module_la_SOURCES = \ $(wl_desktop_shell_wayland_sources) diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/e_mod_main.c index 648ca61..8d7a897 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/e_mod_main.c @@ -1,40 +1,57 @@ #define E_COMP_WL #include "e.h" #include "e_mod_main.h" -#include "xdg-shell-unstable-v5-server-protocol.h" -#define XDG_SERVER_VERSION 5 +EINTERN Eina_Hash *shell_resources; +EINTERN Eina_Hash *xdg_shell_resources; -typedef enum +EINTERN void +e_shell_surface_destroy(struct wl_resource *resource) { - STATE_MAXIMIZED = (1 << 0), - STATE_UNMAXIMIZED = (1 << 1), - STATE_FULLSCREEN = (1 << 2), - STATE_UNFULLSCREEN = (1 << 3), -} State; + E_Client *ec; + E_Shell_Data *shd; -typedef struct Pending_State -{ - State state; - uint32_t serial; -} Pending_State; + /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ + + /* get the client for this resource */ + ec = wl_resource_get_user_data(resource); + if (!ec) return; + if (!e_object_unref(E_OBJECT(ec))) return; + if (e_object_is_del(E_OBJECT(ec))) return; + + shd = ec->comp_data->shell.data; + + if (shd) + { + E_FREE_LIST(shd->pending, free); + E_FREE(ec->comp_data->shell.data); + } + + if (ec->comp_data->mapped) + { + if ((ec->comp_data->shell.surface) && + (ec->comp_data->shell.unmap)) + ec->comp_data->shell.unmap(ec->comp_data->shell.surface); + } + if (ec->parent) + { + ec->parent->transients = + eina_list_remove(ec->parent->transients, ec); + } + /* wl_resource_destroy(ec->comp_data->shell.surface); */ + ec->comp_data->shell.surface = NULL; +} -struct E_Shell_Data +EINTERN void +e_shell_surface_cb_destroy(struct wl_resource *resource) { - uint32_t edges; - int32_t width; - int32_t height; - Eina_List *pending; - Eina_Bool fullscreen : 1; - Eina_Bool maximized : 1; - Eina_Bool activated : 1; -}; + /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ -static Eina_Hash *shell_resources; -static Eina_Hash *xdg_shell_resources; + e_shell_surface_destroy(resource); +} -static void -_e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource) +EINTERN void +e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource) { E_Client *pc; uint64_t pwin = 0; @@ -89,8 +106,8 @@ _e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource) ec->icccm.transient_for = pwin; } -static void -_e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move) +EINTERN void +e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move) { if (move) { @@ -118,1450 +135,20 @@ _e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *e e_focus_event_mouse_down(ec); } -static void -_e_shell_surface_destroy(struct wl_resource *resource) -{ - E_Client *ec; - - /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if ((ec = wl_resource_get_user_data(resource))) - { - if (!e_object_unref(E_OBJECT(ec))) return; - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->comp_data) - { - E_Shell_Data *shd = ec->comp_data->shell.data; - - if (shd) - { - E_FREE_LIST(shd->pending, free); - E_FREE(ec->comp_data->shell.data); - } - - if (ec->comp_data->mapped) - { - if ((ec->comp_data->shell.surface) && - (ec->comp_data->shell.unmap)) - ec->comp_data->shell.unmap(ec->comp_data->shell.surface); - } - if (ec->parent) - { - ec->parent->transients = - eina_list_remove(ec->parent->transients, ec); - } - /* wl_resource_destroy(ec->comp_data->shell.surface); */ - ec->comp_data->shell.surface = NULL; - } - } -} - -static void -_e_shell_surface_cb_destroy(struct wl_resource *resource) -{ - /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ - - _e_shell_surface_destroy(resource); -} - -static void -_e_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - - if ((ec = wl_resource_get_user_data(resource))) - { - ec->ping_ok = EINA_TRUE; - ec->hung = EINA_FALSE; - } -} - -static void -_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); -} - -static void -_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((edges == 0) || (edges > 15) || - ((edges & 3) == 3) || ((edges & 12) == 12)) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - DBG("Comp Resize Edges Set: %d", edges); - - e_comp_wl->resize.resource = resource; - e_comp_wl->resize.edges = edges; - e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x); - e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y); - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); -} - -static void -_e_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set toplevel client properties */ - ec->icccm.accepts_focus = 1; - if (!ec->internal) - ec->borderless = !ec->internal; - - ec->lock_border = EINA_TRUE; - if ((!ec->internal) || (!ec->borderless)) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->netwm.type = E_WINDOW_TYPE_NORMAL; - ec->comp_data->set_win_type = EINA_TRUE; - if ((!ec->lock_user_maximize) && (ec->maximized)) - e_client_unmaximize(ec, E_MAXIMIZE_BOTH); - if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) - e_client_unfullscreen(ec); - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, uint32_t flags EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); - - ec->icccm.accepts_focus = 1; - if (!ec->internal) - ec->borderless = !ec->internal; - - ec->lock_border = EINA_TRUE; - if ((!ec->internal) || (!ec->borderless)) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->netwm.type = E_WINDOW_TYPE_DIALOG; - ec->dialog = EINA_TRUE; - ec->comp_data->set_win_type = EINA_TRUE; - if ((!ec->lock_user_maximize) && (ec->maximized)) - e_client_unmaximize(ec, E_MAXIMIZE_BOTH); - if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) - e_client_unfullscreen(ec); - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t method EINA_UNUSED, uint32_t framerate EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (!ec->lock_user_fullscreen) - e_client_fullscreen(ec, e_config->fullscreen_policy); -} - -static void -_e_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *parent_resource, int32_t x, int32_t y, uint32_t flags EINA_UNUSED) -{ - E_Client *ec; - E_Comp_Client_Data *cdata; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - ec->comp_data->popup.x = x; - ec->comp_data->popup.y = y; - - if (!ec->internal) - ec->borderless = !ec->internal_elm_win; - ec->lock_border = EINA_TRUE; - if (!ec->internal) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->changes.icon = !!ec->icccm.class; - ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU; - ec->comp_data->set_win_type = EINA_TRUE; - - cdata = ec->comp_data; - if (ec->parent) - { - cdata->popup.x = E_CLAMP(x, 0, ec->parent->client.w); - cdata->popup.y = E_CLAMP(y, 0, ec->parent->client.h); - } - else - { - cdata->popup.x = x; - cdata->popup.y = y; - } - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); - - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Client *ec; - - /* DBG("WL_SHELL: Surface Maximize: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* tell E to maximize this client */ - if (!ec->lock_user_maximize) - { - unsigned int edges = 0; - - e_client_maximize(ec, ((e_config->maximize_policy & E_MAXIMIZE_TYPE) | - E_MAXIMIZE_BOTH)); - - edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); - wl_shell_surface_send_configure(resource, edges, ec->w, ec->h); - } -} - -static void -_e_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set title */ - eina_stringshare_replace(&ec->icccm.title, title); - if (ec->frame) e_comp_object_frame_title_set(ec->frame, title); -} - -static void -_e_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *clas) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* use the wl_client to get the pid * and set it in the netwm props */ - wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL); - - /* set class */ - eina_stringshare_replace(&ec->icccm.class, clas); - ec->changes.icon = !!ec->icccm.class; - EC_CHANGED(ec); -} - -static const struct wl_shell_surface_interface _e_shell_surface_interface = -{ - _e_shell_surface_cb_pong, - _e_shell_surface_cb_move, - _e_shell_surface_cb_resize, - _e_shell_surface_cb_toplevel_set, - _e_shell_surface_cb_transient_set, - _e_shell_surface_cb_fullscreen_set, - _e_shell_surface_cb_popup_set, - _e_shell_surface_cb_maximized_set, - _e_shell_surface_cb_title_set, - _e_shell_surface_cb_class_set, -}; - -static void -_e_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges, int32_t width, int32_t height) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_client_util_is_popup(ec)) return; - - wl_shell_surface_send_configure(resource, edges, width, height); -} - -static void -_e_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Client *ec; - - /* DBG("WL_SHELL: Surface Configure: %d \t%d %d %d %d", */ - /* wl_resource_get_id(resource), x, y, w, h); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->parent) - { - if (e_client_util_is_popup(ec)) - { - x = E_CLAMP(ec->parent->client.x + ec->comp_data->popup.x, - ec->parent->client.x, - ec->parent->client.x + - ec->parent->client.w); - y = E_CLAMP(ec->parent->client.y + ec->comp_data->popup.y, - ec->parent->client.y, - ec->parent->client.y + - ec->parent->client.h); - } - } - - e_client_util_move_resize_without_frame(ec, x, y, w, h); -} - -static void -_e_shell_surface_ping(struct wl_resource *resource) -{ - E_Client *ec; - uint32_t serial; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - serial = wl_display_next_serial(e_comp_wl->wl.disp); - wl_shell_surface_send_ping(ec->comp_data->shell.surface, serial); -} - -static void -_e_shell_surface_map(struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* map this surface if needed */ - if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap))) - { - ec->visible = EINA_TRUE; - evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h); - evas_object_show(ec->frame); - ec->comp_data->mapped = EINA_TRUE; - } -} - -static void -_e_shell_surface_unmap(struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->comp_data->mapped) - { - ec->visible = EINA_FALSE; - evas_object_hide(ec->frame); - ec->comp_data->mapped = EINA_FALSE; - } -} +E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" }; -static void -_e_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource) +E_API void * +e_modapi_init(E_Module *m) { - E_Client *ec; - E_Comp_Client_Data *cdata; - - /* get the pixmap from this surface so we can find the client */ - if (!(ec = wl_resource_get_user_data(surface_resource))) + /* try to create global shell interface */ + if (!wl_global_create(e_comp_wl->wl.disp, &wl_shell_interface, 1, + NULL, wl_shell_cb_bind)) { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Pixmap Set On Surface"); - return; + ERR("Could not create shell global"); + return NULL; } - if (e_object_is_del(E_OBJECT(ec))) return; - cdata = ec->comp_data; - ec->netwm.ping = 1; - /* check for existing shell surface */ - if (cdata->shell.surface) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Client already has shell surface"); - return; - } - - /* try to create a shell surface */ - if (!(cdata->shell.surface = - wl_resource_create(client, &wl_shell_surface_interface, 1, id))) - { - ERR("Could not create wl_shell surface"); - wl_resource_post_no_memory(surface_resource); - return; - } - - wl_resource_set_implementation(cdata->shell.surface, - &_e_shell_surface_interface, - ec, _e_shell_surface_cb_destroy); - - e_object_ref(E_OBJECT(ec)); - - cdata->shell.configure_send = _e_shell_surface_configure_send; - cdata->shell.configure = _e_shell_surface_configure; - cdata->shell.ping = _e_shell_surface_ping; - cdata->shell.map = _e_shell_surface_map; - cdata->shell.unmap = _e_shell_surface_unmap; - if (!ec->internal) - e_client_ping(ec); -} - -static void -_e_xdg_surface_state_add(struct wl_resource *resource, struct wl_array *states, uint32_t state) -{ - uint32_t *s; - - s = wl_array_add(states, sizeof(*s)); - if (s) - *s = state; - else - wl_resource_post_no_memory(resource); -} - -static void -_xdg_shell_surface_send_configure(struct wl_resource *resource, Eina_Bool fullscreen, Eina_Bool maximized, uint32_t edges, int32_t width, int32_t height) -{ - struct wl_array states; - uint32_t serial; - E_Client *focused, *ec; - E_Shell_Data *shd; - State pending = 0; - Eina_Bool activated = EINA_FALSE; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_client_util_is_popup(ec)) return; - focused = e_client_focused_get(); - if (ec == focused) - activated = 1; - else if (focused && focused->parent) - { - do - { - if (focused->parent != ec) - focused = focused->parent; - else - activated = 1; - } while (focused && (!activated)); - } - shd = ec->comp_data->shell.data; - if ((shd->edges == edges) && (shd->width == width) && (shd->height == height) && - (shd->fullscreen == fullscreen) && - (shd->maximized == maximized) && - (shd->activated == activated)) return; - shd->edges = edges; - shd->width = width; - shd->height = height; - if (shd->fullscreen != fullscreen) - { - if (fullscreen) - pending |= STATE_FULLSCREEN; - else - pending |= STATE_UNFULLSCREEN; - } - shd->fullscreen = fullscreen; - if (shd->maximized != maximized) - { - if (maximized) - pending |= STATE_MAXIMIZED; - else - pending |= STATE_UNMAXIMIZED; - } - shd->maximized = maximized; - shd->activated = activated; - wl_array_init(&states); - - if (fullscreen) - _e_xdg_surface_state_add(resource, &states, XDG_SURFACE_STATE_FULLSCREEN); - else if (maximized) - _e_xdg_surface_state_add(resource, &states, XDG_SURFACE_STATE_MAXIMIZED); - if (edges) - _e_xdg_surface_state_add(resource, &states, XDG_SURFACE_STATE_RESIZING); - if (activated) - _e_xdg_surface_state_add(resource, &states, XDG_SURFACE_STATE_ACTIVATED); - - serial = wl_display_next_serial(e_comp_wl->wl.disp); - xdg_surface_send_configure(resource, width, height, &states, serial); - { - Pending_State *ps; - - ps = E_NEW(Pending_State, 1); - ps->state = pending; - ps->serial = serial; - shd->pending = eina_list_append(shd->pending, ps); - } - - wl_array_release(&states); -} - -static void -_e_xdg_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges, int32_t width, int32_t height) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - if (e_client_util_is_popup(ec)) return; - - _xdg_shell_surface_send_configure(resource, ec->fullscreen, !!ec->maximized || ec->comp_data->max, edges, width, height); -} - -static void -_e_xdg_shell_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_e_xdg_shell_surface_cb_parent_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); -} - -static void -_e_xdg_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set title */ - eina_stringshare_replace(&ec->icccm.title, title); - if (ec->frame) e_comp_object_frame_title_set(ec->frame, title); -} - -static void -_e_xdg_shell_surface_cb_app_id_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *id) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* use the wl_client to get the pid * and set it in the netwm props */ - wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL); - - /* set class */ - eina_stringshare_replace(&ec->icccm.class, id); - /* eina_stringshare_replace(&ec->netwm.name, id); */ - ec->changes.icon = !!ec->icccm.class; - EC_CHANGED(ec); -} - -static void -_e_xdg_shell_surface_cb_window_menu_show(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t x, int32_t y) -{ - E_Client *ec; - double timestamp; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - timestamp = ecore_loop_time_get(); - e_int_client_menu_show(ec, ec->x + x, ec->y + y, 0, timestamp); -} - -static void -_e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); -} - -static void -_e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* DBG("XDG_SHELL: Surface Resize: %d\tEdges: %d", */ - /* wl_resource_get_id(resource), edges); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((edges == 0) || (edges > 15) || - ((edges & 3) == 3) || ((edges & 12) == 12)) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - e_comp_wl->resize.resource = resource; - e_comp_wl->resize.edges = edges; - e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x); - e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y); - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); -} - -static void -_e_xdg_shell_surface_cb_ack_configure(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial) -{ - E_Client *ec; - Pending_State *ps; - E_Shell_Data *shd; - Eina_List *l, *ll; - - ec = wl_resource_get_user_data(resource); - if (!ec) - { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - shd = ec->comp_data->shell.data; - EINA_LIST_FOREACH_SAFE(shd->pending, l, ll, ps) - { - if (ps->serial > serial) break; - if (ps->state & STATE_FULLSCREEN) - { - ec->comp_data->shell.set.fullscreen = 1; - ec->comp_data->shell.set.unfullscreen = 0; - } - if (ps->state & STATE_UNFULLSCREEN) - { - ec->comp_data->shell.set.unfullscreen = 1; - ec->comp_data->shell.set.fullscreen = 0; - } - if (ps->state & STATE_MAXIMIZED) - { - ec->comp_data->shell.set.maximize = 1; - ec->comp_data->shell.set.unmaximize = 0; - } - if (ps->state & STATE_UNMAXIMIZED) - { - ec->comp_data->shell.set.unmaximize = 1; - ec->comp_data->shell.set.maximize = 0; - } - shd->pending = eina_list_remove_list(shd->pending, l); - free(ps); - } -} - -static void -_e_xdg_shell_surface_cb_window_geometry_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h) -{ - E_Client *ec; - - ec = wl_resource_get_user_data(resource); - if (!ec) - { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - EINA_RECTANGLE_SET(&ec->comp_data->shell.window, x, y, w, h); - //DBG("XDG_SHELL: Window Geom Set: %d \t%d %d, %d %d", wl_resource_get_id(resource), x, y, w, h); -} - -static void -_e_xdg_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - int w, h; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->lock_user_maximize) return; - if (e_config->window_maximize_animate && (!ec->maximize_anims_disabled)) - w = ec->w, h = ec->h; - else - { - switch (e_config->maximize_policy & E_MAXIMIZE_TYPE) - { - case E_MAXIMIZE_FULLSCREEN: - w = ec->zone->w, h = ec->zone->h; - break; - default: - e_zone_useful_geometry_get(ec->zone, NULL, NULL, &w, &h); - } - } - _xdg_shell_surface_send_configure(resource, ec->fullscreen, 1, 0, w, h); -} - -static void -_e_xdg_shell_surface_cb_maximized_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - int w, h; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->lock_user_maximize) return; - ec->comp_data->unmax = (e_config->maximize_policy & E_MAXIMIZE_TYPE) | E_MAXIMIZE_BOTH; - if (e_config->window_maximize_animate && (!ec->maximize_anims_disabled)) - w = ec->w, h = ec->h; - else - w = ec->saved.w, h = ec->saved.h; - _xdg_shell_surface_send_configure(resource, ec->fullscreen, 0, 0, w, h); -} - -static void -_e_xdg_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - - if (ec->lock_user_fullscreen) return; - _xdg_shell_surface_send_configure(resource, 1, !!ec->maximized || ec->comp_data->max, 0, ec->zone->w, ec->zone->h); -} - -static void -_e_xdg_shell_surface_cb_fullscreen_unset(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->lock_user_fullscreen) return; - _xdg_shell_surface_send_configure(resource, 0, !!ec->maximized || ec->comp_data->max, 0, ec->saved.w, ec->saved.h); -} - -static void -_e_xdg_shell_surface_cb_minimized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->lock_user_iconify) return; - ec->comp_data->shell.set.minimize = 1; - ec->comp_data->max = (e_config->maximize_policy & E_MAXIMIZE_TYPE) | E_MAXIMIZE_BOTH; -} - -static const struct xdg_surface_interface _e_xdg_surface_interface = -{ - _e_xdg_shell_surface_cb_destroy, - _e_xdg_shell_surface_cb_parent_set, - _e_xdg_shell_surface_cb_title_set, - _e_xdg_shell_surface_cb_app_id_set, - _e_xdg_shell_surface_cb_window_menu_show, - _e_xdg_shell_surface_cb_move, - _e_xdg_shell_surface_cb_resize, - _e_xdg_shell_surface_cb_ack_configure, - _e_xdg_shell_surface_cb_window_geometry_set, - _e_xdg_shell_surface_cb_maximized_set, - _e_xdg_shell_surface_cb_maximized_unset, - _e_xdg_shell_surface_cb_fullscreen_set, - _e_xdg_shell_surface_cb_fullscreen_unset, - _e_xdg_shell_surface_cb_minimized_set, -}; - -static void -_e_xdg_shell_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static void -_e_xdg_shell_cb_unstable_version(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t version) -{ - if (version > 1) - wl_resource_post_error(resource, 1, "XDG Version Not Implemented Yet"); -} - -static void -_e_xdg_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Client *ec; - - /* DBG("XDG_SHELL: Surface Configure: %d \t%d %d %d %d", */ - /* wl_resource_get_id(resource), x, y, w, h); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->parent) - { - if (e_client_util_is_popup(ec)) - { - x = ec->parent->client.x + ec->comp_data->popup.x; - y = ec->parent->client.y + ec->comp_data->popup.y; - } - } - - e_client_util_move_resize_without_frame(ec, x, y, w, h); -} - -static void -_e_xdg_shell_surface_ping(struct wl_resource *resource) -{ - E_Client *ec; - uint32_t serial; - struct wl_client *client; - struct wl_resource *xdg_shell; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - client = wl_resource_get_client(resource); - xdg_shell = eina_hash_find(xdg_shell_resources, &client); - - if (!xdg_shell) return; - serial = wl_display_next_serial(e_comp_wl->wl.disp); - xdg_shell_send_ping(xdg_shell, serial); -} - -static void -_e_xdg_shell_surface_map(struct wl_resource *resource) -{ - E_Client *ec; - - /* DBG("XDG_SHELL: Map Surface: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap))) - { - /* map this surface if needed */ - ec->visible = EINA_TRUE; - evas_object_show(ec->frame); - ec->comp_data->mapped = EINA_TRUE; - - /* FIXME: sometimes popup surfaces Do Not raise above their - * respective parents... */ - /* if (e_client_util_is_popup(ec)) */ - /* e_client_raise_latest_set(ec); */ - } -} - -static void -_e_xdg_shell_surface_unmap(struct wl_resource *resource) -{ - E_Client *ec; - - /* DBG("XDG_SHELL: Unmap Surface: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->comp_data->mapped) - { - ec->visible = EINA_FALSE; - evas_object_hide(ec->frame); - ec->comp_data->mapped = EINA_FALSE; - } -} - -static void -_e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource) -{ - E_Client *ec; - E_Comp_Client_Data *cdata; - - /* DBG("XDG_SHELL: Surface Get %d", wl_resource_get_id(surface_resource)); */ - - /* get the pixmap from this surface so we can find the client */ - if (!(ec = wl_resource_get_user_data(surface_resource))) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Pixmap Set On Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - ec->netwm.ping = 1; - cdata = ec->comp_data; - - /* check for existing shell surface */ - if (cdata->shell.surface) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Client already has XDG shell surface"); - return; - } - - /* try to create a shell surface */ - if (!(cdata->shell.surface = - wl_resource_create(client, &xdg_surface_interface, 1, id))) - { - ERR("Could not create xdg shell surface"); - wl_resource_post_no_memory(surface_resource); - return; - } - - wl_resource_set_implementation(cdata->shell.surface, - &_e_xdg_surface_interface, ec, - _e_shell_surface_cb_destroy); - - e_object_ref(E_OBJECT(ec)); - - cdata->shell.configure_send = _e_xdg_shell_surface_configure_send; - cdata->shell.configure = _e_xdg_shell_surface_configure; - cdata->shell.ping = _e_xdg_shell_surface_ping; - cdata->shell.map = _e_xdg_shell_surface_map; - cdata->shell.unmap = _e_xdg_shell_surface_unmap; - cdata->shell.data = E_NEW(E_Shell_Data, 1); - cdata->is_xdg_surface = EINA_TRUE; - - /* set toplevel client properties */ - ec->icccm.accepts_focus = 1; - if (!ec->internal) - ec->borderless = 1; - ec->lock_border = EINA_TRUE; - if ((!ec->internal) || (!ec->borderless)) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->netwm.type = E_WINDOW_TYPE_NORMAL; - ec->comp_data->set_win_type = EINA_TRUE; - - if (ec->internal_elm_win && evas_object_visible_get(ec->internal_elm_win)) - _e_xdg_shell_surface_map(surface_resource); - if (!ec->internal) - e_client_ping(ec); -} - -static void -_e_xdg_shell_popup_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - wl_resource_destroy(resource); -} - -static const struct xdg_popup_interface _e_xdg_popup_interface = -{ - _e_xdg_shell_popup_cb_destroy, -}; - -static void -_e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, int32_t x, int32_t y) -{ - E_Client *ec; - E_Comp_Client_Data *cdata; - - /* DBG("XDG_SHELL: Popup Get"); */ - /* DBG("\tSurface: %d", wl_resource_get_id(surface_resource)); */ - /* DBG("\tParent Surface: %d", wl_resource_get_id(parent_resource)); */ - /* DBG("\tLocation: %d %d", x, y); */ - - /* get the pixmap from this surface so we can find the client */ - if (!(ec = wl_resource_get_user_data(surface_resource))) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Pixmap Set On Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - cdata = ec->comp_data; - - /* check for existing shell surface */ - if (cdata->shell.surface) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Client already has shell popup surface"); - return; - } - - /* check for the parent surface */ - if (!parent_resource) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Popup requires a parent shell surface"); - return; - } - - /* try to create a shell surface */ - if (!(cdata->shell.surface = - wl_resource_create(client, &xdg_popup_interface, 1, id))) - { - ERR("Could not create xdg shell surface"); - wl_resource_post_no_memory(surface_resource); - return; - } - - wl_resource_set_implementation(cdata->shell.surface, - &_e_xdg_popup_interface, ec, _e_shell_surface_destroy); - - e_object_ref(E_OBJECT(ec)); - - cdata->shell.configure_send = _e_xdg_shell_surface_configure_send; - cdata->shell.configure = _e_xdg_shell_surface_configure; - cdata->shell.ping = _e_xdg_shell_surface_ping; - cdata->shell.map = _e_xdg_shell_surface_map; - cdata->shell.unmap = _e_xdg_shell_surface_unmap; - cdata->shell.data = E_NEW(E_Shell_Data, 1); - cdata->is_xdg_surface = EINA_TRUE; - - if (!ec->internal) - ec->borderless = !ec->internal_elm_win; - ec->lock_border = EINA_TRUE; - if (!ec->internal) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->changes.icon = !!ec->icccm.class; - ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU; - ec->placed = ec->comp_data->set_win_type = EINA_TRUE; - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); - - if (ec->parent) - { - cdata->popup.x = E_CLAMP(x, 0, ec->parent->client.w); - cdata->popup.y = E_CLAMP(y, 0, ec->parent->client.h); - } - else - { - cdata->popup.x = x; - cdata->popup.y = y; - } - if (ec->internal_elm_win && evas_object_visible_get(ec->internal_elm_win)) - _e_xdg_shell_surface_map(surface_resource); -} - -static void -_e_xdg_shell_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - - if ((ec = wl_resource_get_user_data(resource))) - { - ec->ping_ok = EINA_TRUE; - ec->hung = EINA_FALSE; - } -} - -static const struct wl_shell_interface _e_shell_interface = -{ - _e_shell_cb_shell_surface_get -}; - -static const struct xdg_shell_interface _e_xdg_shell_interface = -{ - _e_xdg_shell_cb_destroy, - _e_xdg_shell_cb_unstable_version, - _e_xdg_shell_cb_surface_get, - _e_xdg_shell_cb_popup_get, - _e_xdg_shell_cb_pong -}; - -static void -_e_xdg_shell_cb_unbind(struct wl_resource *resource) -{ - struct wl_client *client = wl_resource_get_client(resource); - eina_hash_set(shell_resources, &client, NULL); -} - -static int -_e_xdg_shell_cb_dispatch(const void *implementation EINA_UNUSED, void *target, uint32_t opcode, const struct wl_message *message EINA_UNUSED, union wl_argument *args) -{ - struct wl_resource *res; - - if (!(res = target)) return 0; - - if (opcode != 1) - { - wl_resource_post_error(res, WL_DISPLAY_ERROR_INVALID_OBJECT, - "Must call use_unstable_version first"); - return 0; - } - - if (args[0].i != XDG_SERVER_VERSION) - { - wl_resource_post_error(res, WL_DISPLAY_ERROR_INVALID_OBJECT, - "Incompatible versions. " - "Server: %d, Client: %d", - XDG_SERVER_VERSION, args[0].i); - return 0; - } - - wl_resource_set_implementation(res, &_e_xdg_shell_interface, - NULL, _e_xdg_shell_cb_unbind); - - return 1; -} - -static void -_e_shell_cb_unbind(struct wl_resource *resource) -{ - struct wl_client *client = wl_resource_get_client(resource); - eina_hash_set(shell_resources, &client, NULL); -} - -static void -_e_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id) -{ - struct wl_resource *res; - - if (!(res = wl_resource_create(client, &wl_shell_interface, version, id))) - { - wl_client_post_no_memory(client); - return; - } - - eina_hash_set(shell_resources, &client, res); - wl_resource_set_implementation(res, &_e_shell_interface, - NULL, _e_shell_cb_unbind); -} - -static void -_e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id) -{ - struct wl_resource *res; - - if (!(res = wl_resource_create(client, &xdg_shell_interface, version, id))) - { - wl_client_post_no_memory(client); - return; - } - - eina_hash_set(xdg_shell_resources, &client, res); - wl_resource_set_dispatcher(res, _e_xdg_shell_cb_dispatch, NULL, - NULL, NULL); -} - -E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" }; - -E_API void * -e_modapi_init(E_Module *m) -{ - /* try to create global shell interface */ - if (!wl_global_create(e_comp_wl->wl.disp, &wl_shell_interface, 1, - NULL, _e_shell_cb_bind)) - { - ERR("Could not create shell global"); - return NULL; - } - - /* try to create global xdg_shell interface */ - if (!wl_global_create(e_comp_wl->wl.disp, &xdg_shell_interface, 1, - NULL, _e_xdg_shell_cb_bind)) - { - ERR("Could not create xdg_shell global"); - return NULL; - } + if (!e_xdg_shell_init()) return NULL; #ifdef HAVE_WL_TEXT_INPUT if (!e_input_panel_init()) diff --git a/src/modules/wl_desktop_shell/e_mod_main.h b/src/modules/wl_desktop_shell/e_mod_main.h index 6a8a75c..24a7fc8 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.h +++ b/src/modules/wl_desktop_shell/e_mod_main.h @@ -1,7 +1,30 @@ #ifndef _E_MOD_MAIN_H #define _E_MOD_MAIN_H -Eina_Bool e_input_panel_init(void); -void e_input_panel_shutdown(void); +EINTERN Eina_Bool e_input_panel_init(void); +EINTERN void e_input_panel_shutdown(void); + +EINTERN Eina_Hash *shell_resources; +EINTERN Eina_Hash *xdg_shell_resources; + +EINTERN void e_shell_surface_destroy(struct wl_resource *resource); +EINTERN void e_shell_surface_cb_destroy(struct wl_resource *resource); +EINTERN void e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource); +EINTERN void e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move); + +EINTERN Eina_Bool e_xdg_shell_init(void); +EINTERN void wl_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id); + +struct E_Shell_Data +{ + uint32_t edges; + int32_t width; + int32_t height; + Eina_List *pending; + Eina_Bool fullscreen : 1; + Eina_Bool maximized : 1; + Eina_Bool activated : 1; +}; + #endif diff --git a/src/modules/wl_desktop_shell/wl_shell.c b/src/modules/wl_desktop_shell/wl_shell.c new file mode 100644 index 0000000..5b22721 --- /dev/null +++ b/src/modules/wl_desktop_shell/wl_shell.c @@ -0,0 +1,523 @@ +#define E_COMP_WL +#include "e.h" +#include "e_mod_main.h" + +static void +_wl_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial EINA_UNUSED) +{ + E_Client *ec; + + if ((ec = wl_resource_get_user_data(resource))) + { + ec->ping_ok = EINA_TRUE; + ec->hung = EINA_FALSE; + } +} + +static void +_wl_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED) +{ + E_Client *ec; + E_Binding_Event_Mouse_Button ev; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + if ((ec->maximized) || (ec->fullscreen)) return; + + switch (e_comp_wl->ptr.button) + { + case BTN_LEFT: + ev.button = 1; + break; + case BTN_MIDDLE: + ev.button = 2; + break; + case BTN_RIGHT: + ev.button = 3; + break; + default: + ev.button = e_comp_wl->ptr.button; + break; + } + + e_comp_object_frame_xy_unadjust(ec->frame, + wl_fixed_to_int(e_comp_wl->ptr.x), + wl_fixed_to_int(e_comp_wl->ptr.y), + &ev.canvas.x, &ev.canvas.y); + + e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); +} + +static void +_wl_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges) +{ + E_Client *ec; + E_Binding_Event_Mouse_Button ev; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + if ((edges == 0) || (edges > 15) || + ((edges & 3) == 3) || ((edges & 12) == 12)) return; + + if ((ec->maximized) || (ec->fullscreen)) return; + + DBG("Comp Resize Edges Set: %d", edges); + + e_comp_wl->resize.resource = resource; + e_comp_wl->resize.edges = edges; + e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x); + e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y); + + switch (e_comp_wl->ptr.button) + { + case BTN_LEFT: + ev.button = 1; + break; + case BTN_MIDDLE: + ev.button = 2; + break; + case BTN_RIGHT: + ev.button = 3; + break; + default: + ev.button = e_comp_wl->ptr.button; + break; + } + + e_comp_object_frame_xy_unadjust(ec->frame, + wl_fixed_to_int(e_comp_wl->ptr.x), + wl_fixed_to_int(e_comp_wl->ptr.y), + &ev.canvas.x, &ev.canvas.y); + + e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); +} + +static void +_wl_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) +{ + E_Client *ec; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* set toplevel client properties */ + ec->icccm.accepts_focus = 1; + if (!ec->internal) + ec->borderless = !ec->internal; + + ec->lock_border = EINA_TRUE; + if ((!ec->internal) || (!ec->borderless)) + ec->border.changed = ec->changes.border = !ec->borderless; + ec->netwm.type = E_WINDOW_TYPE_NORMAL; + ec->comp_data->set_win_type = EINA_TRUE; + if ((!ec->lock_user_maximize) && (ec->maximized)) + e_client_unmaximize(ec, E_MAXIMIZE_BOTH); + if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) + e_client_unfullscreen(ec); + EC_CHANGED(ec); +} + +static void +_wl_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, uint32_t flags EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* set this client as a transient for parent */ + e_shell_surface_parent_set(ec, parent_resource); + + ec->icccm.accepts_focus = 1; + if (!ec->internal) + ec->borderless = !ec->internal; + + ec->lock_border = EINA_TRUE; + if ((!ec->internal) || (!ec->borderless)) + ec->border.changed = ec->changes.border = !ec->borderless; + ec->netwm.type = E_WINDOW_TYPE_DIALOG; + ec->dialog = EINA_TRUE; + ec->comp_data->set_win_type = EINA_TRUE; + if ((!ec->lock_user_maximize) && (ec->maximized)) + e_client_unmaximize(ec, E_MAXIMIZE_BOTH); + if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) + e_client_unfullscreen(ec); + EC_CHANGED(ec); +} + +static void +_wl_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t method EINA_UNUSED, uint32_t framerate EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED) +{ + E_Client *ec; + + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + if (!ec->lock_user_fullscreen) + e_client_fullscreen(ec, e_config->fullscreen_policy); +} + +static void +_wl_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *parent_resource, int32_t x, int32_t y, uint32_t flags EINA_UNUSED) +{ + E_Client *ec; + E_Comp_Client_Data *cdata; + + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + ec->comp_data->popup.x = x; + ec->comp_data->popup.y = y; + + if (!ec->internal) + ec->borderless = !ec->internal_elm_win; + ec->lock_border = EINA_TRUE; + if (!ec->internal) + ec->border.changed = ec->changes.border = !ec->borderless; + ec->changes.icon = !!ec->icccm.class; + ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU; + ec->comp_data->set_win_type = EINA_TRUE; + + cdata = ec->comp_data; + if (ec->parent) + { + cdata->popup.x = E_CLAMP(x, 0, ec->parent->client.w); + cdata->popup.y = E_CLAMP(y, 0, ec->parent->client.h); + } + else + { + cdata->popup.x = x; + cdata->popup.y = y; + } + + /* set this client as a transient for parent */ + e_shell_surface_parent_set(ec, parent_resource); + + EC_CHANGED(ec); +} + +static void +_wl_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED) +{ + E_Client *ec; + + /* DBG("WL_SHELL: Surface Maximize: %d", wl_resource_get_id(resource)); */ + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* tell E to maximize this client */ + if (!ec->lock_user_maximize) + { + unsigned int edges = 0; + + e_client_maximize(ec, ((e_config->maximize_policy & E_MAXIMIZE_TYPE) | + E_MAXIMIZE_BOTH)); + + edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); + wl_shell_surface_send_configure(resource, edges, ec->w, ec->h); + } +} + +static void +_wl_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title) +{ + E_Client *ec; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* set title */ + eina_stringshare_replace(&ec->icccm.title, title); + if (ec->frame) e_comp_object_frame_title_set(ec->frame, title); +} + +static void +_wl_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *clas) +{ + E_Client *ec; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* use the wl_client to get the pid * and set it in the netwm props */ + wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL); + + /* set class */ + eina_stringshare_replace(&ec->icccm.class, clas); + ec->changes.icon = !!ec->icccm.class; + EC_CHANGED(ec); +} + +static const struct wl_shell_surface_interface _wl_shell_surface_interface = +{ + _wl_shell_surface_cb_pong, + _wl_shell_surface_cb_move, + _wl_shell_surface_cb_resize, + _wl_shell_surface_cb_toplevel_set, + _wl_shell_surface_cb_transient_set, + _wl_shell_surface_cb_fullscreen_set, + _wl_shell_surface_cb_popup_set, + _wl_shell_surface_cb_maximized_set, + _wl_shell_surface_cb_title_set, + _wl_shell_surface_cb_class_set, +}; + +static void +_wl_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges, int32_t width, int32_t height) +{ + E_Client *ec; + + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_client_util_is_popup(ec)) return; + + wl_shell_surface_send_configure(resource, edges, width, height); +} + +static void +_wl_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) +{ + E_Client *ec; + + /* DBG("WL_SHELL: Surface Configure: %d \t%d %d %d %d", */ + /* wl_resource_get_id(resource), x, y, w, h); */ + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + if (ec->parent) + { + if (e_client_util_is_popup(ec)) + { + x = E_CLAMP(ec->parent->client.x + ec->comp_data->popup.x, + ec->parent->client.x, + ec->parent->client.x + + ec->parent->client.w); + y = E_CLAMP(ec->parent->client.y + ec->comp_data->popup.y, + ec->parent->client.y, + ec->parent->client.y + + ec->parent->client.h); + } + } + + e_client_util_move_resize_without_frame(ec, x, y, w, h); +} + +static void +_wl_shell_surface_ping(struct wl_resource *resource) +{ + E_Client *ec; + uint32_t serial; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + serial = wl_display_next_serial(e_comp_wl->wl.disp); + wl_shell_surface_send_ping(ec->comp_data->shell.surface, serial); +} + +static void +_wl_shell_surface_map(struct wl_resource *resource) +{ + E_Client *ec; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + /* map this surface if needed */ + if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap))) + { + ec->visible = EINA_TRUE; + evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h); + evas_object_show(ec->frame); + ec->comp_data->mapped = EINA_TRUE; + } +} + +static void +_wl_shell_surface_unmap(struct wl_resource *resource) +{ + E_Client *ec; + + /* get the client for this resource */ + if (!(ec = wl_resource_get_user_data(resource))) + { + wl_resource_post_error(resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Client For Shell Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + + if (ec->comp_data->mapped) + { + ec->visible = EINA_FALSE; + evas_object_hide(ec->frame); + ec->comp_data->mapped = EINA_FALSE; + } +} + +static void +_wl_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource) +{ + E_Client *ec; + E_Comp_Client_Data *cdata; + + /* get the pixmap from this surface so we can find the client */ + if (!(ec = wl_resource_get_user_data(surface_resource))) + { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "No Pixmap Set On Surface"); + return; + } + if (e_object_is_del(E_OBJECT(ec))) return; + cdata = ec->comp_data; + ec->netwm.ping = 1; + + /* check for existing shell surface */ + if (cdata->shell.surface) + { + wl_resource_post_error(surface_resource, + WL_DISPLAY_ERROR_INVALID_OBJECT, + "Client already has shell surface"); + return; + } + + /* try to create a shell surface */ + if (!(cdata->shell.surface = + wl_resource_create(client, &wl_shell_surface_interface, 1, id))) + { + ERR("Could not create wl_shell surface"); + wl_resource_post_no_memory(surface_resource); + return; + } + + wl_resource_set_implementation(cdata->shell.surface, + &_wl_shell_surface_interface, + ec, e_shell_surface_cb_destroy); + + e_object_ref(E_OBJECT(ec)); + + cdata->shell.configure_send = _wl_shell_surface_configure_send; + cdata->shell.configure = _wl_shell_surface_configure; + cdata->shell.ping = _wl_shell_surface_ping; + cdata->shell.map = _wl_shell_surface_map; + cdata->shell.unmap = _wl_shell_surface_unmap; + if (!ec->internal) + e_client_ping(ec); +} + +static const struct wl_shell_interface _e_shell_interface = +{ + _wl_shell_cb_shell_surface_get +}; + +static void +_wl_shell_cb_unbind(struct wl_resource *resource) +{ + struct wl_client *client = wl_resource_get_client(resource); + eina_hash_set(shell_resources, &client, NULL); +} + +EINTERN void +wl_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id) +{ + struct wl_resource *res; + + if (!(res = wl_resource_create(client, &wl_shell_interface, version, id))) + { + wl_client_post_no_memory(client); + return; + } + + eina_hash_set(shell_resources, &client, res); + wl_resource_set_implementation(res, &_e_shell_interface, + NULL, _wl_shell_cb_unbind); +} diff --git a/src/modules/wl_desktop_shell/e_mod_main.c b/src/modules/wl_desktop_shell/xdg5.c similarity index 55% copy from src/modules/wl_desktop_shell/e_mod_main.c copy to src/modules/wl_desktop_shell/xdg5.c index 648ca61..2af7206 100644 --- a/src/modules/wl_desktop_shell/e_mod_main.c +++ b/src/modules/wl_desktop_shell/xdg5.c @@ -1,6 +1,7 @@ #define E_COMP_WL #include "e.h" #include "e_mod_main.h" + #include "xdg-shell-unstable-v5-server-protocol.h" #define XDG_SERVER_VERSION 5 @@ -19,645 +20,6 @@ typedef struct Pending_State uint32_t serial; } Pending_State; -struct E_Shell_Data -{ - uint32_t edges; - int32_t width; - int32_t height; - Eina_List *pending; - Eina_Bool fullscreen : 1; - Eina_Bool maximized : 1; - Eina_Bool activated : 1; -}; - -static Eina_Hash *shell_resources; -static Eina_Hash *xdg_shell_resources; - -static void -_e_shell_surface_parent_set(E_Client *ec, struct wl_resource *parent_resource) -{ - E_Client *pc; - uint64_t pwin = 0; - - if (!parent_resource) - { - ec->icccm.fetch.transient_for = EINA_FALSE; - ec->icccm.transient_for = 0; - if (ec->parent) - { - ec->parent->transients = - eina_list_remove(ec->parent->transients, ec); - if (ec->parent->modal == ec) ec->parent->modal = NULL; - ec->parent = NULL; - } - return; - } - - pc = wl_resource_get_user_data(parent_resource); - if (!pc) - { - ERR("Could not get parent resource client"); - return; - } - - pwin = e_pixmap_window_get(pc->pixmap); - - e_pixmap_parent_window_set(ec->pixmap, pwin); - - /* If we already have a parent, remove it */ - if (ec->parent) - { - if (pc != ec->parent) - { - ec->parent->transients = - eina_list_remove(ec->parent->transients, ec); - if (ec->parent->modal == ec) ec->parent->modal = NULL; - ec->parent = NULL; - } - } - - if ((pc != ec) && - (eina_list_data_find(pc->transients, ec) != ec)) - { - pc->transients = eina_list_append(pc->transients, ec); - ec->parent = pc; - evas_object_layer_set(ec->frame, evas_object_layer_get(pc->frame)); - evas_object_stack_above(ec->frame, pc->frame); - } - - ec->icccm.fetch.transient_for = EINA_TRUE; - ec->icccm.transient_for = pwin; -} - -static void -_e_shell_surface_mouse_down_helper(E_Client *ec, E_Binding_Event_Mouse_Button *ev, Eina_Bool move) -{ - 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); -} - -static void -_e_shell_surface_destroy(struct wl_resource *resource) -{ - E_Client *ec; - - /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if ((ec = wl_resource_get_user_data(resource))) - { - if (!e_object_unref(E_OBJECT(ec))) return; - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->comp_data) - { - E_Shell_Data *shd = ec->comp_data->shell.data; - - if (shd) - { - E_FREE_LIST(shd->pending, free); - E_FREE(ec->comp_data->shell.data); - } - - if (ec->comp_data->mapped) - { - if ((ec->comp_data->shell.surface) && - (ec->comp_data->shell.unmap)) - ec->comp_data->shell.unmap(ec->comp_data->shell.surface); - } - if (ec->parent) - { - ec->parent->transients = - eina_list_remove(ec->parent->transients, ec); - } - /* wl_resource_destroy(ec->comp_data->shell.surface); */ - ec->comp_data->shell.surface = NULL; - } - } -} - -static void -_e_shell_surface_cb_destroy(struct wl_resource *resource) -{ - /* DBG("Shell Surface Destroy: %d", wl_resource_get_id(resource)); */ - - _e_shell_surface_destroy(resource); -} - -static void -_e_shell_surface_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - - if ((ec = wl_resource_get_user_data(resource))) - { - ec->ping_ok = EINA_TRUE; - ec->hung = EINA_FALSE; - } -} - -static void -_e_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); -} - -static void -_e_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, uint32_t edges) -{ - E_Client *ec; - E_Binding_Event_Mouse_Button ev; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if ((edges == 0) || (edges > 15) || - ((edges & 3) == 3) || ((edges & 12) == 12)) return; - - if ((ec->maximized) || (ec->fullscreen)) return; - - DBG("Comp Resize Edges Set: %d", edges); - - e_comp_wl->resize.resource = resource; - e_comp_wl->resize.edges = edges; - e_comp_wl->ptr.grab_x = e_comp_wl->ptr.x - wl_fixed_from_int(ec->client.x); - e_comp_wl->ptr.grab_y = e_comp_wl->ptr.y - wl_fixed_from_int(ec->client.y); - - switch (e_comp_wl->ptr.button) - { - case BTN_LEFT: - ev.button = 1; - break; - case BTN_MIDDLE: - ev.button = 2; - break; - case BTN_RIGHT: - ev.button = 3; - break; - default: - ev.button = e_comp_wl->ptr.button; - break; - } - - e_comp_object_frame_xy_unadjust(ec->frame, - wl_fixed_to_int(e_comp_wl->ptr.x), - wl_fixed_to_int(e_comp_wl->ptr.y), - &ev.canvas.x, &ev.canvas.y); - - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); -} - -static void -_e_shell_surface_cb_toplevel_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set toplevel client properties */ - ec->icccm.accepts_focus = 1; - if (!ec->internal) - ec->borderless = !ec->internal; - - ec->lock_border = EINA_TRUE; - if ((!ec->internal) || (!ec->borderless)) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->netwm.type = E_WINDOW_TYPE_NORMAL; - ec->comp_data->set_win_type = EINA_TRUE; - if ((!ec->lock_user_maximize) && (ec->maximized)) - e_client_unmaximize(ec, E_MAXIMIZE_BOTH); - if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) - e_client_unfullscreen(ec); - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_transient_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *parent_resource, int32_t x EINA_UNUSED, int32_t y EINA_UNUSED, uint32_t flags EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); - - ec->icccm.accepts_focus = 1; - if (!ec->internal) - ec->borderless = !ec->internal; - - ec->lock_border = EINA_TRUE; - if ((!ec->internal) || (!ec->borderless)) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->netwm.type = E_WINDOW_TYPE_DIALOG; - ec->dialog = EINA_TRUE; - ec->comp_data->set_win_type = EINA_TRUE; - if ((!ec->lock_user_maximize) && (ec->maximized)) - e_client_unmaximize(ec, E_MAXIMIZE_BOTH); - if ((!ec->lock_user_fullscreen) && (ec->fullscreen)) - e_client_unfullscreen(ec); - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_fullscreen_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t method EINA_UNUSED, uint32_t framerate EINA_UNUSED, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (!ec->lock_user_fullscreen) - e_client_fullscreen(ec, e_config->fullscreen_policy); -} - -static void -_e_shell_surface_cb_popup_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *seat_resource EINA_UNUSED, uint32_t serial EINA_UNUSED, struct wl_resource *parent_resource, int32_t x, int32_t y, uint32_t flags EINA_UNUSED) -{ - E_Client *ec; - E_Comp_Client_Data *cdata; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource,WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - ec->comp_data->popup.x = x; - ec->comp_data->popup.y = y; - - if (!ec->internal) - ec->borderless = !ec->internal_elm_win; - ec->lock_border = EINA_TRUE; - if (!ec->internal) - ec->border.changed = ec->changes.border = !ec->borderless; - ec->changes.icon = !!ec->icccm.class; - ec->netwm.type = E_WINDOW_TYPE_POPUP_MENU; - ec->comp_data->set_win_type = EINA_TRUE; - - cdata = ec->comp_data; - if (ec->parent) - { - cdata->popup.x = E_CLAMP(x, 0, ec->parent->client.w); - cdata->popup.y = E_CLAMP(y, 0, ec->parent->client.h); - } - else - { - cdata->popup.x = x; - cdata->popup.y = y; - } - - /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); - - EC_CHANGED(ec); -} - -static void -_e_shell_surface_cb_maximized_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource EINA_UNUSED) -{ - E_Client *ec; - - /* DBG("WL_SHELL: Surface Maximize: %d", wl_resource_get_id(resource)); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* tell E to maximize this client */ - if (!ec->lock_user_maximize) - { - unsigned int edges = 0; - - e_client_maximize(ec, ((e_config->maximize_policy & E_MAXIMIZE_TYPE) | - E_MAXIMIZE_BOTH)); - - edges = (WL_SHELL_SURFACE_RESIZE_TOP | WL_SHELL_SURFACE_RESIZE_LEFT); - wl_shell_surface_send_configure(resource, edges, ec->w, ec->h); - } -} - -static void -_e_shell_surface_cb_title_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *title) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* set title */ - eina_stringshare_replace(&ec->icccm.title, title); - if (ec->frame) e_comp_object_frame_title_set(ec->frame, title); -} - -static void -_e_shell_surface_cb_class_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, const char *clas) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* use the wl_client to get the pid * and set it in the netwm props */ - wl_client_get_credentials(client, &ec->netwm.pid, NULL, NULL); - - /* set class */ - eina_stringshare_replace(&ec->icccm.class, clas); - ec->changes.icon = !!ec->icccm.class; - EC_CHANGED(ec); -} - -static const struct wl_shell_surface_interface _e_shell_surface_interface = -{ - _e_shell_surface_cb_pong, - _e_shell_surface_cb_move, - _e_shell_surface_cb_resize, - _e_shell_surface_cb_toplevel_set, - _e_shell_surface_cb_transient_set, - _e_shell_surface_cb_fullscreen_set, - _e_shell_surface_cb_popup_set, - _e_shell_surface_cb_maximized_set, - _e_shell_surface_cb_title_set, - _e_shell_surface_cb_class_set, -}; - -static void -_e_shell_surface_configure_send(struct wl_resource *resource, uint32_t edges, int32_t width, int32_t height) -{ - E_Client *ec; - - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_client_util_is_popup(ec)) return; - - wl_shell_surface_send_configure(resource, edges, width, height); -} - -static void -_e_shell_surface_configure(struct wl_resource *resource, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h) -{ - E_Client *ec; - - /* DBG("WL_SHELL: Surface Configure: %d \t%d %d %d %d", */ - /* wl_resource_get_id(resource), x, y, w, h); */ - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->parent) - { - if (e_client_util_is_popup(ec)) - { - x = E_CLAMP(ec->parent->client.x + ec->comp_data->popup.x, - ec->parent->client.x, - ec->parent->client.x + - ec->parent->client.w); - y = E_CLAMP(ec->parent->client.y + ec->comp_data->popup.y, - ec->parent->client.y, - ec->parent->client.y + - ec->parent->client.h); - } - } - - e_client_util_move_resize_without_frame(ec, x, y, w, h); -} - -static void -_e_shell_surface_ping(struct wl_resource *resource) -{ - E_Client *ec; - uint32_t serial; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - serial = wl_display_next_serial(e_comp_wl->wl.disp); - wl_shell_surface_send_ping(ec->comp_data->shell.surface, serial); -} - -static void -_e_shell_surface_map(struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - /* map this surface if needed */ - if ((!ec->comp_data->mapped) && (e_pixmap_usable_get(ec->pixmap))) - { - ec->visible = EINA_TRUE; - evas_object_geometry_set(ec->frame, ec->x, ec->y, ec->w, ec->h); - evas_object_show(ec->frame); - ec->comp_data->mapped = EINA_TRUE; - } -} - -static void -_e_shell_surface_unmap(struct wl_resource *resource) -{ - E_Client *ec; - - /* get the client for this resource */ - if (!(ec = wl_resource_get_user_data(resource))) - { - wl_resource_post_error(resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Client For Shell Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - - if (ec->comp_data->mapped) - { - ec->visible = EINA_FALSE; - evas_object_hide(ec->frame); - ec->comp_data->mapped = EINA_FALSE; - } -} - -static void -_e_shell_cb_shell_surface_get(struct wl_client *client, struct wl_resource *resource EINA_UNUSED, uint32_t id, struct wl_resource *surface_resource) -{ - E_Client *ec; - E_Comp_Client_Data *cdata; - - /* get the pixmap from this surface so we can find the client */ - if (!(ec = wl_resource_get_user_data(surface_resource))) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "No Pixmap Set On Surface"); - return; - } - if (e_object_is_del(E_OBJECT(ec))) return; - cdata = ec->comp_data; - ec->netwm.ping = 1; - - /* check for existing shell surface */ - if (cdata->shell.surface) - { - wl_resource_post_error(surface_resource, - WL_DISPLAY_ERROR_INVALID_OBJECT, - "Client already has shell surface"); - return; - } - - /* try to create a shell surface */ - if (!(cdata->shell.surface = - wl_resource_create(client, &wl_shell_surface_interface, 1, id))) - { - ERR("Could not create wl_shell surface"); - wl_resource_post_no_memory(surface_resource); - return; - } - - wl_resource_set_implementation(cdata->shell.surface, - &_e_shell_surface_interface, - ec, _e_shell_surface_cb_destroy); - - e_object_ref(E_OBJECT(ec)); - - cdata->shell.configure_send = _e_shell_surface_configure_send; - cdata->shell.configure = _e_shell_surface_configure; - cdata->shell.ping = _e_shell_surface_ping; - cdata->shell.map = _e_shell_surface_map; - cdata->shell.unmap = _e_shell_surface_unmap; - if (!ec->internal) - e_client_ping(ec); -} - static void _e_xdg_surface_state_add(struct wl_resource *resource, struct wl_array *states, uint32_t state) { @@ -790,7 +152,7 @@ _e_xdg_shell_surface_cb_parent_set(struct wl_client *client EINA_UNUSED, struct if (e_object_is_del(E_OBJECT(ec))) return; /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); + e_shell_surface_parent_set(ec, parent_resource); } static void @@ -897,7 +259,7 @@ _e_xdg_shell_surface_cb_move(struct wl_client *client EINA_UNUSED, struct wl_res wl_fixed_to_int(e_comp_wl->ptr.y), &ev.canvas.x, &ev.canvas.y); - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); + e_shell_surface_mouse_down_helper(ec, &ev, EINA_TRUE); } static void @@ -950,7 +312,7 @@ _e_xdg_shell_surface_cb_resize(struct wl_client *client EINA_UNUSED, struct wl_r wl_fixed_to_int(e_comp_wl->ptr.y), &ev.canvas.x, &ev.canvas.y); - _e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); + e_shell_surface_mouse_down_helper(ec, &ev, EINA_FALSE); } static void @@ -1313,7 +675,7 @@ _e_xdg_shell_cb_surface_get(struct wl_client *client, struct wl_resource *resour wl_resource_set_implementation(cdata->shell.surface, &_e_xdg_surface_interface, ec, - _e_shell_surface_cb_destroy); + e_shell_surface_cb_destroy); e_object_ref(E_OBJECT(ec)); @@ -1403,7 +765,7 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource } wl_resource_set_implementation(cdata->shell.surface, - &_e_xdg_popup_interface, ec, _e_shell_surface_destroy); + &_e_xdg_popup_interface, ec, e_shell_surface_destroy); e_object_ref(E_OBJECT(ec)); @@ -1425,7 +787,7 @@ _e_xdg_shell_cb_popup_get(struct wl_client *client, struct wl_resource *resource ec->placed = ec->comp_data->set_win_type = EINA_TRUE; /* set this client as a transient for parent */ - _e_shell_surface_parent_set(ec, parent_resource); + e_shell_surface_parent_set(ec, parent_resource); if (ec->parent) { @@ -1453,11 +815,6 @@ _e_xdg_shell_cb_pong(struct wl_client *client EINA_UNUSED, struct wl_resource *r } } -static const struct wl_shell_interface _e_shell_interface = -{ - _e_shell_cb_shell_surface_get -}; - static const struct xdg_shell_interface _e_xdg_shell_interface = { _e_xdg_shell_cb_destroy, @@ -1503,30 +860,7 @@ _e_xdg_shell_cb_dispatch(const void *implementation EINA_UNUSED, void *target, u return 1; } -static void -_e_shell_cb_unbind(struct wl_resource *resource) -{ - struct wl_client *client = wl_resource_get_client(resource); - eina_hash_set(shell_resources, &client, NULL); -} - -static void -_e_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id) -{ - struct wl_resource *res; - - if (!(res = wl_resource_create(client, &wl_shell_interface, version, id))) - { - wl_client_post_no_memory(client); - return; - } - - eina_hash_set(shell_resources, &client, res); - wl_resource_set_implementation(res, &_e_shell_interface, - NULL, _e_shell_cb_unbind); -} - -static void +EINTERN void _e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id) { struct wl_resource *res; @@ -1542,48 +876,15 @@ _e_xdg_shell_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t NULL, NULL); } -E_API E_Module_Api e_modapi = { E_MODULE_API_VERSION, "Wl_Desktop_Shell" }; - -E_API void * -e_modapi_init(E_Module *m) +EINTERN Eina_Bool +e_xdg_shell_init(void) { - /* try to create global shell interface */ - if (!wl_global_create(e_comp_wl->wl.disp, &wl_shell_interface, 1, - NULL, _e_shell_cb_bind)) - { - ERR("Could not create shell global"); - return NULL; - } - /* try to create global xdg_shell interface */ if (!wl_global_create(e_comp_wl->wl.disp, &xdg_shell_interface, 1, NULL, _e_xdg_shell_cb_bind)) { ERR("Could not create xdg_shell global"); - return NULL; - } - -#ifdef HAVE_WL_TEXT_INPUT - if (!e_input_panel_init()) - { - ERR("Could not init input panel"); - return NULL; + return EINA_FALSE; } -#endif - e_startup(); - - shell_resources = eina_hash_pointer_new(NULL); - xdg_shell_resources = eina_hash_pointer_new(NULL); - - return m; -} - -E_API int -e_modapi_shutdown(E_Module *m EINA_UNUSED) -{ - e_input_panel_shutdown(); - eina_hash_free(shell_resources); - eina_hash_free(xdg_shell_resources); - - return 1; + return EINA_TRUE; } --
