From 790183d74a6493f601f5bfe80891ed29dbec6758 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Mon, 9 Feb 2015 17:43:17 +0900 Subject: [PATCH] e - randr - laptop lids - handle plug/unplug and well as lid open/close this fixes some issues in the new randr2 code that made it not work right with plug/unplug and lid close/open. now it does work right and plugging/unplugging displays is seamless (if your driver does not give plug/unplug events bind a key to update screen config acvtion and e will figure it out when you hit the key). --- src/bin/e_comp.c | 2 + src/bin/e_comp_canvas.c | 9 ++++ src/bin/e_comp_x.c | 14 ++++-- src/bin/e_randr2.c | 53 +++++++++++++++++--- src/bin/e_randr2.h | 1 + src/bin/e_sys.c | 1 + src/modules/conf_randr/e_int_config_randr2.c | 5 ++ 7 files changed, 75 insertions(+), 10 deletions(-) diff --git a/src/bin/e_comp.c b/src/bin/e_comp.c index 7c25c871e..ff4fff0d4 100644 --- a/src/bin/e_comp.c +++ b/src/bin/e_comp.c @@ -851,6 +851,7 @@ _e_comp_screensaver_on(void *data EINA_UNUSED, int type EINA_UNUSED, void *event Eina_List *l; E_Zone *zone; + printf("_e_comp_screensaver_on\n"); ecore_frametime = ecore_animator_frametime_get(); if (e_comp->saver) return ECORE_CALLBACK_RENEW; e_comp_override_add(e_comp); @@ -874,6 +875,7 @@ _e_comp_screensaver_off(void *data EINA_UNUSED, int type EINA_UNUSED, void *even E_Zone *zone; E_Client *ec; + printf("_e_comp_screensaver_off\n"); ecore_animator_frametime_set(ecore_frametime); if (!e_comp->saver) return ECORE_CALLBACK_RENEW; e_comp_override_del(e_comp); diff --git a/src/bin/e_comp_canvas.c b/src/bin/e_comp_canvas.c index 5425ddc5c..5e494ac9d 100644 --- a/src/bin/e_comp_canvas.c +++ b/src/bin/e_comp_canvas.c @@ -346,17 +346,24 @@ e_comp_canvas_update(void) { zones = e_comp->zones; e_comp->zones = NULL; + printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); EINA_LIST_FOREACH(screens, l, scr) { zone = NULL; + printf("@ match screens %p[%i] = %i %i %ix%i -- %i\n", + scr, scr->escreen, scr->x, scr->y, scr->w, scr->h, scr->escreen); EINA_LIST_FOREACH(zones, ll, zone) { if (zone->id == scr->escreen) break; zone = NULL; } + printf("@ matches existing zone %p\n", zone); if (zone) { + printf(" move resize %i %i %ix%i -> %i %i %ix%i\n", + zone->x, zone->y, zone->w, zone->h, + scr->x, scr->y, scr->w, scr->h); changed |= e_zone_move_resize(zone, scr->x, scr->y, scr->w, scr->h); if (changed) printf("@@@ FOUND ZONE %i %i [%p]\n", zone->num, zone->id, zone); @@ -380,6 +387,7 @@ e_comp_canvas_update(void) { E_Zone *spare_zone; + printf("@zones have been deleted....\n"); changed = EINA_TRUE; spare_zone = eina_list_data_get(e_comp->zones); @@ -387,6 +395,7 @@ e_comp_canvas_update(void) { E_Client *ec; + printf("reassign all clients from deleted zone %p\n", zone); E_CLIENT_FOREACH(e_comp, ec) { if (ec->zone == zone) diff --git a/src/bin/e_comp_x.c b/src/bin/e_comp_x.c index 36ff29afb..1621942d9 100644 --- a/src/bin/e_comp_x.c +++ b/src/bin/e_comp_x.c @@ -4585,15 +4585,21 @@ _e_comp_x_xinerama_setup(int rw, int rh) screen->w = s->config.geom.w; screen->h = s->config.geom.h; all_screens = eina_list_append(all_screens, screen); + printf("xinerama screen %i %i %ix%i\n", screen->x, screen->y, screen->w, screen->h); INF("E INIT: XINERAMA SCREEN: [%i][%i], %ix%i+%i+%i", i, i, screen->w, screen->h, screen->x, screen->y); i++; } } - // XXX: what if we have zero screens? all unplugged? need to flag this - // keep all screens as-is for now and mark comp to hide everything - // and wait for a screen to come back - if (i == 0) + // if we have NO screens at all (above - i will be 0) AND we have no + // existing screens set up in xinerama - then just say root window size + // is the entire screen. this should handle the case where you unplug ALL + // screens from an existing setup (unplug external monitors and/or close + // laptop lid), in which case as long as at least one screen is configured + // in xinerama, it will be left-as is until next time we re-eval screen + // setup and have at least one screen + printf("xinerama setup............... %i %p\n", i, e_xinerama_screens_all_get()); + if ((i == 0) && (!e_xinerama_screens_all_get())) { screen = E_NEW(E_Screen, 1); screen->escreen = screen->screen = 0; diff --git a/src/bin/e_randr2.c b/src/bin/e_randr2.c index db568d179..5eea03922 100644 --- a/src/bin/e_randr2.c +++ b/src/bin/e_randr2.c @@ -186,8 +186,13 @@ static Evas_Object *_fade_obj = NULL; static Eina_Bool _screen_closed(E_Randr2_Screen *s) { + printf("RRR: check lid for %s...\n", s->info.name); if (!_lid_is_closed) return EINA_FALSE; - if (s->info.is_lid) return EINA_TRUE; + if (s->info.is_lid) + { + printf("RRR: is closed lid\n"); + return EINA_TRUE; + } return EINA_FALSE; } @@ -510,6 +515,8 @@ _screens_fingerprint(E_Randr2 *r) eina_strbuf_append(buf, ":"); eina_strbuf_append(buf, s->id); eina_strbuf_append(buf, ":"); + if (s->info.lid_closed) eina_strbuf_append(buf, ":LC:"); + else eina_strbuf_append(buf, ":LO:"); } } str = eina_strbuf_string_steal(buf); @@ -529,7 +536,9 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2) s1 = _screens_fingerprint(r1); s2 = _screens_fingerprint(r2); if ((!s1) && (!s2)) return EINA_FALSE; + printf("RRR: check fingerprint...\n"); if ((s1) && (s2) && (strcmp(s1, s2))) changed = EINA_TRUE; + printf("RRR: ... fingerprint says %i\n", changed); free(s1); free(s2); // check screen config @@ -549,9 +558,11 @@ _screens_differ(E_Randr2 *r1, E_Randr2 *r2) (s->config.mode.w != ss->config.mode.w) || (s->config.mode.h != ss->config.mode.h) || (s->config.enabled != ss->config.enabled) || - (s->config.rotation != ss->config.rotation)) + (s->config.rotation != ss->config.rotation) || + (s->info.lid_closed != ss->info.lid_closed)) changed = EINA_TRUE; } + printf("RRR: changed = %i\n", changed); return changed; } @@ -559,6 +570,7 @@ static Eina_Bool _cb_screen_change_delay(void *data EINA_UNUSED) { _screen_delay_timer = NULL; + printf("RRR: ... %i %i\n", event_screen, event_ignore); // if we had a screen plug/unplug etc. event and we shouldnt ignore it... if ((event_screen) && (!event_ignore)) { @@ -572,6 +584,7 @@ _cb_screen_change_delay(void *data EINA_UNUSED) if (_screens_differ(e_randr2, rtemp)) change = EINA_TRUE; _info_free(rtemp); } + printf("RRR: change = %i\n", change); // we plugged or unplugged some monitor - re-apply config so // known screens can be coonfigured if (change) e_randr2_config_apply(); @@ -600,10 +613,13 @@ _cb_acpi(void *data EINA_UNUSED, int type EINA_UNUSED, void *event) E_Event_Acpi *ev = event; Eina_Bool lid_closed; + printf("RRR: acpi event\n"); if (ev->type != E_ACPI_TYPE_LID) return EINA_TRUE; lid_closed = (ev->status == E_ACPI_LID_CLOSED); if (lid_closed == _lid_is_closed) return EINA_TRUE; + printf("RRR: lid event for lid %i\n", lid_closed); _lid_is_closed = lid_closed; + event_screen = EINA_TRUE; _screen_change_delay(); return EINA_TRUE; } @@ -650,12 +666,13 @@ _screen_config_do(E_Randr2_Screen *s) { E_Randr2_Screen *s2 = NULL; - _config_do_recurse++; - if (_config_do_recurse > 20) + printf("RRR: screen do '%s'\n", s->info.name); + if (_config_do_recurse > 10) { ERR("screen config loop!"); return; } + _config_do_recurse++; // if screen has a dependency... if ((s->config.relative.mode != E_RANDR2_RELATIVE_UNKNOWN) && (s->config.relative.mode != E_RANDR2_RELATIVE_NONE) && @@ -737,6 +754,7 @@ _screen_config_do(E_Randr2_Screen *s) s->config.geom.y = s2->config.geom.y + s2->config.geom.h; } } + _config_do_recurse--; } static void @@ -1159,6 +1177,8 @@ _info_get(void) else if (conn == ECORE_X_RANDR_EDID_DISPLAY_INTERFACE_DISPLAY_PORT) s->info.connector = E_RANDR2_CONNECTOR_DISPLAY_PORT; s->info.is_lid = _is_lid_name(s->info.name); + s->info.lid_closed = s->info.is_lid && _lid_is_closed; + printf("RRR: .... lid_closed = %i (%i && %i)\n", s->info.lid_closed, s->info.is_lid, _lid_is_closed); if (ecore_x_randr_output_connection_status_get(root, outputs[i]) == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) s->info.connected = EINA_TRUE; @@ -1413,7 +1433,7 @@ _screen_config_apply(void) Ecore_X_Randr_Crtc *crtcs = NULL; Ecore_X_Randr_Output *outputs = NULL, out, *outconf; E_Randr2_Screen **screenconf; - int crtcs_num = 0, outputs_num = 0, i; + int crtcs_num = 0, outputs_num = 0, i, numout; Ecore_X_Randr_Crtc_Info *info; int top_priority = 0; @@ -1492,6 +1512,13 @@ _screen_config_apply(void) } } } + numout = 0; + for (i = 0; i < crtcs_num; i++) + { + if (outconf[i]) numout++; + } + if (numout) + { // set up a crtc to drive each output (or not) for (i = 0; i < crtcs_num; i++) { @@ -1544,20 +1571,34 @@ _screen_config_apply(void) ECORE_X_RANDR_ORIENTATION_ROT_0); } } + } + else + { + printf("RRR: EERRRRRROOOORRRRRRR no outputs to configure!\n"); + } } free(outputs); free(crtcs); + printf("RRR: set vsize: %ix%i\n", nw, nh); ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1); { int ww = 0, hh = 0, ww2 = 0, hh2 = 0; ecore_x_randr_screen_current_size_get(root, &ww, &hh, &ww2, &hh2); printf("RRR: cur size: %ix%i\n", ww, hh); +// ecore_x_randr_screen_reset(root); +// ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1); +// ecore_x_sync(); +// ecore_x_randr_screen_current_size_get(root, &ww, &hh, &ww2, &hh2); +// printf("RRR: cur size: %ix%i\n", ww, hh); } ecore_x_randr_screen_size_range_get(root, NULL, NULL, NULL, NULL); ecore_x_ungrab(); ecore_x_sync(); // ignore the next batch of randr events - we caused them ourselves - event_ignore = EINA_TRUE; + // XXX: a problem. thew first time we configure the screen we may not + // get any events back to clear the ignore flag below, so only apply + // here if the randr config now doesnt match what we want to set up. +// event_ignore = EINA_TRUE; } diff --git a/src/bin/e_randr2.h b/src/bin/e_randr2.h index 70fd40f0c..ab7aa0b44 100644 --- a/src/bin/e_randr2.h +++ b/src/bin/e_randr2.h @@ -59,6 +59,7 @@ struct _E_Randr2_Screen char *edid; // full edid data E_Randr2_Connector connector; // the connector type Eina_Bool is_lid : 1; // is an internal screen + Eina_Bool lid_closed : 1; // is lid closed when screen qury'd Eina_Bool connected : 1; // some screen is plugged in or not Eina_Bool backlight : 1; // does it have backlight controls? Eina_Bool can_rot_0 : 1; // can it do this rotation? diff --git a/src/bin/e_sys.c b/src/bin/e_sys.c index 41c0633d2..69400febc 100644 --- a/src/bin/e_sys.c +++ b/src/bin/e_sys.c @@ -114,6 +114,7 @@ _e_sys_comp_emit_cb_wait(E_Sys_Action a, const char *sig, const char *rep, Eina_ if (nocomp_push) e_comp_override_add(e_comp); else e_comp_override_timed_pop(e_comp); + printf("_e_sys_comp_emit_cb_wait - [%x] %s %s\n", a, sig, rep); EINA_LIST_FOREACH(e_comp->zones, l, zone) { e_zone_fade_handle(zone, nocomp_push, 0.5); diff --git a/src/modules/conf_randr/e_int_config_randr2.c b/src/modules/conf_randr/e_int_config_randr2.c index 2f8c4ccac..f823fdb67 100644 --- a/src/modules/conf_randr/e_int_config_randr2.c +++ b/src/modules/conf_randr/e_int_config_randr2.c @@ -378,6 +378,7 @@ _cb_rel_to_set(void *data, Evas_Object *obj, void *event) E_Randr2_Screen *s = _screen_config_id_find(cs2->id); if (s) { + printf("SEt to %p [%s]\n", cs, cs->id); printf("find s = %p\n", s); printf("s id = %s\n", s->id); elm_object_text_set(obj, s->info.name); @@ -710,9 +711,11 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata) E_Config_Randr2_Screen *cs, *cs2; e_randr2_cfg->restore = cfdata->restore; + printf("APPLY....................\n"); EINA_LIST_FOREACH(cfdata->screens, l, cs2) { if (!cs2->id) continue; + printf("APPLY .... %p\n", cs2); cs = _screen_config_randr_id_find(cs2->id); if (!cs) { @@ -722,6 +725,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata) } if (cs->rel_to) eina_stringshare_del(cs->rel_to); cs->rel_to = NULL; + printf("APPLY %s .... rel to %s\n", cs->id, cs2->rel_to); if (cs2->rel_to) cs->rel_to = eina_stringshare_add(cs2->rel_to); cs->rel_align = cs2->rel_align; cs->mode_refresh = cs2->mode_refresh; @@ -731,6 +735,7 @@ _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata) cs->rotation = cs2->rotation; cs->priority = cs2->priority; cs->rel_mode = cs2->rel_mode; + printf("APPLY %s .... rel mode %i\n", cs->id, cs->rel_mode); cs->enabled = cs2->enabled; } e_randr2_config_save();