diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index bcca83903..453fce558 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -62,6 +62,7 @@ e_startup.h \ e_hints.h \ e_signals.h \ e_xinerama.h \ +e_randr.h \ e_table.h \ e_layout.h \ e_test.h \ @@ -203,6 +204,7 @@ e_startup.c \ e_hints.c \ e_signals.c \ e_xinerama.c \ +e_randr.c \ e_table.c \ e_layout.c \ e_test.c \ @@ -358,7 +360,8 @@ enlightenment_sys_LDADD = @E_SYS_LIBS@ enlightenment_init_SOURCES = \ e_init_main.c \ -e_xinerama.c +e_xinerama.c \ +e_randr.c enlightenment_init_LDADD = @E_INIT_LIBS@ diff --git a/src/bin/e_border.c b/src/bin/e_border.c index 80e1b89fe..e76c88ad7 100644 --- a/src/bin/e_border.c +++ b/src/bin/e_border.c @@ -122,7 +122,8 @@ static int grabbed = 0; static Eina_List *focus_stack = NULL; static Eina_List *raise_stack = NULL; -static Ecore_X_Screen_Size screen_size = { -1, -1 }; +static Ecore_X_Randr_Screen_Size screen_size = { -1, -1 }; +static int screen_size_index = -1; static int focus_track_frozen = 0; @@ -213,7 +214,7 @@ e_border_init(void) E_EVENT_BORDER_UNFULLSCREEN = ecore_event_type_new(); // e_init_undone(); - + return 1; } @@ -299,14 +300,14 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map, int internal) bd->y = att->y; bd->changes.pos = 1; bd->re_manage = 1; - // needed to be 1 for internal windw and on restart. + // needed to be 1 for internal windw and on restart. // bd->ignore_first_unmap = 2; } - + bd->client.win = win; bd->zone = e_zone_current_get(con); - - _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd); + + _e_border_hook_call(E_BORDER_HOOK_NEW_BORDER, bd); bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_IN, _e_border_cb_mouse_in, bd)); bd->handlers = eina_list_append(bd->handlers, ecore_event_handler_add(ECORE_X_EVENT_MOUSE_OUT, _e_border_cb_mouse_out, bd)); @@ -361,7 +362,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map, int internal) { int at_num = 0, i; Ecore_X_Atom *atoms; - + atoms = ecore_x_window_prop_list(bd->client.win, &at_num); bd->client.icccm.fetch.command = 1; if (atoms) @@ -483,7 +484,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map, int internal) } } bd->client.border.changed = 1; - + bd->client.w = att->w; bd->client.h = att->h; @@ -542,7 +543,7 @@ e_border_new(E_Container *con, Ecore_X_Window win, int first_map, int internal) ecore_x_window_prop_card32_set(win, E_ATOM_DESK, desk, 2); focus_stack = eina_list_append(focus_stack, bd); - + bd->pointer = e_pointer_window_new(bd->win, 0); return bd; } @@ -575,12 +576,12 @@ e_border_res_change_geometry_restore(E_Border *bd) int x, y, w, h; } saved; } pre_res_change; - + E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); if (!bd->pre_res_change.valid) return; if (bd->new_client) return; - + ecore_x_window_shadow_tree_flush(); memcpy(&pre_res_change, &bd->pre_res_change, sizeof(pre_res_change)); @@ -592,7 +593,7 @@ e_border_res_change_geometry_restore(E_Border *bd) else if (bd->maximized != E_MAXIMIZE_NONE) { E_Maximize max; - + max = bd->maximized; e_border_unmaximize(bd, E_MAXIMIZE_BOTH); e_border_maximize(bd, max); @@ -600,7 +601,7 @@ e_border_res_change_geometry_restore(E_Border *bd) else { int x, y, w, h, zx, zy, zw, zh; - + bd->saved.x = bd->pre_res_change.saved.x; bd->saved.y = bd->pre_res_change.saved.y; bd->saved.w = bd->pre_res_change.saved.w; @@ -612,12 +613,12 @@ e_border_res_change_geometry_restore(E_Border *bd) bd->saved.w = zw; if ((bd->saved.x + bd->saved.w) > (zx + zw)) bd->saved.x = zx + zw - bd->saved.w; - + if (bd->saved.h > zh) bd->saved.h = zh; if ((bd->saved.y + bd->saved.h) > (zy + zh)) bd->saved.y = zy + zh - bd->saved.h; - + x = bd->pre_res_change.x; y = bd->pre_res_change.y; w = bd->pre_res_change.w; @@ -663,7 +664,7 @@ e_border_zone_set(E_Border *bd, E_Zone *zone) if (x < zone->x) x = zone->x; if (y < zone->y) y = zone->y; - if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h)) + if (!E_INTERSECTS(x, y, bd->w, bd->h, zone->x, zone->y, zone->w, zone->h)) { /* still not in zone at all, so just move it to closest edge */ if (x < zone->x) x = zone->x; @@ -803,7 +804,7 @@ e_border_hide(E_Border *bd, int manage) e_border_focus_set(bd, 0, 1); if (manage != 2) { - if ((e_config->focus_policy == E_FOCUS_CLICK) && + if ((e_config->focus_policy == E_FOCUS_CLICK) && (e_config->focus_revert_on_hide_or_close)) e_desk_last_focused_focus(bd->desk); } @@ -819,16 +820,16 @@ e_border_hide(E_Border *bd, int manage) ecore_x_window_hide(bd->client.win); } } - + visible = 0; ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MAPPED, &visible, 1); if (!manage) ecore_x_window_prop_card32_set(bd->client.win, E_ATOM_MANAGED, &visible, 1); - + if (!stopping) { E_Event_Border_Hide *ev; - + ev = E_NEW(E_Event_Border_Hide, 1); ev->border = bd; e_object_ref(E_OBJECT(bd)); @@ -845,7 +846,7 @@ _e_border_client_move_resize_send(E_Border *bd) ecore_evas_managed_move(bd->internal_ecore_evas, bd->x + bd->fx.x + bd->client_inset.l, bd->y + bd->fx.y + bd->client_inset.t); - + ecore_x_icccm_move_resize_send(bd->client.win, bd->x + bd->fx.x + bd->client_inset.l, bd->y + bd->fx.y + bd->client_inset.t, @@ -1086,7 +1087,7 @@ _e_border_move_resize_internal(E_Border *bd, int x, int y, int w, int h, Eina_Bo } _e_border_client_move_resize_send(bd); - + _e_border_resize_update(bd); if (move) { @@ -1096,7 +1097,7 @@ _e_border_move_resize_internal(E_Border *bd, int x, int y, int w, int h, Eina_Bo // e_object_breadcrumb_add(E_OBJECT(bd), "border_move_event"); ecore_event_add(E_EVENT_BORDER_MOVE, mev, _e_border_event_border_move_free, NULL); } - + rev = E_NEW(E_Event_Border_Resize, 1); rev->border = bd; e_object_ref(E_OBJECT(bd)); @@ -1213,9 +1214,9 @@ e_border_layer_set(E_Border *bd, int layer) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); ecore_x_window_shadow_tree_flush(); - + raise = e_config->transient.raise; - + bd->saved.layer = bd->layer; bd->layer = layer; if (e_config->transient.layer) @@ -1249,7 +1250,7 @@ e_border_raise(E_Border *bd) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); ecore_x_window_shadow_tree_flush(); - + if (e_config->transient.raise) { EINA_LIST_REVERSE_FOREACH(bd->transients, l, child) @@ -1335,7 +1336,7 @@ e_border_lower(E_Border *bd) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); ecore_x_window_shadow_tree_flush(); - + if (e_config->transient.lower) { EINA_LIST_REVERSE_FOREACH(bd->transients, l, child) @@ -1421,7 +1422,7 @@ e_border_stack_above(E_Border *bd, E_Border *above) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); ecore_x_window_shadow_tree_flush(); - + if (e_config->transient.raise) { EINA_LIST_REVERSE_FOREACH(bd->transients, l, child) @@ -1475,7 +1476,7 @@ e_border_stack_below(E_Border *bd, E_Border *below) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); ecore_x_window_shadow_tree_flush(); - + if (e_config->transient.lower) { EINA_LIST_REVERSE_FOREACH(bd->transients, l, child) @@ -1566,9 +1567,9 @@ e_border_focus_set_with_pointer(E_Border *bd) if ((!bd->client.icccm.accepts_focus) && (!bd->client.icccm.take_focus)) return; if (bd->lock_focus_out) return; - + /* Try to grab the pointer to make sure it's not "in use" */ -/* +/* * this causes problems as the grab can cause an in/out event (by grab) that * normally would be like a grab from a menu or something else and e gets into * a slef-feeding loop. sorry - can't grab :( @@ -1606,7 +1607,7 @@ EAPI void e_border_focus_set(E_Border *bd, int focus, int set) { int focus_changed = 0; - + E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); /* note: this is here as it seems there are enough apps that do not even @@ -1662,7 +1663,7 @@ e_border_focus_set(E_Border *bd, int focus, int set) } if ((bd->visible) && (bd->changes.visible)) - { + { if ((bd->want_focus) && (set) && (!focus)) bd->want_focus = 0; } @@ -1750,19 +1751,19 @@ e_border_focus_set(E_Border *bd, int focus, int set) (e_object_ref_get(E_OBJECT(focused)) > 0)) { E_Event_Border_Focus_Out *ev; - + edje_object_signal_emit(focused->bg_object, "e,state,unfocused", "e"); if (focused->icon_object) edje_object_signal_emit(focused->icon_object, "e,state,unfocused", "e"); e_focus_event_focus_out(focused); - - ev = E_NEW(E_Event_Border_Focus_Out, 1); - ev->border = focused; + + ev = E_NEW(E_Event_Border_Focus_Out, 1); + ev->border = focused; e_object_ref(E_OBJECT(focused)); - + ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev, _e_border_event_border_focus_out_free, NULL); - + /* FIXME: Sometimes we should leave the window fullscreen! */ // if (focused->fullscreen) e_border_unfullscreen(focused); focused->focused = 0; @@ -1781,7 +1782,7 @@ e_border_focus_set(E_Border *bd, int focus, int set) #if 0 /* i'm pretty sure this case is handled above -- this was resulting in the "passive" * event getting sent twice when going from a window to the desktop. --rephorm */ -/* +/* else if ((!bd->focused) && (focused == bd)) { if (focused) @@ -1810,14 +1811,14 @@ e_border_focus_set(E_Border *bd, int focus, int set) if (bd->focused) { E_Event_Border_Focus_In *ev; - + focused = bd; // Let send the focus event iff the focus is set explicitly, // not via callback - ev = E_NEW(E_Event_Border_Focus_In, 1); - ev->border = bd; - e_object_ref(E_OBJECT(bd)); - + ev = E_NEW(E_Event_Border_Focus_In, 1); + ev->border = bd; + e_object_ref(E_OBJECT(bd)); + ecore_event_add(E_EVENT_BORDER_FOCUS_IN, ev, _e_border_event_border_focus_in_free, NULL); } @@ -1828,8 +1829,8 @@ e_border_focus_set(E_Border *bd, int focus, int set) focused = NULL; // Let send the focus event iff the focus is set explicitly, // not via callback - ev = E_NEW(E_Event_Border_Focus_Out, 1); - ev->border = bd; + ev = E_NEW(E_Event_Border_Focus_Out, 1); + ev->border = bd; e_object_ref(E_OBJECT(bd)); ecore_event_add(E_EVENT_BORDER_FOCUS_OUT, ev, @@ -1847,7 +1848,7 @@ e_border_shade(E_Border *bd, E_Direction dir) E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); if ((bd->shaded) || (bd->shading) || (bd->fullscreen) || ((bd->maximized) && (!e_config->allow_manip))) return; - if ((bd->client.border.name) && + if ((bd->client.border.name) && (!strcmp("borderless", bd->client.border.name))) return; ecore_x_window_shadow_tree_flush(); @@ -2046,7 +2047,7 @@ e_border_maximize(E_Border *bd, E_Maximize max) if (bd->fullscreen) e_border_unfullscreen(bd); /* Only allow changes in vertical/ horizontal maximization */ - if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) || + if (((bd->maximized & E_MAXIMIZE_DIRECTION) == (max & E_MAXIMIZE_DIRECTION)) || ((bd->maximized & E_MAXIMIZE_DIRECTION) == E_MAXIMIZE_BOTH)) return; if (bd->new_client) { @@ -2060,25 +2061,25 @@ e_border_maximize(E_Border *bd, E_Maximize max) int x1, y1, x2, y2; int w, h, pw, ph; int zx, zy, zw, zh; - + zx = zy = zw = zh = 0; bd->pre_res_change.valid = 0; if (!(bd->maximized & E_MAXIMIZE_HORIZONTAL)) { /* Horizontal hasn't been set */ - bd->saved.x = bd->x - bd->zone->x; - bd->saved.w = bd->w; + bd->saved.x = bd->x - bd->zone->x; + bd->saved.w = bd->w; } if (!(bd->maximized & E_MAXIMIZE_VERTICAL)) { /* Vertical hasn't been set */ - bd->saved.y = bd->y - bd->zone->y; + bd->saved.y = bd->y - bd->zone->y; bd->saved.h = bd->h; } bd->saved.zone = bd->zone->num; e_hints_window_size_set(bd); - + e_border_raise(bd); switch (max & E_MAXIMIZE_TYPE) { @@ -2089,13 +2090,13 @@ e_border_maximize(E_Border *bd, E_Maximize max) case E_MAXIMIZE_FULLSCREEN: w = bd->zone->w; h = bd->zone->h; - + if (bd->bg_object) { Evas_Coord cx, cy, cw, ch; edje_object_signal_emit(bd->bg_object, "e,action,maximize,fullscreen", "e"); - + evas_object_resize(bd->bg_object, w, h); edje_object_calc_force(bd->bg_object); edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch); @@ -2144,7 +2145,7 @@ e_border_maximize(E_Border *bd, E_Maximize max) else if (bd->x + bd->w > zx + zw) // window right not useful coordinates x1 = zx + zw - bd->w; else // window normal position - x1 = bd->x; + x1 = bd->x; if (bd->y < zy) // window top not useful coordinates y1 = zy; @@ -2167,13 +2168,13 @@ e_border_maximize(E_Border *bd, E_Maximize max) y1 = bd->zone->y; x2 = bd->zone->x + bd->zone->w; y2 = bd->zone->y + bd->zone->h; - + /* walk through all shelves */ e_maximize_border_shelf_fill(bd, &x1, &y1, &x2, &y2, max); - + /* walk through all windows */ e_maximize_border_border_fill(bd, &x1, &y1, &x2, &y2, max); - + w = x2 - x1; h = y2 - y1; pw = w; @@ -2195,10 +2196,10 @@ e_border_maximize(E_Border *bd, E_Maximize max) bd->maximized &= ~E_MAXIMIZE_TYPE; /* Add new maximization. It must be added, so that VERTICAL + HORIZONTAL == BOTH */ bd->maximized |= max; - + e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_HORIZONTAL, bd->maximized & E_MAXIMIZE_VERTICAL); - + } e_remember_update(bd); } @@ -2230,9 +2231,9 @@ e_border_unmaximize(E_Border *bd, E_Maximize max) if (bd->bg_object) { Evas_Coord cx, cy, cw, ch; - + edje_object_signal_emit(bd->bg_object, "e,action,unmaximize,fullscreen", "e"); - + evas_object_resize(bd->bg_object, 1000, 1000); edje_object_calc_force(bd->bg_object); edje_object_part_geometry_get(bd->bg_object, "e.swallow.client", &cx, &cy, &cw, &ch); @@ -2283,7 +2284,7 @@ e_border_unmaximize(E_Border *bd, E_Maximize max) } e_border_resize_limit(bd, &w, &h); - + _e_border_move_resize_internal(bd, x, y, w, h, 0, 1); if (!(bd->maximized & E_MAXIMIZE_DIRECTION)) { @@ -2320,7 +2321,7 @@ e_border_fullscreen(E_Border *bd, E_Fullscreen policy) if (!bd->fullscreen) { bd->pre_res_change.valid = 0; - + bd->saved.x = bd->x - bd->zone->x; bd->saved.y = bd->y - bd->zone->y; bd->saved.w = bd->client.w; @@ -2345,14 +2346,14 @@ e_border_fullscreen(E_Border *bd, E_Fullscreen policy) } else if (policy == E_FULLSCREEN_ZOOM) { - Ecore_X_Screen_Size *sizes; - int num_sizes, i; + Ecore_X_Randr_Screen_Size_MM *sizes; + int num_sizes, i, best_size_index = 0; - screen_size = ecore_x_randr_current_screen_size_get(bd->zone->container->manager->root); - sizes = ecore_x_randr_screen_sizes_get(bd->zone->container->manager->root, &num_sizes); + ecore_x_randr_screen_primary_output_current_size_get(bd->zone->container->manager->root, &screen_size.width, &screen_size.height, NULL, NULL, NULL); + sizes = ecore_x_randr_screen_primary_output_sizes_get(bd->zone->container->manager->root, &num_sizes); if (sizes) { - Ecore_X_Screen_Size best_size = { -1, -1 }; + Ecore_X_Randr_Screen_Size best_size = { -1, -1 }; int best_dist = INT_MAX, dist; for (i = 0; i < num_sizes; i++) @@ -2362,8 +2363,10 @@ e_border_fullscreen(E_Border *bd, E_Fullscreen policy) dist = (sizes[i].width * sizes[i].height) - (bd->w * bd->h); if (dist < best_dist) { - best_size = sizes[i]; + best_size.width = sizes[i].width; + best_size.height = sizes[i].height; best_dist = dist; + best_size_index = i; } } } @@ -2371,8 +2374,9 @@ e_border_fullscreen(E_Border *bd, E_Fullscreen policy) ((best_size.width != screen_size.width) || (best_size.height != screen_size.height))) { - ecore_x_randr_screen_size_set(bd->zone->container->manager->root, - best_size); + if (ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root, + best_size_index)) + screen_size_index = best_size_index; e_border_move_resize(bd, 0, 0, best_size.width, best_size.height); } else @@ -2421,13 +2425,13 @@ e_border_unfullscreen(E_Border *bd) if ((screen_size.width != -1) && (screen_size.height != -1)) { - ecore_x_randr_screen_size_set(bd->zone->container->manager->root, screen_size); + ecore_x_randr_screen_primary_output_size_set(bd->zone->container->manager->root, screen_size_index); screen_size.width = -1; screen_size.height = -1; } - e_border_move_resize(bd, - bd->saved.x + bd->zone->x, - bd->saved.y + bd->zone->y, + e_border_move_resize(bd, + bd->saved.x + bd->zone->x, + bd->saved.y + bd->zone->y, bd->saved.w, bd->saved.h); e_border_layer_set(bd, bd->saved.layer); @@ -2451,7 +2455,7 @@ e_border_iconify(E_Border *bd) { E_Event_Border_Iconify *ev; unsigned int iconic; - + E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); if (bd->shading) return; @@ -2677,8 +2681,8 @@ e_border_find_by_alarm(Ecore_X_Sync_Alarm alarm) { Eina_List *l; E_Border *bd; - - EINA_LIST_FOREACH(borders, l, bd) + + EINA_LIST_FOREACH(borders, l, bd) { if ((bd) && (!e_object_is_del(E_OBJECT(bd))) && (bd->client.netwm.sync.alarm == alarm)) @@ -2709,7 +2713,7 @@ e_border_idler_before(void) { E_Border_List *bl; E_Border *bd; - + // pass 1 - eval0. fetch properties on new or on change and // call hooks to decide what to do - maybe move/resize bl = e_container_border_list_last(con); @@ -2718,21 +2722,21 @@ e_border_idler_before(void) if (bd->changed) _e_border_eval0(bd); } e_container_border_list_free(bl); - + // layout hook - this is where a hook gets to figure out what to // do if anything. _e_border_container_layout_hook(con); - + // pass 2 - show windows needing show bl = e_container_border_list_last(con); while ((bd = e_container_border_list_prev(bl))) { - if ((bd->changes.visible) && (bd->visible) && + if ((bd->changes.visible) && (bd->visible) && (!bd->new_client) && (!bd->changes.pos) && (!bd->changes.size)) { ecore_evas_show(bd->bg_ecore_evas); - if ((1) && + if ((1) && ((bd->changes.pos && !bd->changes.size) || (!bd->changes.pos && bd->changes.size) || (bd->post_job))) @@ -2749,7 +2753,7 @@ e_border_idler_before(void) } } e_container_border_list_free(bl); - + // pass 3 - hide windows needing hide and eval (main eval) bl = e_container_border_list_first(con); while ((bd = e_container_border_list_next(bl))) @@ -2769,11 +2773,11 @@ e_border_idler_before(void) bd->changes.visible = 0; } if (bd->changed) _e_border_eval(bd); - if ((bd->changes.visible) && (bd->visible) && + if ((bd->changes.visible) && (bd->visible) && (!bd->new_client)) { ecore_evas_show(bd->bg_ecore_evas); - if ((1) && + if ((1) && ((bd->changes.pos && !bd->changes.size) || (!bd->changes.pos && bd->changes.size) || (bd->post_job))) @@ -3140,14 +3144,14 @@ e_border_act_move_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev) if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return; if (!_e_border_move_begin(bd)) return; - + e_zone_edge_disable(); bd->moving = 1; _e_border_pointer_move_begin(bd); if (ev) { char source[256]; - + snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons); _e_border_moveinfo_gather(bd, source); } @@ -3205,7 +3209,7 @@ e_border_act_resize_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev) if (ev) { char source[256]; - + snprintf(source, sizeof(source) - 1, "mouse,down,%i", ev->buttons); _e_border_moveinfo_gather(bd, source); } @@ -3241,7 +3245,7 @@ e_border_act_menu_begin(E_Border *bd, Ecore_Event_Mouse_Button *ev, int key) else { int x, y; - + ecore_x_pointer_xy_get(bd->zone->container->win, &x, &y); e_int_border_menu_show(bd, x, y, key, 0); } @@ -3290,7 +3294,7 @@ EAPI Evas_Object * e_border_icon_add(E_Border *bd, Evas *evas) { Evas_Object *o; - + E_OBJECT_CHECK_RETURN(bd, NULL); E_OBJECT_TYPE_CHECK_RETURN(bd, E_BORDER_TYPE, NULL); @@ -3298,14 +3302,14 @@ e_border_icon_add(E_Border *bd, Evas *evas) if (bd->internal) { o = edje_object_add(evas); - if (!bd->internal_icon) + if (!bd->internal_icon) e_util_edje_icon_set(o, "enlightenment"); else { if (!bd->internal_icon_key) { char *ext; - + ext = strrchr(bd->internal_icon, '.'); if ((ext) && ((!strcmp(ext, ".edj")))) { @@ -3364,7 +3368,7 @@ e_border_icon_add(E_Border *bd, Evas *evas) return o; } } - + o = e_icon_add(evas); e_util_icon_theme_set(o, "unknown"); return o; @@ -3376,7 +3380,7 @@ e_border_button_bindings_ungrab_all(void) Eina_List *l; E_Border *bd; - EINA_LIST_FOREACH(borders, l, bd) + EINA_LIST_FOREACH(borders, l, bd) { e_focus_setdown(bd); e_bindings_mouse_ungrab(E_BINDING_CONTEXT_BORDER, bd->win); @@ -3389,8 +3393,8 @@ e_border_button_bindings_grab_all(void) { Eina_List *l; E_Border *bd; - - EINA_LIST_FOREACH(borders, l, bd) + + EINA_LIST_FOREACH(borders, l, bd) { e_bindings_mouse_grab(E_BINDING_CONTEXT_BORDER, bd->win); e_bindings_wheel_grab(E_BINDING_CONTEXT_BORDER, bd->win); @@ -3416,7 +3420,7 @@ e_border_lost_windows_get(E_Zone *zone) Eina_List *list = NULL, *l; E_Border *bd; int loss_overlap = 5; - + E_OBJECT_CHECK_RETURN(zone, NULL); E_OBJECT_TYPE_CHECK_RETURN(zone, E_ZONE_TYPE, NULL); EINA_LIST_FOREACH(borders, l, bd) @@ -3426,7 +3430,7 @@ e_border_lost_windows_get(E_Zone *zone) if ((bd->zone == zone) || (bd->zone->container == zone->container)) { - if (!E_INTERSECTS(bd->zone->x + loss_overlap, + if (!E_INTERSECTS(bd->zone->x + loss_overlap, bd->zone->y + loss_overlap, bd->zone->w - (2 * loss_overlap), bd->zone->h - (2 * loss_overlap), @@ -3441,12 +3445,12 @@ e_border_lost_windows_get(E_Zone *zone) { Ecore_X_Rectangle *rect; int i, num; - + rect = ecore_x_window_shape_rectangles_get(bd->win, &num); if (rect) { int ok; - + ok = 0; for (i = 0; i < num; i++) { @@ -3545,7 +3549,7 @@ e_border_immortal_windows_get(void) { Eina_List *list = NULL, *l; E_Border *bd; - + EINA_LIST_FOREACH(borders, l, bd) { if (bd->lock_life) @@ -3572,7 +3576,7 @@ e_border_signal_move_begin(E_Border *bd, const char *sig, const char *src) { E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return; + if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return; if (!_e_border_move_begin(bd)) return; bd->moving = 1; _e_border_pointer_move_begin(bd); @@ -3610,8 +3614,8 @@ e_border_signal_resize_begin(E_Border *bd, const char *dir, const char *sig, con E_OBJECT_CHECK(bd); E_OBJECT_TYPE_CHECK(bd, E_BORDER_TYPE); - - if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return; + + if ((bd->resize_mode != RESIZE_NONE) || (bd->moving)) return; if (!_e_border_resize_begin(bd)) return; if (!strcmp(dir, "tl")) @@ -3689,7 +3693,7 @@ e_border_resize_limit(E_Border *bd, int *w, int *h) (bd->client.icccm.base_h >= 0)) { int tw, th; - + tw = *w - bd->client.icccm.base_w; th = *h - bd->client.icccm.base_h; if (tw < 1) tw = 1; @@ -3767,7 +3771,7 @@ _e_border_free(E_Border *bd) ecore_idle_enterer_del(bd->post_job); bd->post_job = NULL; } - if (bd->pointer) + if (bd->pointer) { e_object_del(E_OBJECT(bd->pointer)); bd->pointer = NULL; @@ -3791,7 +3795,7 @@ _e_border_free(E_Border *bd) E_FREE(bd->shape_rects); bd->shape_rects_num = 0; -/* +/* if (bd->dangling_ref_check) { ecore_timer_del(bd->dangling_ref_check); @@ -3828,12 +3832,12 @@ _e_border_free(E_Border *bd) e_object_del(E_OBJECT(bd->border_border_dialog)); bd->border_border_dialog = NULL; } - if (bd->border_prop_dialog) + if (bd->border_prop_dialog) { e_object_del(E_OBJECT(bd->border_prop_dialog)); bd->border_prop_dialog = NULL; } - + e_int_border_menu_del(bd); if (focused == bd) @@ -3847,7 +3851,7 @@ _e_border_free(E_Border *bd) if (bd->remember) { E_Remember *rem; - + rem = bd->remember; bd->remember = NULL; e_remember_unuse(rem); @@ -3882,7 +3886,7 @@ _e_border_free(E_Border *bd) if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv)) { int i; - + for (i = 0; i < bd->client.icccm.command.argc; i++) free(bd->client.icccm.command.argv[i]); free(bd->client.icccm.command.argv); @@ -3918,7 +3922,7 @@ static int _e_border_del_dangling_ref_check(void *data) { E_Border *bd; - + bd = data; printf("---\n"); printf("EEK EEK border still around 1 second after being deleted!\n"); @@ -3961,14 +3965,14 @@ _e_border_del(E_Border *bd) e_object_del(E_OBJECT(bd->border_border_dialog)); bd->border_border_dialog = NULL; } - if (bd->border_prop_dialog) + if (bd->border_prop_dialog) { e_object_del(E_OBJECT(bd->border_prop_dialog)); bd->border_prop_dialog = NULL; } e_int_border_menu_del(bd); - + if (bd->raise_timer) { ecore_timer_del(bd->raise_timer); @@ -4089,7 +4093,7 @@ _e_border_cb_window_hide(__UNUSED__ void *data, __UNUSED__ int ev_type, void *ev return ECORE_CALLBACK_PASS_ON; } /* Don't delete hidden or iconified windows */ - if ((bd->iconic) || ((!bd->visible) && (!bd->new_client)) || + if ((bd->iconic) || ((!bd->visible) && (!bd->new_client)) || (bd->await_hide_event > 0)) { // printf(" Don't delete hidden or iconified windows\n"); @@ -4227,7 +4231,7 @@ _e_border_cb_window_configure_request(__UNUSED__ void *data, __UNUSED__ int ev_t if ((bd->shaded) || (bd->shading)) { int pw, ph; - + pw = bd->client.w; ph = bd->client.h; if ((bd->shade.dir == E_DIRECTION_UP) || @@ -4284,7 +4288,7 @@ _e_border_cb_window_configure_request(__UNUSED__ void *data, __UNUSED__ int ev_t if ((bd->shaded) || (bd->shading)) { int pw, ph; - + pw = bd->client.w; ph = bd->client.h; if ((bd->shade.dir == E_DIRECTION_UP) || @@ -4324,7 +4328,7 @@ _e_border_cb_window_configure_request(__UNUSED__ void *data, __UNUSED__ int ev_t if (h > zh) h = zh; } - + e_border_resize(bd, w, h); if (e_config->geometry_auto_move == 1) @@ -4353,7 +4357,7 @@ _e_border_cb_window_configure_request(__UNUSED__ void *data, __UNUSED__ int ev_t (e->value_mask & ECORE_X_WINDOW_CONFIGURE_MASK_SIBLING)) { E_Border *obd; - + if (e->detail == ECORE_X_WINDOW_STACK_ABOVE) { obd = e_border_find_by_client_window(e->abovewin); @@ -4430,7 +4434,7 @@ _e_border_cb_window_resize_request(__UNUSED__ void *data, __UNUSED__ int ev_type if ((bd->shaded) || (bd->shading)) { int pw, ph; - + pw = bd->client.w; ph = bd->client.h; if ((bd->shade.dir == E_DIRECTION_UP) || @@ -4607,42 +4611,42 @@ _e_border_cb_window_property(__UNUSED__ void *data, __UNUSED__ int ev_type, void bd->client.vkbd.fetch.vkbd = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_CONFORMANT) { bd->client.illume.conformant.fetch.conformant = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_STATE) { bd->client.illume.quickpanel.fetch.state = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL) { bd->client.illume.quickpanel.fetch.quickpanel = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MAJOR) { bd->client.illume.quickpanel.fetch.priority.major = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_PRIORITY_MINOR) { bd->client.illume.quickpanel.fetch.priority.minor = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_QUICKPANEL_ZONE) { bd->client.illume.quickpanel.fetch.zone = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG_LOCKED) { bd->client.illume.drag.fetch.locked = 1; bd->changed = 1; } - else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG) + else if (e->atom == ECORE_X_ATOM_E_ILLUME_DRAG) { bd->client.illume.drag.fetch.drag = 1; bd->changed = 1; @@ -4808,7 +4812,7 @@ _e_border_cb_window_focus_out(__UNUSED__ void *data, __UNUSED__ int ev_type, voi modes[e->mode], details[e->detail]); } -#endif +#endif if (e->mode == ECORE_X_EVENT_MODE_NORMAL) { if (e->detail == ECORE_X_EVENT_DETAIL_INFERIOR) return ECORE_CALLBACK_PASS_ON; @@ -4923,7 +4927,7 @@ _e_border_cb_window_move_resize_request(__UNUSED__ void *data, __UNUSED__ int ev if (bd->cur_mouse_action) { e_object_ref(E_OBJECT(bd->cur_mouse_action)); - bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL); + bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL); } } return ECORE_CALLBACK_PASS_ON; @@ -4969,7 +4973,7 @@ _e_border_cb_window_move_resize_request(__UNUSED__ void *data, __UNUSED__ int ev default: return ECORE_CALLBACK_PASS_ON; } - + bd->cur_mouse_action = e_action_find("window_resize"); if (bd->cur_mouse_action) { @@ -4979,7 +4983,7 @@ _e_border_cb_window_move_resize_request(__UNUSED__ void *data, __UNUSED__ int ev } if (bd->cur_mouse_action) e_object_ref(E_OBJECT(bd->cur_mouse_action)); - + return ECORE_CALLBACK_PASS_ON; } @@ -5017,7 +5021,7 @@ _e_border_cb_sync_alarm(__UNUSED__ void *data, __UNUSED__ int ev_type, void *ev) E_Border *bd; Ecore_X_Event_Sync_Alarm *e; unsigned int serial; - + e = ev; bd = e_border_find_by_alarm(e->alarm); if (!bd) return ECORE_CALLBACK_PASS_ON; @@ -5054,14 +5058,14 @@ _e_border_cb_sync_alarm(__UNUSED__ void *data, __UNUSED__ int ev_type, void *ev) } bd->changes.size = 1; - bd->changes.pos = 1; + bd->changes.pos = 1; _e_border_eval(bd); evas_render(bd->bg_evas); ecore_x_pointer_xy_get(e_manager_current_get()->root, &bd->mouse.current.mx, - &bd->mouse.current.my); + &bd->mouse.current.my); bd->client.netwm.sync.send_time = ecore_loop_time_get(); _e_border_resize_handle(bd); @@ -5074,7 +5078,7 @@ _e_border_cb_efreet_cache_update(__UNUSED__ void *data, __UNUSED__ int ev_type, { Eina_List *l; E_Border *bd; - + /* mark all borders for desktop/icon updates */ EINA_LIST_FOREACH(borders, l, bd) { @@ -5098,7 +5102,7 @@ _e_border_cb_config_icon_theme(__UNUSED__ void *data, __UNUSED__ int ev_type, __ { Eina_List *l; E_Border *bd; - + /* mark all borders for desktop/icon updates */ EINA_LIST_FOREACH(borders, l, bd) { @@ -5130,7 +5134,7 @@ _e_border_cb_signal_bind(void *data, Evas_Object *obj, const char *emission, con bd = data; if (e_dnd_active()) return; - e_bindings_signal_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), + e_bindings_signal_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), emission, source); } @@ -5233,7 +5237,7 @@ _e_border_cb_mouse_out(void *data, __UNUSED__ int type, void *event) } #endif if (grabbed) return ECORE_CALLBACK_PASS_ON; -#if 0 +#if 0 if (ev->event_win == bd->win) { if (bd->fullscreen) @@ -5248,7 +5252,7 @@ _e_border_cb_mouse_out(void *data, __UNUSED__ int type, void *event) return ECORE_CALLBACK_PASS_ON; e_focus_event_mouse_out(bd); } -#endif +#endif #if 0 if ((ev->win != bd->win) && (ev->win != bd->event_win) && @@ -5316,7 +5320,7 @@ _e_border_cb_mouse_down(void *data, __UNUSED__ int type, void *event) bd->mouse.current.my = ev->root.y; if (!bd->cur_mouse_action) { - bd->cur_mouse_action = + bd->cur_mouse_action = e_bindings_mouse_down_event_handle(E_BINDING_CONTEXT_BORDER, E_OBJECT(bd), ev); if (bd->cur_mouse_action) @@ -5356,7 +5360,7 @@ _e_border_cb_mouse_down(void *data, __UNUSED__ int type, void *event) } bd->mouse.current.mx = ev->root.x; bd->mouse.current.my = ev->root.y; -/* +/* if (bd->moving) { } @@ -5525,10 +5529,10 @@ _e_border_cb_mouse_move(void *data, __UNUSED__ int type, void *event) else { int dx, dy; - + dx = bd->drag.x - ev->root.x; dy = bd->drag.y - ev->root.y; - if (((dx * dx) + (dy * dy)) > + if (((dx * dx) + (dy * dy)) > (e_config->drag_resist * e_config->drag_resist)) { /* start drag! */ @@ -5542,7 +5546,7 @@ _e_border_cb_mouse_move(void *data, __UNUSED__ int type, void *event) evas_object_geometry_get(bd->icon_object, &x, &y, &w, &h); drag_border = e_drag_new(bd->zone->container, - bd->x + bd->fx.x + x, + bd->x + bd->fx.x + x, bd->y + bd->fx.y + y, drag_types, 1, bd, -1, NULL, @@ -5570,16 +5574,16 @@ _e_border_cb_mouse_move(void *data, __UNUSED__ int type, void *event) static Eina_Bool _e_border_cb_grab_replay(void *data, int type, void *event) -{ +{ Ecore_Event_Mouse_Button *ev; if (type != ECORE_EVENT_MOUSE_BUTTON_DOWN) return ECORE_CALLBACK_DONE; - + ev = event; if ((e_config->pass_click_on) || (e_config->always_click_to_raise) || (e_config->always_click_to_focus)) { E_Border *bd; - + bd = e_border_find_by_window(ev->event_window); if (bd) { @@ -5610,12 +5614,12 @@ static Eina_Bool _e_border_post_move_resize_job(void *data) { E_Border *bd; - + bd = (E_Border *)data; if ((bd->post_move) && (bd->post_resize)) { - ecore_x_window_move_resize(bd->win, - bd->x + bd->fx.x, + ecore_x_window_move_resize(bd->win, + bd->x + bd->fx.x, bd->y + bd->fx.y, bd->w, bd->h); } @@ -5654,13 +5658,13 @@ _e_border_eval0(E_Border *bd) { int change_urgent = 0; int rem_change = 0; - + if (e_object_is_del(E_OBJECT(bd))) { fprintf(stderr, "ERROR: _e_border_eval(%p) with deleted border!\n", bd); return; } - + _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_FETCH, bd); /* fetch any info queued to be fetched */ @@ -5815,7 +5819,7 @@ _e_border_eval0(E_Border *bd) if ((bd->client.icccm.command.argc > 0) && (bd->client.icccm.command.argv)) { int i; - + for (i = 0; i < bd->client.icccm.command.argc; i++) free(bd->client.icccm.command.argv[i]); free(bd->client.icccm.command.argv); @@ -5995,7 +5999,7 @@ _e_border_eval0(E_Border *bd) if (bd->client.netwm.icons) { int i; - + for (i = 0; i < bd->client.netwm.num_icons; i++) free(bd->client.netwm.icons[i].data); free(bd->client.netwm.icons); @@ -6070,51 +6074,51 @@ _e_border_eval0(E_Border *bd) bd->client.vkbd.fetch.vkbd = 0; rem_change = 1; } - if (bd->client.illume.conformant.fetch.conformant) + if (bd->client.illume.conformant.fetch.conformant) { - bd->client.illume.conformant.conformant = + bd->client.illume.conformant.conformant = ecore_x_e_illume_conformant_get(bd->client.win); bd->client.illume.conformant.fetch.conformant = 0; } - if (bd->client.illume.quickpanel.fetch.state) + if (bd->client.illume.quickpanel.fetch.state) { - bd->client.illume.quickpanel.state = + bd->client.illume.quickpanel.state = ecore_x_e_illume_quickpanel_state_get(bd->client.win); bd->client.illume.quickpanel.fetch.state = 0; } - if (bd->client.illume.quickpanel.fetch.quickpanel) + if (bd->client.illume.quickpanel.fetch.quickpanel) { - bd->client.illume.quickpanel.quickpanel = + bd->client.illume.quickpanel.quickpanel = ecore_x_e_illume_quickpanel_get(bd->client.win); bd->client.illume.quickpanel.fetch.quickpanel = 0; } - if (bd->client.illume.quickpanel.fetch.priority.major) + if (bd->client.illume.quickpanel.fetch.priority.major) { - bd->client.illume.quickpanel.priority.major = + bd->client.illume.quickpanel.priority.major = ecore_x_e_illume_quickpanel_priority_major_get(bd->client.win); bd->client.illume.quickpanel.fetch.priority.major = 0; } - if (bd->client.illume.quickpanel.fetch.priority.minor) + if (bd->client.illume.quickpanel.fetch.priority.minor) { - bd->client.illume.quickpanel.priority.minor = + bd->client.illume.quickpanel.priority.minor = ecore_x_e_illume_quickpanel_priority_minor_get(bd->client.win); bd->client.illume.quickpanel.fetch.priority.minor = 0; } - if (bd->client.illume.quickpanel.fetch.zone) + if (bd->client.illume.quickpanel.fetch.zone) { - bd->client.illume.quickpanel.zone = + bd->client.illume.quickpanel.zone = ecore_x_e_illume_quickpanel_zone_get(bd->client.win); bd->client.illume.quickpanel.fetch.zone = 0; } - if (bd->client.illume.drag.fetch.drag) + if (bd->client.illume.drag.fetch.drag) { - bd->client.illume.drag.drag = + bd->client.illume.drag.drag = ecore_x_e_illume_drag_get(bd->client.win); bd->client.illume.drag.fetch.drag = 0; } - if (bd->client.illume.drag.fetch.locked) + if (bd->client.illume.drag.fetch.locked) { - bd->client.illume.drag.locked = + bd->client.illume.drag.locked = ecore_x_e_illume_drag_locked_get(bd->client.win); bd->client.illume.drag.fetch.locked = 0; } @@ -6163,7 +6167,7 @@ _e_border_eval0(E_Border *bd) else { bd->client.shaped = 0; - if (!bd->bordername) + if (!bd->bordername) bd->client.border.changed = 1; } bd->need_shape_merge = 1; @@ -6261,7 +6265,7 @@ _e_border_eval0(E_Border *bd) ecore_x_window_reparent(bd->client.win, bd->client.shell_win, 0, 0); if (bd->visible) { - if ((bd->new_client) && (bd->internal) && + if ((bd->new_client) && (bd->internal) && (bd->internal_ecore_evas)) ecore_evas_show(bd->internal_ecore_evas); ecore_x_window_show(bd->client.win); @@ -6307,13 +6311,13 @@ _e_border_eval0(E_Border *bd) else if ((bd->client.netwm.state.skip_taskbar) || (bd->client.netwm.state.skip_pager)) bordername = "skipped"; - else + else bordername = e_config->theme_default_border_style; if (!bordername) bordername = "default"; if ((!bd->client.border.name) || (strcmp(bd->client.border.name, bordername))) { - if (bd->client.border.name) + if (bd->client.border.name) eina_stringshare_del(bd->client.border.name); bd->client.border.name = eina_stringshare_add(bordername); @@ -6336,7 +6340,7 @@ _e_border_eval0(E_Border *bd) { ok = e_theme_edje_object_set(o, "base/theme/borders", "e/widgets/border/default/border"); - if (ok) + if (ok) { /* Reset default border style to default */ if (e_config->theme_default_border_style) @@ -6364,7 +6368,7 @@ _e_border_eval0(E_Border *bd) bd->client.icccm.title); evas_object_resize(o, 1000, 1000); edje_object_calc_force(o); - edje_object_part_geometry_get(o, "e.swallow.client", + edje_object_part_geometry_get(o, "e.swallow.client", &cx, &cy, &cw, &ch); l = cx; r = 1000 - (cx + cw); @@ -6459,7 +6463,7 @@ _e_border_eval0(E_Border *bd) static void _e_border_eval(E_Border *bd) -{ +{ E_Event_Border_Property *event; E_Border_Pending_Move_Resize *pnd; int rem_change = 0; @@ -6473,7 +6477,7 @@ _e_border_eval(E_Border *bd) } _e_border_hook_call(E_BORDER_HOOK_EVAL_PRE_NEW_BORDER, bd); - + if (bd->new_client) { int zx, zy, zw, zh; @@ -6563,17 +6567,17 @@ _e_border_eval(E_Border *bd) } /* - * This ensures that windows that like to open with a x/y + * This ensures that windows that like to open with a x/y * position smaller than returned by e_zone_useful_geometry_get() * are moved to useful positions. */ // -> if (bd->x < zx) bd->x = zx; - + if (bd->y < zy) bd->y = zy; - + if (bd->x + bd->w > zw) bd->x = zx + zw - bd->w; @@ -6641,7 +6645,7 @@ _e_border_eval(E_Border *bd) } else { - e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h, + e_place_zone_cursor(bd->zone, bd->x, bd->y, bd->w, bd->h, bd->client_inset.t, &new_x, &new_y); } bd->x = new_x; @@ -6677,7 +6681,7 @@ _e_border_eval(E_Border *bd) /* Recreate state */ e_hints_window_init(bd); - if ((bd->client.e.state.centered) && + if ((bd->client.e.state.centered) && ((!bd->remember) || ((bd->remember) && (!(bd->remember->apply & E_REMEMBER_APPLY_POS))))) { @@ -6693,7 +6697,7 @@ _e_border_eval(E_Border *bd) * in another zone - well move it there */ { E_Zone *zone; - + zone = e_container_zone_at_point_get(bd->zone->container, bd->x + (bd->w / 2), bd->y + (bd->h / 2)); @@ -6720,9 +6724,9 @@ _e_border_eval(E_Border *bd) } } } - + _e_border_hook_call(E_BORDER_HOOK_EVAL_POST_NEW_BORDER, bd); - + /* effect changes to the window border itself */ if ((bd->changes.shading)) { @@ -6783,7 +6787,7 @@ _e_border_eval(E_Border *bd) { xx = bd->w - (bd->client_inset.l + bd->client_inset.r); yy = bd->h - (bd->client_inset.t + bd->client_inset.b); - + evas_obscured_clear(bd->bg_evas); evas_obscured_rectangle_add(bd->bg_evas, bd->client_inset.l, bd->client_inset.t, xx, yy); @@ -6797,7 +6801,7 @@ _e_border_eval(E_Border *bd) else if (bd->shade.dir == E_DIRECTION_LEFT) { x = xx - bd->client.w; - } + } } } @@ -6820,12 +6824,12 @@ _e_border_eval(E_Border *bd) if ((!bd->shaded) || (bd->shading)) ecore_x_window_move_resize(bd->client.shell_win, bd->client_inset.l, bd->client_inset.t, xx, yy); - + if (bd->internal_ecore_evas) ecore_evas_move_resize(bd->internal_ecore_evas, x, y, bd->client.w, bd->client.h); else ecore_x_window_move_resize(bd->client.win, x, y, bd->client.w, bd->client.h); - + ecore_evas_move_resize(bd->bg_ecore_evas, 0, 0, bd->w, bd->h); evas_object_resize(bd->bg_object, bd->w, bd->h); e_container_shape_resize(bd->shape, bd->w, bd->h); @@ -6865,21 +6869,21 @@ _e_border_eval(E_Border *bd) bd->changes.reset_gravity = 0; rem_change = 1; } - + if (bd->need_shape_merge) { if ((bd->shaped) || (bd->client.shaped)) { Ecore_X_Window twin, twin2; int x, y; - + twin = ecore_x_window_override_new(bd->win, 0, 0, bd->w, bd->h); if (bd->shaped) ecore_x_window_shape_window_set(twin, bd->bg_win); else { Ecore_X_Rectangle rects[4]; - + rects[0].x = 0; rects[0].y = 0; rects[0].width = bd->w; @@ -6898,7 +6902,7 @@ _e_border_eval(E_Border *bd) rects[3].height = bd->client_inset.b; ecore_x_window_shape_rectangles_set(twin, rects, 4); } - twin2 = ecore_x_window_override_new(bd->win, 0, 0, + twin2 = ecore_x_window_override_new(bd->win, 0, 0, bd->w - bd->client_inset.l - bd->client_inset.r, bd->h - bd->client_inset.t - bd->client_inset.b); x = 0; @@ -6912,11 +6916,11 @@ _e_border_eval(E_Border *bd) } ecore_x_window_shape_window_set_xy(twin2, bd->client.win, x, y); - ecore_x_window_shape_rectangle_clip(twin2, 0, 0, + ecore_x_window_shape_rectangle_clip(twin2, 0, 0, bd->w - bd->client_inset.l - bd->client_inset.r, bd->h - bd->client_inset.t - bd->client_inset.b); ecore_x_window_shape_window_add_xy(twin, twin2, - bd->client_inset.l, + bd->client_inset.l, bd->client_inset.t); ecore_x_window_free(twin2); ecore_x_window_shape_window_set(bd->win, twin); @@ -6927,22 +6931,22 @@ _e_border_eval(E_Border *bd) // bd->need_shape_export = 1; bd->need_shape_merge = 0; } - + if (bd->need_shape_export) { Ecore_X_Rectangle *rects, *orects; int num; - + rects = ecore_x_window_shape_rectangles_get(bd->win, &num); if (rects) { int changed; - + changed = 1; if ((num == bd->shape_rects_num) && (bd->shape_rects)) { int i; - + orects = bd->shape_rects; changed = 0; for (i = 0; i < num; i++) @@ -6961,7 +6965,7 @@ _e_border_eval(E_Border *bd) } if ((rects[i].y + (int) rects[i].height) > bd->h) rects[i].height = rects[i].height - rects[i].y; - + if ((orects[i].x != rects[i].x) || (orects[i].y != rects[i].y) || (orects[i].width != rects[i].width) || @@ -7051,7 +7055,7 @@ _e_border_eval(E_Border *bd) grabbed = 1; e_object_ref(E_OBJECT(bd->cur_mouse_action)); - bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL); + bd->cur_mouse_action->func.go(E_OBJECT(bd), NULL); if (e_config->border_raise_on_mouse_action) e_border_raise(bd); e_border_focus_set(bd, 1, 1); @@ -7076,7 +7080,7 @@ _e_border_eval(E_Border *bd) { const char *desktop = bd->remember->prop.desktop_file; - bd->desktop = efreet_desktop_get(desktop); + bd->desktop = efreet_desktop_get(desktop); if (!bd->desktop) bd->desktop = efreet_util_desktop_name_find(desktop); } @@ -7100,7 +7104,7 @@ _e_border_eval(E_Border *bd) } if (!bd->desktop && bd->client.icccm.transient_for) { - E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for); + E_Border *bd2 = e_border_find_by_client_window(bd->client.icccm.transient_for); if (bd2 && bd2->desktop) { efreet_desktop_ref(bd2->desktop); @@ -7142,7 +7146,7 @@ _e_border_eval(E_Border *bd) bd->changes.stack = 0; bd->changes.prop = 0; bd->changes.border = 0; - + if ((bd->take_focus) || (bd->want_focus)) { bd->take_focus = 0; @@ -7191,13 +7195,13 @@ _e_border_eval(E_Border *bd) e_border_maximize(bd, max); bd->need_maximize = 0; } - + if (bd->need_fullscreen) { e_border_fullscreen(bd, e_config->fullscreen_policy); bd->need_fullscreen = 0; } - + if (rem_change) e_remember_update(bd); @@ -7694,7 +7698,7 @@ _e_border_resize_begin(E_Border *bd) grabbed = 0; return 0; } - + if (bd->client.netwm.sync.request) { bd->client.netwm.sync.alarm = ecore_x_sync_alarm_new(bd->client.netwm.sync.counter); @@ -7703,8 +7707,8 @@ _e_border_resize_begin(E_Border *bd) bd->client.netwm.sync.send_time = ecore_loop_time_get(); } - _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd); - + _e_border_hook_call(E_BORDER_HOOK_RESIZE_BEGIN, bd); + resize = bd; return 1; } @@ -7720,7 +7724,7 @@ _e_border_resize_end(E_Border *bd) if (bd->client.netwm.sync.alarm) { E_Border_Pending_Move_Resize *pnd; - + ecore_x_sync_alarm_free(bd->client.netwm.sync.alarm); bd->client.netwm.sync.alarm = 0; /* resize to last geometry if sync alarm for it was not yet handled */ @@ -7731,18 +7735,18 @@ _e_border_resize_end(E_Border *bd) bd->changes.size = 1; _e_border_client_move_resize_send(bd); } - + EINA_LIST_FREE(bd->pending_move_resize, pnd) E_FREE(pnd); } - _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd); - + _e_border_hook_call(E_BORDER_HOOK_RESIZE_END, bd); + resize = NULL; - + /* If this border was maximized, we need to unset Maximized state or * on restart, E still thinks it's maximized */ - if (bd->maximized != E_MAXIMIZE_NONE) + if (bd->maximized != E_MAXIMIZE_NONE) e_hints_window_maximized_set(bd, bd->maximized & E_MAXIMIZE_NONE, bd->maximized & E_MAXIMIZE_NONE); return 1; @@ -7783,7 +7787,7 @@ _e_border_move_begin(E_Border *bd) } #endif _e_border_hook_call(E_BORDER_HOOK_MOVE_BEGIN, bd); - + move = bd; return 1; } @@ -7804,7 +7808,7 @@ _e_border_move_end(E_Border *bd) } #endif _e_border_hook_call(E_BORDER_HOOK_MOVE_END, bd); - + move = NULL; return 1; } @@ -7819,7 +7823,7 @@ static Eina_Bool _e_border_cb_ping_poller(void *data) { E_Border *bd; - + bd = data; if (bd->ping_ok) { @@ -7857,7 +7861,7 @@ static Eina_Bool _e_border_cb_kill_timer(void *data) { E_Border *bd; - + bd = data; if (bd->hung) { @@ -7953,7 +7957,7 @@ _e_border_hooks_clean(void) { Eina_List *l, *ln; E_Border_Hook *bh; - + EINA_LIST_FOREACH_SAFE(_e_border_hooks, l, ln, bh) { if (bh->delete_me) @@ -7985,7 +7989,7 @@ EAPI E_Border_Hook * e_border_hook_add(E_Border_Hook_Point hookpoint, void (*func) (void *data, void *bd), void *data) { E_Border_Hook *bh; - + bh = E_NEW(E_Border_Hook, 1); if (!bh) return NULL; bh->hookpoint = hookpoint; @@ -8112,17 +8116,17 @@ e_border_pointer_warp_to_center(E_Border *bd) (y >= bd->y) && (y <= (bd->y + bd->h))) return 0; - warp_to_x = bd->x + (bd->w / 2); + warp_to_x = bd->x + (bd->w / 2); if (warp_to_x < (bd->zone->x + 1)) warp_to_x = bd->zone->x + ((bd->x + bd->w - bd->zone->x) / 2); else if (warp_to_x > (bd->zone->x + bd->zone->w)) - warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2; + warp_to_x = (bd->zone->x + bd->zone->w + bd->x) / 2; warp_to_y = bd->y + (bd->h / 2); if (warp_to_y < (bd->zone->y + 1)) warp_to_y = bd->zone->y + ((bd->y + bd->h - bd->zone->y) / 2); else if (warp_to_y > (bd->zone->y + bd->zone->h)) - warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2; + warp_to_y = (bd->zone->y + bd->zone->h + bd->y) / 2; warp_to = 1; warp_to_win = bd->zone->container->win; diff --git a/src/bin/e_config.c b/src/bin/e_config.c index 168d34957..44c603c92 100644 --- a/src/bin/e_config.c +++ b/src/bin/e_config.c @@ -6,6 +6,24 @@ #define DEF_MENUCLICK 0.25 #endif +typedef enum _Eet_Union +{ + EET_SCREEN_INFO_11 = (int)((1 << 16) | 1), + EET_SCREEN_INFO_12 = (int)((1 << 16) | 2), + EET_SCREEN_INFO_13 = (int)((1 << 16) | 3), + EET_UNKNOWN +} Eet_Union; + +struct { + Eet_Union u; + const char *name; +} eet_mapping[] = { + { EET_SCREEN_INFO_11, "E_Config_Screen_11" }, + { EET_SCREEN_INFO_12, "E_Config_Screen_12" }, + { EET_SCREEN_INFO_12, "E_Config_Screen_13" }, + { EET_UNKNOWN, NULL } +}; + EAPI E_Config *e_config = NULL; static int _e_config_revisions = 0; @@ -16,6 +34,8 @@ static void _e_config_free(E_Config *cfg); static Eina_Bool _e_config_cb_timer(void *data); static int _e_config_eet_close_handle(Eet_File *ef, char *file); static void _e_config_acpi_bindings_add(void); +static const char * _eet_union_type_get(const void *data, Eina_Bool *unknow); +static Eina_Bool _eet_union_type_set(const char *type, void *data, Eina_Bool unknow); /* local subsystem globals */ static int _e_config_save_block = 0; @@ -44,6 +64,15 @@ static E_Config_DD *_e_config_shelf_edd = NULL; static E_Config_DD *_e_config_shelf_desk_edd = NULL; static E_Config_DD *_e_config_mime_icon_edd = NULL; static E_Config_DD *_e_config_syscon_action_edd = NULL; +static E_Config_DD *_e_config_screen_size_edd = NULL; +static E_Config_DD *_e_config_screen_size_mm_edd = NULL; +static E_Config_DD *_e_config_eina_rectangle_edd = NULL; +static E_Config_DD *_e_config_screen_info_edd = NULL; +static E_Config_DD *_e_config_screen_restore_info_11_edd = NULL; +static E_Config_DD *_e_config_screen_restore_info_12_edd = NULL; +static E_Config_DD *_e_config_screen_output_restore_info_edd = NULL; +static E_Config_DD *_e_config_screen_crtc_restore_info_edd = NULL; + EAPI int E_EVENT_CONFIG_ICON_THEME = 0; EAPI int E_EVENT_CONFIG_MODE_CHANGED = 0; @@ -54,12 +83,12 @@ _e_config_profile_name_get(Eet_File *ef) /* profile config exists */ char *data, *s = NULL; int data_len = 0; - + data = eet_read(ef, "config", &data_len); if ((data) && (data_len > 0)) { int ok = 1; - + for (s = data; s < (data + data_len); s++) { // if profile is not all ascii (valid printable ascii - no @@ -97,7 +126,7 @@ e_config_init(void) if (_e_config_profile) /* if environment var set - use this profile name */ _e_config_profile = strdup(_e_config_profile); - else + else { Eet_File *ef; char buf[4096]; @@ -114,7 +143,7 @@ e_config_init(void) if (!_e_config_profile) { int i; - + for (i =1; i <= _e_config_revisions; i++) { e_user_dir_snprintf(buf, sizeof(buf), "config/profile.%i.cfg", i); @@ -144,7 +173,7 @@ e_config_init(void) { /* no profile config - try other means */ char *link = NULL; - + /* check symlink - if default is a symlink to another dir */ e_prefix_data_concat_static(buf, "data/config/default"); link = ecore_file_readlink(buf); @@ -181,7 +210,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, orient, INT); E_CONFIG_VAL(D, T, autoscroll, UCHAR); E_CONFIG_VAL(D, T, resizable, UCHAR); - + _e_config_gadcon_edd = E_CONFIG_DD_NEW("E_Config_Gadcon", E_Config_Gadcon); #undef T #undef D @@ -199,7 +228,7 @@ e_config_init(void) #define D _e_config_shelf_desk_edd E_CONFIG_VAL(D, T, x, INT); E_CONFIG_VAL(D, T, y, INT); - + _e_config_shelf_edd = E_CONFIG_DD_NEW("E_Config_Shelf", E_Config_Shelf); #undef T #undef D @@ -234,7 +263,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, desk_x, INT); E_CONFIG_VAL(D, T, desk_y, INT); E_CONFIG_VAL(D, T, file, STR); - + _e_config_desktop_name_edd = E_CONFIG_DD_NEW("E_Config_Desktop_Name", E_Config_Desktop_Name); #undef T #undef D @@ -260,7 +289,7 @@ e_config_init(void) #define D _e_config_theme_edd E_CONFIG_VAL(D, T, category, STR); E_CONFIG_VAL(D, T, file, STR); - + _e_config_module_edd = E_CONFIG_DD_NEW("E_Config_Module", E_Config_Module); #undef T #undef D @@ -271,7 +300,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, delayed, UCHAR); E_CONFIG_VAL(D, T, priority, INT); - _e_config_font_default_edd = E_CONFIG_DD_NEW("E_Font_Default", + _e_config_font_default_edd = E_CONFIG_DD_NEW("E_Font_Default", E_Font_Default); #undef T #undef D @@ -281,7 +310,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, font, STR); E_CONFIG_VAL(D, T, size, INT); - _e_config_font_fallback_edd = E_CONFIG_DD_NEW("E_Font_Fallback", + _e_config_font_fallback_edd = E_CONFIG_DD_NEW("E_Font_Fallback", E_Font_Fallback); #undef T #undef D @@ -289,7 +318,7 @@ e_config_init(void) #define D _e_config_font_fallback_edd E_CONFIG_VAL(D, T, name, STR); - _e_config_bindings_mouse_edd = E_CONFIG_DD_NEW("E_Config_Binding_Mouse", + _e_config_bindings_mouse_edd = E_CONFIG_DD_NEW("E_Config_Binding_Mouse", E_Config_Binding_Mouse); #undef T #undef D @@ -302,7 +331,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, button, UCHAR); E_CONFIG_VAL(D, T, any_mod, UCHAR); - _e_config_bindings_key_edd = E_CONFIG_DD_NEW("E_Config_Binding_Key", + _e_config_bindings_key_edd = E_CONFIG_DD_NEW("E_Config_Binding_Key", E_Config_Binding_Key); #undef T #undef D @@ -315,7 +344,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, params, STR); E_CONFIG_VAL(D, T, any_mod, UCHAR); - _e_config_bindings_edge_edd = E_CONFIG_DD_NEW("E_Config_Binding_Edge", + _e_config_bindings_edge_edd = E_CONFIG_DD_NEW("E_Config_Binding_Edge", E_Config_Binding_Edge); #undef T #undef D @@ -329,7 +358,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, any_mod, UCHAR); E_CONFIG_VAL(D, T, delay, FLOAT); - _e_config_bindings_signal_edd = E_CONFIG_DD_NEW("E_Config_Binding_Signal", + _e_config_bindings_signal_edd = E_CONFIG_DD_NEW("E_Config_Binding_Signal", E_Config_Binding_Signal); #undef T #undef D @@ -343,7 +372,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, action, STR); E_CONFIG_VAL(D, T, params, STR); - _e_config_bindings_wheel_edd = E_CONFIG_DD_NEW("E_Config_Binding_Wheel", + _e_config_bindings_wheel_edd = E_CONFIG_DD_NEW("E_Config_Binding_Wheel", E_Config_Binding_Wheel); #undef T #undef D @@ -357,7 +386,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, action, STR); E_CONFIG_VAL(D, T, params, STR); - _e_config_bindings_acpi_edd = E_CONFIG_DD_NEW("E_Config_Binding_Acpi", + _e_config_bindings_acpi_edd = E_CONFIG_DD_NEW("E_Config_Binding_Acpi", E_Config_Binding_Acpi); #undef T #undef D @@ -451,7 +480,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, b3, INT); E_CONFIG_VAL(D, T, a3, INT); - _e_config_mime_icon_edd = E_CONFIG_DD_NEW("E_Config_Mime_Icon", + _e_config_mime_icon_edd = E_CONFIG_DD_NEW("E_Config_Mime_Icon", E_Config_Mime_Icon); #undef T #undef D @@ -472,6 +501,95 @@ e_config_init(void) E_CONFIG_VAL(D, T, icon, STR); E_CONFIG_VAL(D, T, is_main, INT); + _e_config_screen_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size); +#undef T +#undef D +#define T Ecore_X_Randr_Screen_Size +#define D _e_config_screen_size_edd + E_CONFIG_VAL(D, T, width, INT); + E_CONFIG_VAL(D, T, height, INT); + E_CONFIG_VAL(D, T, width, INT); + E_CONFIG_VAL(D, T, height, INT); + + _e_config_screen_size_mm_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size_MM", Ecore_X_Randr_Screen_Size_MM); +#undef T +#undef D +#define T Ecore_X_Randr_Screen_Size_MM +#define D _e_config_screen_size_mm_edd + E_CONFIG_VAL(D, T, width, INT); + E_CONFIG_VAL(D, T, height, INT); + E_CONFIG_VAL(D, T, width_mm, INT); + E_CONFIG_VAL(D, T, height_mm, INT); + + _e_config_screen_restore_info_11_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11", E_Randr_Screen_Restore_Info_11); +#undef T +#undef D +#define T E_Randr_Screen_Restore_Info_11 +#define D _e_config_screen_restore_info_11_edd + E_CONFIG_SUB(D, T, size, _e_config_screen_size_edd); + E_CONFIG_VAL(D, T, orientation, INT); + E_CONFIG_VAL(D, T, refresh_rate, SHORT); + + _e_config_eina_rectangle_edd = E_CONFIG_DD_NEW("Eina_Rectangle", Eina_Rectangle); +#undef T +#undef D +#define T Eina_Rectangle +#define D _e_config_eina_rectangle_edd + E_CONFIG_VAL(D, T, x, INT); + E_CONFIG_VAL(D, T, y, INT); + E_CONFIG_VAL(D, T, w, INT); + E_CONFIG_VAL(D, T, h, INT); + + _e_config_screen_output_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Output_Restore_Info", Eina_Rectangle); +#undef T +#undef D +#define T E_Randr_Output_Restore_Info +#define D _e_config_screen_output_restore_info_edd + E_CONFIG_VAL(D, T, edid, STR); + E_CONFIG_VAL(D, T, backlight_level, DOUBLE); + + _e_config_screen_crtc_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Crtc_Restore_Info", E_Randr_Crtc_Restore_Info); +#undef T +#undef D +#define T E_Randr_Crtc_Restore_Info +#define D _e_config_screen_crtc_restore_info_edd + E_CONFIG_SUB(D, T, geometry, _e_config_eina_rectangle_edd); + E_CONFIG_LIST(D, T, outputs, _e_config_screen_output_restore_info_edd); + E_CONFIG_VAL(D, T, orientation, INT); + + _e_config_screen_restore_info_12_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12", E_Randr_Screen_Restore_Info_12); +#undef T +#undef D +#define T E_Randr_Screen_Restore_Info_12 +#define D _e_config_screen_restore_info_12_edd + E_CONFIG_LIST(D, T, crtcs, _e_config_screen_crtc_restore_info_edd); + E_CONFIG_VAL(D, T, output_policy, INT); + E_CONFIG_VAL(D, T, alignment, INT); + +#undef T +#undef D +#define T E_Randr_Screen_Restore_Info +#define D _e_config_screen_info_edd + Eet_Data_Descriptor_Class eddc; + Eet_Data_Descriptor *unified, *edd_11_info, *edd_12_info; + EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, T); + D = eet_data_descriptor_stream_new(&eddc); + eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; + eddc.func.type_get = _eet_union_type_get; + eddc.func.type_set = _eet_union_type_set; + //virtual types to work around EET's inability to differentiate when it + //comes to pointers (a->b) vs. values (a.b) in union mappings + edd_11_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11_Struct", E_Randr_Screen_Restore_Info_11); + E_CONFIG_SUB(edd_11_info, E_Randr_Screen_Restore_Info_Union, restore_info_11, _e_config_screen_restore_info_11_edd); + edd_12_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12_Struct", E_Randr_Screen_Restore_Info_12); + E_CONFIG_LIST(edd_12_info, E_Randr_Screen_Restore_Info_Union, restore_info_12, _e_config_screen_restore_info_12_edd); + unified = eet_data_descriptor_stream_new(&eddc); + EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_11", edd_11_info); + EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_12", edd_12_info); + EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_13", edd_12_info); + EET_DATA_DESCRIPTOR_ADD_UNION(D, T, "E_Randr_Screen_Restore_Info_Union", rrvd_restore_info, randr_version, unified); + E_CONFIG_VAL(D, T, randr_version, INT); + _e_config_edd = E_CONFIG_DD_NEW("E_Config", E_Config); #undef T #undef D @@ -631,12 +749,8 @@ e_config_init(void) E_CONFIG_VAL(D, T, desklock_ask_presentation, UCHAR); E_CONFIG_VAL(D, T, desklock_ask_presentation_timeout, DOUBLE); - E_CONFIG_VAL(D, T, display_res_restore, INT); - E_CONFIG_VAL(D, T, display_res_width, INT); - E_CONFIG_VAL(D, T, display_res_height, INT); - E_CONFIG_VAL(D, T, display_res_hz, INT); - E_CONFIG_VAL(D, T, display_res_rotation, INT); - + E_CONFIG_LIST(D, T, screen_info, _e_config_screen_info_edd); + E_CONFIG_VAL(D, T, screensaver_enable, INT); E_CONFIG_VAL(D, T, screensaver_timeout, INT); E_CONFIG_VAL(D, T, screensaver_interval, INT); @@ -652,7 +766,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, dpms_standby_timeout, INT); E_CONFIG_VAL(D, T, dpms_suspend_timeout, INT); E_CONFIG_VAL(D, T, dpms_off_timeout, INT); - + E_CONFIG_VAL(D, T, clientlist_group_by, INT); E_CONFIG_VAL(D, T, clientlist_include_all_zones, INT); E_CONFIG_VAL(D, T, clientlist_separate_with, INT); @@ -661,7 +775,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, clientlist_warp_to_iconified_desktop, INT); E_CONFIG_VAL(D, T, clientlist_limit_caption_len, INT); E_CONFIG_VAL(D, T, clientlist_max_caption_len, INT); - + E_CONFIG_VAL(D, T, mouse_hand, INT); E_CONFIG_VAL(D, T, mouse_accel_numerator, INT); E_CONFIG_VAL(D, T, mouse_accel_denominator, INT); @@ -674,14 +788,14 @@ e_config_init(void) E_CONFIG_VAL(D, T, icon_theme, STR); E_CONFIG_VAL(D, T, icon_theme_overrides, UCHAR); - + E_CONFIG_VAL(D, T, desk_flip_animate_mode, INT); E_CONFIG_VAL(D, T, desk_flip_animate_interpolation, INT); E_CONFIG_VAL(D, T, desk_flip_animate_time, DOUBLE); E_CONFIG_VAL(D, T, desk_flip_pan_bg, UCHAR); E_CONFIG_VAL(D, T, desk_flip_pan_x_axis_factor, DOUBLE); E_CONFIG_VAL(D, T, desk_flip_pan_y_axis_factor, DOUBLE); - + E_CONFIG_VAL(D, T, wallpaper_import_last_dev, STR); E_CONFIG_VAL(D, T, wallpaper_import_last_path, STR); @@ -693,7 +807,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, wallpaper_grad_c2_b, INT); E_CONFIG_VAL(D, T, theme_default_border_style, STR); - + E_CONFIG_LIST(D, T, mime_icons, _e_config_mime_icon_edd); /**/ E_CONFIG_VAL(D, T, desk_auto_switch, INT); @@ -702,7 +816,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, menu_favorites_show, INT); E_CONFIG_VAL(D, T, menu_apps_show, INT); - + E_CONFIG_VAL(D, T, ping_clients_interval, INT); E_CONFIG_VAL(D, T, cache_flush_poll_interval, INT); @@ -710,7 +824,7 @@ e_config_init(void) E_CONFIG_VAL(D, T, thumbscroll_threshhold, INT); E_CONFIG_VAL(D, T, thumbscroll_momentum_threshhold, DOUBLE); E_CONFIG_VAL(D, T, thumbscroll_friction, DOUBLE); - + E_CONFIG_VAL(D, T, dbus_desktop, INT); E_CONFIG_VAL(D, T, dbus_auto_mount, INT); E_CONFIG_VAL(D, T, dbus_auto_open, INT); @@ -748,9 +862,9 @@ e_config_init(void) E_CONFIG_VAL(D, T, exec.expire_timeout, DOUBLE); E_CONFIG_VAL(D, T, exec.show_run_dialog, UCHAR); E_CONFIG_VAL(D, T, exec.show_exit_dialog, UCHAR); - + e_config_load(); - + e_config_save_queue(); return 1; } @@ -780,6 +894,7 @@ e_config_shutdown(void) E_CONFIG_DD_FREE(_e_config_shelf_desk_edd); E_CONFIG_DD_FREE(_e_config_mime_icon_edd); E_CONFIG_DD_FREE(_e_config_syscon_action_edd); + E_CONFIG_DD_FREE(_e_config_screen_info_edd); return 1; } @@ -787,12 +902,12 @@ EAPI void e_config_load(void) { E_Config *tcfg = NULL; - + e_config = e_config_domain_load("e", _e_config_edd); if (e_config) { int reload = 0; - + /* major version change - that means wipe and restart */ if ((e_config->config_version >> 16) < E_CONFIG_FILE_EPOCH) { @@ -871,7 +986,7 @@ e_config_load(void) if (!tcfg) { const char *pprofile; - + pprofile = e_config_profile_get(); if (pprofile) pprofile = eina_stringshare_add(pprofile); e_config_profile_set("standard"); @@ -884,7 +999,7 @@ e_config_load(void) if (!tcfg) { E_Action *a; - + e_config_profile_set("default"); e_config_profile_del(e_config_profile_get()); e_config_save_block_set(1); @@ -907,11 +1022,11 @@ e_config_load(void) COPYVAL(thumbscroll_momentum_threshhold); COPYVAL(thumbscroll_friction); IFCFGEND; - + IFCFG(0x0125); COPYVAL(mouse_hand); IFCFGEND; - + IFCFG(0x0126); COPYVAL(border_keyboard.timeout); COPYVAL(border_keyboard.move.dx); @@ -919,7 +1034,7 @@ e_config_load(void) COPYVAL(border_keyboard.resize.dx); COPYVAL(border_keyboard.resize.dy); IFCFGEND; - + IFCFG(0x0127); COPYVAL(scale.min); COPYVAL(scale.max); @@ -928,24 +1043,24 @@ e_config_load(void) COPYVAL(scale.use_dpi); COPYVAL(scale.use_custom); IFCFGEND; - + IFCFG(0x0128); COPYVAL(show_cursor); COPYVAL(idle_cursor); IFCFGEND; - + IFCFG(0x0129); COPYSTR(default_system_menu); IFCFGEND; - + IFCFG(0x012a); COPYVAL(desklock_start_locked); IFCFGEND; - + IFCFG(0x012b); COPYVAL(cfgdlg_normal_wins); IFCFGEND; - + IFCFG(0x012c); COPYVAL(syscon.main.icon_size); COPYVAL(syscon.secondary.icon_size); @@ -954,15 +1069,15 @@ e_config_load(void) COPYVAL(syscon.do_input); COPYPTR(syscon.actions); IFCFGEND; - + IFCFG(0x012d); COPYVAL(priority); IFCFGEND; - + IFCFG(0x012e); COPYVAL(fullscreen_flip); IFCFGEND; - + IFCFG(0x012f); COPYVAL(icon_theme_overrides); IFCFGEND; @@ -1008,7 +1123,7 @@ e_config_load(void) COPYVAL(geometry_auto_move); IFCFGEND; - e_config->config_version = E_CONFIG_FILE_VERSION; + e_config->config_version = E_CONFIG_FILE_VERSION; _e_config_free(tcfg); } @@ -1044,8 +1159,8 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->desk_resist, 0, 100); E_CONFIG_LIMIT(e_config->window_resist, 0, 100); E_CONFIG_LIMIT(e_config->gadget_resist, 0, 100); - E_CONFIG_LIMIT(e_config->geometry_auto_move, 0, 1); - E_CONFIG_LIMIT(e_config->geometry_auto_resize_limit, 0, 1); + E_CONFIG_LIMIT(e_config->geometry_auto_move, 0, 1); + E_CONFIG_LIMIT(e_config->geometry_auto_resize_limit, 0, 1); E_CONFIG_LIMIT(e_config->winlist_warp_while_selecting, 0, 1); E_CONFIG_LIMIT(e_config->winlist_warp_at_end, 0, 1); E_CONFIG_LIMIT(e_config->winlist_warp_speed, 0.0, 1.0); @@ -1102,11 +1217,6 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->desklock_use_custom_desklock, 0, 1); E_CONFIG_LIMIT(e_config->desklock_ask_presentation, 0, 1); E_CONFIG_LIMIT(e_config->desklock_ask_presentation_timeout, 1.0, 300.0); - E_CONFIG_LIMIT(e_config->display_res_restore, 0, 1); - E_CONFIG_LIMIT(e_config->display_res_width, 1, 8192); - E_CONFIG_LIMIT(e_config->display_res_height, 1, 8192); - E_CONFIG_LIMIT(e_config->display_res_hz, 0, 250); - E_CONFIG_LIMIT(e_config->display_res_rotation, 0, 0xff); E_CONFIG_LIMIT(e_config->border_raise_on_mouse_action, 0, 1); E_CONFIG_LIMIT(e_config->border_raise_on_focus, 0, 1); E_CONFIG_LIMIT(e_config->desk_flip_wrap, 0, 1); @@ -1142,7 +1252,7 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->mouse_hand, 0, 1); E_CONFIG_LIMIT(e_config->clientlist_limit_caption_len, 0, 1); E_CONFIG_LIMIT(e_config->clientlist_max_caption_len, 2, E_CLIENTLIST_MAX_CAPTION_LEN); - + E_CONFIG_LIMIT(e_config->mouse_accel_numerator, 1, 10); E_CONFIG_LIMIT(e_config->mouse_accel_denominator, 1, 10); E_CONFIG_LIMIT(e_config->mouse_accel_threshold, 1, 10); @@ -1158,7 +1268,7 @@ e_config_load(void) E_CONFIG_LIMIT(e_config->exec.expire_timeout, 0.1, 1000); E_CONFIG_LIMIT(e_config->exec.show_run_dialog, 0, 1); E_CONFIG_LIMIT(e_config->exec.show_exit_dialog, 0, 1); - + /* FIXME: disabled auto apply because it causes problems */ e_config->cfgdlg_auto_apply = 0; /* FIXME: desklock personalized password id disabled for security reasons */ @@ -1375,7 +1485,7 @@ e_config_domain_load(const char *domain, E_Config_DD *edd) eet_close(ef); if (data) return data; } - + for (i =1; i <= _e_config_revisions; i++) { e_user_dir_snprintf(buf, sizeof(buf), "config/%s/%s.%i.cfg", @@ -1425,17 +1535,17 @@ e_config_profile_save(void) ef = eet_open(buf2, EET_FILE_MODE_WRITE); if (ef) { - ok = eet_write(ef, "config", _e_config_profile, + ok = eet_write(ef, "config", _e_config_profile, strlen(_e_config_profile), 0); if (_e_config_eet_close_handle(ef, buf2)) { int ret; - + if (_e_config_revisions > 0) { int i; char bsrc[4096], bdst[4096]; - + for (i = _e_config_revisions; i > 1; i--) { e_user_dir_snprintf(bsrc, sizeof(bsrc), "config/profile.%i.cfg", i - 1); @@ -1497,7 +1607,7 @@ e_config_domain_save(const char *domain, E_Config_DD *edd, const void *data) { int i; char bsrc[4096], bdst[4096]; - + for (i = _e_config_revisions; i > 1; i--) { e_user_dir_snprintf(bsrc, sizeof(bsrc), "config/%s/%s.%i.cfg", _e_config_profile, domain, i - 1); @@ -1525,7 +1635,7 @@ e_config_binding_mouse_match(E_Config_Binding_Mouse *eb_in) Eina_List *l; E_Config_Binding_Mouse *eb; - EINA_LIST_FOREACH(e_config->mouse_bindings, l, eb) + EINA_LIST_FOREACH(e_config->mouse_bindings, l, eb) { if ((eb->context == eb_in->context) && (eb->button == eb_in->button) && @@ -1545,8 +1655,8 @@ e_config_binding_key_match(E_Config_Binding_Key *eb_in) { Eina_List *l; E_Config_Binding_Key *eb; - - EINA_LIST_FOREACH(e_config->mouse_bindings, l, eb) + + EINA_LIST_FOREACH(e_config->mouse_bindings, l, eb) { if ((eb->context == eb_in->context) && (eb->modifiers == eb_in->modifiers) && @@ -1567,7 +1677,7 @@ e_config_binding_edge_match(E_Config_Binding_Edge *eb_in) { Eina_List *l; E_Config_Binding_Edge *eb; - + EINA_LIST_FOREACH(e_config->edge_bindings, l, eb) { if ((eb->context == eb_in->context) && @@ -1589,7 +1699,7 @@ e_config_binding_signal_match(E_Config_Binding_Signal *eb_in) { Eina_List *l; E_Config_Binding_Signal *eb; - + EINA_LIST_FOREACH(e_config->signal_bindings, l, eb) { if ((eb->context == eb_in->context) && @@ -1631,7 +1741,7 @@ e_config_binding_wheel_match(E_Config_Binding_Wheel *eb_in) } EAPI E_Config_Binding_Acpi * -e_config_binding_acpi_match(E_Config_Binding_Acpi *eb_in) +e_config_binding_acpi_match(E_Config_Binding_Acpi *eb_in) { Eina_List *l; E_Config_Binding_Acpi *eb; @@ -1639,12 +1749,12 @@ e_config_binding_acpi_match(E_Config_Binding_Acpi *eb_in) EINA_LIST_FOREACH(e_config->acpi_bindings, l, eb) { if ((eb->context == eb_in->context) && - (eb->type == eb_in->type) && - (eb->status == eb_in->status) && - (((eb->action) && (eb_in->action) && + (eb->type == eb_in->type) && + (eb->status == eb_in->status) && + (((eb->action) && (eb_in->action) && (!strcmp(eb->action, eb_in->action))) || ((!eb->action) && (!eb_in->action))) && - (((eb->params) && (eb_in->params) && + (((eb->params) && (eb_in->params) && (!strcmp(eb->params, eb_in->params))) || ((!eb->params) && (!eb_in->params)))) return eb; @@ -1685,7 +1795,12 @@ _e_config_free(E_Config *ecf) E_Color_Class *cc; E_Path_Dir *epd; E_Remember *rem; - + E_Randr_Screen_Restore_Info *screen_info; + E_Randr_Crtc_Restore_Info *crtc_info; + E_Randr_Output_Info *output_info; + E_Randr_Screen_Restore_Info_12 *restore_info_12; + + if (!ecf) return; EINA_LIST_FREE(ecf->modules, em) @@ -1798,7 +1913,7 @@ _e_config_free(E_Config *ecf) { if (rem->name) eina_stringshare_del(rem->name); if (rem->class) eina_stringshare_del(rem->class); - if (rem->title) eina_stringshare_del(rem->title); + if (rem->title) eina_stringshare_del(rem->title); if (rem->role) eina_stringshare_del(rem->role); if (rem->prop.border) eina_stringshare_del(rem->prop.border); if (rem->prop.command) eina_stringshare_del(rem->prop.command); @@ -1833,6 +1948,37 @@ _e_config_free(E_Config *ecf) if (sca->icon) eina_stringshare_del(sca->icon); E_FREE(sca); } + if (ecf->screen_info) + { + EINA_LIST_FREE(ecf->screen_info, screen_info) + { + switch (screen_info->randr_version) + { + case EET_SCREEN_INFO_11: + free(screen_info->rrvd_restore_info.restore_info_11); + break; + case EET_SCREEN_INFO_12: + case EET_SCREEN_INFO_13: + EINA_LIST_FREE(screen_info->rrvd_restore_info.restore_info_12, restore_info_12) + { + EINA_LIST_FREE(restore_info_12->crtcs, crtc_info) + { + EINA_LIST_FREE(crtc_info->outputs, output_info) + { + free(output_info->name); + free(output_info->edid); + free (output_info); + } + free (crtc_info); + } + free(restore_info_12); + } + eina_list_free(screen_info->rrvd_restore_info.restore_info_12); + break; + } + free(screen_info); + } + } E_FREE(ecf); } @@ -1857,7 +2003,7 @@ _e_config_eet_close_handle(Eet_File *ef, char *file) { Eet_Error err; char *erstr = NULL; - + err = eet_close(ef); switch (err) { @@ -1951,8 +2097,8 @@ _e_config_eet_close_handle(Eet_File *ef, char *file) return 1; } -static void -_e_config_acpi_bindings_add(void) +static void +_e_config_acpi_bindings_add(void) { E_Config_Binding_Acpi *bind; @@ -1996,3 +2142,36 @@ _e_config_acpi_bindings_add(void) bind->params = eina_stringshare_add("now"); e_config->acpi_bindings = eina_list_append(e_config->acpi_bindings, bind); } + +static const char * +_eet_union_type_get(const void *data, Eina_Bool *unknow) +{ + const Eet_Union *u = data; + int i; + + if (unknow) *unknow = EINA_FALSE; + for (i = 0; eet_mapping[i].name != NULL; ++i) + if (*u == eet_mapping[i].u) + return eet_mapping[i].name; + + if (unknow) *unknow = EINA_TRUE; + return NULL; +} + +static Eina_Bool +_eet_union_type_set(const char *type, void *data, Eina_Bool unknow) +{ + Eet_Union *u = data; + int i; + + if (unknow) return EINA_FALSE; + + for (i = 0; eet_mapping[i].name != NULL; ++i) + if (strcmp(eet_mapping[i].name, type) == 0) + { + *u = eet_mapping[i].u; + return EINA_TRUE; + } + + return EINA_FALSE; +} \ No newline at end of file diff --git a/src/bin/e_config.h b/src/bin/e_config.h index 29e35e96b..1880c5aab 100644 --- a/src/bin/e_config.h +++ b/src/bin/e_config.h @@ -25,14 +25,14 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme; #ifndef E_CONFIG_H #define E_CONFIG_H -/* increment this whenever we change config enough that you need new +/* increment this whenever we change config enough that you need new * defaults for e to work. */ #define E_CONFIG_FILE_EPOCH 0x0001 /* increment this whenever a new set of config values are added but the users * config doesn't need to be wiped - simply new values need to be put in */ -#define E_CONFIG_FILE_GENERATION 0x0138 +#define E_CONFIG_FILE_GENERATION 0x0140 #define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION) #define E_EVAS_ENGINE_DEFAULT 0 @@ -194,7 +194,7 @@ struct _E_Config int use_app_icon; // GUI int cnfmdlg_disabled; // GUI int cfgdlg_auto_apply; // GUI - int cfgdlg_default_mode; // GUI + int cfgdlg_default_mode; // GUI Eina_List *gadcons; // GUI Eina_List *shelves; // GUI int font_hinting; // GUI @@ -221,7 +221,7 @@ struct _E_Config int screensaver_expose; // GUI Eina_Bool screensaver_ask_presentation; // GUI double screensaver_ask_presentation_timeout; // GUI - + int dpms_enable; // GUI int dpms_standby_enable; // GUI int dpms_standby_timeout; // GUI @@ -243,12 +243,9 @@ struct _E_Config int mouse_accel_numerator; // GUI int mouse_accel_denominator; // GUI int mouse_accel_threshold; // GUI - - int display_res_restore; // GUI - int display_res_width; // GUI - int display_res_height; // GUI - int display_res_hz; // GUI - int display_res_rotation; // GUI + + Eina_List *screen_info; // GUI + int border_raise_on_mouse_action; // GUI int border_raise_on_focus; // GUI int desk_flip_wrap; // GUI @@ -256,14 +253,14 @@ struct _E_Config const char *icon_theme; // GUI Eina_Bool icon_theme_overrides; // GUI - + int desk_flip_animate_mode; // GUI int desk_flip_animate_interpolation; // GUI double desk_flip_animate_time; // GUI Eina_Bool desk_flip_pan_bg; double desk_flip_pan_x_axis_factor; double desk_flip_pan_y_axis_factor; - + const char *wallpaper_import_last_dev; // INTERNAL const char *wallpaper_import_last_path; // INTERNAL @@ -275,15 +272,15 @@ struct _E_Config int wallpaper_grad_c2_b; // INTERNAL const char *theme_default_border_style; // GUI - + Eina_List *mime_icons; // GUI int desk_auto_switch; // GUI; int thumb_nice; - + int ping_clients_interval; int cache_flush_poll_interval; // GUI - + int thumbscroll_enable; // GUI int thumbscroll_threshhold; // GUI double thumbscroll_momentum_threshhold; // GUI @@ -304,7 +301,7 @@ struct _E_Config unsigned char dy; } resize; } border_keyboard; - + struct { double min; // GUI double max; // GUI @@ -316,11 +313,11 @@ struct _E_Config unsigned char show_cursor; // GUI unsigned char idle_cursor; // GUI - + const char *default_system_menu; unsigned char cfgdlg_normal_wins; // GUI - + struct { struct { int icon_size; @@ -334,7 +331,7 @@ struct _E_Config Eina_Bool presentation; Eina_Bool offline; } mode; - + struct { double expire_timeout; Eina_Bool show_run_dialog; @@ -418,7 +415,7 @@ struct _E_Config_Binding_Wheel const char *params; }; -struct _E_Config_Binding_Acpi +struct _E_Config_Binding_Acpi { int context, type, status; const char *action, *params; @@ -508,7 +505,7 @@ EAPI int e_config_init(void); EAPI int e_config_shutdown(void); EAPI void e_config_load(void); - + EAPI int e_config_save(void); EAPI void e_config_save_flush(void); EAPI void e_config_save_queue(void); @@ -524,7 +521,7 @@ EAPI Eina_List *e_config_engine_list(void); EAPI void e_config_save_block_set(int block); EAPI int e_config_save_block_get(void); - + EAPI void *e_config_domain_load(const char *domain, E_Config_DD *edd); EAPI void *e_config_domain_system_load(const char *domain, E_Config_DD *edd); EAPI int e_config_profile_save(void); diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index 1f18433b9..fab763dbe 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -31,6 +31,7 @@ #include "e_hints.h" #include "e_signals.h" #include "e_xinerama.h" +#include "e_randr.h" #include "e_table.h" #include "e_layout.h" #include "e_font.h" diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 69f01b76b..57e02a683 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -500,6 +500,16 @@ main(int argc, char **argv) } _e_main_shutdown_push(e_xinerama_shutdown); + TS("randr"); + if (!e_randr_init()) + { + e_error_message_show(_("Enlightenment cannot setup randr wrapping.\n" + "This should not happen.")); + _e_main_shutdown(-1); + } + _e_main_shutdown_push(e_randr_shutdown); + + /* ecore_x_grab(); */ ecore_x_io_error_handler_set(_e_main_cb_x_fatal, NULL); diff --git a/src/bin/e_manager.c b/src/bin/e_manager.c index d05fc6056..db899e1d3 100644 --- a/src/bin/e_manager.c +++ b/src/bin/e_manager.c @@ -105,26 +105,6 @@ e_manager_new(Ecore_X_Window root, int num) man->win = man->root; } - /* FIXME: this handles 1 screen only - not multihead. multihead randr - * and xinerama are complex oin terms of interaction, so for now only - * really have this work in single head. the randr module kept this - * as a list, and i might move it to be the same too, but for now, keep - * it as is - */ - if (e_config->display_res_restore) - { - Ecore_X_Screen_Size size; - Ecore_X_Screen_Refresh_Rate rate; - - size.width = e_config->display_res_width; - size.height = e_config->display_res_height; - rate.rate = e_config->display_res_hz; - ecore_x_randr_screen_refresh_rate_set(man->root, size, rate); - if (e_config->display_res_rotation) - ecore_x_randr_screen_rotation_set(man->root, - e_config->display_res_rotation); - } - h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_SHOW_REQUEST, _e_manager_cb_window_show_request, man); if (h) man->handlers = eina_list_append(man->handlers, h); h = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CONFIGURE, _e_manager_cb_window_configure, man); @@ -153,7 +133,7 @@ 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 + /* 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) @@ -169,7 +149,7 @@ e_manager_manage_windows(E_Manager *man) Ecore_X_Atom atom_xmbed, atom_kde_netwm_systray, atom_kwm_dockwindow; unsigned char *data = NULL; int count; - + ecore_x_atoms_get(atom_names, 3, atoms); atom_xmbed = atoms[0]; atom_kde_netwm_systray = atoms[1]; @@ -188,8 +168,8 @@ e_manager_manage_windows(E_Manager *man) if (att.override) { char *wname = NULL, *wclass = NULL; - - ecore_x_icccm_name_class_get(windows[i], + + ecore_x_icccm_name_class_get(windows[i], &wname, &wclass); if ((wname) && (wclass) && (!strcmp(wname, "E")) && @@ -251,7 +231,7 @@ e_manager_manage_windows(E_Manager *man) char *path; Efreet_Desktop *desktop = NULL; - /* get all information from window before it is + /* 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, @@ -260,7 +240,7 @@ e_manager_manage_windows(E_Manager *man) con = e_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); @@ -305,7 +285,7 @@ e_manager_manage_windows(E_Manager *man) * should be seen */ E_Container *con; E_Border *bd; - + con = e_container_current_get(man); bd = e_border_new(con, windows[i], 1, 0); if (bd) @@ -324,7 +304,7 @@ e_manager_show(E_Manager *man) { Eina_List *l; E_Container *con; - + E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (man->visible) return; @@ -335,7 +315,7 @@ e_manager_show(E_Manager *man) if (man->root != man->win) { Ecore_X_Window mwin; - + mwin = e_menu_grab_window_get(); if (!mwin) mwin = man->initwin; if (!mwin) @@ -356,7 +336,7 @@ e_manager_hide(E_Manager *man) { Eina_List *l; E_Container *con; - + E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if (!man->visible) return; @@ -366,7 +346,7 @@ e_manager_hide(E_Manager *man) } if (man->root != man->win) ecore_x_window_hide(man->win); - man->visible = 0; + man->visible = 0; } EAPI void @@ -388,7 +368,7 @@ e_manager_resize(E_Manager *man, int w, int h) { Eina_List *l; E_Container *con; - + E_OBJECT_CHECK(man); E_OBJECT_TYPE_CHECK(man, E_MANAGER_TYPE); if ((w == man->w) && (h == man->h)) return; @@ -396,7 +376,7 @@ e_manager_resize(E_Manager *man, int w, int h) man->h = h; if (man->root != man->win) ecore_x_window_resize(man->win, man->w, man->h); - + EINA_LIST_FOREACH(man->containers, l, con) { e_container_resize(con, man->w, man->h); @@ -410,7 +390,7 @@ e_manager_move_resize(E_Manager *man, int x, int y, int w, int h) { Eina_List *l; E_Container *con; - + 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; @@ -437,7 +417,7 @@ e_manager_raise(E_Manager *man) if (man->root != man->win) { Ecore_X_Window mwin; - + mwin = e_menu_grab_window_get(); if (!mwin) mwin = man->initwin; if (!mwin) @@ -466,7 +446,7 @@ e_manager_current_get(void) Eina_List *l; E_Manager *man; int x, y; - + if (!managers) return NULL; EINA_LIST_FOREACH(managers, l, man) { @@ -484,7 +464,7 @@ e_manager_number_get(int num) { Eina_List *l; E_Manager *man; - + if (!managers) return NULL; EINA_LIST_FOREACH(managers, l, man) { @@ -511,7 +491,7 @@ e_managers_keys_ungrab(void) { Eina_List *l; E_Manager *man; - + EINA_LIST_FOREACH(managers, l, man) { e_bindings_key_ungrab(E_BINDING_CONTEXT_ANY, man->root); @@ -674,7 +654,7 @@ _e_manager_free(E_Manager *man) ecore_x_window_free(man->win); } if (man->pointer) e_object_del(E_OBJECT(man->pointer)); - managers = eina_list_remove(managers, man); + managers = eina_list_remove(managers, man); free(man); } @@ -710,7 +690,7 @@ _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 ECORE_CALLBACK_PASS_ON; @@ -723,7 +703,7 @@ _e_manager_cb_key_down(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; Ecore_Event_Key *e; - + man = data; e = ev; @@ -739,7 +719,7 @@ _e_manager_cb_key_up(void *data, int ev_type __UNUSED__, void *ev) { E_Manager *man; Ecore_Event_Key *e; - + man = data; e = ev; @@ -763,7 +743,7 @@ _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev const char *border, *signal, *key; int ok; unsigned int i, num; - + man = data; con = e_container_current_get(man); e = ev; @@ -787,7 +767,7 @@ _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev ok = ecore_x_netwm_window_type_get(e->win, &type); if ((ok) && - ((type == ECORE_X_WINDOW_TYPE_DESKTOP) || + ((type == ECORE_X_WINDOW_TYPE_DESKTOP) || (type == ECORE_X_WINDOW_TYPE_DOCK))) { border = "borderless"; @@ -861,7 +841,7 @@ _e_manager_cb_frame_extents_request(void *data, int ev_type __UNUSED__, void *ev evas_object_resize(o, 1000, 1000); edje_object_calc_force(o); - edje_object_part_geometry_get(o, "e.swallow.client", + edje_object_part_geometry_get(o, "e.swallow.client", &x, &y, &w, &h); extents->l = x; extents->r = 1000 - (x + w); @@ -892,7 +872,7 @@ _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; @@ -948,15 +928,15 @@ _e_manager_cb_client_message(__UNUSED__ void *data, __UNUSED__ int ev_type, void { Ecore_X_Event_Client_Message *e; E_Border *bd; - + e = ev; - + if (e->message_type == ECORE_X_ATOM_NET_ACTIVE_WINDOW) { bd = e_border_find_by_client_window(e->win); if ((bd) && (!bd->focused)) { -#if 0 /* notes */ +#if 0 /* notes */ if (e->data.l[0] == 0 /* 0 == old, 1 == client, 2 == pager */) { // FIXME: need config for the below - what to do given each @@ -971,23 +951,23 @@ _e_manager_cb_client_message(__UNUSED__ void *data, __UNUSED__ int ev_type, void requestor_id e->data.l[2]; #endif if ((e_config->focus_setting == E_FOCUS_NEW_WINDOW) || - ((bd->parent) && + ((bd->parent) && ((e_config->focus_setting == E_FOCUS_NEW_DIALOG) || - ((bd->parent->focused) && + ((bd->parent->focused) && (e_config->focus_setting == E_FOCUS_NEW_DIALOG_IF_OWNER_FOCUSED))))) { if (bd->iconic) { if (e_config->clientlist_warp_to_iconified_desktop == 1) e_desk_show(bd->desk); - + if (!bd->lock_user_iconify) e_border_uniconify(bd); } if (!bd->iconic) e_desk_show(bd->desk); if (!bd->lock_user_stacking) e_border_raise(bd); if (!bd->lock_focus_out) - { + { if (e_config->focus_policy != E_FOCUS_CLICK) ecore_x_pointer_warp(bd->zone->container->win, bd->x + (bd->w / 2), bd->y + (bd->h / 2)); diff --git a/src/bin/e_randr.c b/src/bin/e_randr.c new file mode 100644 index 000000000..a434f7130 --- /dev/null +++ b/src/bin/e_randr.c @@ -0,0 +1,1749 @@ +/* + * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" +#include +#include +#include "e_randr.h" + +#define ECORE_X_RANDR_1_1 ((1 << 16) | 1) +#define ECORE_X_RANDR_1_2 ((1 << 16) | 2) +#define ECORE_X_RANDR_1_3 ((1 << 16) | 3) + +#define Ecore_X_Randr_None 0 +#define Ecore_X_Randr_Unset -1 + +/* + * TODO: + * -fix output policies above and left + */ + +//following macro namescheme follows cardinal relation +//1 : M +#define E_RANDR_NO_SCREEN_RET(ret) if (!e_randr_screen_info) return ret +#define E_RANDR_NO_11_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1) || !e_randr_screen_info->rrvd_info.randr_info_11) return ret +#define E_RANDR_NO_12_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12) return ret +#define E_RANDR_NO_CRTCS_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs) return ret +#define E_RANDR_NO_OUTPUTS_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs) return ret +#define E_RANDR_NO_CRTC_RET(crtc, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc) return ret +#define E_RANDR_NO_OUTPUT_RET(output, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) return ret +#define E_RANDR_NO_MODE_RET(mode, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode) return ret +#define E_RANDR_NO_CRTC_OUTPUT_RET(crtc, output, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) return ret +#define E_RANDR_NO_CRTC_OUTPUT_MODE_RET(crtc, output, mode, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode) return ret + +#define E_RANDR_NO_11 (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1) || !e_randr_screen_info->rrvd_info.randr_info_11) +#define E_RANDR_NO_12 (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12) +#define E_RANDR_NO_CRTCS (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs) +#define E_RANDR_NO_OUTPUTS (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs) +#define E_RANDR_NO_MODES (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->modes) +#define E_RANDR_NO_CRTC(crtc) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc) +#define E_RANDR_NO_OUTPUT(output) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) +#define E_RANDR_NO_CRTC_OUTPUT(crtc, output) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) +#define E_RANDR_NO_CRTC_OUTPUT_MODE(crtc, output, mode) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode) + + +static Eina_Bool _e_randr_init (void); +static void _e_randr_shutdown (void); +static inline void _e_randr_event_listeners_add (void); +static inline void _e_randr_event_listeners_remove (void); +static Eina_Bool _e_randr_event_cb (void *data, int type, void *e); +static E_Randr_Screen_Info * _e_randr_screen_info_new (void); +static void _e_randr_screen_info_free (E_Randr_Screen_Info *screen_info); +static E_Randr_Screen_Info_11 * _e_randr_screen_info_11_new (void); +static const Eina_Bool _e_randr_screen_info_11_set (void); +static void _e_randr_screen_info_11_free (E_Randr_Screen_Info_11 *screen_info_11); +static E_Randr_Screen_Info_12 * _e_randr_screen_info_12_new (void); +static const Eina_Bool _e_randr_screen_info_12_set (E_Randr_Screen_Info_12 *screen_info_12); +static void _e_randr_screen_info_12_free (E_Randr_Screen_Info_12 *screen_info_12); +static E_Randr_Output_Info * _e_randr_output_info_new (int nrequested); +static void _e_randr_output_info_free (E_Randr_Output_Info *output_info); +static E_Randr_Crtc_Info * _e_randr_crtc_info_new (int nrequested); +static void _e_randr_crtc_info_free (E_Randr_Crtc_Info *crtc_info); +static inline Eina_Bool _e_randr_screen_outputs_init (void); +static inline Eina_Bool _e_randr_screen_crtcs_init (void); +static inline Eina_Bool _e_randr_output_modes_add (E_Randr_Output_Info *output_info); +static inline void _e_randr_notify_crtc_mode_change (E_Randr_Crtc_Info *crtc_info); +static inline void _e_randr_notify_output_change (E_Randr_Output_Info *output_info); +static inline Ecore_X_Randr_Mode_Info * _e_randr_mode_info_get (Ecore_X_Randr_Mode mode); +static inline E_Randr_Crtc_Info * _e_randr_crtc_info_get (Ecore_X_Randr_Crtc crtc); +static inline E_Randr_Output_Info * _e_randr_output_info_get (Ecore_X_Randr_Output output); +static void _e_randr_output_info_set (E_Randr_Output_Info *output_info); +static const inline Eina_Bool _e_randr_outputs_connected (Eina_List *outputs_info); +static void _e_randr_crtc_info_set (E_Randr_Crtc_Info *crtc_info); +static const inline E_Randr_Crtc_Info * _e_randr_policy_crtc_get (E_Randr_Crtc_Info* but, E_Randr_Crtc_Info *hint, Ecore_X_Randr_Output_Policy policy); +static const inline Eina_Bool _e_randr_outputs_connected (Eina_List *outputs_info); +static inline Ecore_X_Randr_Output * _e_randr_outputs_to_array (Eina_List *outputs_info); +static int _e_randr_config_find_suiting_config_11 (E_Randr_Screen_Restore_Info_11** restore_info); +static inline E_Randr_Screen_Restore_Info_12 * _e_randr_config_find_suiting_config_12 (void); +static Eina_Bool _e_randr_config_enable_11 (int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation); +static Eina_Bool _e_randr_config_enable_12 (const E_Randr_Screen_Restore_Info_12 *restore_info); +static Eina_Bool _e_randr_try_enable_output (E_Randr_Output_Info *output_info, Eina_Bool force); +static void _e_randr_crtcs_possible_output_update (E_Randr_Output_Info *output_info); +static void _e_randr_crtc_outputs_refs_update (E_Randr_Crtc_Info *crtc_info); +static Eina_Bool _e_randr_crtc_move_policy (E_Randr_Crtc_Info *new_crtc); +static int _crtcs_size_sort_cb (const void *d1, const void *d2); +static int _outputs_size_sort_cb (const void *d1, const void *d2); +static int _modes_size_sort_cb (const void *d1, const void *d2); +static Eina_List * _e_randr_outputs_common_modes_get (Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode); +static Ecore_X_Randr_Mode_Info * _e_randr_outputs_common_mode_max_get (Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode); +static inline Ecore_X_Randr_Mode_Info * _e_randr_mode_geo_identical_find (Eina_List *modes, Ecore_X_Randr_Mode_Info *mode); +static inline Eina_Bool _e_randr_crtc_mode_intersects_crtcs (E_Randr_Crtc_Info *crtc_info, Ecore_X_Randr_Mode_Info *mode); +static inline Eina_Bool _e_randr_crtc_outputs_mode_max_set (E_Randr_Crtc_Info *crtc_info); +static Eina_Bool _e_randr_crtcs_clone_crtc_removed (E_Randr_Crtc_Info *former_clone); +static void _e_randr_screen_primary_output_assign (E_Randr_Output_Info *removed); +static void _e_randr_output_info_hw_info_set (E_Randr_Output_Info *output_info); +static void _e_randr_output_hw_info_free (E_Randr_Output_Info *output_info); +static const inline Eina_Bool _e_randr_outputs_are_clones (E_Randr_Output_Info *output_info, Eina_List *outputs); + +E_Randr_Screen_Info * e_randr_screen_info = NULL; +static Eina_List * _e_randr_event_handlers = NULL; + + EAPI Eina_Bool +e_randr_init(void) +{ + return _e_randr_init(); +} + + EAPI int +e_randr_shutdown(void) +{ + _e_randr_shutdown(); + return 1; +} + + static Eina_Bool +_e_randr_init(void) +{ + int n; + Ecore_X_Window *roots; + Ecore_X_Window root; + + if(!(roots = ecore_x_window_root_list(&n))) return EINA_FALSE; + /* first (and only) root window */ + root = roots[0]; + free(roots); + + if (!eina_init()) return EINA_FALSE; + if (!ecore_init()) goto ecore_x_randr_init_fail_eina_shutdown; + + if (!ecore_x_randr_query() || !(e_randr_screen_info = _e_randr_screen_info_new())) goto ecore_x_randr_init_fail_ecore_shutdown; + + if ((e_randr_screen_info->randr_version = ecore_x_randr_version_get())) e_randr_screen_info->root = root; + if (e_randr_screen_info->randr_version == ECORE_X_RANDR_1_1) + { + if (!(e_randr_screen_info->rrvd_info.randr_info_11 = _e_randr_screen_info_11_new())) goto ecore_x_randr_init_fail_ecore_shutdown; + _e_randr_screen_info_11_set(); + //_e_randr_config_find_and_enable(); + return EINA_TRUE; + } + else if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2) + { + if (!(e_randr_screen_info->rrvd_info.randr_info_12 = _e_randr_screen_info_12_new())) goto ecore_x_randr_init_fail_ecore_shutdown; + _e_randr_screen_info_12_set(e_randr_screen_info->rrvd_info.randr_info_12); + _e_randr_event_listeners_add(); + if (!_e_randr_screen_outputs_init()) goto ecore_x_randr_init_fail_free_screen; + if (!_e_randr_screen_crtcs_init()) goto ecore_x_randr_init_fail_free_screen; + _e_randr_screen_primary_output_assign(NULL); + return EINA_TRUE; + } + + //FILO free stack in case we fail to allocate something/can't get hold of + //necessary information +ecore_x_randr_init_fail_free_screen: + _e_randr_screen_info_free(e_randr_screen_info); +ecore_x_randr_init_fail_ecore_shutdown: + ecore_shutdown(); +ecore_x_randr_init_fail_eina_shutdown: + eina_shutdown(); + + return EINA_FALSE; +} + + static void +_e_randr_shutdown(void) +{ + _e_randr_screen_info_free(e_randr_screen_info); + ecore_shutdown(); + eina_shutdown(); +} + +/** + * @param nrequeste + * @return Instance of E_Randr_Screen_Info or if memory couldn't be + * allocated NULL. + */ + static E_Randr_Screen_Info * +_e_randr_screen_info_new(void) +{ + E_Randr_Screen_Info *ret = NULL; + E_Randr_Screen_Info default_info = { + .root = Ecore_X_Randr_Unset, + .randr_version = Ecore_X_Randr_None, + .rrvd_info.randr_info_11 = NULL + }; + + if (!(ret = malloc(sizeof(E_Randr_Screen_Info)))) return NULL; + + ret = memcpy(ret, &default_info, sizeof(default_info)); + + return ret; +} + +/** + * @param screen_info the screen info to free. + */ + static inline void +_e_randr_screen_info_free(E_Randr_Screen_Info *screen_info) +{ + if (!screen_info || !(screen_info->rrvd_info.randr_info_11)) return; + switch (e_randr_screen_info->randr_version) + { + case ECORE_X_RANDR_1_1: + _e_randr_screen_info_11_free(screen_info->rrvd_info.randr_info_11); + break; + case ECORE_X_RANDR_1_2: + case ECORE_X_RANDR_1_3: + _e_randr_screen_info_12_free(screen_info->rrvd_info.randr_info_12); + break; + } + free(screen_info); + screen_info = NULL; +} + +/** + * @return array of E_Randr_Screen_Info_11 elements, or in case not all could + * be created or parameter 'nrequested'==0, NULL + */ + static E_Randr_Screen_Info_11 * +_e_randr_screen_info_11_new(void) +{ + E_Randr_Screen_Info_11 *ret = NULL; + static const E_Randr_Screen_Info_11 default_info = { + .sizes = NULL, + .csize_index = Ecore_X_Randr_Unset, + .corientation = Ecore_X_Randr_Unset, + .orientations = Ecore_X_Randr_Unset, + .rates = NULL, + .current_rate = Ecore_X_Randr_Unset + }; + + if (!(ret = malloc(sizeof(E_Randr_Screen_Info_11)))) return NULL; + + ret = memcpy(ret, &default_info, sizeof(default_info)); + + return ret; +} + +/** + * @param screen_info the screen info to be freed. + */ + static void +_e_randr_screen_info_11_free(E_Randr_Screen_Info_11 *screen_info) +{ + if (!screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1)) return; + + if (screen_info->sizes) + { + free(eina_list_nth(screen_info->sizes, 0)); + eina_list_free(screen_info->sizes); + } + if (screen_info->rates) + { + free(eina_list_nth(screen_info->rates, 0)); + eina_list_free(screen_info->rates); + } + free(screen_info); + screen_info = NULL; +} + +/** + * @return array of E_Randr_Screen_Info_12 elements, or in case not all could + * be created or parameter 'nrequested'==0, NULL + */ + static E_Randr_Screen_Info_12 * +_e_randr_screen_info_12_new(void) +{ + E_Randr_Screen_Info_12 *ret = NULL; + static const E_Randr_Screen_Info_12 default_info = { + .min_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .max_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .current_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .crtcs = NULL, + .outputs = NULL, + .primary_output = NULL, + .output_policy = ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, + .alignment = ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE + }; + + if (!(ret = malloc(sizeof(E_Randr_Screen_Info_12)))) return NULL; + ret = memcpy(ret, &default_info, sizeof(default_info)); + + return ret; +} + + static const Eina_Bool +_e_randr_screen_info_12_set(E_Randr_Screen_Info_12 *screen_info) +{ + E_RANDR_NO_12_RET(EINA_FALSE); + + ecore_x_randr_screen_size_range_get(e_randr_screen_info->root, &screen_info->min_size.width, &screen_info->min_size.height, &screen_info->max_size.width , &screen_info->max_size.height); + ecore_x_randr_screen_current_size_get(e_randr_screen_info->root, &screen_info->current_size.width , &screen_info->current_size.height , NULL, NULL); + + return EINA_TRUE; +} + + static const Eina_Bool +_e_randr_screen_info_11_set(void) +{ + E_RANDR_NO_11_RET(EINA_FALSE); + + E_Randr_Screen_Info_11 *screen_info_11 = e_randr_screen_info->rrvd_info.randr_info_11; + Ecore_X_Randr_Screen_Size_MM *sizes = NULL; + Ecore_X_Randr_Refresh_Rate *rates = NULL; + Eina_List *rates_list; + int i, nsizes, nrates; + + if (!(sizes = ecore_x_randr_screen_primary_output_sizes_get(e_randr_screen_info->root, &nsizes))) return EINA_FALSE; + for (i = 0; i < nsizes; i++) + if (!(screen_info_11->sizes = eina_list_append(screen_info_11->sizes, &sizes[i]))) goto _e_randr_screen_info_11_fill_fail_sizes; + ecore_x_randr_screen_primary_output_current_size_get(e_randr_screen_info->root, NULL, NULL, NULL, NULL, &(screen_info_11->csize_index)); + screen_info_11->corientation = ecore_x_randr_screen_primary_output_orientation_get(e_randr_screen_info->root); + screen_info_11->orientations = ecore_x_randr_screen_primary_output_orientations_get(e_randr_screen_info->root); + for (i = 0; i < nsizes; i++) + { + rates_list = NULL; + if (!(rates = ecore_x_randr_screen_primary_output_refresh_rates_get(e_randr_screen_info->root, i, &nrates))) return EINA_FALSE; + for (i = 0; i < nrates; i++) + if (!(rates_list = eina_list_append(rates_list, &rates[i]))) goto _e_randr_screen_info_11_fill_fail_rates_list; + if (!(screen_info_11->rates = eina_list_append(screen_info_11->rates, rates_list))) goto _e_randr_screen_info_11_fill_fail_rates; + } + screen_info_11->current_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(e_randr_screen_info->root); + + return EINA_TRUE; + +_e_randr_screen_info_11_fill_fail_rates_list: + eina_list_free(rates_list); +_e_randr_screen_info_11_fill_fail_rates: + free(rates); +_e_randr_screen_info_11_fill_fail_sizes: + free(sizes); + free(screen_info_11); + return EINA_FALSE; +} + +/** + * @param screen_info the screen info to be freed. + */ + static void +_e_randr_screen_info_12_free(E_Randr_Screen_Info_12 *screen_info) +{ + Ecore_X_Randr_Mode_Info *mode_info; + E_Randr_Crtc_Info *crtc_info; + E_Randr_Output_Info *output_info; + + if (!screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2)) return; + + if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->crtcs) + { + EINA_LIST_FREE(screen_info->crtcs, crtc_info) + _e_randr_crtc_info_free(crtc_info); + free(eina_list_nth(screen_info->crtcs, 0)); + } + + if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->outputs) + { + EINA_LIST_FREE(screen_info->outputs, output_info) + _e_randr_output_info_free(output_info); + free(eina_list_nth(screen_info->outputs, 0)); + } + + if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->modes) + { + EINA_LIST_FREE(screen_info->modes, mode_info) + ecore_x_randr_mode_info_free(mode_info); + } + + _e_randr_event_listeners_remove(); + + free (screen_info); + screen_info = NULL; +} + +/** + * @brief allocates structs with and fills them with default values. The + * returned pointer is allocated as one chunk of data since it won't change. + * @param nrequested number of E_Randr_Crtc_Info to be created + * @return array of E_Randr_Crtc_Info elements, or in case not all could + * be created or parameter 'nrequested'==0, NULL + */ + static E_Randr_Crtc_Info * +_e_randr_crtc_info_new(int nrequested) +{ + E_Randr_Crtc_Info *ret = NULL; + static E_Randr_Crtc_Info default_info = { + .xid = Ecore_X_Randr_Unset, + .geometry = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .panning = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .tracking = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .border = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .current_orientation = ECORE_X_RANDR_ORIENTATION_ROT_0, + .orientations = Ecore_X_Randr_Unset, + .gamma_ramps = NULL, + .gamma_ramp_size = Ecore_X_Randr_Unset, + .outputs = NULL, + .possible_outputs = NULL + }; + + if (!(ret = malloc(sizeof(E_Randr_Crtc_Info) * nrequested))) return NULL; + + while (nrequested > 0) + { + memcpy(&ret[--nrequested], &default_info, sizeof(default_info)); + } + + return ret; +} + +/** + * @param crtc_info the crtc info to be freed. + */ + static void +_e_randr_crtc_info_free(E_Randr_Crtc_Info *crtc_info) +{ + if (!crtc_info) return; + + if (crtc_info->gamma_ramps) free(crtc_info->gamma_ramps); + if (crtc_info->outputs) eina_list_free(crtc_info->outputs); + if (crtc_info->possible_outputs) eina_list_free(crtc_info->possible_outputs); +} + +/** + * @brief allocates structs with and fills them with default values. The + * returned pointer is allocated as one chunk of data since it won't change. + * @param nrequested number of E_Randr_Output_Info to be created + * @return E_Randr_Output_Info element, or it could not be + * created, NULL + */ + static inline E_Randr_Output_Info * +_e_randr_output_info_new(int nrequested) +{ + E_Randr_Output_Info *ret = NULL; + static E_Randr_Output_Info default_info = { + .xid = Ecore_X_Randr_Unset, + .name = NULL, + .crtc = NULL, + .possible_crtcs = NULL, + .preferred_modes = NULL, + .max_backlight = Ecore_X_Randr_Unset, + .current_backlight = Ecore_X_Randr_Unset, + .edid = NULL, + .edid_length = 0, + .size_mm = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset}, + .wired_clones = NULL, + .signalformats = Ecore_X_Randr_Unset, + .signalformat = Ecore_X_Randr_Unset, + .connector_number = Ecore_X_Randr_Unset, + .connector_type = Ecore_X_Randr_Unset, + .connection_status = ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, + .subpixel_order= Ecore_X_Randr_Unset, + .compatible_outputs = NULL + }; + + if (!(ret = malloc(sizeof(E_Randr_Output_Info) * nrequested))) return NULL; + + while (nrequested > 0) + { + memcpy(&ret[--nrequested], &default_info, sizeof(default_info)); + } + + return ret; +} + +/* + * removes all traces of an output within the data. + * @param output_info the output info to be freed. + */ + static void +_e_randr_output_info_free(E_Randr_Output_Info *output_info) +{ + Eina_List *iter; + E_Randr_Crtc_Info *crtc_info; + if (!output_info) return; + + if (output_info->name) + { + free(output_info->name); + output_info->name = NULL; + } + _e_randr_output_hw_info_free(output_info); + + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + crtc_info->outputs = eina_list_remove(crtc_info->outputs, output_info); + } +} + + static void +_e_randr_output_info_set(E_Randr_Output_Info *output_info) +{ + if (E_RANDR_NO_12 || !output_info) return; + + output_info->name = ecore_x_randr_output_name_get(e_randr_screen_info->root, output_info->xid, &output_info->name_length); + output_info->connection_status = ecore_x_randr_output_connection_status_get(e_randr_screen_info->root, output_info->xid); +} + +/* + * fills a given crtc_info using its xid with + * - geometry data (x,y,w,h) + * - used outputs structs + * - possible outputs structs + * - mode + * - connection status + * - orientation + */ + static void +_e_randr_crtc_info_set(E_Randr_Crtc_Info *crtc_info) +{ + Ecore_X_Randr_Mode mode = 0; + fprintf(stderr, "Fillng CRTC %d (%p)\n", crtc_info->xid, crtc_info); + if (E_RANDR_NO_12 || !crtc_info) return; + + //get references to used and possible E_Randr_Output_Info structs + _e_randr_crtc_outputs_refs_update(crtc_info); + + ecore_x_randr_crtc_geometry_get(e_randr_screen_info->root, crtc_info->xid, &crtc_info->geometry.x, &crtc_info->geometry.y, &crtc_info->geometry.w, &crtc_info->geometry.h); + mode = ecore_x_randr_crtc_mode_get(e_randr_screen_info->root, crtc_info->xid); + crtc_info->current_mode = _e_randr_mode_info_get(mode); + fprintf(stderr, "CRTC %d apparently is in mode %d, trying to find it in the list of modes..\n", crtc_info->xid, mode); + if (crtc_info->current_mode) + fprintf(stderr, "found CRTC %d in mode %d\n", crtc_info->xid, crtc_info->current_mode->xid); + crtc_info->current_orientation = ecore_x_randr_crtc_orientation_get(e_randr_screen_info->root, crtc_info->xid); +} + +/* + * looks up modes supported by an output and adds them - if they are not already + * known by - to the screen's information struct ant the output_info itself + */ + static inline Eina_Bool +_e_randr_output_modes_add(E_Randr_Output_Info *output_info) +{ + Ecore_X_Randr_Mode *modes; + Ecore_X_Randr_Mode_Info *mode_info; + int nmodes, npreferred; + Eina_List *iter; + Eina_Bool added_yet = EINA_FALSE; + + if (E_RANDR_NO_12 || !(modes = ecore_x_randr_output_modes_get(e_randr_screen_info->root, output_info->xid, &nmodes, &npreferred))) return EINA_FALSE; + + while (--nmodes >= 0) + { + added_yet = EINA_FALSE; + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->modes, iter, mode_info) + { + if (mode_info->xid == modes[nmodes]) + { + added_yet = EINA_TRUE; + break; + } + } + if(!added_yet) + { + mode_info = ecore_x_randr_mode_info_get(e_randr_screen_info->root, modes[nmodes]); + e_randr_screen_info->rrvd_info.randr_info_12->modes = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->modes, mode_info); + } + output_info->modes = eina_list_append(output_info->modes, mode_info); + if (nmodes < npreferred) output_info->preferred_modes = eina_list_append(output_info->preferred_modes, mode_info); + + } + + free(modes); + return EINA_TRUE; +} + + static inline Eina_Bool +_e_randr_screen_crtcs_init(void) +{ + Ecore_X_Randr_Crtc *crtcs = NULL; + E_Randr_Crtc_Info *crtcs_info = NULL, *crtc = NULL; + + int i, ncrtcs; + if (E_RANDR_NO_12 || !(crtcs = ecore_x_randr_crtcs_get(e_randr_screen_info->root, &ncrtcs))) return EINA_FALSE; + + if (!(crtcs_info = _e_randr_crtc_info_new(ncrtcs))) goto ecore_x_randr_screen_crtcs_init_fail_free_crtcs; + for (i = 0; i < ncrtcs; i++) + { + fprintf (stderr, "E_RANDR: filling %d/%d (%d)\n", (i + 1), ncrtcs, crtcs[i]); + crtcs_info[i].xid = crtcs[i]; + _e_randr_crtc_info_set(&crtcs_info[i]); + if(!(e_randr_screen_info->rrvd_info.randr_info_12->crtcs = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, &crtcs_info[i]))) break; + } + if (i == ncrtcs) + { + //successfully initialized crtcs! + free (crtcs); + return EINA_TRUE; + } + EINA_LIST_FREE(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, crtc) + _e_randr_crtc_info_free(crtc); + if (e_randr_screen_info->rrvd_info.randr_info_12->crtcs) + { + free(eina_list_nth(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, 0)); + } + +ecore_x_randr_screen_crtcs_init_fail_free_crtcs: + free(crtcs); + return EINA_FALSE; +} + + + + static inline Eina_Bool +_e_randr_screen_outputs_init(void) +{ + Ecore_X_Randr_Output *outputs; + E_Randr_Output_Info *outputs_info = NULL, *output_info = NULL; + int noutputs = 0; + if (E_RANDR_NO_12 || !(outputs = ecore_x_randr_outputs_get(e_randr_screen_info->root, &noutputs))) return EINA_FALSE; + + if (!(outputs_info = _e_randr_output_info_new(noutputs))) goto _e_randr_screen_outputs_init_fail_free_outputs; + while (--noutputs >= 0) + { + outputs_info[noutputs].xid = outputs[noutputs]; + _e_randr_output_info_set(&outputs_info[noutputs]); + outputs_info[noutputs].connection_status = ecore_x_randr_output_connection_status_get(e_randr_screen_info->root, outputs_info[noutputs].xid); + if (outputs_info[noutputs].connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) + _e_randr_output_info_hw_info_set(&outputs_info[noutputs]); + + if (!(e_randr_screen_info->rrvd_info.randr_info_12->outputs = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->outputs, &outputs_info[noutputs]))) goto _e_randr_screen_outputs_init_fail_free_outputs_list; + } + + free(outputs); + return EINA_TRUE; + +_e_randr_screen_outputs_init_fail_free_outputs_list: + if (e_randr_screen_info->rrvd_info.randr_info_12->outputs) + { + EINA_LIST_FREE(e_randr_screen_info->rrvd_info.randr_info_12->outputs, output_info) + free(output_info); + } +_e_randr_screen_outputs_init_fail_free_outputs: + free(outputs); + return EINA_FALSE; +} + + static inline Ecore_X_Randr_Mode_Info* +_e_randr_mode_info_get(Ecore_X_Randr_Mode mode) +{ + Eina_List *iter; + Ecore_X_Randr_Mode_Info* mode_info; + + E_RANDR_NO_MODE_RET(mode, NULL); + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->modes, iter, mode_info) + { + if (mode_info->xid == mode) return mode_info; + } + return NULL; +} + + static inline E_Randr_Output_Info* +_e_randr_output_info_get(Ecore_X_Randr_Output output) +{ + Eina_List *iter; + E_Randr_Output_Info* output_info; + + E_RANDR_NO_OUTPUTS_RET(NULL); + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info) + { + if (output_info->xid == output) return output_info; + } + return NULL; +} + + static inline E_Randr_Crtc_Info* +_e_randr_crtc_info_get(Ecore_X_Randr_Crtc crtc) +{ + Eina_List *iter; + E_Randr_Crtc_Info* crtc_info; + + E_RANDR_NO_CRTCS_RET(NULL); + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if (crtc_info->xid == crtc) return crtc_info; + } + return NULL; +} + + static Eina_Bool +_e_randr_event_cb(void *data, int type, void *ev) +{ + E_Randr_Crtc_Info *crtc_info; + Eina_Bool enabled; + if (!e_randr_screen_info) return ECORE_CALLBACK_RENEW; + + if (type == ECORE_X_EVENT_RANDR_CRTC_CHANGE) + { + Ecore_X_Event_Randr_Crtc_Change *event = (Ecore_X_Event_Randr_Crtc_Change*) ev; + /* available information: + struct _Ecore_X_Event_Randr_Crtc_Change + { + Ecore_X_Window win; + Ecore_X_Randr_Crtc crtc; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Orientation orientation; + int x; + int y; + int width; + int height; + }; + */ + crtc_info = _e_randr_crtc_info_get(event->crtc); + if (event->mode != Ecore_X_Randr_None) + { + //switched (on) + if ((crtc_info->current_mode != _e_randr_mode_info_get(event->mode))) + { + crtc_info->current_mode = _e_randr_mode_info_get(event->mode); + _e_randr_notify_crtc_mode_change(crtc_info); + } + else + crtc_info->current_mode = _e_randr_mode_info_get(event->mode); + crtc_info->current_orientation = event->orientation; + crtc_info->geometry.x = event->geo.x; + crtc_info->geometry.y = event->geo.y; + crtc_info->geometry.w = event->geo.w; + crtc_info->geometry.h = event->geo.h; + //update screensize if necessary + e_randr_screen_info->rrvd_info.randr_info_12->current_size.width = MAX((event->geo.x + event->geo.w), e_randr_screen_info->rrvd_info.randr_info_12->current_size.width); + e_randr_screen_info->rrvd_info.randr_info_12->current_size.height = MAX((event->geo.y + event->geo.h), e_randr_screen_info->rrvd_info.randr_info_12->current_size.height); + } + else + { + //set the max mode common amongst outputs + _e_randr_crtcs_clone_crtc_removed(crtc_info); + + //disabled + crtc_info->current_orientation = event->orientation; + crtc_info->geometry.x = 0; + crtc_info->geometry.y = 0; + crtc_info->geometry.w = 0; + crtc_info->geometry.h = 0; + crtc_info->current_mode = NULL; + if (crtc_info->outputs) eina_list_free(crtc_info->outputs); + + //update screensize of necessary + ecore_x_randr_screen_reset(e_randr_screen_info->root); + ecore_x_randr_screen_current_size_get(e_randr_screen_info->root, &e_randr_screen_info->rrvd_info.randr_info_12->current_size.width, &e_randr_screen_info->rrvd_info.randr_info_12->current_size.height, NULL, NULL); + } + } + else if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE) + { + Ecore_X_Event_Randr_Output_Change *event = (Ecore_X_Event_Randr_Output_Change*) ev; + const E_Randr_Screen_Restore_Info_12 *restore_info; + E_Randr_Output_Info* output_info = NULL; + /* available information: + struct _Ecore_X_Event_Randr_Output_Change + { + Ecore_X_Window win; + Ecore_X_Randr_Output output; + Ecore_X_Randr_Crtc crtc; + Ecore_X_Randr_Mode mode; + Ecore_X_Randr_Orientation orientation; + Ecore_X_Randr_Connection_Status connection; + Ecore_X_Render_Subpixel_Order subpixel_order; + }; + */ + fprintf(stderr, "E_RANDR: Output connected!: \n \ + E_RANDR: relative to win: %d\n \ + E_RANDR: relative to output: %d\n \ + E_RANDR: relative to crtc: %d\n \ + E_RANDR: relative to mode: %d\n \ + E_RANDR: relative to orientation: %d\n \ + E_RANDR: relative to connction: %d (connected = %d, disconnected = %d, unknown %d)\n \ + E_RANDR: relative to subpixel_order: %d\n", + event->win, event->output, event->crtc, event->mode, event->orientation, event->connection, ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN, event->subpixel_order); + + output_info = _e_randr_output_info_get(event->output); + if((output_info->crtc = _e_randr_crtc_info_get(event->crtc))) + { + if (!eina_list_data_find(output_info->crtc->outputs, output_info)) + output_info->crtc->outputs = eina_list_append(output_info->crtc->outputs, output_info); + } + + output_info->connection_status = event->connection; + output_info->subpixel_order = event->subpixel_order; + + + if(event->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) + { + if (event->crtc) + output_info->crtc = _e_randr_crtc_info_get(event->crtc); + + if (!event->crtc && !event->mode) + { + //Monitor was attached! + _e_randr_output_info_hw_info_set(output_info); + //make the crtcs aware of their possibly new output + _e_randr_crtcs_possible_output_update(output_info); + if((restore_info = _e_randr_config_find_suiting_config_12())) + //maybe we have a suiting configuration + //_e_randr_config_enable_12(restore_info); + ; + else + enabled = _e_randr_try_enable_output(output_info, EINA_FALSE); //maybe give a success message? + } + _e_randr_notify_output_change(output_info); + } + else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED) + { + if (output_info->crtc) + { + //remove output from CRTC + output_info->crtc->outputs = eina_list_remove(output_info->crtc->outputs, output_info); + if (output_info->crtc->current_mode) + { + //in case this output was enabled on some CRTC + if (eina_list_count(output_info->crtc->outputs) == 0) + { + //in case it was the only output running on this CRTC, disable + //it. + ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, output_info->crtc->xid, NULL, Ecore_X_Randr_None, Ecore_X_Randr_None); + //crop the screen of course. + ecore_x_randr_screen_reset(e_randr_screen_info->root); + } + else + _e_randr_crtc_outputs_mode_max_set(output_info->crtc); + } + + if (e_randr_screen_info->rrvd_info.randr_info_12->primary_output && (output_info == e_randr_screen_info->rrvd_info.randr_info_12->primary_output)) + _e_randr_screen_primary_output_assign(output_info); + //let's try to get a proper config for the new setup and crop the + //screen afterwards. + if((restore_info = _e_randr_config_find_suiting_config_12())) + //in case we didn't have, init it anyway... + //_e_randr_config_enable_12(restore_info); + ; + } + _e_randr_notify_output_change(output_info); + _e_randr_output_hw_info_free(output_info); + } + } + else if (type == ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY) + { + //Ecore_X_Event_Randr_Output_Property_Notify *event = (Ecore_X_Event_Randr_Output_Property_Notify*) ev; + /* available information: + struct _Ecore_X_Event_Randr_Output_Property_Notify + { + Ecore_X_Window win; + Ecore_X_Randr_Output output; + Ecore_X_Atom property; + Ecore_X_Time time; + int state; // NewValue, Deleted + }; + */ + } + return ECORE_CALLBACK_RENEW; +} + + static inline void +_e_randr_event_listeners_add(void) +{ + if (E_RANDR_NO_12) return; + ecore_x_randr_events_select(e_randr_screen_info->root, EINA_TRUE); + _e_randr_event_handlers= eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, _e_randr_event_cb, NULL)); + _e_randr_event_handlers= eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, _e_randr_event_cb, NULL)); + _e_randr_event_handlers= eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, _e_randr_event_cb, NULL)); +} + + static inline void +_e_randr_event_listeners_remove(void) +{ + Ecore_Event_Handler *_event_handler = NULL; + EINA_LIST_FREE(_e_randr_event_handlers, _event_handler) + ecore_event_handler_del(_event_handler); +} + + static inline void +_e_randr_notify_crtc_mode_change(E_Randr_Crtc_Info *crtc_info) +{ +// E_Notification *n; +// char buff[200]; + + if (crtc_info->current_mode) + { +// snprintf(buff, 200, "New resolution is %dx%d. Click here for further information.", crtc_info->current_mode->width, crtc_info->current_mode->height); +// n = e_notification_full_new("RandRR", crtc_info->xid, NULL, "Resolution changed", buff, -1); +// //n = e_notification_full_new("RandRR", id, icon, function, body, timeout); +// e_notification_send(n, NULL, NULL); +// e_notification_unref(n); + } +} + static inline void +_e_randr_notify_output_change(E_Randr_Output_Info *output_info) +{ +// E_Notification *n; +// char buff[100]; + if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) + { +// snprintf(buff, 100, "Output %s connected", output_info->name); +// n = e_notification_full_new("RandRR", output_info->xid, NULL, buff, "Click here for further information.", -1); + } + else + { +// snprintf(buff, 100, "Output %s disconnected", output_info->name); +// n = e_notification_full_new("RandRR", output_info->xid, NULL, buff, "Click here to adjust screen setup.", -1); + } + +// //n = e_notification_full_new("RandRR", id, icon, function, body, timeout); +// e_notification_send(n, NULL, NULL); +// e_notification_unref(n); +} + +/* + * this retrieves a CRTC depending on a policy. + * Note that this is enlightenment specific! Enlightenment doesn't 'allow' zones + * to overlap. Thus we always use the output with the most extreme position + * instead of trying to fill gaps like tetris. Though this could be done by + * simply implementing another policy. + */ + static const inline E_Randr_Crtc_Info* +_e_randr_policy_crtc_get(E_Randr_Crtc_Info *but, E_Randr_Crtc_Info *hint, Ecore_X_Randr_Output_Policy policy) +{ + Eina_List *iter; + E_Randr_Crtc_Info *crtc_info, *ret = NULL; + + E_RANDR_NO_CRTCS_RET(NULL); + + //get any crtc that besides 'but' to start with + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if (crtc_info != but) + { + ret = crtc_info; + break; + } + } + if (!ret && (policy != ECORE_X_RANDR_OUTPUT_POLICY_CLONE)) return NULL; + + switch (policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if ((crtc_info != but) && (crtc_info->geometry.y <= ret->geometry.y)) + { + ret = crtc_info; + } + } + break; + case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT: + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if ((crtc_info != but) && ((crtc_info->geometry.x + crtc_info->geometry.w) >= (ret->geometry.x + ret->geometry.w))) + { + ret = crtc_info; + } + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_BELOW: + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if ((crtc_info != but) && ((crtc_info->geometry.y + crtc_info->geometry.h) >= (ret->geometry.y + ret->geometry.h))) + { + ret = crtc_info; + } + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if ((crtc_info != but) && (crtc_info->geometry.x <= ret->geometry.x)) + { + ret = crtc_info; + } + } + break; + + case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: + ret = (e_randr_screen_info->rrvd_info.randr_info_12->primary_output) ? e_randr_screen_info->rrvd_info.randr_info_12->primary_output->crtc : NULL; + break; + + default: + break; + } + return ret; +} + + static const inline Eina_Bool +_e_randr_outputs_connected(Eina_List *outputs_info) +{ + Eina_List *iter; + E_Randr_Output_Info *output_info; + EINA_LIST_FOREACH(outputs_info, iter, output_info) + if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) return EINA_TRUE; + return EINA_FALSE; +} + + static Eina_Bool +_e_randr_config_enable_11(int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation) +{ + E_Randr_Screen_Info_11 *current_info_11; + + if (E_RANDR_NO_11 || (size_index < 0) || (refresh_rate < 0) || (orientation < 0)) return EINA_FALSE; + + if (!ecore_x_randr_screen_primary_output_size_set(e_randr_screen_info->root, size_index) + || !ecore_x_randr_screen_primary_output_orientation_set(e_randr_screen_info->root, orientation) + || !ecore_x_randr_screen_primary_output_refresh_rate_set(e_randr_screen_info->root, size_index, refresh_rate)) return EINA_FALSE; + + //TODO: move this to the screen event later. + current_info_11 = e_randr_screen_info->rrvd_info.randr_info_11; + + current_info_11->csize_index = size_index; + current_info_11->corientation = orientation; + current_info_11->current_rate = refresh_rate; + + return EINA_TRUE; +} + + static Eina_Bool +_e_randr_config_enable_12(const E_Randr_Screen_Restore_Info_12* restore_info) +{ + /* + if (E_RANDR_NO_12 || !restore_info) return EINA_FALSE; + E_Randr_Screen_Info_12 *current_info_12; + E_Randr_Screen_Restore_Info_12 *restore_info_12 = NULL; + E_Randr_Crtc_Restore_Info *crtc_restore_info = NULL; + E_Randr_Crtc_Info *crtc_info; + E_Randr_Output_Info *output_info; + Eina_List *crtc_restore_iter; + + current_info_12 = (e_randr_screen_info->rrvd_info).randr_info_12; + EINA_LIST_FOREACH(restore_info_12->crtcs, crtc_restore_iter, crtc_restore_info) + { + ; + } + current_info_12->alignment = restore_info_12->alignment; + current_info_12->output_policy = restore_info_12->output_policy; + return EINA_TRUE; + */ + return EINA_FALSE; +} + + static inline int +_e_randr_config_find_suiting_config_11(E_Randr_Screen_Restore_Info_11 **restore_info) +{ + E_RANDR_NO_11_RET(Ecore_X_Randr_None); + Eina_List *cfg_screen_restore_info_iter; + E_Randr_Screen_Restore_Info *screen_restore_info; + + E_Randr_Screen_Restore_Info_11 *restore_info_11; + Ecore_X_Randr_Screen_Size_MM *sizes; + Ecore_X_Randr_Refresh_Rate *rates = NULL; + int i = 0, j = 0, nsizes = 0, nrates = 0; + + EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info) + { + if (screen_restore_info->randr_version != ECORE_X_RANDR_1_1) continue; + restore_info_11 = screen_restore_info->rrvd_restore_info.restore_info_11; + if((sizes = ecore_x_randr_screen_primary_output_sizes_get(e_randr_screen_info->root, &nsizes))) + { + for (i = 0; i < nsizes; i++) + { + if ((restore_info_11->size.width == sizes[i].width) + && (restore_info_11->size.height == sizes[i].height)) + { + if ((rates = ecore_x_randr_screen_primary_output_refresh_rates_get(e_randr_screen_info->root, i, &nrates))) + { + for (j = 0; j < nrates; j++) + if (rates[j] == restore_info_11->refresh_rate) + { + if (restore_info) *restore_info = restore_info_11; + free(rates); + free(sizes); + return i; + } + free(rates); + } + } + } + if (sizes) free(sizes); + } + } + return Ecore_X_Randr_Unset; +} + +/** + * @Brief find configuration with the most hardware currently available + */ + static inline E_Randr_Screen_Restore_Info_12 * +_e_randr_config_find_suiting_config_12(void) +{ + //TODO: write geometry based loading + /* + Eina_List *cfg_screen_restore_info_iter; + E_Randr_Screen_Restore_Info *screen_restore_info; + + E_Randr_Screen_Info_12 *current_info_12; + E_Randr_Screen_Restore_Info_12 *restore_info_12, *most_matches = NULL; + E_Randr_Output_Info *output_info; + E_Randr_Crtc_Restore_Info *crtc_restore_info; + Ecore_X_Randr_Output *outputs_xids; + Ecore_X_Randr_Crtc *crtcs_xids; + Eina_List *restore_info_12_iter, *output_iter, *restore_crtcs_iter; + + if (e_randr_screen_info && e_config && e_config->screen_info) + { + + EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info) + { + if (screen_restore_info->randr_version < ECORE_X_RANDR_1_2) continue; + + //HINT: use eina_list_clone and a sort callback to find proper + //crtcs and outputs + + //current_info_12 = e_randr_screen_info->rrvd_info.randr_info_12; + } + + } + */ + return NULL; +} + + + static inline Ecore_X_Randr_Output * +_e_randr_outputs_to_array(Eina_List *outputs_info) +{ + Ecore_X_Randr_Output *ret = NULL; + E_Randr_Output_Info *output_info; + Eina_List *output_iter; + int i = 0; + + if (!outputs_info || !(ret = malloc(sizeof(Ecore_X_Randr_Output) * eina_list_count(outputs_info)))) return NULL; + EINA_LIST_FOREACH(outputs_info, output_iter, output_info) + ret[i++] = output_info->xid; + return ret; +} + +/* + * Try to enable this output on an unoccupied CRTC. 'Force' in this context + * means, that if there are only occupied CRTCs, we disable another output to + * enable this one. If not forced we will - if we don't find an unoccupied CRTC + * - try to share the output of a CRTC with other outputs already using it + * (clone). + */ + static Eina_Bool +_e_randr_try_enable_output(E_Randr_Output_Info *output_info, Eina_Bool force) +{ + if (!output_info) return EINA_FALSE; + else if (output_info->crtc && output_info->crtc->current_mode) return EINA_TRUE; + + Eina_List *iter, *outputs_list = NULL; + E_Randr_Crtc_Info *crtc_info, *usable_crtc = NULL; + E_Randr_Output_Info *primary_output; + Ecore_X_Randr_Output *outputs; + Ecore_X_Randr_Mode_Info *mode_info; + Eina_Bool ret = EINA_FALSE; + + /* + * Try to find a usable crtc for this output. Either unused or forced. + */ + EINA_LIST_FOREACH(output_info->possible_crtcs, iter, crtc_info) + { + if (!crtc_info->current_mode || force) + { + usable_crtc = crtc_info; + break; + } + } + + /* + * apparently we don't have a CRTC to make use of the device + */ + if (!usable_crtc) return EINA_FALSE; + + //get the CRTC we will refer to, dependend on policy + switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_CLONE: + /* + * Order of approaches to enable a clone (of the primary output): + * + * 0. Get Primary output from Server + * 1. Try to add new Output to primary output's CRTC, using the mode used + * by the primary output + * 2. Try to enable clone in the same + * 2a. exact mode or a + * 2b. geometrically identical mode + * 3. Find a most high resolution mode in common to enable on primary output's CRTC and the new + * output's CRTC + * 4. fail. + */ + if ((primary_output = e_randr_screen_info->rrvd_info.randr_info_12->primary_output)) + { + if (primary_output->crtc && primary_output->crtc->current_mode && eina_list_data_find(output_info->modes, primary_output->crtc->current_mode)) + { + /* + * mode currently used by primary output's CRTC is also supported by the new output + */ + if (_e_randr_outputs_are_clones(output_info, primary_output->crtc->outputs)) + { + /* + * 1. Try to add new Output to primary output's CRTC, using the mode used + * by the primary output + * TODO: check with compatibility list in RandRR >= 1.3 + * if available + * + * The new output is also usable by the primary output's + * CRTC. Try to enable this output together with the already + * enabled outputs on the CRTC in already used mode. + */ + outputs_list = eina_list_clone(primary_output->crtc->outputs); + outputs_list = eina_list_append(outputs_list, output_info); + outputs = _e_randr_outputs_to_array(outputs_list); + ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, primary_output->crtc->xid, outputs, eina_list_count(outputs_list), primary_output->crtc->current_mode->xid); + free(outputs); + eina_list_free(outputs_list); + return ret; + } + else + { + /* + * 2. Try to enable clone in the same + */ + + /* + * 2a. exact mode. + */ + ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, primary_output->crtc->current_mode->xid); + return (ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment)); + + } + } + else + { + /* + * 2b. geometrically identical mode + */ + if ((mode_info = _e_randr_mode_geo_identical_find(output_info->modes, primary_output->crtc->current_mode))) + { + ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid); + return (ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment)); + } + /* + * 3. Find the highest resolution mode common to enable on primary output's CRTC and the new one. + */ + if (((outputs_list = eina_list_append(outputs_list, primary_output)) && (outputs_list = eina_list_append(outputs_list, output_info)))) + { + if((mode_info = _e_randr_outputs_common_mode_max_get(outputs_list, primary_output->crtc->current_mode))) + { + fprintf(stderr, "Will try to set mode: %dx%d for primary and clone.\n", mode_info->width, mode_info->height); + ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, primary_output->crtc->xid, ((Ecore_X_Randr_Output*)Ecore_X_Randr_Unset), Ecore_X_Randr_Unset, mode_info->xid); + ret = (ret && ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid)); + ret = (ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment)); + } + eina_list_free(outputs_list); + } + } + + } + else + fprintf(stderr, "Couldn't get primary output!\n"); + /* + * 4. FAIL + */ + break; + + default: + if ((!usable_crtc->current_mode) || force) + { + //enable and position according to used policies + mode_info = ((Ecore_X_Randr_Mode_Info*)eina_list_nth(output_info->preferred_modes, 0)); + if((ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid))) + { + usable_crtc->geometry.w = mode_info->width; + usable_crtc->geometry.h = mode_info->height; + usable_crtc->geometry.x = 0; + usable_crtc->geometry.y = 0; + + ret &= _e_randr_crtc_move_policy(usable_crtc); + } + } + } + ecore_x_randr_screen_reset(e_randr_screen_info->root); + return ret; +} + +/* + * updates all crtcs information regarding a new output + */ + static void +_e_randr_crtcs_possible_output_update(E_Randr_Output_Info *output_info) +{ + Eina_List *iter; + E_Randr_Crtc_Info *crtc_info; + Ecore_X_Randr_Output *outputs = NULL; + int noutputs = 0; + + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if (!eina_list_data_find(crtc_info->possible_outputs, output_info)) + { + if ((outputs = ecore_x_randr_crtc_possible_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs))) + { + while (--noutputs >= 0) + { + if (outputs[noutputs] == output_info->xid) + { + crtc_info->possible_outputs = eina_list_append(crtc_info->possible_outputs, output_info); + break; + } + } + free(outputs); + } + } + } +} + +/* + * setup a crtc's current (possible) outputs references + */ + static void +_e_randr_crtc_outputs_refs_update(E_Randr_Crtc_Info *crtc_info) +{ + Ecore_X_Randr_Output *outputs; + E_Randr_Output_Info *output_info; + int i, noutputs; + + //get references to output_info structs which are related to this CRTC + if (e_randr_screen_info->rrvd_info.randr_info_12->outputs && (outputs = ecore_x_randr_crtc_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs))) + { + for(i = 0; i < noutputs; i++) + { + if (!(output_info = _e_randr_output_info_get(outputs[i])) || eina_list_data_find(crtc_info->outputs, output_info) || (ecore_x_randr_output_crtc_get(e_randr_screen_info->root, outputs[i]) != crtc_info->xid)) continue; + if(!(crtc_info->outputs = eina_list_append(crtc_info->outputs, output_info))) fprintf(stderr, "E_RANDR: could not add output(%d) to CRTC's(%d) output list!\n", output_info->xid, crtc_info->xid); + output_info->crtc = crtc_info; + } + free(outputs); + } + //get references to possible output_info structs which are related to this CRTC + if (e_randr_screen_info->rrvd_info.randr_info_12->outputs && (outputs = ecore_x_randr_crtc_possible_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs))) + { + for(i = 0; i < noutputs; i++) + { + if (!(output_info = _e_randr_output_info_get(outputs[i])) || eina_list_data_find(crtc_info->possible_outputs, output_info)) continue; + if(!(crtc_info->possible_outputs = eina_list_append(crtc_info->possible_outputs, output_info))) fprintf(stderr, "E_RANDR: could not add output(%d) to CRTC's(%d) possible output list!\n", output_info->xid, crtc_info->xid); + } + free(outputs); + } +} + +/* + * reconfigure screen setup according to policy. This is only required if all + * CRTCs' positions might be affected by the another screens' movement. This includes 'virtual' moves, + * which means that e.g. when a crtc should be placed at a position < 0, all + * other crtcs are accordingly moved instead, so the result is the same. + */ + static Eina_Bool +_e_randr_crtc_move_policy(E_Randr_Crtc_Info *new_crtc) +{ + const E_Randr_Crtc_Info *crtc_rel; + int dx = Ecore_X_Randr_None, dy = Ecore_X_Randr_None; + Eina_Bool ret = EINA_TRUE; + + //get the crtc we will place our's relative to. If it's NULL, this is the + //only output attached, work done. + if(!(crtc_rel = _e_randr_policy_crtc_get(new_crtc, NULL, e_randr_screen_info->rrvd_info.randr_info_12->output_policy))) return EINA_TRUE; + + //following is policy dependend. + switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy) + { + case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE: + dy = (crtc_rel->geometry.y - new_crtc->geometry.h); + if (dy < 0) + { + //virtual move (move other CRTCs as nessesary) + dy = -dy; + ret = ecore_x_randr_move_all_crtcs_but(e_randr_screen_info->root, + &new_crtc->xid, + 1, + dx, + dy); + } + break; + case ECORE_X_RANDR_OUTPUT_POLICY_LEFT: + dx = (crtc_rel->geometry.x - new_crtc->geometry.w); + if (dx < 0) + { + //virtual move (move other CRTCs as nessesary) + dx = -dx; + ret = ecore_x_randr_move_all_crtcs_but(e_randr_screen_info->root, + &new_crtc->xid, + 1, + dx, + dy); + } + break; + default: + break; + } + ret &= ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, new_crtc->xid, crtc_rel->xid, e_randr_screen_info->rrvd_info.randr_info_12->output_policy, e_randr_screen_info->rrvd_info.randr_info_12->alignment); + return ret; +} + +/* + * returns the highest resolution mode common ammongst the given outputs, + * optionally limited by max_size_mode. If none is found, NULL is returned. + */ + static Ecore_X_Randr_Mode_Info * +_e_randr_outputs_common_mode_max_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode) +{ + Eina_List *all_modes = NULL, *iter, *output_iter, *right; + E_Randr_Output_Info *output_info; + Ecore_X_Randr_Mode_Info *mode_info; + int outputs_mode_found; + + //create a list of all available modes + EINA_LIST_FOREACH(outputs, iter, output_info) + { + right = eina_list_clone(output_info->modes); + all_modes = eina_list_merge(all_modes, right); + } + + if (max_size_mode) + { + //remove all modes that are larger than max_size_mode + EINA_LIST_FOREACH(all_modes, iter, mode_info) + { + if (_modes_size_sort_cb((void*)max_size_mode, (void*)mode_info) < 0) + { + all_modes = eina_list_remove(all_modes, mode_info); + } + } + } + + //sort modes by their sizes + all_modes = eina_list_sort(all_modes, eina_list_count(all_modes), _modes_size_sort_cb); + EINA_LIST_REVERSE_FOREACH(all_modes, iter, mode_info) + { + outputs_mode_found = 0; + EINA_LIST_FOREACH(outputs, output_iter, output_info) + { + if (eina_list_data_find(output_info->modes, mode_info)) + { + outputs_mode_found++; + } + } + if (outputs_mode_found == eina_list_count(outputs)) + break; + mode_info = NULL; + } + return mode_info; +} + + static int +_crtcs_size_sort_cb(const void *d1, const void *d2) +{ + E_Randr_Crtc_Info *crtc1 = ((E_Randr_Crtc_Info*)d1), *crtc2 = ((E_Randr_Crtc_Info*)d2); + + return ((crtc1->geometry.w * crtc1->geometry.h) - (crtc2->geometry.w * crtc2->geometry.h)); +} + + static int +_outputs_size_sort_cb(const void *d1, const void *d2) +{ + E_Randr_Output_Info *output1 = ((E_Randr_Output_Info*)d1), *output2 = ((E_Randr_Output_Info*)d2); + + return (output1 && output1->crtc && output1->crtc->current_mode && output2 && output2->crtc && output2->crtc->current_mode) ? ((output1->crtc->current_mode->width * output1->crtc->current_mode->height) - (output2->crtc->current_mode->width * output2->crtc->current_mode->height)) : 0; +} + + static int +_modes_size_sort_cb(const void *d1, const void *d2) +{ + Ecore_X_Randr_Mode_Info *mode1 = ((Ecore_X_Randr_Mode_Info*)d1), *mode2 = ((Ecore_X_Randr_Mode_Info*)d2); + + return ((mode1->width * mode1->height) - (mode2->width * mode2->height)); +} + +/* + * returns a mode within a given list of modes that is gemetrically identical. + * If none is found, NULL is returned. + */ + static inline Ecore_X_Randr_Mode_Info * +_e_randr_mode_geo_identical_find(Eina_List *modes, Ecore_X_Randr_Mode_Info *mode) +{ + Eina_List *iter; + Ecore_X_Randr_Mode_Info *mode_info; + + EINA_LIST_FOREACH(modes, iter, mode_info) + { + if ((mode_info->width == mode->width) && (mode_info->height == mode->height)) + return mode_info; + } + return NULL; +} + +/* + * reconfigures a CRTC enabling the highest resolution amongst its outputs, + * without touching any other CRTC currently activated + */ + static inline Eina_Bool +_e_randr_crtc_outputs_mode_max_set(E_Randr_Crtc_Info *crtc_info) +{ + Ecore_X_Randr_Mode_Info *mode_info; + Eina_List *common_modes, *iter; + Eina_Bool ret = EINA_TRUE; + Ecore_X_Randr_Output *outputs; + + if (!crtc_info || !crtc_info->outputs || !(common_modes = _e_randr_outputs_common_modes_get(crtc_info->outputs, NULL))) return EINA_FALSE; + + EINA_LIST_REVERSE_FOREACH(common_modes, iter, mode_info) + { + if (!_e_randr_crtc_mode_intersects_crtcs(crtc_info, mode_info)) + break; + } + if (!mode_info) + { + eina_list_free(common_modes); + return EINA_FALSE; + } + if ((outputs = _e_randr_outputs_to_array(crtc_info->outputs))) + { + ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, crtc_info->xid, outputs, eina_list_count(crtc_info->outputs), mode_info->xid); + free(outputs); + } + eina_list_free(common_modes); + + ecore_x_randr_screen_reset(e_randr_screen_info->root); + + return ret; +} + +/* + * returns EINA_TRUE if given CRTC would intersect with other CRTCs if set to + * given mode + */ + static inline Eina_Bool +_e_randr_crtc_mode_intersects_crtcs(E_Randr_Crtc_Info *crtc_info, Ecore_X_Randr_Mode_Info *mode) +{ + Eina_List *iter; + E_Randr_Crtc_Info *tmp; + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, tmp) + { + if ((tmp == crtc_info) || ((tmp->geometry.w <= 0) || (tmp->geometry.h <= 0))) continue; + if (E_INTERSECTS(crtc_info->geometry.x, crtc_info->geometry.y, mode->width, mode->height, tmp->geometry.x, tmp->geometry.y, tmp->geometry.w, tmp->geometry.h) + && ((crtc_info->geometry.x != tmp->geometry.x) && (crtc_info->geometry.y != tmp->geometry.y))) + return EINA_TRUE; + } + return EINA_FALSE; +} + +/* + * returns a list of modes common ammongst the given outputs, + * optionally limited by max_size_mode. If none are found, NULL is returned. + */ + static Eina_List * +_e_randr_outputs_common_modes_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode) +{ + Eina_List *common_modes = NULL, *iter, *output_iter, *right; + E_Randr_Output_Info *output_info; + Ecore_X_Randr_Mode_Info *mode_info; + int outputs_mode_found; + + if (!outputs) return NULL; + + //create a list of all available modes + EINA_LIST_FOREACH(outputs, iter, output_info) + { + right = eina_list_clone(output_info->modes); + common_modes = eina_list_merge(common_modes, right); + } + + if (max_size_mode) + { + //remove all modes that are larger than max_size_mode + EINA_LIST_FOREACH(common_modes, iter, mode_info) + { + if (_modes_size_sort_cb((void*)max_size_mode, (void*)mode_info) < 0) + { + common_modes = eina_list_remove(common_modes, mode_info); + } + } + } + + //sort modes desc. by their sizes + EINA_LIST_REVERSE_FOREACH(common_modes, iter, mode_info) + { + outputs_mode_found = 0; + EINA_LIST_FOREACH(outputs, output_iter, output_info) + { + if (eina_list_data_find(output_info->modes, mode_info)) + { + outputs_mode_found++; + } + } + if (outputs_mode_found != eina_list_count(outputs)) + { + common_modes = eina_list_remove(common_modes, mode_info); + } + } + return common_modes; +} + +/* + * reconfigure all CRTCs that had a given CRTC as a clone + */ + static Eina_Bool +_e_randr_crtcs_clone_crtc_removed(E_Randr_Crtc_Info *former_clone) +{ + Eina_List *iter; + E_Randr_Crtc_Info *crtc_info; + + if (!former_clone) return EINA_FALSE; + + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + if ((crtc_info == former_clone) || ((crtc_info->geometry.w <= 0) || (crtc_info->geometry.h <= 0))) continue; + if ((former_clone->geometry.x == crtc_info->geometry.x) && (former_clone->geometry.y == crtc_info->geometry.y) && (former_clone->geometry.w == crtc_info->geometry.w) && (former_clone->geometry.h == crtc_info->geometry.h)) + { + if (!_e_randr_crtc_outputs_mode_max_set(crtc_info)) return EINA_FALSE; + } + } + + return EINA_TRUE; + +} + + static void +_e_randr_screen_primary_output_assign(E_Randr_Output_Info *removed) +{ + Eina_List *iter; + E_Randr_Output_Info *primary_output = NULL, *output_info; + + E_RANDR_NO_OUTPUTS_RET(); + + if (e_randr_screen_info->rrvd_info.randr_info_12->primary_output && (removed != e_randr_screen_info->rrvd_info.randr_info_12->primary_output)) return; + if (!(primary_output = _e_randr_output_info_get(ecore_x_randr_primary_output_get(e_randr_screen_info->root)))) + { + primary_output = eina_list_data_get(eina_list_last(e_randr_screen_info->rrvd_info.randr_info_12->outputs)); + + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info) + { + if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED || !output_info->crtc || !output_info->crtc->current_mode) continue; + if ((!primary_output->crtc || !primary_output->crtc->current_mode) || _outputs_size_sort_cb(output_info, primary_output) > 0) primary_output = output_info; + } + if (!primary_output->crtc || !primary_output->crtc->current_mode) primary_output = NULL; + } + e_randr_screen_info->rrvd_info.randr_info_12->primary_output = primary_output; +} + + static void +_e_randr_output_info_hw_info_set(E_Randr_Output_Info *output_info) +{ + Ecore_X_Randr_Output *outputs; + Ecore_X_Randr_Crtc *crtcs; + E_Randr_Output_Info *output; + E_Randr_Crtc_Info *crtc; + int i, num; + + _e_randr_output_modes_add(output_info); + output_info->edid = ecore_x_randr_output_edid_get(e_randr_screen_info->root, output_info->xid, &output_info->edid_length); + //get the outputs we can use on the same CRTC alongside this one. + if ((outputs = ecore_x_randr_output_clones_get(e_randr_screen_info->root, output_info->xid, &num))) + { + for (i = 0; i < num; i++) + { + if ((output = _e_randr_output_info_get(outputs[i]))) + output_info->clones = eina_list_append(output_info->clones, output); + } + free(outputs); + } + + //get the CRTCs which are usable with this output. + if ((crtcs = ecore_x_randr_output_possible_crtcs_get(e_randr_screen_info->root, output_info->xid, &num))) + { + for (i = 0; i < num; i++) + { + fprintf(stderr, "E_RANDR: possible CRTC: %d\n", crtcs[i]); + if ((crtc = _e_randr_crtc_info_get(crtcs[i]))) + { + fprintf(stderr, "E_RANDR: \tfound the suiting struct at %p\n", crtc); + output_info->possible_crtcs = eina_list_append(output_info->possible_crtcs, crtc); + } + } + free(crtcs); + } +} + +/* + * free the hardware specifig parts of the information + * removes all traces of an output within the data. + * @param output_info the output info to be freed. + */ + static void +_e_randr_output_hw_info_free(E_Randr_Output_Info *output_info) +{ + E_Randr_Crtc_Info *crtc_info; + Eina_List *iter; + if (!output_info) return; + + if (output_info->modes) + { + eina_list_free(output_info->modes); + output_info->modes = NULL; + } + if (output_info->preferred_modes) + { + eina_list_free(output_info->preferred_modes); + output_info->preferred_modes = NULL; + } + if (output_info->edid) + { + free(output_info->edid); + output_info->edid = NULL; + } + if (output_info->wired_clones) + { + eina_list_free(output_info->wired_clones); + output_info->wired_clones = NULL; + } + if (output_info->compatible_outputs) + { + eina_list_free(output_info->compatible_outputs); + output_info->compatible_outputs = NULL; + } + if (output_info->possible_crtcs) + { + eina_list_free(output_info->possible_crtcs); + output_info->possible_crtcs = NULL; + } + if (output_info->clones) + { + eina_list_free(output_info->clones); + output_info->clones = NULL; + } + + EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info) + { + crtc_info->possible_outputs = eina_list_remove(crtc_info->possible_outputs, output_info); + } +} + +/* + * checks whether a given output is a common clone of the given list's outputs + */ + static const inline Eina_Bool +_e_randr_outputs_are_clones(E_Randr_Output_Info *output_info, Eina_List *outputs) +{ + E_Randr_Output_Info *output; + Eina_List *iter; + if (!outputs || !output_info) + return EINA_FALSE; + + EINA_LIST_FOREACH(output_info->clones, iter, output) + { + if (!eina_list_data_find(output_info->clones, output)) + return EINA_FALSE; + } + return EINA_TRUE; +} diff --git a/src/bin/e_randr.h b/src/bin/e_randr.h new file mode 100644 index 000000000..698adac40 --- /dev/null +++ b/src/bin/e_randr.h @@ -0,0 +1,124 @@ +#ifndef E_RANDR_H +#define E_RANDR_H + +#include +#include + +typedef struct _E_Randr_Crtc_Info { + Ecore_X_ID xid; + Eina_Rectangle geometry; + Eina_Rectangle panning; + Eina_Rectangle tracking; + Eina_Rectangle border; + Ecore_X_Randr_Orientation current_orientation; + Ecore_X_Randr_Orientation orientations; + Ecore_X_Randr_Crtc_Gamma **gamma_ramps; + int gamma_ramp_size; + Eina_List *outputs; + Eina_List *possible_outputs; + Ecore_X_Randr_Mode_Info *current_mode; +} E_Randr_Crtc_Info; + +typedef struct _E_Randr_Output_Info { + Ecore_X_ID xid; + char *name; + int name_length; + E_Randr_Crtc_Info *crtc; + Eina_List *wired_clones; + Ecore_X_Randr_Signal_Format signalformats; + Ecore_X_Randr_Signal_Format signalformat; + int connector_number; + Ecore_X_Randr_Connector_Type connector_type; + Ecore_X_Randr_Connection_Status connection_status; + /* + * Attached Monitor specific: + */ + Eina_List *modes; + Eina_List *preferred_modes; + Eina_List *clones; + Eina_List *possible_crtcs; + Ecore_X_Randr_Screen_Size size_mm; + unsigned char *edid; + unsigned long edid_length; + int max_backlight; + double current_backlight; + Ecore_X_Render_Subpixel_Order subpixel_order; + Eina_List *compatible_outputs; +} E_Randr_Output_Info; + +typedef struct _E_Randr_Screen_Info_11 { + //List of Ecore_X_Randr_Screen_Size_MM* + Eina_List *sizes; + int csize_index; + Ecore_X_Randr_Orientation corientation; + Ecore_X_Randr_Orientation orientations; + //List of Ecore_X_Randr_Refresh_Rate* + Eina_List *rates; + Ecore_X_Randr_Refresh_Rate current_rate; +} E_Randr_Screen_Info_11; + +typedef struct _E_Randr_Screen_Info_12 { + Ecore_X_Randr_Screen_Size min_size; + Ecore_X_Randr_Screen_Size max_size; + Ecore_X_Randr_Screen_Size current_size; + Eina_List *modes; + Eina_List *crtcs; + Eina_List *outputs; + E_Randr_Output_Info *primary_output; + Ecore_X_Randr_Output_Policy output_policy; + Ecore_X_Randr_Relative_Alignment alignment; +} E_Randr_Screen_Info_12; + +//RRVD == RandR(R) Version Depended +typedef union _E_Randr_Screen_RRVD_Info { + E_Randr_Screen_Info_11 *randr_info_11; + E_Randr_Screen_Info_12 *randr_info_12; +} E_Randr_Screen_RRVD_Info; + +typedef struct _E_Randr_Screen_Info { + Ecore_X_Window root; + int randr_version; + E_Randr_Screen_RRVD_Info rrvd_info; +} E_Randr_Screen_Info; + +//Following stuff is just for configuration purposes +typedef struct _E_Randr_Output_Restore_Info { + const char *edid; + double backlight_level; +} E_Randr_Output_Restore_Info; + +typedef struct _E_Randr_Crtc_Restore_Info { + Eina_Rectangle geometry; + Ecore_X_Randr_Orientation orientation; + //list of the outputs; + Eina_List *outputs; +} E_Randr_Crtc_Restore_Info; + +typedef struct _E_Randr_Screen_Restore_Info_11 { + Ecore_X_Randr_Screen_Size size; + Ecore_X_Randr_Refresh_Rate refresh_rate; + Ecore_X_Randr_Orientation orientation; +} E_Randr_Screen_Restore_Info_11; + +typedef struct _E_Randr_Screen_Restore_Info_12 { + Eina_List *crtcs; + Ecore_X_Randr_Output_Policy output_policy; + Ecore_X_Randr_Relative_Alignment alignment; +} E_Randr_Screen_Restore_Info_12; + +typedef union _E_Randr_Screen_Restore_Info_Union { + E_Randr_Screen_Restore_Info_11 *restore_info_11; + Eina_List *restore_info_12; +} E_Randr_Screen_Restore_Info_Union; + +typedef struct _E_Randr_Screen_Restore_Info { + int randr_version; + E_Randr_Screen_Restore_Info_Union rrvd_restore_info; +} E_Randr_Screen_Restore_Info; + +EAPI Eina_Bool e_randr_init(void); +EAPI int e_randr_shutdown(void); + +extern E_Randr_Screen_Info *e_randr_screen_info; + +#endif diff --git a/src/modules/conf_display/e_int_config_display.c b/src/modules/conf_display/e_int_config_display.c index 235e2cbff..a56db8300 100644 --- a/src/modules/conf_display/e_int_config_display.c +++ b/src/modules/conf_display/e_int_config_display.c @@ -1,10 +1,12 @@ #include "e.h" /* TODO: - * + * * Give list some icons. */ +#define RANDR_11 ((1 << 16) | 1) + static void _fill_data (E_Config_Dialog_Data *cfdata); static void *_create_data (E_Config_Dialog *cfd); static void _free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata); @@ -21,10 +23,13 @@ static int _sort_resolutions (const void *d1, const void *d2); typedef struct _Resolution Resolution; typedef struct _SureBox SureBox; -struct _Resolution +static E_Randr_Screen_Restore_Info_11 *e_screen_config_11 = NULL; + +struct _Resolution { int id; - Ecore_X_Screen_Size size; + Ecore_X_Randr_Screen_Size size; + int size_index; Eina_List *rates; }; @@ -37,18 +42,19 @@ struct _SureBox E_Config_Dialog_Data *cfdata; }; -struct _E_Config_Dialog_Data +struct _E_Config_Dialog_Data { E_Config_Dialog *cfd; Eina_List *resolutions; - Ecore_X_Screen_Size orig_size; - Ecore_X_Screen_Refresh_Rate orig_rate; - int orig_rotation; + Ecore_X_Randr_Screen_Size orig_size; + int orig_size_index; + Ecore_X_Randr_Refresh_Rate orig_rate; + int orig_orientation; int orig_flip; int restore; int can_rotate; int can_flip; - int rotation; + int orientation; int flip; int flip_x; int flip_y; @@ -81,18 +87,22 @@ static void _surebox_dialog_cb_yes(void *data, E_Dialog *dia) { SureBox *sb; - Ecore_X_Screen_Size c_size; - Ecore_X_Screen_Refresh_Rate c_rate; + Ecore_X_Randr_Screen_Size c_size; + Ecore_X_Randr_Refresh_Rate c_rate; E_Manager *man; sb = data; man = e_manager_current_get(); - c_size = ecore_x_randr_current_screen_size_get(man->root); - c_rate = ecore_x_randr_current_screen_refresh_rate_get(man->root); - e_config->display_res_width = c_size.width; - e_config->display_res_height = c_size.height; - e_config->display_res_hz = c_rate.rate; - e_config_save_queue(); + ecore_x_randr_screen_primary_output_current_size_get(man->root, &c_size.width, &c_size.height, NULL, NULL, NULL); + c_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root); + + if (e_screen_config_11) + { + e_screen_config_11->size.width = c_size.width; + e_screen_config_11->size.height = c_size.height; + e_screen_config_11->refresh_rate = c_rate; + e_config_save_queue(); + } _fill_data(sb->cfdata); _load_resolutions(sb->cfdata); /* No need to load rates as the currently selected resolution has not been @@ -106,8 +116,8 @@ _surebox_dialog_cb_no(void *data, E_Dialog *dia) SureBox *sb; sb = data; - ecore_x_randr_screen_refresh_rate_set(sb->dia->win->container->manager->root, - sb->cfdata->orig_size, sb->cfdata->orig_rate); + ecore_x_randr_screen_primary_output_refresh_rate_set(sb->dia->win->container->manager->root, + sb->cfdata->orig_size_index, sb->cfdata->orig_rate); _load_resolutions(sb->cfdata); _load_rates(sb->cfdata); _surebox_dialog_cb_delete(dia->win); @@ -127,7 +137,7 @@ _surebox_text_fill(SureBox *sb) "If you do not press a button, the old resolution of
" "%dx%d at %d Hz will be restored in %d seconds."), sb->cfdata->orig_size.width, sb->cfdata->orig_size.height, - sb->cfdata->orig_rate.rate, sb->iterations); + sb->cfdata->orig_rate, sb->iterations); else snprintf(buf, sizeof(buf), _("Does this look OK? Save if it does, or Restore if not.
" @@ -144,7 +154,7 @@ _surebox_text_fill(SureBox *sb) "If you do not press a button, the old resolution of
" "%dx%d at %d Hz will be restored IMMEDIATELY."), sb->cfdata->orig_size.width, sb->cfdata->orig_size.height, - sb->cfdata->orig_rate.rate); + sb->cfdata->orig_rate); else snprintf(buf, sizeof(buf), _("Does this look OK? Save if it does, or Restore if not.
" @@ -201,7 +211,7 @@ _surebox_new(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) } E_Config_Dialog * -e_int_config_display(E_Container *con, const char *params __UNUSED__) +e_int_config_display(E_Container *con, const char *params __UNUSED__) { E_Config_Dialog *cfd; E_Config_Dialog_View *v; @@ -229,43 +239,53 @@ e_int_config_display(E_Container *con, const char *params __UNUSED__) } static void -_fill_data(E_Config_Dialog_Data *cfdata) +_fill_data(E_Config_Dialog_Data *cfdata) { E_Manager *man; + E_Randr_Screen_Restore_Info *restore_info; + Eina_List *iter; int rots; man = e_manager_current_get(); - cfdata->orig_size = ecore_x_randr_current_screen_size_get(man->root); - cfdata->orig_rate = ecore_x_randr_current_screen_refresh_rate_get(man->root); - cfdata->restore = e_config->display_res_restore; + ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index); + cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root); - rots = ecore_x_randr_screen_rotations_get(man->root); - if ((rots) && (rots != ECORE_X_RANDR_ROT_0)) + EINA_LIST_FOREACH(e_config->screen_info, iter, restore_info) { - cfdata->rotation = ecore_x_randr_screen_rotation_get(man->root); - cfdata->can_flip = rots & (ECORE_X_RANDR_FLIP_X | ECORE_X_RANDR_FLIP_Y); - cfdata->flip = cfdata->rotation & - (ECORE_X_RANDR_FLIP_X | ECORE_X_RANDR_FLIP_Y); + if (restore_info->randr_version == RANDR_11) + { + e_screen_config_11 = restore_info->rrvd_restore_info.restore_info_11; + break; + } + } + + rots = ecore_x_randr_screen_primary_output_orientations_get(man->root); + if ((rots) && (rots != ECORE_X_RANDR_ORIENTATION_ROT_0)) + { + cfdata->orientation = ecore_x_randr_screen_primary_output_orientation_get(man->root); + cfdata->can_flip = rots & (ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y); + cfdata->flip = cfdata->orientation & + (ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y); cfdata->orig_flip = cfdata->flip; - if (cfdata->rotation & (ECORE_X_RANDR_FLIP_X)) + if (cfdata->orientation & (ECORE_X_RANDR_ORIENTATION_FLIP_X)) cfdata->flip_x = 1; - if (cfdata->rotation & (ECORE_X_RANDR_FLIP_Y)) + if (cfdata->orientation & (ECORE_X_RANDR_ORIENTATION_FLIP_Y)) cfdata->flip_y = 1; - cfdata->can_rotate = - rots & (ECORE_X_RANDR_ROT_0 | ECORE_X_RANDR_ROT_90 | - ECORE_X_RANDR_ROT_180 | ECORE_X_RANDR_ROT_270); - cfdata->rotation = - cfdata->rotation & - (ECORE_X_RANDR_ROT_0 | ECORE_X_RANDR_ROT_90 | - ECORE_X_RANDR_ROT_180 | ECORE_X_RANDR_ROT_270); - cfdata->orig_rotation = cfdata->rotation; + cfdata->can_rotate = + rots & (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 | + ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270); + cfdata->orientation = + cfdata->orientation & + (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 | + ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270); + cfdata->orig_orientation = cfdata->orientation; } } static void * -_create_data(E_Config_Dialog *cfd) +_create_data(E_Config_Dialog *cfd) { E_Config_Dialog_Data *cfdata; @@ -276,7 +296,7 @@ _create_data(E_Config_Dialog *cfd) } static void -_free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) +_free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) { Resolution *r; @@ -285,7 +305,7 @@ _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) EINA_LIST_FREE(cfdata->resolutions, r) { - Ecore_X_Screen_Refresh_Rate *rt; + Ecore_X_Randr_Refresh_Rate *rt; EINA_LIST_FREE(r->rates, rt) E_FREE(rt); @@ -296,11 +316,11 @@ _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) } static int -_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) +_basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata) { int r; Resolution *res; - Ecore_X_Screen_Refresh_Rate *rt; + Ecore_X_Randr_Refresh_Rate *rt; r = e_widget_ilist_selected_get(cfdata->res_list); if (r < 0) return 0; @@ -311,25 +331,25 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda rt = eina_list_nth(res->rates, r); if (!rt) return 0; - return (e_config->display_res_restore != cfdata->restore) || - (res->size.width != cfdata->orig_size.width) || + if (!e_screen_config_11) return EINA_FALSE; + return ((res->size.width != cfdata->orig_size.width) || (res->size.height != cfdata->orig_size.height) || - (cfdata->has_rates && (rt->rate != cfdata->orig_rate.rate)) || + (cfdata->has_rates && (*rt != cfdata->orig_rate)) || (cfdata->can_rotate && - (cfdata->orig_rotation != cfdata->rotation)) || + (cfdata->orig_orientation != cfdata->orientation)) || (cfdata->can_flip && - (((!(cfdata->orig_flip & ECORE_X_RANDR_FLIP_X)) != + (((!(cfdata->orig_flip & ECORE_X_RANDR_ORIENTATION_FLIP_X)) != (!cfdata->flip_x)) || - ((!(cfdata->orig_flip & ECORE_X_RANDR_FLIP_Y)) != - (!cfdata->flip_y)))); + ((!(cfdata->orig_flip & ECORE_X_RANDR_ORIENTATION_FLIP_Y)) != + (!cfdata->flip_y))))); } static int -_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) +_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) { int r; Resolution *res; - Ecore_X_Screen_Refresh_Rate *rate; + Ecore_X_Randr_Refresh_Rate *rate; E_Manager *man; r = e_widget_ilist_selected_get(cfdata->res_list); @@ -341,12 +361,12 @@ _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) if (!((cfdata->orig_size.width == res->size.width) && (cfdata->orig_size.height == res->size.height) && - (cfdata->orig_rate.rate == rate->rate || !cfdata->has_rates))) + (cfdata->orig_rate == *rate || !cfdata->has_rates))) { if (cfdata->has_rates) - ecore_x_randr_screen_refresh_rate_set(man->root, res->size, *rate); + ecore_x_randr_screen_primary_output_refresh_rate_set(man->root, res->size_index, *rate); else - ecore_x_randr_screen_size_set(man->root, res->size); + ecore_x_randr_screen_primary_output_size_set(man->root, res->size_index); if (e_config->cnfmdlg_disabled) { @@ -363,39 +383,40 @@ _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata) if ((cfdata->can_rotate) || (cfdata->can_flip)) { - cfdata->flip = cfdata->rotation; + cfdata->flip = cfdata->orientation; if (cfdata->flip_x) - cfdata->flip = (cfdata->flip | ECORE_X_RANDR_FLIP_X); + cfdata->flip = (cfdata->flip | ECORE_X_RANDR_ORIENTATION_FLIP_X); if (cfdata->flip_y) - cfdata->flip = (cfdata->flip | ECORE_X_RANDR_FLIP_Y); + cfdata->flip = (cfdata->flip | ECORE_X_RANDR_ORIENTATION_FLIP_Y); - ecore_x_randr_screen_rotation_set(man->root, - (cfdata->rotation | cfdata->flip)); - cfdata->orig_rotation = cfdata->rotation; + ecore_x_randr_screen_primary_output_orientation_set(man->root, + (cfdata->orientation | cfdata->flip)); + cfdata->orig_orientation = cfdata->orientation; cfdata->orig_flip = cfdata->flip; - e_config->display_res_rotation = (cfdata->rotation | cfdata->flip); + if (e_screen_config_11) + e_screen_config_11->orientation = (cfdata->orientation | cfdata->flip); } else - e_config->display_res_rotation = 0; + if (e_screen_config_11) + e_screen_config_11->orientation = 0; - e_config->display_res_restore = cfdata->restore; e_config_save_queue(); return 1; } static Evas_Object * -_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) +_basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata) { Evas_Object *o, *of, *ob, *ot; E_Radio_Group *rg; E_Manager *man; - Ecore_X_Screen_Size *sizes; + Ecore_X_Randr_Screen_Size_MM *sizes; int i, s; o = e_widget_table_add(evas, 0); - of = e_widget_framelist_add(evas, _("Resolution"), 0); + of = e_widget_framelist_add(evas, _("Resolution"), 0); ob = e_widget_ilist_add(evas, 16, 16, NULL); cfdata->res_list = ob; e_widget_size_min_set(ob, 170, 215); @@ -406,7 +427,7 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf e_widget_table_object_append(o, ob, 0, 1, 2, 1, 1, 1, 0, 0); ot = e_widget_table_add(evas, 0); - of = e_widget_framelist_add(evas, _("Refresh"), 0); + of = e_widget_framelist_add(evas, _("Refresh"), 0); ob = e_widget_ilist_add(evas, 16, 16, NULL); cfdata->rate_list = ob; e_widget_size_min_set(ob, 100, 80); @@ -414,20 +435,20 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf e_widget_table_object_append(ot, of, 0, 0, 1, 1, 1, 1, 1, 1); man = e_manager_current_get(); - sizes = ecore_x_randr_screen_sizes_get(man->root, &s); + sizes = ecore_x_randr_screen_primary_output_sizes_get(man->root, &s); cfdata->has_rates = 0; if ((!sizes) || (s == 0)) ecore_timer_add(0.5, _deferred_noxrandr_error, NULL); else { - cfdata->orig_size = ecore_x_randr_current_screen_size_get(man->root); - cfdata->orig_rate = ecore_x_randr_current_screen_refresh_rate_get(man->root); + ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index); + cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root); for (i = 0; i < (s - 1); i++) { Resolution * res; - Ecore_X_Screen_Refresh_Rate * rates; + Ecore_X_Randr_Refresh_Rate * rates; int r = 0, j; res = E_NEW(Resolution, 1); @@ -435,22 +456,23 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf res->size.width = sizes[i].width; res->size.height = sizes[i].height; - rates = ecore_x_randr_screen_refresh_rates_get(man->root, i, &r); + res->size_index = i; + rates = ecore_x_randr_screen_primary_output_refresh_rates_get(man->root, i, &r); for (j = 0; j < r; j++) { - Ecore_X_Screen_Refresh_Rate * rt; + Ecore_X_Randr_Refresh_Rate * rt; cfdata->has_rates = 1; - rt = E_NEW(Ecore_X_Screen_Refresh_Rate, 1); + rt = E_NEW(Ecore_X_Randr_Refresh_Rate, 1); if (!rt) continue; - rt->rate = rates[j].rate; + *rt = rates[j]; res->rates = eina_list_append(res->rates, rt); } if (rates) E_FREE(rates); cfdata->resolutions = eina_list_append(cfdata->resolutions, res); } - cfdata->resolutions = eina_list_sort(cfdata->resolutions, + cfdata->resolutions = eina_list_sort(cfdata->resolutions, eina_list_count(cfdata->resolutions), _sort_resolutions); cfdata->resolutions = eina_list_reverse(cfdata->resolutions); @@ -466,19 +488,19 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf if (cfdata->can_rotate) { of = e_widget_framelist_add(evas, _("Rotation"), 0); - rg = e_widget_radio_group_new(&(cfdata->rotation)); - ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-normal", 24, 24, ECORE_X_RANDR_ROT_0, rg); + rg = e_widget_radio_group_new(&(cfdata->orientation)); + ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-normal", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_0, rg); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_rotate & ECORE_X_RANDR_ROT_0)) e_widget_disabled_set(ob, 1); - ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-left", 24, 24, ECORE_X_RANDR_ROT_90, rg); + if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_0)) e_widget_disabled_set(ob, 1); + ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-left", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_90, rg); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_rotate & ECORE_X_RANDR_ROT_90)) e_widget_disabled_set(ob, 1); - ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-around", 24, 24, ECORE_X_RANDR_ROT_180, rg); + if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_90)) e_widget_disabled_set(ob, 1); + ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-around", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_180, rg); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_rotate & ECORE_X_RANDR_ROT_180)) e_widget_disabled_set(ob, 1); - ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-right", 24, 24, ECORE_X_RANDR_ROT_270, rg); + if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_180)) e_widget_disabled_set(ob, 1); + ob = e_widget_radio_icon_add(evas, NULL, "preferences-screen-right", 24, 24, ECORE_X_RANDR_ORIENTATION_ROT_270, rg); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_rotate & ECORE_X_RANDR_ROT_270)) e_widget_disabled_set(ob, 1); + if (!(cfdata->can_rotate & ECORE_X_RANDR_ORIENTATION_ROT_270)) e_widget_disabled_set(ob, 1); e_widget_table_object_append(ot, of, 0, 1, 1, 1, 1, 0, 1, 0); } @@ -487,10 +509,10 @@ _basic_create_widgets(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cf of = e_widget_framelist_add(evas, _("Mirroring"), 0); ob = e_widget_check_icon_add(evas, NULL, "preferences-screen-hflip", 24, 24, &(cfdata->flip_x)); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_flip & ECORE_X_RANDR_FLIP_X)) e_widget_disabled_set(ob, 1); + if (!(cfdata->can_flip & ECORE_X_RANDR_ORIENTATION_FLIP_X)) e_widget_disabled_set(ob, 1); ob = e_widget_check_icon_add(evas, NULL, "preferences-screen-vflip", 24, 24, &(cfdata->flip_y)); e_widget_framelist_object_append(of, ob); - if (!(cfdata->can_flip & ECORE_X_RANDR_FLIP_Y)) + if (!(cfdata->can_flip & ECORE_X_RANDR_ORIENTATION_FLIP_Y)) e_widget_disabled_set(ob, 1); e_widget_table_object_append(ot, of, 0, 2, 1, 1, 1, 0, 1, 0); } @@ -545,7 +567,7 @@ _load_resolutions(E_Config_Dialog_Data *cfdata) e_util_icon_theme_set(ob, "dialog-ok-apply"); sel = res->id; } - e_widget_ilist_append(cfdata->res_list, ob, buf, + e_widget_ilist_append(cfdata->res_list, ob, buf, _ilist_item_change, cfdata, NULL); } @@ -593,16 +615,16 @@ _load_rates(E_Config_Dialog_Data *cfdata) EINA_LIST_FOREACH(cfdata->resolutions, l, res) if (res->id == r) { - Ecore_X_Screen_Refresh_Rate *rt; + Ecore_X_Randr_Refresh_Rate *rt; Eina_List *ll; EINA_LIST_FOREACH(res->rates, ll, rt) { Evas_Object *ob = NULL; - snprintf(buf, sizeof(buf), "%i Hz", rt->rate); + snprintf(buf, sizeof(buf), "%i Hz", (int)*rt); - if (rt->rate == cfdata->orig_rate.rate) + if (*rt == cfdata->orig_rate) { ob = e_icon_add(evas); e_util_icon_theme_set(ob, "dialog-ok-apply"); @@ -622,7 +644,7 @@ _load_rates(E_Config_Dialog_Data *cfdata) } static void -_ilist_item_change(void *data) +_ilist_item_change(void *data) { _load_rates(data); }