randr: further cleanup

Primarly two things removed:
1. crtc->outputs should only contain outputs which should be enabled
So looping them twice in e_randr_apply is definitly wrong.

2. _e_randr_crtc_find should find a crtc for an output
So looping our crtcs again in _active_set is definitly wrong. If
_e_randr_crtc_find does not find us a crtc, it should be fixed there.
This commit is contained in:
Sebastian Dransfeld 2014-12-15 12:25:22 +01:00
parent 95b4f14098
commit 3e02824663
2 changed files with 60 additions and 125 deletions

View File

@ -19,7 +19,7 @@ static E_Config_Randr_Output *_e_randr_config_output_new(void);
static E_Config_Randr_Output *_e_randr_config_output_find(E_Randr_Output *output); static E_Config_Randr_Output *_e_randr_config_output_find(E_Randr_Output *output);
static E_Randr_Crtc *_e_randr_crtc_find(Ecore_X_Randr_Crtc xid); static E_Randr_Crtc *_e_randr_crtc_find(Ecore_X_Randr_Crtc xid);
static E_Randr_Output *_e_randr_output_find(Ecore_X_Randr_Output xid); static E_Randr_Output *_e_randr_output_find(Ecore_X_Randr_Output xid);
static E_Randr_Crtc *_e_randr_output_crtc_find(E_Randr_Output *output); static void _e_randr_output_crtc_find(E_Randr_Output *output);
static void _e_randr_config_mode_geometry(Ecore_X_Randr_Orientation orient, Eina_Rectangle *rect); static void _e_randr_config_mode_geometry(Ecore_X_Randr_Orientation orient, Eina_Rectangle *rect);
static void _e_randr_config_primary_update(void); static void _e_randr_config_primary_update(void);
@ -140,31 +140,30 @@ e_randr_config_apply(void)
EINA_LIST_FOREACH(e_randr->outputs, l, output) EINA_LIST_FOREACH(e_randr->outputs, l, output)
{ {
printf("RR: apply out %p... [%s]\n", output, output->name); printf("RR: apply out %p... [%s]\n", output, output->name);
if ((output->cfg) && (!output->cfg->connect)) if (output->cfg)
{ {
printf("RR: output disabled\n"); if (!output->cfg->connect)
_e_randr_output_active_set(output, EINA_FALSE); {
} printf("RR: output disabled\n");
else if ((output->cfg) && (output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)) _e_randr_output_active_set(output, EINA_FALSE);
{ }
if (output->cfg) else if (output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
{ {
printf("RR: output enabled [%i %i %ix%i | %2.3f orient %i]\n", printf("RR: output enabled [%i %i %ix%i | %2.3f orient %i]\n",
output->cfg->geo.x, output->cfg->geo.y, output->cfg->geo.x, output->cfg->geo.y,
output->cfg->geo.w, output->cfg->geo.h, output->cfg->geo.w, output->cfg->geo.h,
output->cfg->refresh_rate, output->cfg->orient); output->cfg->refresh_rate, output->cfg->orient);
printf("RR: update mode\n");
_e_randr_output_mode_update(output);
printf("RR: active set...\n"); printf("RR: active set...\n");
_e_randr_output_active_set(output, EINA_TRUE); _e_randr_output_active_set(output, EINA_TRUE);
printf("RR: active set done\n"); printf("RR: update mode\n");
_e_randr_output_mode_update(output);
} }
else else
printf("RR: no cfg\n"); printf("RR: not connected and not connect\n");
} }
else else
{ {
printf("RR: ???\n"); printf("RR: no cfg\n");
} }
} }
printf("RR: ... lid update\n"); printf("RR: ... lid update\n");
@ -474,7 +473,7 @@ _e_randr_load(void)
output->xid = outputs[j]; output->xid = outputs[j];
output->name = _e_randr_output_name_get(root, output->xid); output->name = _e_randr_output_name_get(root, output->xid);
output->is_lid = _e_randr_is_lid(output); output->is_lid = _e_randr_is_lid(output);
output->edid = _e_randr_output_edid_string_get(root, outputs[j]); output->edid = _e_randr_output_edid_string_get(root, output->xid);
output->status = ecore_x_randr_output_connection_status_get(root, output->xid); output->status = ecore_x_randr_output_connection_status_get(root, output->xid);
output->cfg = _e_randr_config_output_find(output); output->cfg = _e_randr_config_output_find(output);
if (!output->cfg) if (!output->cfg)
@ -484,30 +483,27 @@ _e_randr_load(void)
if (output->edid) output->cfg->edid = strdup(output->edid); if (output->edid) output->cfg->edid = strdup(output->edid);
unknown = EINA_TRUE; unknown = EINA_TRUE;
} }
printf("RR: output %x %s %i %p\n", output->xid, output->name, output->status, output->cfg); printf("RR: output %x %s %s %i %p\n", output->xid, output->name, output->edid, output->status, output->cfg);
/* find a crtc if we want this output connected */ /* find a crtc if we want this output connected */
if (output->cfg->connect && if (output->cfg->connect &&
(output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)) (output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED))
{ {
E_Randr_Crtc *crtc; _e_randr_output_active_set(output, EINA_TRUE);
if (output->crtc)
crtc = _e_randr_output_crtc_find(output);
printf("RR: ouput on crtc = %p\n", crtc);
if (crtc)
{ {
_e_randr_output_active_set(output, EINA_TRUE); printf("RR: output on crtc = %p\n", output->crtc);
/* get orientation from crtc if not set */ /* get orientation from crtc if not set */
if (!output->cfg->orient) if (!output->cfg->orient)
output->cfg->orient = crtc->orient; output->cfg->orient = output->crtc->orient;
/* find mode for output */ /* find mode for output */
_e_randr_output_mode_update(output); _e_randr_output_mode_update(output);
/* set position from crtc if unknown */ /* set position from crtc if unknown */
if (unknown) if (unknown)
{ {
output->cfg->geo.x = crtc->geo.x; output->cfg->geo.x = output->crtc->geo.x;
output->cfg->geo.y = crtc->geo.y; output->cfg->geo.y = output->crtc->geo.y;
} }
} }
} }
@ -598,6 +594,14 @@ _e_randr_apply(void)
Ecore_X_Randr_Output *coutputs; Ecore_X_Randr_Output *coutputs;
printf("RRR2: crtc: %x %i %i %ix%i rot: %i mode: %i\n", crtc->xid, crtc->geo.x, crtc->geo.y, crtc->geo.w, crtc->geo.h, crtc->orient, crtc->mode); printf("RRR2: crtc: %x %i %i %ix%i rot: %i mode: %i\n", crtc->xid, crtc->geo.x, crtc->geo.y, crtc->geo.w, crtc->geo.h, crtc->orient, crtc->mode);
/* if nothing connected, disable crtc */
if (!crtc->outputs)
{
printf("RRR2: crtc has no outputs - off\n");
ecore_x_randr_crtc_settings_set(root, crtc->xid, NULL, 0, 0, 0, 0,
ECORE_X_RANDR_ORIENTATION_ROT_0);
continue;
}
/* set config from connected outputs */ /* set config from connected outputs */
_e_randr_crtc_from_outputs_set(crtc); _e_randr_crtc_from_outputs_set(crtc);
@ -613,10 +617,11 @@ _e_randr_apply(void)
w = rect.w; w = rect.w;
h = rect.h; h = rect.h;
/* if the crtc does not fit, disable it */ /* if the output does not fit, disable it */
if (((x + w) > maxw) || ((y + h) > maxh) || (mode == 0)) if (((x + w) > maxw) || ((y + h) > maxh) || (mode == 0))
{ {
printf("RRR2: crtc dose not fit - off\n"); printf("RRR2: crtc does not fit - off\n");
/* TODO: This is wrong, should remove output from crtc->outputs */
ecore_x_randr_crtc_settings_set(root, crtc->xid, NULL, 0, 0, 0, 0, ecore_x_randr_crtc_settings_set(root, crtc->xid, NULL, 0, 0, 0, 0,
ECORE_X_RANDR_ORIENTATION_ROT_0); ECORE_X_RANDR_ORIENTATION_ROT_0);
continue; continue;
@ -629,34 +634,10 @@ _e_randr_apply(void)
printf("RRR2: cannot alloc coutputs\n"); printf("RRR2: cannot alloc coutputs\n");
continue; continue;
} }
count = 0;
EINA_LIST_FOREACH(crtc->outputs, ll, output) EINA_LIST_FOREACH(crtc->outputs, ll, output)
{ {
E_Randr_Output *out2 = _e_randr_output_find(output->xid); coutputs[count++] = output->xid;
if (out2)
{
if ((out2->cfg) && (out2->crtc == crtc) && (out2->mode) &&
(out2->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED))
{
int i;
Eina_Bool ok;
ok = EINA_TRUE;
for (i = 0; i < count; i++)
{
if (coutputs[i] == out2->xid)
{
ok = EINA_FALSE;
break;
}
}
if (ok)
{
printf("RRR2: add output %s\n", out2->name);
coutputs[count] = out2->xid;
count++;
}
}
}
} }
printf("RRR2: set mode %x | %i %i %ix%i | %x | %i\n", printf("RRR2: set mode %x | %i %i %ix%i | %x | %i\n",
@ -664,16 +645,9 @@ _e_randr_apply(void)
crtc->geo.x, crtc->geo.y, crtc->geo.w, crtc->geo.h, crtc->geo.x, crtc->geo.y, crtc->geo.w, crtc->geo.h,
crtc->mode, crtc->orient); crtc->mode, crtc->orient);
/* apply our stored crtc settings */ /* apply our stored crtc settings */
if (count > 0) ecore_x_randr_crtc_settings_set(root, crtc->xid, coutputs,
ecore_x_randr_crtc_settings_set(root, crtc->xid, coutputs, count, crtc->geo.x, crtc->geo.y,
count, crtc->geo.x, crtc->geo.y, crtc->mode, crtc->orient);
crtc->mode, crtc->orient);
else
{
printf("RRR2: no coutputs - off\n");
ecore_x_randr_crtc_settings_set(root, crtc->xid, NULL, 0, 0, 0, 0,
ECORE_X_RANDR_ORIENTATION_ROT_0);
}
/* cleanup */ /* cleanup */
free(coutputs); free(coutputs);
@ -725,6 +699,7 @@ _e_randr_event_cb_crtc_change(void *data EINA_UNUSED, int type EINA_UNUSED, void
ev = event; ev = event;
crtc = _e_randr_crtc_find(ev->crtc); crtc = _e_randr_crtc_find(ev->crtc);
/* TODO: If crtc is disconnected, we must remove it from E_Randr_Output->crtc */
if (!crtc) if (!crtc)
{ {
crtc = E_NEW(E_Randr_Crtc, 1); crtc = E_NEW(E_Randr_Crtc, 1);
@ -801,7 +776,6 @@ _e_randr_event_cb_output_change(void *data EINA_UNUSED, int type EINA_UNUSED, vo
} }
else if (ev->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) else if (ev->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
{ {
E_Randr_Crtc *crtc = NULL;
Eina_Bool unknown = EINA_FALSE; Eina_Bool unknown = EINA_FALSE;
if ((!output->crtc) || (output->crtc->xid == 0)) unknown = EINA_TRUE; if ((!output->crtc) || (output->crtc->xid == 0)) unknown = EINA_TRUE;
@ -811,19 +785,18 @@ _e_randr_event_cb_output_change(void *data EINA_UNUSED, int type EINA_UNUSED, vo
{ {
/* remove from old crtc */ /* remove from old crtc */
_e_randr_output_active_set(output, EINA_FALSE); _e_randr_output_active_set(output, EINA_FALSE);
/* set new crtc on output */ /* forget out crtc */
output->crtc = _e_randr_crtc_find(ev->crtc); output->crtc = NULL;
} }
if ((!output->active) && (output->cfg->connect)) if ((!output->active) && (output->cfg->connect))
{ {
crtc = _e_randr_output_crtc_find(output); /* connect to crtc */
if (crtc) _e_randr_output_active_set(output, EINA_TRUE);
if (output->crtc)
{ {
/* connect to crtc */
_e_randr_output_active_set(output, EINA_TRUE);
/* get orientation from crtc if not set */ /* get orientation from crtc if not set */
if (!output->cfg->orient) if (!output->cfg->orient)
output->cfg->orient = crtc->orient; output->cfg->orient = output->crtc->orient;
/* validate output mode */ /* validate output mode */
_e_randr_output_mode_update(output); _e_randr_output_mode_update(output);
/* if unknown position at far right */ /* if unknown position at far right */
@ -942,19 +915,12 @@ _e_randr_output_mode_update(E_Randr_Output *output)
printf("RR: ... 5\n"); printf("RR: ... 5\n");
/* see if we can use the mode of the crtc */ /* see if we can use the mode of the crtc */
if ((!output->mode) && (output->crtc)) if ((!output->mode) && (output->crtc) && (output->crtc->mode))
{ {
E_Randr_Crtc *crtc;
crtc = _e_randr_crtc_find(ecore_x_randr_output_crtc_get(root, output->xid));
printf("RR: ... 6\n"); printf("RR: ... 6\n");
if (crtc && crtc->mode) if (_e_randr_output_mode_valid(output->crtc->mode, modes, nmodes))
{ output->mode = output->crtc->mode;
printf("RR: ... 6.1\n"); /* TODO: See if we have a mode of the same size with another mode id */
if (_e_randr_output_mode_valid(crtc->mode, modes, nmodes))
output->mode = crtc->mode;
/* TODO: See if we have a mode of the same size with another mode id */
}
} }
printf("RR: ... 7\n"); printf("RR: ... 7\n");
@ -1028,6 +994,7 @@ _e_randr_config_output_find(E_Randr_Output *output)
E_Config_Randr_Output *output_cfg; E_Config_Randr_Output *output_cfg;
char b1[4096], b2[4096]; char b1[4096], b2[4096];
/* TODO: Should not match if unknown name and edid */
snprintf(b1, sizeof(b1), "%s.%s", snprintf(b1, sizeof(b1), "%s.%s",
output->name ? output->name : "???", output->name ? output->name : "???",
output->edid ? output->edid : "???"); output->edid ? output->edid : "???");
@ -1072,7 +1039,7 @@ _e_randr_output_find(Ecore_X_Randr_Output xid)
return NULL; return NULL;
} }
static E_Randr_Crtc * static void
_e_randr_output_crtc_find(E_Randr_Output *output) _e_randr_output_crtc_find(E_Randr_Output *output)
{ {
Ecore_X_Window root = 0; Ecore_X_Window root = 0;
@ -1085,7 +1052,7 @@ _e_randr_output_crtc_find(E_Randr_Output *output)
/* grab the root window */ /* grab the root window */
root = ecore_x_window_root_first_get(); root = ecore_x_window_root_first_get();
/* check if last is available */ /* check if current is available */
if ((crtc = _e_randr_crtc_find(ecore_x_randr_output_crtc_get(root, output->xid)))) if ((crtc = _e_randr_crtc_find(ecore_x_randr_output_crtc_get(root, output->xid))))
{ {
if (!crtc->outputs) if (!crtc->outputs)
@ -1130,14 +1097,13 @@ done:
free(modes); free(modes);
output->crtc = crtc; output->crtc = crtc;
return output->crtc; return;
error: error:
free(possible); free(possible);
free(modes); free(modes);
output->crtc = NULL; output->crtc = NULL;
return output->crtc;
} }
static void static void
@ -1256,8 +1222,6 @@ _e_randr_crtc_from_outputs_set(E_Randr_Crtc *crtc)
EINA_LIST_FOREACH(crtc->outputs, l, output) EINA_LIST_FOREACH(crtc->outputs, l, output)
{ {
if (!output->active) continue;
if (output->status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) continue;
printf("RRR: output: '%s' lid: %i active: %i status: %i\n", output->name, output->is_lid, output->active, output->status); printf("RRR: output: '%s' lid: %i active: %i status: %i\n", output->name, output->is_lid, output->active, output->status);
/* TODO: Match all connected outputs, not only the first */ /* TODO: Match all connected outputs, not only the first */
crtc->mode = output->mode; crtc->mode = output->mode;
@ -1315,60 +1279,31 @@ _e_randr_output_mode_valid(Ecore_X_Randr_Mode mode, Ecore_X_Randr_Mode *modes, i
static void static void
_e_randr_output_active_set(E_Randr_Output *output, Eina_Bool active) _e_randr_output_active_set(E_Randr_Output *output, Eina_Bool active)
{ {
E_Randr_Crtc *crtc;
Ecore_X_Window root = 0;
printf("RR: _e_randr_output_active_set... [%s] %i %i\n", output->name, output->active, active); printf("RR: _e_randr_output_active_set... [%s] %i %i\n", output->name, output->active, active);
output->active = active;
root = ecore_x_window_root_first_get(); if (!output->crtc)
printf("RR: ecore_x_randr_output_crtc_get %x = %x\n", output->xid, ecore_x_randr_output_crtc_get(root, output->xid));
crtc = _e_randr_crtc_find(ecore_x_randr_output_crtc_get(root, output->xid));
if (!crtc)
{ {
crtc = _e_randr_output_crtc_find(output); _e_randr_output_crtc_find(output);
if (!crtc) crtc = output->crtc;
if (!crtc)
{
Eina_List *l;
E_Randr_Crtc *crtc2;
EINA_LIST_FOREACH(e_randr->crtcs, l, crtc2)
{
printf("RR: ... looking at %x, outputs = %p\n", crtc2->xid, crtc2->outputs);
if (!crtc2->outputs) break;
else
{
if (!crtc2->mode) break;
}
crtc2 = NULL;
}
if (crtc2) crtc = crtc2;
}
printf("RR: ... output crtc2 = %p\n", crtc);
if (crtc) printf("RR: ... id = %x\n", crtc->xid);
} }
if (crtc) if (output->crtc)
{ {
output->active = active;
printf("RR: ... found crtc %i\n", active); printf("RR: ... found crtc %i\n", active);
if (active) if (active)
{ {
crtc->outputs = output->crtc->outputs =
eina_list_append(crtc->outputs, output); eina_list_append(output->crtc->outputs, output);
output->crtc = crtc;
e_randr->active++; e_randr->active++;
printf("RR: ... add active output for crtc now\n"); printf("RR: ... add active output for crtc now\n");
} }
else else
{ {
crtc->outputs = output->crtc->outputs =
eina_list_remove(crtc->outputs, output); eina_list_remove(output->crtc->outputs, output);
output->crtc = NULL;
e_randr->active--; e_randr->active--;
printf("RR: ... remove output for crtc now\n"); printf("RR: ... remove output for crtc now\n");
} }
} }
else output->crtc = NULL;
printf("RR: _e_randr_output_active_set... done - %p\n", output->crtc); printf("RR: _e_randr_output_active_set... done - %p\n", output->crtc);
} }

View File

@ -138,7 +138,7 @@ _item_submenu_new(E_DBusMenu_Item *item, E_Menu_Item *mi)
{ {
e_menu_item_label_set(submi, child->label); e_menu_item_label_set(submi, child->label);
e_menu_item_callback_set(submi, _sub_item_clicked_cb, child); e_menu_item_callback_set(submi, _sub_item_clicked_cb, child);
if (!child->enabled) e_menu_item_disabled_set(submi, 1); //if (!child->enabled) e_menu_item_disabled_set(submi, 1);
if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_CHECKMARK) if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_CHECKMARK)
e_menu_item_check_set(submi, 1); e_menu_item_check_set(submi, 1);
else if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_RADIO) else if (child->toggle_type == E_DBUSMENU_ITEM_TOGGLE_TYPE_RADIO)