Fix randr plug-n-play for cedric because he asked nicely ;)
- Add config timestamping to our randr config. - remove property_notify handler as we never use it. - Unify some code to remove duplication - Add a lot of debugging output. Yes, e_randr is going to be noisy for a little while until I can verify that it works for others also. - Too many other changes to list. Suffice to say, this makes e_randr plug-n-play work (here anyway). NB: Right now, this just clones. It Could be changed to extend new monitors tho NB: This works here, on my laptop at home. If you find it does not work for you, please supply the output of E's startup/restart when you plug AND unplug monitors. Signed-off-by: Chris Michael <devilhorns@comcast.net>
This commit is contained in:
parent
1edb77e5c4
commit
9e605ebce8
|
@ -6,11 +6,15 @@ static void _e_randr_config_new(void);
|
||||||
static void _e_randr_config_free(void);
|
static void _e_randr_config_free(void);
|
||||||
static Eina_Bool _e_randr_config_cb_timer(void *data);
|
static Eina_Bool _e_randr_config_cb_timer(void *data);
|
||||||
static void _e_randr_config_restore(void);
|
static void _e_randr_config_restore(void);
|
||||||
|
static Eina_Bool _e_randr_config_crtc_update(E_Randr_Crtc_Config *cfg);
|
||||||
|
static Eina_Bool _e_randr_config_output_update(E_Randr_Output_Config *cfg);
|
||||||
|
static E_Randr_Crtc_Config *_e_randr_config_output_crtc_find(E_Randr_Output_Config *cfg);
|
||||||
|
static Ecore_X_Randr_Mode _e_randr_config_output_preferred_mode_get(E_Randr_Output_Config *cfg);
|
||||||
|
static E_Randr_Output_Config *_e_randr_config_output_new(unsigned int id);
|
||||||
|
|
||||||
static Eina_Bool _e_randr_event_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
static Eina_Bool _e_randr_event_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||||
static Eina_Bool _e_randr_event_cb_crtc_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
static Eina_Bool _e_randr_event_cb_crtc_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||||
static Eina_Bool _e_randr_event_cb_output_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
static Eina_Bool _e_randr_event_cb_output_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
|
||||||
static Eina_Bool _e_randr_event_cb_property_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED);
|
|
||||||
|
|
||||||
/* local variables */
|
/* local variables */
|
||||||
static Eina_List *_randr_event_handlers = NULL;
|
static Eina_List *_randr_event_handlers = NULL;
|
||||||
|
@ -55,9 +59,6 @@ e_randr_init(void)
|
||||||
E_LIST_HANDLER_APPEND(_randr_event_handlers,
|
E_LIST_HANDLER_APPEND(_randr_event_handlers,
|
||||||
ECORE_X_EVENT_RANDR_OUTPUT_CHANGE,
|
ECORE_X_EVENT_RANDR_OUTPUT_CHANGE,
|
||||||
_e_randr_event_cb_output_change, NULL);
|
_e_randr_event_cb_output_change, NULL);
|
||||||
E_LIST_HANDLER_APPEND(_randr_event_handlers,
|
|
||||||
ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY,
|
|
||||||
_e_randr_event_cb_property_change, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EINA_TRUE;
|
return EINA_TRUE;
|
||||||
|
@ -154,6 +155,7 @@ _e_randr_config_load(void)
|
||||||
E_CONFIG_LIST(D, T, crtcs, _e_randr_crtc_edd);
|
E_CONFIG_LIST(D, T, crtcs, _e_randr_crtc_edd);
|
||||||
E_CONFIG_VAL(D, T, restore, UCHAR);
|
E_CONFIG_VAL(D, T, restore, UCHAR);
|
||||||
E_CONFIG_VAL(D, T, poll_interval, INT);
|
E_CONFIG_VAL(D, T, poll_interval, INT);
|
||||||
|
E_CONFIG_VAL(D, T, config_timestamp, ULL);
|
||||||
|
|
||||||
/* try to load the randr config */
|
/* try to load the randr config */
|
||||||
if ((e_randr_cfg = e_config_domain_load("e_randr", _e_randr_edd)))
|
if ((e_randr_cfg = e_config_domain_load("e_randr", _e_randr_edd)))
|
||||||
|
@ -199,12 +201,6 @@ _e_randr_config_load(void)
|
||||||
/* e_randr_config_new could return without actually creating a new config */
|
/* e_randr_config_new could return without actually creating a new config */
|
||||||
if (!e_randr_cfg) return EINA_FALSE;
|
if (!e_randr_cfg) return EINA_FALSE;
|
||||||
|
|
||||||
/* handle upgrading any old config */
|
|
||||||
/* if (e_randr_cfg->version < E_RANDR_CONFIG_FILE_VERSION) */
|
|
||||||
/* { */
|
|
||||||
|
|
||||||
/* } */
|
|
||||||
|
|
||||||
if ((do_restore) && (e_randr_cfg->restore))
|
if ((do_restore) && (e_randr_cfg->restore))
|
||||||
_e_randr_config_restore();
|
_e_randr_config_restore();
|
||||||
|
|
||||||
|
@ -216,7 +212,6 @@ _e_randr_config_new(void)
|
||||||
{
|
{
|
||||||
Ecore_X_Window root = 0;
|
Ecore_X_Window root = 0;
|
||||||
Ecore_X_Randr_Crtc *crtcs = NULL;
|
Ecore_X_Randr_Crtc *crtcs = NULL;
|
||||||
Ecore_X_Randr_Output primary = 0;
|
|
||||||
int ncrtcs = 0, i = 0;
|
int ncrtcs = 0, i = 0;
|
||||||
|
|
||||||
/* create new randr cfg */
|
/* create new randr cfg */
|
||||||
|
@ -235,9 +230,6 @@ _e_randr_config_new(void)
|
||||||
/* grab the root window once */
|
/* grab the root window once */
|
||||||
root = ecore_x_window_root_first_get();
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
/* get which output is primary */
|
|
||||||
primary = ecore_x_randr_primary_output_get(root);
|
|
||||||
|
|
||||||
/* record the current screen size in our config */
|
/* record the current screen size in our config */
|
||||||
ecore_x_randr_screen_current_size_get(root, &e_randr_cfg->screen.width,
|
ecore_x_randr_screen_current_size_get(root, &e_randr_cfg->screen.width,
|
||||||
&e_randr_cfg->screen.height,
|
&e_randr_cfg->screen.height,
|
||||||
|
@ -261,18 +253,8 @@ _e_randr_config_new(void)
|
||||||
crtc_cfg->xid = crtcs[i];
|
crtc_cfg->xid = crtcs[i];
|
||||||
crtc_cfg->exists = EINA_TRUE;
|
crtc_cfg->exists = EINA_TRUE;
|
||||||
|
|
||||||
/* record the geometry of this crtc in our config */
|
/* fill in crtc_cfg values from X */
|
||||||
ecore_x_randr_crtc_geometry_get(root, crtcs[i],
|
_e_randr_config_crtc_update(crtc_cfg);
|
||||||
&crtc_cfg->x, &crtc_cfg->y,
|
|
||||||
&crtc_cfg->width,
|
|
||||||
&crtc_cfg->height);
|
|
||||||
|
|
||||||
/* record the orientation of this crtc in our config */
|
|
||||||
crtc_cfg->orient =
|
|
||||||
ecore_x_randr_crtc_orientation_get(root, crtcs[i]);
|
|
||||||
|
|
||||||
/* record the mode id of this crtc in our config */
|
|
||||||
crtc_cfg->mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
|
|
||||||
|
|
||||||
/* try to get any outputs on this crtc */
|
/* try to get any outputs on this crtc */
|
||||||
if ((outputs =
|
if ((outputs =
|
||||||
|
@ -283,46 +265,13 @@ _e_randr_config_new(void)
|
||||||
for (j = 0; j < noutputs; j++)
|
for (j = 0; j < noutputs; j++)
|
||||||
{
|
{
|
||||||
E_Randr_Output_Config *output_cfg = NULL;
|
E_Randr_Output_Config *output_cfg = NULL;
|
||||||
Ecore_X_Randr_Connection_Status status = 1;
|
|
||||||
int clone_count = 0;
|
|
||||||
|
|
||||||
/* try to create new output config */
|
/* try to create new output config */
|
||||||
if (!(output_cfg = E_NEW(E_Randr_Output_Config, 1)))
|
if (!(output_cfg = _e_randr_config_output_new(outputs[j])))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* assign output xid */
|
|
||||||
output_cfg->xid = outputs[j];
|
|
||||||
|
|
||||||
/* assign crtc for this output */
|
/* assign crtc for this output */
|
||||||
output_cfg->crtc = crtcs[i];
|
output_cfg->crtc = crtcs[i];
|
||||||
|
|
||||||
/* set this output policy */
|
|
||||||
output_cfg->policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
|
|
||||||
|
|
||||||
/* get if this output is the primary */
|
|
||||||
output_cfg->primary = EINA_FALSE;
|
|
||||||
if (outputs[j] == primary)
|
|
||||||
output_cfg->primary = EINA_TRUE;
|
|
||||||
|
|
||||||
/* record the edid for this output */
|
|
||||||
output_cfg->edid =
|
|
||||||
ecore_x_randr_output_edid_get(root, outputs[j],
|
|
||||||
&output_cfg->edid_count);
|
|
||||||
|
|
||||||
/* get the clones for this output */
|
|
||||||
output_cfg->clones =
|
|
||||||
ecore_x_randr_output_clones_get(root, outputs[j],
|
|
||||||
&clone_count);
|
|
||||||
|
|
||||||
output_cfg->clone_count = (long)clone_count;
|
|
||||||
|
|
||||||
status =
|
|
||||||
ecore_x_randr_output_connection_status_get(root, outputs[j]);
|
|
||||||
|
|
||||||
output_cfg->connected = EINA_FALSE;
|
|
||||||
if (status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
|
|
||||||
output_cfg->connected = EINA_TRUE;
|
|
||||||
|
|
||||||
output_cfg->exists = EINA_TRUE;
|
output_cfg->exists = EINA_TRUE;
|
||||||
|
|
||||||
/* add this output to the list for this crtc */
|
/* add this output to the list for this crtc */
|
||||||
|
@ -341,6 +290,9 @@ _e_randr_config_new(void)
|
||||||
free(crtcs);
|
free(crtcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* update recorded config timestamp */
|
||||||
|
e_randr_cfg->config_timestamp = ecore_x_randr_config_timestamp_get(root);
|
||||||
|
|
||||||
/* set limits */
|
/* set limits */
|
||||||
E_CONFIG_LIMIT(e_randr_cfg->poll_interval, 1, 1024);
|
E_CONFIG_LIMIT(e_randr_cfg->poll_interval, 1, 1024);
|
||||||
|
|
||||||
|
@ -390,37 +342,34 @@ _e_randr_config_restore(void)
|
||||||
Ecore_X_Window root = 0;
|
Ecore_X_Window root = 0;
|
||||||
Ecore_X_Randr_Crtc *crtcs;
|
Ecore_X_Randr_Crtc *crtcs;
|
||||||
int ncrtcs = 0;
|
int ncrtcs = 0;
|
||||||
Eina_Bool need_reset = EINA_FALSE;
|
|
||||||
|
|
||||||
/* try to restore settings
|
printf("E_RANDR Restore\n");
|
||||||
*
|
|
||||||
* NB: When we restore, check the resolutions (current vs saved)
|
|
||||||
* and if there is no change then we do not need to call
|
|
||||||
* screen_reset as this triggers a full comp refresh. We can
|
|
||||||
* accomplish this simply by checking the mode */
|
|
||||||
|
|
||||||
/* grab the root window */
|
/* grab the root window */
|
||||||
root = ecore_x_window_root_first_get();
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
/* try to get the list of crtcs */
|
/* set the screen size */
|
||||||
|
/* NB: Disabled for now as our saved screen size may not be valid
|
||||||
|
* if any of our saved outputs are missing in X */
|
||||||
|
/* ecore_x_randr_screen_current_size_set(root, e_randr_cfg->screen.width, */
|
||||||
|
/* e_randr_cfg->screen.height, -1, -1); */
|
||||||
|
|
||||||
|
/* try to get the list of existing crtcs from X */
|
||||||
if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
|
if ((crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs)))
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
Eina_List *valid_crtcs = NULL;
|
||||||
|
Eina_List *l;
|
||||||
|
E_Randr_Crtc_Config *crtc_cfg;
|
||||||
|
|
||||||
|
printf("\tHave Crtcs\n");
|
||||||
|
|
||||||
|
/* for each crtc that X has, check our config and see if we have it */
|
||||||
for (i = 0; i < ncrtcs; i++)
|
for (i = 0; i < ncrtcs; i++)
|
||||||
{
|
{
|
||||||
Eina_List *l;
|
Eina_Bool crtc_found = EINA_FALSE;
|
||||||
E_Randr_Crtc_Config *crtc_cfg;
|
|
||||||
Ecore_X_Randr_Mode mode;
|
|
||||||
Ecore_X_Randr_Output *outputs;
|
|
||||||
int noutputs = 0;
|
|
||||||
|
|
||||||
/* get the mode */
|
printf("\t\tChecking For Crtc: %d in Our Config\n", crtcs[i]);
|
||||||
mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
|
|
||||||
|
|
||||||
/* get the outputs */
|
|
||||||
outputs =
|
|
||||||
ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs);
|
|
||||||
|
|
||||||
/* loop our config and find this crtc */
|
/* loop our config and find this crtc */
|
||||||
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
||||||
|
@ -428,33 +377,167 @@ _e_randr_config_restore(void)
|
||||||
/* try to find this crtc */
|
/* try to find this crtc */
|
||||||
if (crtc_cfg->xid != crtcs[i]) continue;
|
if (crtc_cfg->xid != crtcs[i]) continue;
|
||||||
|
|
||||||
/* apply the stored settings */
|
crtc_found = EINA_TRUE;
|
||||||
if (!crtc_cfg->mode)
|
printf("\t\t\tFound Crtc in Config\n");
|
||||||
ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid,
|
valid_crtcs = eina_list_append(valid_crtcs, crtc_cfg);
|
||||||
NULL, 0, 0, 0, 0,
|
|
||||||
ECORE_X_RANDR_ORIENTATION_ROT_0);
|
|
||||||
else
|
|
||||||
ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid,
|
|
||||||
outputs, noutputs,
|
|
||||||
crtc_cfg->x, crtc_cfg->y,
|
|
||||||
crtc_cfg->mode,
|
|
||||||
crtc_cfg->orient);
|
|
||||||
|
|
||||||
if (crtc_cfg->mode != mode)
|
|
||||||
need_reset = EINA_TRUE;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free any allocated memory from ecore_x_randr */
|
if (!crtc_found)
|
||||||
free(outputs);
|
{
|
||||||
|
printf("\t\t\tCrtc Not Found in Config\n");
|
||||||
|
printf("\t\t\t\tCreating New\n");
|
||||||
|
/* create new crtc config */
|
||||||
|
if ((crtc_cfg = E_NEW(E_Randr_Crtc_Config, 1)))
|
||||||
|
{
|
||||||
|
/* assign id */
|
||||||
|
crtc_cfg->xid = crtcs[i];
|
||||||
|
crtc_cfg->exists = EINA_TRUE;
|
||||||
|
|
||||||
|
/* fill in crtc_cfg values from X */
|
||||||
|
_e_randr_config_crtc_update(crtc_cfg);
|
||||||
|
|
||||||
|
printf("\t\t\t\tNew Crtc Geom: %d %d %d %d\n",
|
||||||
|
crtc_cfg->x, crtc_cfg->y, crtc_cfg->width,
|
||||||
|
crtc_cfg->height);
|
||||||
|
printf("\t\t\t\tNew Crtc Mode: %d\n", crtc_cfg->mode);
|
||||||
|
|
||||||
|
/* append to randr cfg */
|
||||||
|
e_randr_cfg->crtcs =
|
||||||
|
eina_list_append(e_randr_cfg->crtcs, crtc_cfg);
|
||||||
|
|
||||||
|
e_randr_config_save();
|
||||||
|
|
||||||
|
/* append to our short list */
|
||||||
|
valid_crtcs = eina_list_append(valid_crtcs, crtc_cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* free any allocated memory from ecore_x_randr */
|
|
||||||
free(crtcs);
|
free(crtcs);
|
||||||
|
|
||||||
|
printf("\t\tLooping Valid Crtcs\n");
|
||||||
|
|
||||||
|
/* for each X crtc that we have config for, check outputs */
|
||||||
|
EINA_LIST_FOREACH(valid_crtcs, l, crtc_cfg)
|
||||||
|
{
|
||||||
|
Ecore_X_Randr_Output *outputs;
|
||||||
|
int noutputs;
|
||||||
|
Eina_List *valid_outputs = NULL;
|
||||||
|
|
||||||
|
/* we have this crtc. try to get list of outputs from X */
|
||||||
|
if ((outputs =
|
||||||
|
ecore_x_randr_crtc_outputs_get(root, crtc_cfg->xid, &noutputs)))
|
||||||
|
{
|
||||||
|
int j = 0;
|
||||||
|
|
||||||
|
printf("\t\t\tHave X Outputs For Crtc: %d\n", crtc_cfg->xid);
|
||||||
|
|
||||||
|
/* loop the X outputs and find a matching config */
|
||||||
|
for (j = 0; j < noutputs; j++)
|
||||||
|
{
|
||||||
|
Eina_List *ll;
|
||||||
|
E_Randr_Output_Config *output_cfg;
|
||||||
|
/* Eina_Bool output_found = EINA_FALSE; */
|
||||||
|
|
||||||
|
printf("\t\t\t\tChecking for Output: %d in Our Config\n", outputs[j]);
|
||||||
|
|
||||||
|
/* loop our outputs for this crtc */
|
||||||
|
EINA_LIST_FOREACH(crtc_cfg->outputs, ll, output_cfg)
|
||||||
|
{
|
||||||
|
/* try to find this output */
|
||||||
|
if (output_cfg->xid != outputs[j]) continue;
|
||||||
|
|
||||||
|
/* we have this output */
|
||||||
|
/* output_found = EINA_TRUE; */
|
||||||
|
|
||||||
|
printf("\t\t\t\tFound Output In Config: %d\n", outputs[j]);
|
||||||
|
|
||||||
|
/* add this output config to the list of
|
||||||
|
* ones that we are going to restore for
|
||||||
|
* this crtc */
|
||||||
|
valid_outputs =
|
||||||
|
eina_list_append(valid_outputs, output_cfg);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if (!output_found) */
|
||||||
|
/* { */
|
||||||
|
/* printf("\t\t\tOutput Not Found, Creating New\n"); */
|
||||||
|
|
||||||
|
/* if ((output_cfg = */
|
||||||
|
/* _e_randr_output_config_new(outputs[j]))) */
|
||||||
|
/* { */
|
||||||
|
/* valid_outputs = */
|
||||||
|
/* eina_list_append(valid_outputs, output_cfg); */
|
||||||
|
/* } */
|
||||||
|
/* } */
|
||||||
|
}
|
||||||
|
|
||||||
|
free(outputs);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\t\t\tNo Outputs For Crtc: %d\n", crtc_cfg->xid);
|
||||||
|
/* crtc has no outputs assigned */
|
||||||
|
/* Need to check possibles */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply settings for this crtc */
|
||||||
|
printf("\t\t\t\tApplying Crtc Settings: %d\n", crtc_cfg->xid);
|
||||||
|
|
||||||
|
if (!crtc_cfg->mode)
|
||||||
|
{
|
||||||
|
printf("\t\t\t\t\tCRTC HAS NO MODE !!!\n");
|
||||||
|
ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid,
|
||||||
|
NULL, 0, 0, 0, 0,
|
||||||
|
ECORE_X_RANDR_ORIENTATION_ROT_0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ocount, c = 0;
|
||||||
|
|
||||||
|
ocount = eina_list_count(valid_outputs);
|
||||||
|
printf("\t\t\t\t\tNum Outputs: %d\n", ocount);
|
||||||
|
|
||||||
|
if (ocount > 0)
|
||||||
|
{
|
||||||
|
Ecore_X_Randr_Output *couts;
|
||||||
|
Eina_List *o;
|
||||||
|
E_Randr_Output_Config *out;
|
||||||
|
|
||||||
|
couts = malloc(ocount * sizeof(Ecore_X_Randr_Output));
|
||||||
|
EINA_LIST_FOREACH(valid_outputs, o, out)
|
||||||
|
{
|
||||||
|
couts[c] = out->xid;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\t\t\t\t\tCrtc Settings: %d %d %d %d\n", crtc_cfg->xid,
|
||||||
|
crtc_cfg->x, crtc_cfg->y, crtc_cfg->mode);
|
||||||
|
|
||||||
|
/* Evas_Coord mw, mh; */
|
||||||
|
/* get the size of the mode */
|
||||||
|
/* ecore_x_randr_mode_size_get(root, crtc_cfg->mode, &mw, &mh); */
|
||||||
|
/* printf("\t\t\t\t\t\tMode Size: %d %d\n", mw, mh); */
|
||||||
|
|
||||||
|
ecore_x_randr_crtc_settings_set(root, crtc_cfg->xid,
|
||||||
|
couts, ocount,
|
||||||
|
crtc_cfg->x,
|
||||||
|
crtc_cfg->y,
|
||||||
|
crtc_cfg->mode,
|
||||||
|
crtc_cfg->orient);
|
||||||
|
free(couts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
eina_list_free(valid_outputs);
|
||||||
|
}
|
||||||
|
eina_list_free(valid_crtcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (need_reset) ecore_x_randr_screen_reset(root);
|
// e_randr_config_save();
|
||||||
|
|
||||||
|
// if (need_reset) ecore_x_randr_screen_reset(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
|
@ -465,20 +548,34 @@ _e_randr_event_cb_screen_change(void *data EINA_UNUSED, int type EINA_UNUSED, vo
|
||||||
|
|
||||||
ev = event;
|
ev = event;
|
||||||
|
|
||||||
printf("E_RANDR Event: Screen Change\n");
|
printf("E_RANDR Event: Screen Change: %d %d\n",
|
||||||
|
ev->size.width, ev->size.height);
|
||||||
|
|
||||||
|
/* check if this event's root window is Our root window */
|
||||||
|
if (ev->root != e_manager_current_get()->root)
|
||||||
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
|
||||||
if (e_randr_cfg->screen.width != ev->size.width)
|
if (e_randr_cfg->screen.width != ev->size.width)
|
||||||
{
|
{
|
||||||
|
printf("\tWidth Changed\n");
|
||||||
e_randr_cfg->screen.width = ev->size.width;
|
e_randr_cfg->screen.width = ev->size.width;
|
||||||
changed = EINA_TRUE;
|
changed = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e_randr_cfg->screen.height != ev->size.height)
|
if (e_randr_cfg->screen.height != ev->size.height)
|
||||||
{
|
{
|
||||||
|
printf("\tHeight Changed\n");
|
||||||
e_randr_cfg->screen.height = ev->size.height;
|
e_randr_cfg->screen.height = ev->size.height;
|
||||||
changed = EINA_TRUE;
|
changed = EINA_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e_randr_cfg->config_timestamp != ev->config_time)
|
||||||
|
{
|
||||||
|
printf("\tConfig Timestamp Changed\n");
|
||||||
|
e_randr_cfg->config_timestamp = ev->config_time;
|
||||||
|
changed = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
if (changed) e_randr_config_save();
|
if (changed) e_randr_config_save();
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
|
@ -490,39 +587,50 @@ _e_randr_event_cb_crtc_change(void *data EINA_UNUSED, int type EINA_UNUSED, void
|
||||||
Ecore_X_Event_Randr_Crtc_Change *ev;
|
Ecore_X_Event_Randr_Crtc_Change *ev;
|
||||||
Eina_List *l = NULL;
|
Eina_List *l = NULL;
|
||||||
E_Randr_Crtc_Config *crtc_cfg;
|
E_Randr_Crtc_Config *crtc_cfg;
|
||||||
Eina_Bool changed = EINA_FALSE;
|
Eina_Bool crtc_new = EINA_FALSE;
|
||||||
|
Eina_Bool crtc_found = EINA_FALSE;
|
||||||
|
Eina_Bool crtc_changed = EINA_FALSE;
|
||||||
|
|
||||||
ev = event;
|
ev = event;
|
||||||
if (ev->crtc == 0) return ECORE_CALLBACK_RENEW;
|
|
||||||
|
|
||||||
printf("E_RANDR Event: Crtc Change: %d\n", ev->crtc);
|
|
||||||
|
|
||||||
|
/* loop our crtc configs and try to find this one */
|
||||||
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
||||||
{
|
{
|
||||||
if (crtc_cfg->xid == ev->crtc)
|
/* skip if not this crtc */
|
||||||
|
if (crtc_cfg->xid != ev->crtc) continue;
|
||||||
|
|
||||||
|
crtc_found = EINA_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!crtc_found)
|
||||||
|
{
|
||||||
|
/* if this crtc is not found in our config, create it */
|
||||||
|
if ((crtc_cfg = E_NEW(E_Randr_Crtc_Config, 1)))
|
||||||
{
|
{
|
||||||
if ((crtc_cfg->x != ev->geo.x) ||
|
/* assign id */
|
||||||
(crtc_cfg->y != ev->geo.y) ||
|
crtc_cfg->xid = ev->crtc;
|
||||||
(crtc_cfg->width != ev->geo.w) ||
|
crtc_cfg->exists = EINA_TRUE;
|
||||||
(crtc_cfg->height != ev->geo.h) ||
|
|
||||||
(crtc_cfg->orient != ev->orientation) ||
|
|
||||||
(crtc_cfg->mode != ev->mode))
|
|
||||||
{
|
|
||||||
crtc_cfg->x = ev->geo.x;
|
|
||||||
crtc_cfg->y = ev->geo.y;
|
|
||||||
crtc_cfg->width = ev->geo.w;
|
|
||||||
crtc_cfg->height = ev->geo.h;
|
|
||||||
crtc_cfg->orient = ev->orientation;
|
|
||||||
crtc_cfg->mode = ev->mode;
|
|
||||||
|
|
||||||
changed = EINA_TRUE;
|
crtc_new = EINA_TRUE;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
/* append to randr cfg */
|
||||||
|
e_randr_cfg->crtcs =
|
||||||
|
eina_list_append(e_randr_cfg->crtcs, crtc_cfg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) e_randr_config_save();
|
/* check (and update if needed) our crtc config
|
||||||
|
* NB: This will fill in any new ones also */
|
||||||
|
crtc_changed = _e_randr_config_crtc_update(crtc_cfg);
|
||||||
|
|
||||||
|
/* save the config if anything changed or we added a new one */
|
||||||
|
if ((crtc_changed) || (crtc_new))
|
||||||
|
{
|
||||||
|
printf("E_RANDR Event: Crtc Change\n");
|
||||||
|
printf("\tCrtc: %d Changed or New. Saving Config\n", ev->crtc);
|
||||||
|
e_randr_config_save();
|
||||||
|
}
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
}
|
}
|
||||||
|
@ -533,71 +641,418 @@ _e_randr_event_cb_output_change(void *data EINA_UNUSED, int type EINA_UNUSED, vo
|
||||||
Ecore_X_Event_Randr_Output_Change *ev;
|
Ecore_X_Event_Randr_Output_Change *ev;
|
||||||
Eina_List *l = NULL;
|
Eina_List *l = NULL;
|
||||||
E_Randr_Crtc_Config *crtc_cfg;
|
E_Randr_Crtc_Config *crtc_cfg;
|
||||||
Eina_Bool changed = EINA_FALSE;
|
E_Randr_Output_Config *output_cfg;
|
||||||
|
Eina_Bool output_new = EINA_FALSE;
|
||||||
|
Eina_Bool output_found = EINA_FALSE;
|
||||||
|
Eina_Bool output_changed = EINA_FALSE;
|
||||||
|
Eina_Bool output_removed = EINA_FALSE;
|
||||||
|
|
||||||
ev = event;
|
ev = event;
|
||||||
|
|
||||||
/* TODO: NB: Hmmm, this is problematic :( The spec says we should get an
|
/* check if this event's root window is Our root window */
|
||||||
* event here when an output is disconnected (hotplug) if
|
if (ev->win != e_manager_current_get()->root)
|
||||||
* the hardware (video card) is capable of detecting this HOWEVER, in my
|
return ECORE_CALLBACK_RENEW;
|
||||||
* tests, my nvidia card does not detect this.
|
|
||||||
*
|
|
||||||
* To work around this, we have added a poller to check X randr config
|
|
||||||
* against what we have saved in e_randr_cfg */
|
|
||||||
printf("E_RANDR Event: Output Change: %d\n", ev->output);
|
|
||||||
|
|
||||||
|
printf("E_RANDR Event: Output Change\n");
|
||||||
|
printf("\tOutput: %d\n", ev->output);
|
||||||
|
|
||||||
|
if (ev->crtc)
|
||||||
|
printf("\t\tCrtc: %lu\n", (unsigned long)ev->crtc);
|
||||||
|
else
|
||||||
|
printf("\t\tNo Crtc\n");
|
||||||
|
|
||||||
|
printf("\t\tMode: %d\n", ev->mode);
|
||||||
|
|
||||||
|
if (ev->connection == 0)
|
||||||
|
printf("\t\tOutput Connected\n");
|
||||||
|
else if (ev->connection == 1)
|
||||||
|
printf("\t\tOutput Disconnected\n");
|
||||||
|
|
||||||
|
/* loop our crtcs and try to find this output */
|
||||||
|
printf("\tLooping Our Crtc Configs\n");
|
||||||
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
||||||
{
|
{
|
||||||
Eina_List *o;
|
Eina_List *ll;
|
||||||
E_Randr_Output_Config *output_cfg;
|
|
||||||
|
|
||||||
if (ev->crtc != crtc_cfg->xid) continue;
|
/* loop the outputs in our crtc cfg and try to find this one */
|
||||||
|
printf("\t\tLooping Our Output Configs on this Crtc: %d\n", crtc_cfg->xid);
|
||||||
if ((crtc_cfg->mode != ev->mode) ||
|
EINA_LIST_FOREACH(crtc_cfg->outputs, ll, output_cfg)
|
||||||
(crtc_cfg->orient != ev->orientation))
|
|
||||||
{
|
{
|
||||||
crtc_cfg->mode = ev->mode;
|
/* try to find this output */
|
||||||
crtc_cfg->orient = ev->orientation;
|
if (output_cfg->xid != ev->output) continue;
|
||||||
changed = EINA_TRUE;
|
|
||||||
|
/* FIXME: NB: Hmmm, we may need to also compare edids here (not just X id) */
|
||||||
|
|
||||||
|
printf("\t\t\tFound Output %d on Crtc: %d\n", output_cfg->xid, output_cfg->crtc);
|
||||||
|
output_found = EINA_TRUE;
|
||||||
|
|
||||||
|
/* is this output still on the same crtc ? */
|
||||||
|
if (output_cfg->crtc != ev->crtc)
|
||||||
|
{
|
||||||
|
printf("\t\t\t\tOutput Moved Crtc or Removed\n");
|
||||||
|
|
||||||
|
/* if event crtc is 0, then this output is not assigned to any crtc,
|
||||||
|
* so we need to remove it from any existing crtc_cfg Outputs.
|
||||||
|
*
|
||||||
|
* NB: In a typical scenario, we would remove and free this output cfg,
|
||||||
|
* HOWEVER we will NOT do that here. Reasoning is that if someone
|
||||||
|
* replugs this output, we can restore any saved config.
|
||||||
|
*
|
||||||
|
* NB: Do not call _e_randr_config_output_update in this case as that will
|
||||||
|
* overwrite any of our saved config
|
||||||
|
*
|
||||||
|
* So for now, just disable it in config by setting exists == FALSE */
|
||||||
|
if (!ev->crtc)
|
||||||
|
{
|
||||||
|
/* free this output_cfg */
|
||||||
|
/* if (output_cfg->clones) free(output_cfg->clones); */
|
||||||
|
/* if (output_cfg->edid) free(output_cfg->edid); */
|
||||||
|
/* E_FREE(output_cfg); */
|
||||||
|
|
||||||
|
/* remove from this crtc */
|
||||||
|
/* crtc_cfg->outputs = eina_list_remove_list(crtc_cfg->outputs, ll); */
|
||||||
|
|
||||||
|
/* just mark it as not existing */
|
||||||
|
output_cfg->exists = EINA_FALSE;
|
||||||
|
|
||||||
|
/* set flag */
|
||||||
|
output_removed = EINA_TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* output moved to new crtc */
|
||||||
|
printf("\t\t\tOutput Moved to New Crtc\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\t\t\t\tOutput On Same Crtc\n");
|
||||||
|
|
||||||
|
/* check (and update if needed) our output config */
|
||||||
|
output_changed = _e_randr_config_output_update(output_cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (output_found) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
EINA_LIST_FOREACH(crtc_cfg->outputs, o, output_cfg)
|
if (output_found) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the output was not found above, and it is plugged in,
|
||||||
|
* then we need to create a new one */
|
||||||
|
if ((!output_found) && (ev->connection == 0))
|
||||||
|
{
|
||||||
|
printf("\tOutput Not Found In Config: %d\n", ev->output);
|
||||||
|
printf("\t\tCreate New Output Config\n");
|
||||||
|
|
||||||
|
if ((output_cfg = _e_randr_config_output_new(ev->output)))
|
||||||
{
|
{
|
||||||
if (output_cfg->xid == ev->output)
|
output_new = EINA_TRUE;
|
||||||
|
|
||||||
|
/* since this is a new output cfg, the above
|
||||||
|
* output_update function (inside new) will set 'exists' to false
|
||||||
|
* because no crtc has been assigned yet.
|
||||||
|
*
|
||||||
|
* We need to find a valid crtc for this output and set the
|
||||||
|
* 'crtc' and 'exists' properties */
|
||||||
|
if ((crtc_cfg = _e_randr_config_output_crtc_find(output_cfg)))
|
||||||
{
|
{
|
||||||
Eina_Bool connected = EINA_FALSE;
|
Ecore_X_Randr_Mode mode;
|
||||||
|
|
||||||
connected = ((ev->connection) ? EINA_FALSE : EINA_TRUE);
|
/* we found a valid crtc for this output */
|
||||||
|
output_cfg->crtc = crtc_cfg->xid;
|
||||||
|
output_cfg->exists = (output_cfg->crtc != 0);
|
||||||
|
|
||||||
if ((output_cfg->crtc != ev->crtc) ||
|
printf("\t\t\tOutput Crtc Is: %d\n", output_cfg->crtc);
|
||||||
(output_cfg->connected != connected))
|
|
||||||
|
/* get the preferred mode for this output */
|
||||||
|
if ((mode = _e_randr_config_output_preferred_mode_get(output_cfg)))
|
||||||
{
|
{
|
||||||
printf("Output Changed: %d\n", ev->output);
|
Evas_Coord mw = 0, mh = 0;
|
||||||
printf("\tConnected: %d\n", connected);
|
|
||||||
|
|
||||||
output_cfg->crtc = ev->crtc;
|
/* get the size of this mode */
|
||||||
output_cfg->connected = connected;
|
ecore_x_randr_mode_size_get(ev->win, mode, &mw, &mh);
|
||||||
output_cfg->exists = connected;
|
|
||||||
|
|
||||||
changed = EINA_TRUE;
|
/* update crtc config with this mode info */
|
||||||
|
crtc_cfg->mode = mode;
|
||||||
|
crtc_cfg->width = mw;
|
||||||
|
crtc_cfg->height = mh;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
/* append this output_cfg to the crtc_cfg list of outputs */
|
||||||
|
crtc_cfg->outputs =
|
||||||
|
eina_list_append(crtc_cfg->outputs, output_cfg);
|
||||||
|
|
||||||
|
printf("APPLY NEW OUTPUT: %d\n", output_cfg->xid);
|
||||||
|
/* tell X about this new output */
|
||||||
|
int ocount, c = 0;
|
||||||
|
|
||||||
|
ocount = eina_list_count(crtc_cfg->outputs);
|
||||||
|
printf("\tNum Outputs: %d\n", ocount);
|
||||||
|
|
||||||
|
if (ocount > 0)
|
||||||
|
{
|
||||||
|
Ecore_X_Randr_Output *couts;
|
||||||
|
Eina_List *o;
|
||||||
|
E_Randr_Output_Config *out;
|
||||||
|
|
||||||
|
couts = malloc(ocount * sizeof(Ecore_X_Randr_Output));
|
||||||
|
EINA_LIST_FOREACH(crtc_cfg->outputs, o, out)
|
||||||
|
{
|
||||||
|
couts[c] = out->xid;
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\tCrtc Settings: %d %d %d %d\n", crtc_cfg->xid,
|
||||||
|
crtc_cfg->x, crtc_cfg->y, crtc_cfg->mode);
|
||||||
|
|
||||||
|
/* Evas_Coord mw, mh; */
|
||||||
|
/* get the size of the mode */
|
||||||
|
/* ecore_x_randr_mode_size_get(root, crtc_cfg->mode, &mw, &mh); */
|
||||||
|
/* printf("\t\t\t\t\t\tMode Size: %d %d\n", mw, mh); */
|
||||||
|
|
||||||
|
ecore_x_randr_crtc_settings_set(ev->win, crtc_cfg->xid,
|
||||||
|
couts, ocount,
|
||||||
|
crtc_cfg->x,
|
||||||
|
crtc_cfg->y,
|
||||||
|
crtc_cfg->mode,
|
||||||
|
crtc_cfg->orient);
|
||||||
|
free(couts);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed) e_randr_config_save();
|
/* save the config if anything changed or we added a new one */
|
||||||
|
if ((output_changed) || (output_new) || (output_removed))
|
||||||
|
{
|
||||||
|
printf("\t\t\t\tOutput Changed, Added, or Removed. Saving Config\n");
|
||||||
|
e_randr_config_save();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if we added or removed any outputs, we need to reset */
|
||||||
|
if ((output_new) || (output_removed))
|
||||||
|
{
|
||||||
|
/* we need to inform X about the changes */
|
||||||
|
/* easier just to call the restore function with the updated config */
|
||||||
|
/* _e_randr_config_restore(); */
|
||||||
|
|
||||||
|
ecore_x_randr_screen_reset(ev->win);
|
||||||
|
}
|
||||||
|
|
||||||
return ECORE_CALLBACK_RENEW;
|
return ECORE_CALLBACK_RENEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This function compares our crtc config against what X has and updates our
|
||||||
|
* view of this crtc. It returns EINA_TRUE is anything changed
|
||||||
|
*
|
||||||
|
* NB: This Does Not Handle Outputs on the Crtc.*/
|
||||||
|
static Eina_Bool
|
||||||
|
_e_randr_config_crtc_update(E_Randr_Crtc_Config *cfg)
|
||||||
|
{
|
||||||
|
Ecore_X_Window root = 0;
|
||||||
|
Eina_Bool ret = EINA_FALSE;
|
||||||
|
|
||||||
|
/* grab the root window */
|
||||||
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
|
#if ((ECORE_VERSION_MAJOR >= 1) && (ECORE_VERSION_MINOR >= 8))
|
||||||
|
Ecore_X_Randr_Crtc_Info *cinfo;
|
||||||
|
|
||||||
|
/* get crtc info from X */
|
||||||
|
if ((cinfo = ecore_x_randr_crtc_info_get(root, cfg->xid)))
|
||||||
|
{
|
||||||
|
/* check for changes */
|
||||||
|
if ((cfg->x != cinfo->x) || (cfg->y != cinfo->y) ||
|
||||||
|
(cfg->width != (int)cinfo->width) || (cfg->height != (int)cinfo->height) ||
|
||||||
|
(cfg->mode != cinfo->mode) || (cfg->orient != cinfo->rotation))
|
||||||
|
{
|
||||||
|
cfg->x = cinfo->x;
|
||||||
|
cfg->y = cinfo->y;
|
||||||
|
cfg->width = cinfo->width;
|
||||||
|
cfg->height = cinfo->height;
|
||||||
|
cfg->mode = cinfo->mode;
|
||||||
|
cfg->orient = cinfo->rotation;
|
||||||
|
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecore_x_randr_crtc_info_free(cinfo);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
Evas_Coord x, y, w, h;
|
||||||
|
unsigned int orient, mode;
|
||||||
|
|
||||||
|
/* get geometry of this crtc */
|
||||||
|
ecore_x_randr_crtc_geometry_get(root, ev->crtc, &x, &y, &w, &h);
|
||||||
|
if ((cfg->x != x) || (cfg->y != y) ||
|
||||||
|
(cfg->width != w) || (cfg->height != h))
|
||||||
|
{
|
||||||
|
cfg->x = x;
|
||||||
|
cfg->y = y;
|
||||||
|
cfg->width = w;
|
||||||
|
cfg->height = h;
|
||||||
|
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get orientation */
|
||||||
|
orient = ecore_x_randr_crtc_orientation_get(root, cfg->xid);
|
||||||
|
if (cfg->orient != orient)
|
||||||
|
{
|
||||||
|
cfg->orient = orient;
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get mode */
|
||||||
|
mode = ecore_x_randr_crtc_mode_get(root, cfg->xid);
|
||||||
|
if (cfg->mode != mode)
|
||||||
|
{
|
||||||
|
cfg->mode = mode;
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
static Eina_Bool
|
static Eina_Bool
|
||||||
_e_randr_event_cb_property_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
|
_e_randr_config_output_update(E_Randr_Output_Config *cfg)
|
||||||
{
|
{
|
||||||
/* Ecore_X_Event_Randr_Output_Property_Notify *ev; */
|
Ecore_X_Window root = 0;
|
||||||
|
Eina_Bool ret = EINA_FALSE;
|
||||||
|
Ecore_X_Randr_Output primary = 0;
|
||||||
|
Ecore_X_Randr_Crtc crtc;
|
||||||
|
Ecore_X_Randr_Connection_Status status;
|
||||||
|
/* int clone_count = 0; */
|
||||||
|
|
||||||
/* ev = event; */
|
/* grab the root window */
|
||||||
printf("E_RANDR Event: Property Change\n");
|
root = ecore_x_window_root_first_get();
|
||||||
return ECORE_CALLBACK_RENEW;
|
|
||||||
|
/* get which output is primary */
|
||||||
|
primary = ecore_x_randr_primary_output_get(root);
|
||||||
|
|
||||||
|
/* set this output policy */
|
||||||
|
cfg->policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
|
||||||
|
|
||||||
|
/* get if this output is the primary */
|
||||||
|
if (cfg->primary != ((cfg->xid == primary)))
|
||||||
|
{
|
||||||
|
cfg->primary = ((cfg->xid == primary));
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get the crtc for this output */
|
||||||
|
crtc = ecore_x_randr_output_crtc_get(root, cfg->xid);
|
||||||
|
if (cfg->crtc != crtc)
|
||||||
|
{
|
||||||
|
cfg->crtc = crtc;
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* does it exist in X ?? */
|
||||||
|
if (cfg->exists != (crtc != 0))
|
||||||
|
{
|
||||||
|
cfg->exists = (crtc != 0);
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* record the edid for this output */
|
||||||
|
/* cfg->edid = ecore_x_randr_output_edid_get(root, cfg->xid, &cfg->edid_count); */
|
||||||
|
|
||||||
|
/* get the clones for this output */
|
||||||
|
/* cfg->clones = */
|
||||||
|
/* ecore_x_randr_output_clones_get(root, cfg->xid, &clone_count); */
|
||||||
|
/* cfg->clone_count = (unsigned long)clone_count; */
|
||||||
|
|
||||||
|
status = ecore_x_randr_output_connection_status_get(root, cfg->xid);
|
||||||
|
if (cfg->connected != (status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED))
|
||||||
|
{
|
||||||
|
cfg->connected = (status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED);
|
||||||
|
ret = EINA_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static E_Randr_Crtc_Config *
|
||||||
|
_e_randr_config_output_crtc_find(E_Randr_Output_Config *cfg)
|
||||||
|
{
|
||||||
|
Ecore_X_Window root = 0;
|
||||||
|
E_Randr_Crtc_Config *crtc_cfg = NULL;
|
||||||
|
Ecore_X_Randr_Crtc *possible;
|
||||||
|
int num = 0, i = 0;
|
||||||
|
Eina_List *l;
|
||||||
|
Eina_Bool crtc_found = EINA_FALSE;
|
||||||
|
|
||||||
|
/* grab the root window */
|
||||||
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
|
/* get a list of possible crtcs for this output */
|
||||||
|
possible = ecore_x_randr_output_possible_crtcs_get(root, cfg->xid, &num);
|
||||||
|
if ((!possible) || (num == 0)) return NULL;
|
||||||
|
|
||||||
|
/* loop the possible crtcs */
|
||||||
|
for (i = 0; i < num; i++)
|
||||||
|
{
|
||||||
|
/* loop our crtc configs and try to find this one */
|
||||||
|
EINA_LIST_FOREACH(e_randr_cfg->crtcs, l, crtc_cfg)
|
||||||
|
{
|
||||||
|
/* skip if not the one we are looking for */
|
||||||
|
if (crtc_cfg->xid != possible[i]) continue;
|
||||||
|
|
||||||
|
/* check if this crtc already has outputs assigned.
|
||||||
|
* skip if it does because we are trying to find a free crtc */
|
||||||
|
if (eina_list_count(crtc_cfg->outputs) > 0) continue;
|
||||||
|
|
||||||
|
crtc_found = EINA_TRUE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (crtc_found) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(possible);
|
||||||
|
|
||||||
|
if (crtc_found) return crtc_cfg;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Ecore_X_Randr_Mode
|
||||||
|
_e_randr_config_output_preferred_mode_get(E_Randr_Output_Config *cfg)
|
||||||
|
{
|
||||||
|
Ecore_X_Window root = 0;
|
||||||
|
Ecore_X_Randr_Mode *modes;
|
||||||
|
Ecore_X_Randr_Mode mode;
|
||||||
|
int n = 0, p = 0;
|
||||||
|
|
||||||
|
/* grab the root window */
|
||||||
|
root = ecore_x_window_root_first_get();
|
||||||
|
|
||||||
|
/* get the list of modes for this output */
|
||||||
|
modes = ecore_x_randr_output_modes_get(root, cfg->xid, &n, &p);
|
||||||
|
if ((!modes) || (n == 0)) return 0;
|
||||||
|
|
||||||
|
mode = modes[p];
|
||||||
|
free(modes);
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static E_Randr_Output_Config *
|
||||||
|
_e_randr_config_output_new(unsigned int id)
|
||||||
|
{
|
||||||
|
E_Randr_Output_Config *cfg = NULL;
|
||||||
|
|
||||||
|
if ((cfg = E_NEW(E_Randr_Output_Config, 1)))
|
||||||
|
{
|
||||||
|
/* assign output xid */
|
||||||
|
cfg->xid = id;
|
||||||
|
|
||||||
|
/* check (and update if needed) our output config */
|
||||||
|
_e_randr_config_output_update(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cfg;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue