/* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" /* local subsystem functions */ static void _e_manager_free(E_Manager *man); static int _e_manager_cb_window_show_request(void *data, int ev_type, void *ev); static int _e_manager_cb_window_configure(void *data, int ev_type, void *ev); static int _e_manager_cb_key_down(void *data, int ev_type, void *ev); static int _e_manager_cb_frame_extents_request(void *data, int ev_type, void *ev); static int _e_manager_cb_ping(void *data, int ev_type, void *ev); #if 0 /* use later - maybe */ static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev); static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev); static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev); static int _e_manager_cb_window_create(void *data, int ev_type, void *ev); static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev); static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev); static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev); static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev); static int _e_manager_cb_window_property(void *data, int ev_type, void *ev); static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev); static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev); static int _e_manager_cb_client_message(void *data, int ev_type, void *ev); #endif /* local subsystem globals */ static Evas_List *managers = NULL; /* externally accessible functions */ int e_manager_init(void) { return 1; } int e_manager_shutdown(void) { Evas_List *l, *tmp; for (l = managers; l;) { tmp = l; l = l->next; e_object_del(E_OBJECT(tmp->data)); } return 1; } Evas_List * e_manager_list(void) { return managers; } E_Manager * e_manager_new(Ecore_X_Window root) { E_Manager *man; Ecore_Event_Handler *h; if (!ecore_x_window_manage(root)) return NULL; man = E_OBJECT_ALLOC(E_Manager, E_MANAGER_TYPE, _e_manager_free); if (!man) return NULL; managers = evas_list_append(managers, man); man->root = root; ecore_x_window_size_get(man->root, &(man->w), &(man->h)); if (e_config->use_virtual_roots) { Ecore_X_Window mwin; man->win = ecore_x_window_override_new(man->root, man->x, man->y, man->w, man->h); ecore_x_icccm_title_set(man->win, "Enlightenment Manager"); ecore_x_netwm_name_set(man->win, "Enlightenment Manager"); mwin = e_menu_grab_window_get(); if (!mwin) mwin = e_init_window_get(); if (!mwin) ecore_x_window_raise(man->win); else ecore_x_window_configure(man->win, ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE, 0, 0, 0, 0, 0, mwin, ECORE_X_WINDOW_STACK_BELOW); } else { man->win = man->root; } h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_manager_cb_window_show_request, man); if (h) man->handlers = evas_list_append(man->handlers, h); h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_manager_cb_window_configure, man); if (h) man->handlers = evas_list_append(man->handlers, h); h = ecore_event_handler_add(ECORE_X_EVENT_KEY_DOWN, _e_manager_cb_key_down, man); if (h) man->handlers = evas_list_append(man->handlers, h); h = ecore_event_handler_add(ECORE_X_EVENT_FRAME_EXTENTS_REQUEST, _e_manager_cb_frame_extents_request, man); h = ecore_event_handler_add(ECORE_X_EVENT_PING, _e_manager_cb_ping, man); if (h) man->handlers = evas_list_append(man->handlers, h); return man; } void e_manager_manage_windows(E_Manager *man) { Ecore_X_Window *windows; int wnum; /* a manager is designated for each root. lets get all the windows in the managers root */ windows = ecore_x_window_children_get(man->root, &wnum); if (windows) { int i; for (i = 0; i < wnum; i++) { Ecore_X_Window_Attributes att; unsigned int ret_val, deskxy[2]; int ret; ecore_x_window_attributes_get(windows[i], &att); ret = ecore_x_window_prop_card32_get(windows[i], E_ATOM_MANAGED, &ret_val, 1); /* we have seen this window before */ if ((ret > -1) && (ret_val == 1)) { E_Container *con = NULL; E_Zone *zone = NULL; E_Desk *desk = NULL; E_Border *bd = NULL; unsigned int id; /* get all information from window before it is * reset by e_border_new */ ret = ecore_x_window_prop_card32_get(windows[i], E_ATOM_CONTAINER, &id, 1); if (ret == 1) con = e_manager_container_number_get(man, id); if (!con) con = e_container_current_get(man); ret = ecore_x_window_prop_card32_get(windows[i], E_ATOM_ZONE, &id, 1); if (ret == 1) zone = e_container_zone_number_get(con, id); if (!zone) zone = e_zone_current_get(con); ret = ecore_x_window_prop_card32_get(windows[i], E_ATOM_DESK, deskxy, 2); if (ret == 2) desk = e_desk_at_xy_get(zone, deskxy[0], deskxy[1]); { bd = e_border_new(con, windows[i], 1); if (bd) { /* FIXME: * It's enough to set the desk, the zone will * be set according to the desk */ if (zone) e_border_zone_set(bd, zone); if (desk) e_border_desk_set(bd, desk); } } } else if ((att.visible) && (!att.override) && (!att.input_only)) { /* We have not seen this window, and X tells us it * should be seen */ E_Container *con; E_Border *bd; con = e_container_current_get(man); bd = e_border_new(con, windows[i], 1); if (bd) e_border_show(bd); } } free(windows); } } void e_manager_show(E_Manager *man) { Evas_List *l; E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (man->visible) return; for (l = man->containers; l; l = l->next) { E_Container *con; con = l->data; e_container_show(con); } if (man->root != man->win) { Ecore_X_Window mwin; mwin = e_menu_grab_window_get(); if (!mwin) mwin = e_init_window_get(); if (!mwin) ecore_x_window_raise(man->win); else ecore_x_window_configure(man->win, ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE, 0, 0, 0, 0, 0, mwin, ECORE_X_WINDOW_STACK_BELOW); ecore_x_window_show(man->win); } man->visible = 1; } void e_manager_hide(E_Manager *man) { Evas_List *l; E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (!man->visible) return; for (l = man->containers; l; l = l->next) { E_Container *con; con = l->data; e_container_hide(con); } if (man->root != man->win) ecore_x_window_hide(man->win); man->visible = 0; } void e_manager_move(E_Manager *man, int x, int y) { E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if ((x == man->x) && (y == man->y)) return; if (man->root != man->win) { man->x = x; man->y = y; ecore_x_window_move(man->win, man->x, man->y); } } void e_manager_resize(E_Manager *man, int w, int h) { Evas_List *l; E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if ((w == man->w) && (h == man->h)) return; man->w = w; man->h = h; if (man->root != man->win) ecore_x_window_resize(man->win, man->w, man->h); for (l = man->containers; l; l = l->next) { E_Container *con; con = l->data; e_container_resize(con, man->w, man->h); } ecore_x_netwm_desk_size_set(man->root, man->w, man->h); } void e_manager_move_resize(E_Manager *man, int x, int y, int w, int h) { Evas_List *l; E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if ((x == man->x) && (y == man->y) && (w == man->w) && (h == man->h)) return; if (man->root != man->win) { man->x = x; man->y = y; } man->w = w; man->h = h; ecore_x_window_move_resize(man->win, man->x, man->y, man->w, man->h); for (l = man->containers; l; l = l->next) { E_Container *con; con = l->data; e_container_resize(con, man->w, man->h); } } void e_manager_raise(E_Manager *man) { E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (man->root != man->win) { Ecore_X_Window mwin; mwin = e_menu_grab_window_get(); if (!mwin) mwin = e_init_window_get(); if (!mwin) ecore_x_window_raise(man->win); else ecore_x_window_configure(man->win, ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING | ECORE_X_WINDOW_CONFIGURE_MASK_STACK_MODE, 0, 0, 0, 0, 0, mwin, ECORE_X_WINDOW_STACK_BELOW); } } void e_manager_lower(E_Manager *man) { E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (man->root != man->win) ecore_x_window_lower(man->win); } E_Manager * e_manager_current_get(void) { Evas_List *l; E_Manager *man; int x, y; if (!managers) return NULL; for (l = managers; l; l = l->next) { man = l->data; ecore_x_pointer_xy_get(man->win, &x, &y); if (E_INSIDE(x, y, man->x, man->y, man->w, man->h)) return man; } return managers->data; } E_Container * e_manager_container_number_get(E_Manager *man, int num) { Evas_List *l; E_OBJECT_CHECK_RETURN(man, NULL); E_OBJECT_TYPE_CHECK_RETURN(man, E_MANAGER_TYPE, NULL); for (l = man->containers; l; l = l->next) { E_Container *con; con = l->data; if (con->num == num) return con; } return NULL; } void e_managers_keys_grab(void) { Evas_List *l; for (l = managers; l; l = l->next) { E_Manager *man; man = l->data; e_bindings_key_grab(E_BINDING_CONTEXT_ANY, man->root); } } void e_managers_keys_ungrab(void) { Evas_List *l; for (l = managers; l; l = l->next) { E_Manager *man; man = l->data; e_bindings_key_ungrab(E_BINDING_CONTEXT_ANY, man->root); } } /* local subsystem functions */ static void _e_manager_free(E_Manager *man) { Evas_List *l, *tmp; while (man->handlers) { Ecore_Event_Handler *h; h = man->handlers->data; man->handlers = evas_list_remove_list(man->handlers, man->handlers); ecore_event_handler_del(h); } for (l = man->containers; l;) { tmp = l; l = l->next; e_object_del(E_OBJECT(tmp->data)); } if (man->root != man->win) { ecore_x_window_del(man->win); } managers = evas_list_remove(managers, man); free(man); } static int _e_manager_cb_window_show_request(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; Ecore_X_Event_Window_Show_Request *e; man = data; e = ev; #if 0 if (e->parent != man->root) return 1; /* try other handlers for this */ #endif if (ecore_x_window_parent_get(e->win) != man->root) return 1; /* try other handlers for this */ { E_Container *con; E_Border *bd; con = e_container_current_get(man); if (!e_border_find_by_client_window(e->win)) { bd = e_border_new(con, e->win, 0); if (!bd) ecore_x_window_show(e->win); } } return 1; } static int _e_manager_cb_window_configure(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; Ecore_X_Event_Window_Configure *e; man = data; e = ev; if (e->win != man->root) return 1; e_manager_resize(man, e->w, e->h); return 1; } static int _e_manager_cb_key_down(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; Ecore_X_Event_Key_Down *e; man = data; e = ev; // printf("KEY %s [win=%x event_win=%x]\n", e->keyname, e->win, e->event_win); if (e->event_win != man->root) return 1; if (e_bindings_key_down_event_handle(E_BINDING_CONTEXT_MANAGER, E_OBJECT(man), ev)) return 0; return 1; } static int _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; E_Container *con; Ecore_X_Event_Frame_Extents_Request *e; Evas_Object *o; int ok; man = data; con = e_container_current_get(man); e = ev; if (ecore_x_window_parent_get(e->win) != man->root) return 1; /* FIXME: this is definitely not perfect - we need to handle a border guess here */ o = edje_object_add(con->bg_evas); ok = e_theme_edje_object_set(o, "base/theme/borders", "widgets/border/default/border"); if (ok) { Evas_Coord x, y, w, h; int l, r, t, b; evas_object_resize(o, 1000, 1000); edje_object_calc_force(o); edje_object_part_geometry_get(o, "client", &x, &y, &w, &h); l = x; r = 1000 - (x + w); t = y; b = 1000 - (y + h); ecore_x_netwm_frame_size_set(e->win, l, r, t, b); } evas_object_del(o); return 1; } static int _e_manager_cb_ping(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; E_Border *bd; Ecore_X_Event_Ping *e; man = data; e = ev; if (e->win != man->root) return 1; bd = e_border_find_by_client_window(e->event_win); if (!bd) return 1; bd->ping_ok = 1; return 1; } #if 0 /* use later - maybe */ static int _e_manager_cb_window_destroy(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_hide(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_reparent(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_create(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_configure_request(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_configure(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_gravity(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_stack(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_stack_request(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_property(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_colormap(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_window_shape(void *data, int ev_type, void *ev){return 1;} static int _e_manager_cb_client_message(void *data, int ev_type, void *ev){return 1;} #endif