Revert "Randr: Fix null dereference."

This reverts commit 4aef218d28.

Revert "randr: remember crtcid for fast lookup on reconnect"
This reverts commit 55b4ad41d1.

Revert "randr: further cleanup"
This reverts commit 3e02824663.

these make nvidia randr resolution changing work again. sorry seb.
even though cleanups might be nice... this code is FIDDLY and every
driver seems to work differently, so take it easy and be very careful
- make no assumptions. i know it works on my intel desktop and nvidia
deskop atm. once i get a vga cable i'll fix up intel laptop with
external display that has problems. i can try radeon too later. but
right now - this stuff needs to work. being clean is far less
important than working. :)
This commit is contained in:
Carsten Haitzler 2014-12-17 09:33:45 +09:00
parent 9677b71902
commit 43f1dc012d
3 changed files with 137 additions and 76 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 void _e_randr_output_crtc_find(E_Randr_Output *output); static E_Randr_Crtc *_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,30 +140,31 @@ 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) if ((output->cfg) && (!output->cfg->connect))
{ {
if (!output->cfg->connect) printf("RR: output disabled\n");
{ _e_randr_output_active_set(output, EINA_FALSE);
printf("RR: output disabled\n"); }
_e_randr_output_active_set(output, EINA_FALSE); else if ((output->cfg) && (output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED))
} {
else if (output->status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) if (output->cfg)
{ {
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: active set...\n");
_e_randr_output_active_set(output, EINA_TRUE);
printf("RR: update mode\n"); printf("RR: update mode\n");
_e_randr_output_mode_update(output); _e_randr_output_mode_update(output);
printf("RR: active set...\n");
_e_randr_output_active_set(output, EINA_TRUE);
printf("RR: active set done\n");
} }
else else
printf("RR: not connected and not connect\n"); printf("RR: no cfg\n");
} }
else else
{ {
printf("RR: no cfg\n"); printf("RR: ???\n");
} }
} }
printf("RR: ... lid update\n"); printf("RR: ... lid update\n");
@ -474,9 +475,8 @@ _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, output->xid); output->edid = _e_randr_output_edid_string_get(root, outputs[j]);
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->crtcid = ecore_x_randr_output_crtc_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)
{ {
@ -485,27 +485,30 @@ _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 %s %i %p\n", output->xid, output->name, output->edid, output->status, output->cfg); printf("RR: output %x %s %i %p\n", output->xid, output->name, 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_output_active_set(output, EINA_TRUE); E_Randr_Crtc *crtc;
if (output->crtc)
crtc = _e_randr_output_crtc_find(output);
printf("RR: ouput on crtc = %p\n", crtc);
if (crtc)
{ {
printf("RR: output on crtc = %p\n", output->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 = output->crtc->orient; output->cfg->orient = 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 = output->crtc->geo.x; output->cfg->geo.x = crtc->geo.x;
output->cfg->geo.y = output->crtc->geo.y; output->cfg->geo.y = crtc->geo.y;
} }
} }
} }
@ -596,14 +599,6 @@ _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);
@ -619,11 +614,10 @@ _e_randr_apply(void)
w = rect.w; w = rect.w;
h = rect.h; h = rect.h;
/* if the output does not fit, disable it */ /* if the crtc 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 does not fit - off\n"); printf("RRR2: crtc dose 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;
@ -636,10 +630,34 @@ _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)
{ {
coutputs[count++] = output->xid; E_Randr_Output *out2 = _e_randr_output_find(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",
@ -647,9 +665,16 @@ _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 */
ecore_x_randr_crtc_settings_set(root, crtc->xid, coutputs, if (count > 0)
count, crtc->geo.x, crtc->geo.y, ecore_x_randr_crtc_settings_set(root, crtc->xid, coutputs,
crtc->mode, crtc->orient); count, crtc->geo.x, crtc->geo.y,
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);
@ -701,7 +726,6 @@ _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);
@ -778,28 +802,29 @@ _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;
/* connected */ /* connected */
output->crtcid = ev->crtc;
if ((ev->crtc != 0) && ((!unknown) && (output->crtc->xid != ev->crtc))) if ((ev->crtc != 0) && ((!unknown) && (output->crtc->xid != ev->crtc)))
{ {
/* remove from old crtc */ /* remove from old crtc */
_e_randr_output_active_set(output, EINA_FALSE); _e_randr_output_active_set(output, EINA_FALSE);
/* forget out crtc */ /* set new crtc on output */
output->crtc = NULL; output->crtc = _e_randr_crtc_find(ev->crtc);
} }
if ((!output->active) && (output->cfg->connect)) if ((!output->active) && (output->cfg->connect))
{ {
/* connect to crtc */ crtc = _e_randr_output_crtc_find(output);
_e_randr_output_active_set(output, EINA_TRUE); if (crtc)
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 = output->crtc->orient; output->cfg->orient = 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 */
@ -918,12 +943,19 @@ _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) && (output->crtc->mode)) if ((!output->mode) && (output->crtc))
{ {
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 (_e_randr_output_mode_valid(output->crtc->mode, modes, nmodes)) if (crtc && crtc->mode)
output->mode = output->crtc->mode; {
/* TODO: See if we have a mode of the same size with another mode id */ printf("RR: ... 6.1\n");
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");
@ -997,7 +1029,6 @@ _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 : "???");
@ -1042,7 +1073,7 @@ _e_randr_output_find(Ecore_X_Randr_Output xid)
return NULL; return NULL;
} }
static void static E_Randr_Crtc *
_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;
@ -1052,17 +1083,17 @@ _e_randr_output_crtc_find(E_Randr_Output *output)
int num = 0, i = 0; int num = 0, i = 0;
int nmodes, pref; int nmodes, pref;
/* check if current is available */ /* grab the root window */
if ((crtc = _e_randr_crtc_find(output->crtcid))) root = ecore_x_window_root_first_get();
/* check if last is available */
if ((crtc = _e_randr_crtc_find(ecore_x_randr_output_crtc_get(root, output->xid))))
{ {
if (!crtc->outputs) if (!crtc->outputs)
goto done; goto done;
} }
crtc = NULL; crtc = NULL;
/* grab the root window */
root = ecore_x_window_root_first_get();
/* get a list of possible crtcs for this output */ /* get a list of possible crtcs for this output */
possible = ecore_x_randr_output_possible_crtcs_get(root, output->xid, &num); possible = ecore_x_randr_output_possible_crtcs_get(root, output->xid, &num);
if (num == 0) goto error; if (num == 0) goto error;
@ -1093,20 +1124,21 @@ _e_randr_output_crtc_find(E_Randr_Output *output)
goto done; goto done;
} }
} }
crtc = NULL;
done:
free(possible);
free(modes);
output->crtc = crtc;
return output->crtc;
error: error:
free(possible); free(possible);
free(modes); free(modes);
output->crtc = NULL; output->crtc = NULL;
return; return output->crtc;
done:
free(possible);
free(modes);
output->crtcid = crtc->xid;
output->crtc = crtc;
} }
static void static void
@ -1226,6 +1258,8 @@ _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;
@ -1283,32 +1317,60 @@ _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)
{ {
printf("RR: _e_randr_output_active_set... [%s] %i %i\n", output->name, output->active, active); E_Randr_Crtc *crtc;
Ecore_X_Window root = 0;
if (!output->crtc) 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();
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)
{ {
_e_randr_output_crtc_find(output); crtc = _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 (output->crtc) if (crtc)
{ {
output->active = active;
printf("RR: ... found crtc %i\n", active); printf("RR: ... found crtc %i\n", active);
if (active) if (active)
{ {
output->crtc->outputs = crtc->outputs =
eina_list_append(output->crtc->outputs, output); eina_list_append(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
{ {
output->crtc->outputs = crtc->outputs =
eina_list_remove(output->crtc->outputs, output); eina_list_remove(crtc->outputs, output);
e_randr->active--;
output->crtc = NULL; output->crtc = NULL;
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

@ -55,7 +55,6 @@ struct _E_Randr_Output
E_Config_Randr_Output *cfg; E_Config_Randr_Output *cfg;
E_Randr_Crtc *crtc; E_Randr_Crtc *crtc;
Ecore_X_Randr_Crtc crtcid;
}; };
struct _E_Randr_Crtc struct _E_Randr_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)