/* * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 */ #include "e.h" /* E_Zone is a child object of E_Container. There is one zone per screen * in a xinerama setup. Each zone has one or more desktops. */ static void _e_zone_free(E_Zone *zone); static void _e_zone_cb_bg_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _e_zone_cb_bg_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info); static void _e_zone_event_zone_desk_count_set_free(void *data, void *ev); static int _e_zone_cb_mouse_in(void *data, int type, void *event); static int _e_zone_cb_mouse_out(void *data, int type, void *event); static int _e_zone_cb_timer(void *data); static int _e_zone_cb_desk_show(void *data, int type, void *event); static void _e_zone_update_flip(E_Zone *zone); EAPI int E_EVENT_ZONE_DESK_COUNT_SET = 0; EAPI int E_EVENT_POINTER_WARP = 0; #define E_ZONE_FLIP_LEFT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || ((zone)->desk_x_current > 0)) #define E_ZONE_FLIP_RIGHT(zone) ((e_config->desk_flip_wrap && ((zone)->desk_x_count > 1)) || (((zone)->desk_x_current + 1) < (zone)->desk_x_count)) #define E_ZONE_FLIP_UP(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || ((zone)->desk_y_current > 0)) #define E_ZONE_FLIP_DOWN(zone) ((e_config->desk_flip_wrap && ((zone)->desk_y_count > 1)) || (((zone)->desk_y_current + 1) < (zone)->desk_y_count)) static int startup_id = 0; EAPI int e_zone_init(void) { E_EVENT_ZONE_DESK_COUNT_SET = ecore_event_type_new(); E_EVENT_POINTER_WARP = ecore_event_type_new(); return 1; } EAPI int e_zone_shutdown(void) { char buf[256]; snprintf(buf, sizeof(buf), "%i", startup_id); e_util_env_set("E_STARTUP_ID", buf); return 1; } EAPI E_Zone * e_zone_new(E_Container *con, int num, int x, int y, int w, int h) { E_Zone *zone; char name[40]; Evas_Object *o; zone = E_OBJECT_ALLOC(E_Zone, E_ZONE_TYPE, _e_zone_free); if (!zone) return NULL; zone->container = con; zone->x = x; zone->y = y; zone->w = w; zone->h = h; zone->num = num; zone->flip.left = ecore_x_window_input_new(con->win, zone->x, zone->y, 1, zone->h); zone->flip.right = ecore_x_window_input_new(con->win, zone->x + zone->w - 1, zone->y, 1, zone->h); zone->flip.top = ecore_x_window_input_new(con->win, zone->x + 1, zone->y, zone->w - 2, 1); zone->flip.bottom = ecore_x_window_input_new(con->win, zone->x + 1, zone->y + zone->h - 1, zone->w - 2, 1); zone->handlers = evas_list_append(zone->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_zone_cb_mouse_in, zone)); zone->handlers = evas_list_append(zone->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_zone_cb_mouse_out, zone)); zone->handlers = evas_list_append(zone->handlers, ecore_event_handler_add(E_EVENT_DESK_SHOW, _e_zone_cb_desk_show, zone)); snprintf(name, sizeof(name), "Zone %d", zone->num); zone->name = evas_stringshare_add(name); con->zones = evas_list_append(con->zones, zone); o = evas_object_rectangle_add(con->bg_evas); zone->bg_clip_object = o; evas_object_move(o, x, y); evas_object_resize(o, w, h); evas_object_color_set(o, 255, 255, 255, 255); evas_object_show(o); o = evas_object_rectangle_add(con->bg_evas); zone->bg_event_object = o; evas_object_clip_set(o, zone->bg_clip_object); evas_object_move(o, x, y); evas_object_resize(o, w, h); evas_object_color_set(o, 255, 255, 255, 0); evas_object_repeat_events_set(o, 1); evas_object_show(o); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN, _e_zone_cb_bg_mouse_down, zone); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_UP, _e_zone_cb_bg_mouse_up, zone); evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_MOVE, _e_zone_cb_bg_mouse_move, zone); /* TODO: config the ecore_evas type. */ zone->black_ecore_evas = e_canvas_new(e_config->evas_engine_zone, zone->container->win, 0, 0, zone->w, zone->h, 1, 1, &(zone->black_win), NULL); e_canvas_add(zone->black_ecore_evas); ecore_evas_layer_set(zone->black_ecore_evas, 6); zone->black_evas = ecore_evas_get(zone->black_ecore_evas); o = evas_object_rectangle_add(zone->black_evas); evas_object_move(o, 0, 0); evas_object_resize(o, zone->w, zone->h); evas_object_color_set(o, 0, 0, 0, 255); evas_object_show(o); ecore_evas_name_class_set(zone->black_ecore_evas, "E", "Black_Window"); snprintf(name, sizeof(name), "Enlightenment Black Zone (%d)", zone->num); ecore_evas_title_set(zone->black_ecore_evas, name); zone->desk_x_count = 0; zone->desk_y_count = 0; zone->desk_x_current = 0; zone->desk_y_current = 0; e_zone_desk_count_set(zone, e_config->zone_desks_x_count, e_config->zone_desks_y_count); _e_zone_update_flip(zone); return zone; } EAPI void e_zone_name_set(E_Zone *zone, const char *name) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if (zone->name) evas_stringshare_del(zone->name); zone->name = evas_stringshare_add(name); } EAPI void e_zone_move(E_Zone *zone, int x, int y) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if ((x == zone->x) && (y == zone->y)) return; zone->x = x; zone->y = y; evas_object_move(zone->bg_object, x, y); evas_object_move(zone->bg_event_object, x, y); evas_object_move(zone->bg_clip_object, x, y); ecore_x_window_move_resize(zone->flip.left, zone->x, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.right, zone->x + zone->w - 1, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.top, zone->x + 1, zone->y, zone->w - 2, 1); ecore_x_window_move_resize(zone->flip.bottom, zone->x + 1, zone->y + zone->h - 1, zone->w - 2, 1); } EAPI void e_zone_resize(E_Zone *zone, int w, int h) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if ((w == zone->w) && (h == zone->h)) return; zone->w = w; zone->h = h; evas_object_resize(zone->bg_object, w, h); evas_object_resize(zone->bg_event_object, w, h); evas_object_resize(zone->bg_clip_object, w, h); ecore_x_window_move_resize(zone->flip.left, zone->x, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.right, zone->x + zone->w - 1, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.top, zone->x + 1, zone->y, zone->w - 2, 1); ecore_x_window_move_resize(zone->flip.bottom, zone->x + 1, zone->y + zone->h - 1, zone->w - 2, 1); } EAPI void e_zone_move_resize(E_Zone *zone, int x, int y, int w, int h) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if ((x == zone->x) && (y == zone->y) && (w == zone->w) && (h == zone->h)) return; zone->x = x; zone->y = y; zone->w = w; zone->h = h; evas_object_move(zone->bg_object, x, y); evas_object_move(zone->bg_event_object, x, y); evas_object_move(zone->bg_clip_object, x, y); evas_object_resize(zone->bg_object, w, h); evas_object_resize(zone->bg_event_object, w, h); evas_object_resize(zone->bg_clip_object, w, h); ecore_x_window_move_resize(zone->flip.left, zone->x, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.right, zone->x + zone->w - 1, zone->y, 1, zone->h); ecore_x_window_move_resize(zone->flip.top, zone->x + 1, zone->y, zone->w - 2, 1); ecore_x_window_move_resize(zone->flip.bottom, zone->x + 1, zone->y + zone->h - 1, zone->w - 2, 1); } EAPI void e_zone_fullscreen_set(E_Zone *zone, int on) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if ((!zone->fullscreen) && (on)) { ecore_evas_show(zone->black_ecore_evas); e_container_window_raise(zone->container, zone->black_win, 150); zone->fullscreen = 1; } else if ((zone->fullscreen) && (!on)) { ecore_evas_hide(zone->black_ecore_evas); zone->fullscreen = 0; } } EAPI E_Zone * e_zone_current_get(E_Container *con) { Evas_List *l; E_OBJECT_CHECK_RETURN(con, NULL); E_OBJECT_TYPE_CHECK_RETURN(con, E_CONTAINER_TYPE, NULL); if (!starting) { int x, y; ecore_x_pointer_xy_get(con->win, &x, &y); for (l = con->zones; l; l = l->next) { E_Zone *zone; zone = l->data; if (E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h)) return zone; } } if (!con->zones) return NULL; l = con->zones; return (E_Zone *)l->data; } EAPI void e_zone_bg_reconfigure(E_Zone *zone) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); e_bg_zone_update(zone, E_BG_TRANSITION_CHANGE); } EAPI void e_zone_flip_coords_handle(E_Zone *zone, int x, int y) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); int one_row = 1; int one_col = 1; if (!e_config->edge_flip_dragging) return; /* if we have only 1 row we can flip up/down even if we have xinerama */ if (evas_list_count(zone->container->zones) > 1) { Evas_List *zones; E_Zone *next_zone; int cx, cy; zones = zone->container->zones; next_zone = (E_Zone *) evas_list_data(zones); cx = next_zone->x; cy = next_zone->y; zones = evas_list_next(zones); while (zones) { next_zone = (E_Zone *)zones->data; if (next_zone->x != cx) one_col = 0; if (next_zone->y != cy) one_row = 0; zones = zones->next; } } if (evas_list_count(zone->container->manager->containers) > 1) goto noflip; if (!E_INSIDE(x, y, zone->x, zone->y, zone->w, zone->h)) goto noflip; if ((one_row) && (y == 0) && E_ZONE_FLIP_UP(zone)) { /* top */ if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_UP; } else if ((one_col) && (x == (zone->w - 1)) && E_ZONE_FLIP_RIGHT(zone)) { /* right */ if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_RIGHT; } else if ((one_row) && (y == (zone->h - 1)) && E_ZONE_FLIP_DOWN(zone)) { /* bottom */ if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_DOWN; } else if ((one_col) && (x == 0) && E_ZONE_FLIP_LEFT(zone)) { /* left */ if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_LEFT; } else { noflip: /* in zone */ if (zone->flip.timer) ecore_timer_del(zone->flip.timer); zone->flip.timer = NULL; } } EAPI void e_zone_desk_count_set(E_Zone *zone, int x_count, int y_count) { E_Desk **new_desks; E_Desk *desk, *new_desk; int x, y, xx, yy, moved; E_Border *bd; E_Event_Zone_Desk_Count_Set *ev; E_Border_List *bl; E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); xx = x_count; if (xx < 1) xx = 1; yy = y_count; if (yy < 1) yy = 1; new_desks = malloc(xx * yy * sizeof(E_Desk *)); for (x = 0; x < xx; x++) { for (y = 0; y < yy; y++) { if ((x < zone->desk_x_count) && (y < zone->desk_y_count)) desk = zone->desks[x + (y * zone->desk_x_count)]; else desk = e_desk_new(zone, x, y); new_desks[x + (y * xx)] = desk; } } /* catch windoes that have fallen off the end if we got smaller */ if (xx < zone->desk_x_count) { for (y = 0; y < zone->desk_y_count; y++) { new_desk = zone->desks[xx - 1 + (y * zone->desk_x_count)]; for (x = xx; x < zone->desk_x_count; x++) { desk = zone->desks[x + (y * zone->desk_x_count)]; bl = e_container_border_list_first(zone->container); while ((bd = e_container_border_list_next(bl))) { if (bd->desk == desk) e_border_desk_set(bd, new_desk); } e_container_border_list_free(bl); e_object_del(E_OBJECT(desk)); } } } if (yy < zone->desk_y_count) { for (x = 0; x < zone->desk_x_count; x++) { new_desk = zone->desks[x + ((yy - 1) * zone->desk_x_count)]; for (y = yy; y < zone->desk_y_count; y++) { desk = zone->desks[x + (y * zone->desk_x_count)]; bl = e_container_border_list_first(zone->container); while ((bd = e_container_border_list_next(bl))) { if (bd->desk == desk) e_border_desk_set(bd, new_desk); } e_container_border_list_free(bl); e_object_del(E_OBJECT(desk)); } } } if (zone->desks) free(zone->desks); zone->desks = new_desks; zone->desk_x_count = xx; zone->desk_y_count = yy; moved = 0; if (zone->desk_x_current >= xx) { moved = 1; } if (zone->desk_y_current >= yy) { moved = 1; } if (moved) e_desk_show(e_desk_at_xy_get(zone, xx - 1, yy - 1)); else { desk = e_desk_current_get(zone); desk->visible = 0; e_desk_show(desk); } e_config->zone_desks_x_count = xx; e_config->zone_desks_y_count = yy; e_config_save_queue(); ev = E_NEW(E_Event_Zone_Desk_Count_Set, 1); if (!ev) return; ev->zone = zone; e_object_ref(E_OBJECT(zone)); ecore_event_add(E_EVENT_ZONE_DESK_COUNT_SET, ev, _e_zone_event_zone_desk_count_set_free, NULL); } EAPI void e_zone_desk_count_get(E_Zone *zone, int *x_count, int *y_count) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); *x_count = zone->desk_x_count; *y_count = zone->desk_y_count; } EAPI void e_zone_update_flip(E_Zone *zone) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); _e_zone_update_flip(zone); } EAPI void e_zone_update_flip_all(void) { Evas_List *l, *ll; E_Manager *man; E_Container *con; E_Zone *zone; for (l = e_manager_list(); l; l = l->next) { man = l->data; for (ll = man->containers; ll; ll = ll->next) { con = ll->data; zone = e_zone_current_get(con); e_zone_update_flip(zone); } } } EAPI void e_zone_desk_flip_by(E_Zone *zone, int dx, int dy) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); dx = zone->desk_x_current + dx; dy = zone->desk_y_current + dy; e_zone_desk_flip_to(zone, dx, dy); } EAPI void e_zone_desk_flip_to(E_Zone *zone, int x, int y) { E_Desk *desk; E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); if (e_config->desk_flip_wrap) { x = x % zone->desk_x_count; y = y % zone->desk_y_count; if (x < 0) x += zone->desk_x_count; if (y < 0) y += zone->desk_y_count; } else { if (x < 0) x = 0; else if (x >= zone->desk_x_count) x = zone->desk_x_count - 1; if (y < 0) y = 0; else if (y >= zone->desk_y_count) y = zone->desk_y_count - 1; } desk = e_desk_at_xy_get(zone, x, y); if (desk) e_desk_show(desk); } EAPI void e_zone_desk_linear_flip_by(E_Zone *zone, int dx) { E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); dx = zone->desk_x_current + (zone->desk_y_current * zone->desk_x_count) + dx; dx = dx % (zone->desk_x_count * zone->desk_y_count); while (dx < 0) dx += (zone->desk_x_count * zone->desk_y_count); e_zone_desk_linear_flip_to(zone, dx); } EAPI void e_zone_desk_linear_flip_to(E_Zone *zone, int x) { int y; E_OBJECT_CHECK(zone); E_OBJECT_TYPE_CHECK(zone, E_ZONE_TYPE); y = x / zone->desk_x_count; x = x - (y * zone->desk_x_count); e_zone_desk_flip_to(zone, x, y); } EAPI void e_zone_flip_win_disable(void) { Evas_List *l, *ll, *lll; E_Manager *man; E_Container *con; for (l = e_manager_list(); l; l = l->next) { man = l->data; for (ll = man->containers; ll; ll = ll->next) { con = ll->data; for (lll = con->zones; lll; lll = lll->next) { E_Zone *zone; zone = lll->data; ecore_x_window_hide(zone->flip.left); ecore_x_window_hide(zone->flip.right); ecore_x_window_hide(zone->flip.top); ecore_x_window_hide(zone->flip.bottom); } } } } EAPI void e_zone_flip_win_restore(void) { Evas_List *l, *ll, *lll; E_Manager *man; E_Container *con; for (l = e_manager_list(); l; l = l->next) { man = l->data; for (ll = man->containers; ll; ll = ll->next) { con = ll->data; for (lll = con->zones; lll; lll = lll->next) { E_Zone *zone; zone = lll->data; _e_zone_update_flip(zone); } } } } EAPI int e_zone_exec(E_Zone *zone, char *exe) { int ret = 0; char *p1, *p2; char *penv_display; char buf[4096], buf2[32]; Ecore_Exe *ex; E_App_Instance *inst = NULL; E_App *a; E_OBJECT_CHECK_RETURN(zone, 0); E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0); if (startup_id == 0) { p1 = getenv("E_STARTUP_ID"); if (p1) startup_id = atoi(p1); } if (++startup_id < 1) startup_id = 1; /* save previous env vars we need to save */ penv_display = getenv("DISPLAY"); if (penv_display) penv_display = strdup(penv_display); /* set env vars */ p1 = strrchr(penv_display, ':'); p2 = strrchr(penv_display, '.'); if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */ { /* yes it could overflow... but who will overflow DISPLAY eh? why? to * "exploit" your own applications running as you? */ strcpy(buf, penv_display); buf[p2 - penv_display + 1] = 0; snprintf(buf2, sizeof(buf2), "%i", zone->container->manager->num); strcat(buf, buf2); } else if (p1) /* "blah:x */ { strcpy(buf, penv_display); snprintf(buf2, sizeof(buf2), ".%i", zone->container->manager->num); strcat(buf, buf2); } else strcpy(buf, penv_display); e_util_env_set("DISPLAY", buf); snprintf(buf, sizeof(buf), "E_START|%i", startup_id); e_util_env_set("DESKTOP_STARTUP_ID", buf); /* execute */ a = e_app_exe_find(exe); if (!a) { a = E_NEW(E_App, 1); a->name = strdup (exe); a->exe = strdup (exe); } inst = E_NEW(E_App_Instance, 1); if (!inst) return 0; ex = ecore_exe_pipe_run(exe, ECORE_EXE_PIPE_AUTO | ECORE_EXE_PIPE_READ | ECORE_EXE_PIPE_ERROR | ECORE_EXE_PIPE_READ_LINE_BUFFERED | ECORE_EXE_PIPE_ERROR_LINE_BUFFERED, inst); if (!ex) { free(inst); e_error_dialog_show(_("Run Error"), _("Enlightenment was unable to fork a child process:\n" "\n" "%s\n" "\n"), exe); ret = 0; } /* reset env vars */ else ret = 1; if (penv_display) { e_util_env_set("DISPLAY", penv_display); free(penv_display); } /* 20 lines at start and end, 20x100 limit on bytes at each end. */ ecore_exe_auto_limits_set(ex, 2000, 2000, 20, 20); ecore_exe_tag_set(ex, "E/app"); inst->app = a; inst->exe = ex; inst->launch_id = startup_id; inst->launch_time = ecore_time_get(); a->instances = evas_list_append(a->instances, inst); if (a->startup_notify) a->starting = 1; return ret; } EAPI int e_zone_app_exec(E_Zone *zone, E_App *a) { int ret; char *p1, *p2; char *penv_display; char buf[4096], buf2[32]; E_OBJECT_CHECK_RETURN(zone, 0); E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, 0); if (!a) return 0; if (startup_id == 0) { p1 = getenv("E_STARTUP_ID"); if (p1) startup_id = atoi(p1); } if (++startup_id < 1) startup_id = 1; /* save previous env vars we need to save */ penv_display = getenv("DISPLAY"); if (penv_display) penv_display = strdup(penv_display); /* set env vars */ p1 = strrchr(penv_display, ':'); p2 = strrchr(penv_display, '.'); if ((p1) && (p2) && (p2 > p1)) /* "blah:x.y" */ { /* yes it could overflow... but who will overflow DISPLAY eh? why? to * "exploit" your own applications running as you? */ strcpy(buf, penv_display); buf[p2 - penv_display + 1] = 0; snprintf(buf2, sizeof(buf2), "%i", zone->container->manager->num); strcat(buf, buf2); } else if (p1) /* "blah:x */ { strcpy(buf, penv_display); snprintf(buf2, sizeof(buf2), ".%i", zone->container->manager->num); strcat(buf, buf2); } else strcpy(buf, penv_display); e_util_env_set("DISPLAY", buf); snprintf(buf, sizeof(buf), "E_START|%i", startup_id); e_util_env_set("DESKTOP_STARTUP_ID", buf); /* execute */ ret = e_app_exec(a, startup_id); /* reset env vars */ if (penv_display) { e_util_env_set("DISPLAY", penv_display); free(penv_display); } return ret; } /* local subsystem functions */ static void _e_zone_free(E_Zone *zone) { E_Container *con; Evas_List *l; int x, y; if (zone->black_ecore_evas) { e_canvas_del(zone->black_ecore_evas); ecore_evas_free(zone->black_ecore_evas); } if (zone->cur_mouse_action) { e_object_unref(E_OBJECT(zone->cur_mouse_action)); zone->cur_mouse_action = NULL; } /* remove handlers */ for (l = zone->handlers; l; l = l->next) { Ecore_Event_Handler *h; h = l->data; ecore_event_handler_del(h); } evas_list_free(zone->handlers); zone->handlers = NULL; con = zone->container; if (zone->name) evas_stringshare_del(zone->name); con->zones = evas_list_remove(con->zones, zone); evas_object_del(zone->bg_event_object); evas_object_del(zone->bg_clip_object); evas_object_del(zone->bg_object); if (zone->prev_bg_object) evas_object_del(zone->prev_bg_object); if (zone->transition_object) evas_object_del(zone->transition_object); /* free desks */ for (x = 0; x < zone->desk_x_count; x++) { for(y = 0; y < zone->desk_y_count; y++) e_object_del(E_OBJECT(zone->desks[x + (y * zone->desk_x_count)])); } free(zone->desks); free(zone); } static void _e_zone_cb_bg_mouse_down(void *data, Evas *evas, Evas_Object *obj, void *event_info) { E_Zone *zone; Evas_Event_Mouse_Down *ev; ev = (Evas_Event_Mouse_Down *)event_info; zone = data; if (e_menu_grab_window_get()) return; if (!zone->cur_mouse_action) { if (ecore_event_current_type_get() == ECORE_X_EVENT_MOUSE_BUTTON_DOWN) { Ecore_X_Event_Mouse_Button_Down *ev2; ev2 = ecore_event_current_event_get(); zone->cur_mouse_action = e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), ev2); if (zone->cur_mouse_action) { if ((!zone->cur_mouse_action->func.end_mouse) && (!zone->cur_mouse_action->func.end)) zone->cur_mouse_action = NULL; if (zone->cur_mouse_action) e_object_ref(E_OBJECT(zone->cur_mouse_action)); } } } } static void _e_zone_cb_bg_mouse_up(void *data, Evas *evas, Evas_Object *obj, void *event_info) { E_Zone *zone; Evas_Event_Mouse_Up *ev; ev = (Evas_Event_Mouse_Up *)event_info; zone = data; if (zone->cur_mouse_action) { if (ecore_event_current_type_get() == ECORE_X_EVENT_MOUSE_BUTTON_UP) { Ecore_X_Event_Mouse_Button_Up *ev2; ev2 = ecore_event_current_event_get(); if (zone->cur_mouse_action->func.end_mouse) zone->cur_mouse_action->func.end_mouse(E_OBJECT(zone), "", ev2); else if (zone->cur_mouse_action->func.end) zone->cur_mouse_action->func.end(E_OBJECT(zone), ""); } e_object_unref(E_OBJECT(zone->cur_mouse_action)); zone->cur_mouse_action = NULL; } else { if (ecore_event_current_type_get() == ECORE_X_EVENT_MOUSE_BUTTON_UP) { Ecore_X_Event_Mouse_Button_Up *ev2; ev2 = ecore_event_current_event_get(); e_bindings_mouse_up_event_handle(E_BINDING_CONTEXT_ZONE, E_OBJECT(zone), ev2); } } } static void _e_zone_cb_bg_mouse_move(void *data, Evas *evas, Evas_Object *obj, void *event_info) { E_Zone *zone; Evas_Event_Mouse_Move *ev; ev = (Evas_Event_Mouse_Move *)event_info; zone = data; } static void _e_zone_event_zone_desk_count_set_free(void *data, void *ev) { E_Event_Zone_Desk_Count_Set *e; e = ev; e_object_unref(E_OBJECT(e->zone)); free(e); } static int _e_zone_cb_mouse_in(void *data, int type, void *event) { Ecore_X_Event_Mouse_In *ev; E_Zone *zone; ev = event; zone = data; if (ev->win == zone->flip.top) { if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_UP; } else if (ev->win == zone->flip.right) { if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_RIGHT; } else if (ev->win == zone->flip.bottom) { if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_DOWN; } else if (ev->win == zone->flip.left) { if (!zone->flip.timer) zone->flip.timer = ecore_timer_add(e_config->edge_flip_timeout, _e_zone_cb_timer, zone); zone->flip.direction = E_DIRECTION_LEFT; } return 1; } static int _e_zone_cb_mouse_out(void *data, int type, void *event) { Ecore_X_Event_Mouse_Out *ev; E_Zone *zone; ev = event; zone = data; if ((ev->win == zone->flip.top) || (ev->win == zone->flip.bottom) || (ev->win == zone->flip.left) || (ev->win == zone->flip.right)) { if (zone->flip.timer) ecore_timer_del(zone->flip.timer); zone->flip.timer = NULL; } return 1; } static int _e_zone_cb_timer(void *data) { E_Zone *zone; E_Desk *prev = NULL, *current = NULL; E_Event_Pointer_Warp *ev; int x, y; ev = E_NEW(E_Event_Pointer_Warp, 1); if (!ev) return 0; zone = data; if (zone != e_zone_current_get(zone->container)) { zone->flip.timer = NULL; return 0; } ecore_x_pointer_xy_get(zone->container->win, &x, &y); ev->prev.x = x; ev->prev.y = y; prev = e_desk_at_xy_get(zone, zone->desk_x_current, zone->desk_y_current); switch (zone->flip.direction) { case E_DIRECTION_UP: if (E_ZONE_FLIP_UP(zone)) { e_zone_desk_flip_by(zone, 0, -1); ecore_x_pointer_warp(zone->container->win, x, zone->h - 2); ev->curr.x = x; ev->curr.y = zone->h - 2; } break; case E_DIRECTION_RIGHT: if (E_ZONE_FLIP_RIGHT(zone)) { e_zone_desk_flip_by(zone, 1, 0); ecore_x_pointer_warp(zone->container->win, 2, y); ev->curr.y = y; ev->curr.x = 2; } break; case E_DIRECTION_DOWN: if (E_ZONE_FLIP_DOWN(zone)) { e_zone_desk_flip_by(zone, 0, 1); ecore_x_pointer_warp(zone->container->win, x, 2); ev->curr.x = x; ev->curr.y = 2; } break; case E_DIRECTION_LEFT: if (E_ZONE_FLIP_LEFT(zone)) { e_zone_desk_flip_by(zone, -1, 0); ecore_x_pointer_warp(zone->container->win, zone->w - 2, y); ev->curr.y = y; ev->curr.x = zone->w - 2; } break; } zone->flip.timer = NULL; if (current) ecore_event_add(E_EVENT_POINTER_WARP, ev, NULL, NULL); else free(ev); return 0; } static int _e_zone_cb_desk_show(void *data, int type, void *event) { E_Event_Desk_Show *ev; E_Zone *zone; ev = event; zone = data; if (ev->desk->zone != zone) return 1; _e_zone_update_flip(zone); return 1; } static void _e_zone_update_flip(E_Zone *zone) { if (e_config->edge_flip_moving) { /* if we have only 1 row we can flip up/down even if we have xinerama */ int one_row = 1; int one_col = 1; if (evas_list_count(zone->container->zones) > 1) { Evas_List *zones; E_Zone *next_zone; int x, y; zones = zone->container->zones; next_zone = (E_Zone *) evas_list_data(zones); x = next_zone->x; y = next_zone->y; zones = evas_list_next(zones); while (zones) { next_zone = (E_Zone *)zones->data; if (next_zone->x != x) one_col = 0; if (next_zone->y != y) one_row = 0; zones = zones->next; } } if (evas_list_count(zone->container->manager->containers) > 1) { one_col = 0; one_row = 0; } if (one_col && E_ZONE_FLIP_LEFT(zone)) { ecore_x_window_show(zone->flip.left); e_container_window_raise(zone->container, zone->flip.left, 999); } else ecore_x_window_hide(zone->flip.left); if (one_col && E_ZONE_FLIP_RIGHT(zone)) { ecore_x_window_show(zone->flip.right); e_container_window_raise(zone->container, zone->flip.right, 999); } else ecore_x_window_hide(zone->flip.right); if (one_row && E_ZONE_FLIP_UP(zone)) { ecore_x_window_show(zone->flip.top); e_container_window_raise(zone->container, zone->flip.top, 999); } else ecore_x_window_hide(zone->flip.top); if (one_row && E_ZONE_FLIP_DOWN(zone)) { ecore_x_window_show(zone->flip.bottom); e_container_window_raise(zone->container, zone->flip.bottom, 999); } else ecore_x_window_hide(zone->flip.bottom); } else { ecore_x_window_hide(zone->flip.left); ecore_x_window_hide(zone->flip.right); ecore_x_window_hide(zone->flip.top); ecore_x_window_hide(zone->flip.bottom); } }