conf_randr: redo randr dialog to trust e_randr_cfg

Prevously conf_randr worked directly against ecore_x_randr. Now we
rather modify e_randr_cfg, and use e_randr to apply changes against
ecore_x_randr.
This commit is contained in:
Sebastian Dransfeld 2014-03-06 15:14:30 +01:00
parent c994e235f9
commit 35fea59e2d
4 changed files with 132 additions and 525 deletions

View File

@ -155,20 +155,14 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
static int
_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
Eina_Bool change_primary = EINA_FALSE;
change_primary = (e_randr_cfg->primary != (unsigned int)cfdata->primary);
e_randr_cfg->primary = cfdata->primary;
e_randr_cfg->restore = cfdata->restore;
e_randr_config_save();
if (change_primary)
ecore_x_randr_primary_output_set(ecore_x_window_root_first_get(),
(Ecore_X_Randr_Output)cfdata->primary);
e_smart_randr_changes_apply(cfdata->o_randr);
e_randr_config_apply();
e_randr_config_save();
return 1;
}

View File

@ -42,18 +42,8 @@ struct _E_Smart_Data
/* refresh rate object */
Evas_Object *o_refresh;
struct
{
Ecore_X_Randr_Crtc id;
Evas_Coord x, y, w, h;
Ecore_X_Randr_Orientation orient;
Ecore_X_Randr_Mode mode;
double refresh_rate;
Eina_Bool enabled : 1;
} crtc;
/* output config */
Ecore_X_Randr_Output output;
E_Randr_Output *output;
Eina_Bool primary : 1;
struct
@ -186,8 +176,6 @@ static inline Ecore_X_Randr_Orientation _e_smart_monitor_orientation_get(int rot
static void _e_smart_monitor_frame_map_apply(Evas_Object *o_frame, int rotation);
static void _e_smart_monitor_thumb_map_apply(Evas_Object *o_thumb, int rotation);
static Ecore_X_Randr_Crtc _e_smart_monitor_crtc_find(Ecore_X_Randr_Output output);
/* external functions exposed by this widget */
Evas_Object *
e_smart_monitor_add(Evas *evas)
@ -214,111 +202,10 @@ e_smart_monitor_add(Evas *evas)
}
void
e_smart_monitor_crtc_set(Evas_Object *obj, Ecore_X_Randr_Crtc crtc, Evas_Coord cx, Evas_Coord cy, Evas_Coord cw, Evas_Coord ch)
{
E_Smart_Data *sd;
Ecore_X_Randr_Orientation orients = ECORE_X_RANDR_ORIENTATION_ROT_0;
Ecore_X_Window root = 0;
Ecore_X_Randr_Crtc_Info *crtc_info;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* set the crtc config */
sd->crtc.id = crtc;
/* record the crtc geometry */
sd->crtc.x = cx;
sd->crtc.y = cy;
sd->crtc.w = cw;
sd->crtc.h = ch;
sd->current.x = cx;
sd->current.y = cy;
sd->current.w = cw;
sd->current.h = ch;
/* get the root window */
root = ecore_x_window_root_first_get();
if ((crtc_info = ecore_x_randr_crtc_info_get(root, crtc)))
{
/* get current orientation */
sd->crtc.orient = crtc_info->rotation;
/* get possible orientations for this crtc */
orients = crtc_info->rotations;
/* check if orientation is possible and disable if not */
if (orients <= ECORE_X_RANDR_ORIENTATION_ROT_0)
edje_object_signal_emit(sd->o_frame, "e,state,rotate,disabled", "e");
/* get current mode */
sd->crtc.mode = crtc_info->mode;
/* free any memory allocated from ecore_x_randr */
ecore_x_randr_crtc_info_free(crtc_info);
}
/* check crtc current mode to determine if enabled */
if (sd->crtc.mode != 0)
{
Ecore_X_Randr_Mode_Info *mode;
/* try to get current refresh rate for this mode */
if ((mode = ecore_x_randr_mode_info_get(root, sd->crtc.mode)))
{
/* record current refresh rate */
sd->crtc.refresh_rate =
e_randr_mode_refresh_rate_get(mode);
/* free any memory allocated from ecore_x_randr */
free(mode);
}
}
/* default refresh rate to 60 if not set */
if (!sd->crtc.refresh_rate) sd->crtc.refresh_rate = 60.0;
/* fill in current values */
sd->current.mode = sd->crtc.mode;
sd->current.orient = sd->crtc.orient;
sd->crtc.enabled = sd->current.enabled =
((sd->crtc.mode != 0) ? EINA_TRUE : EINA_FALSE);
if (!sd->current.enabled)
edje_object_signal_emit(sd->o_frame, "e,state,disabled", "e");
/* get the degree of rotation */
sd->current.rotation = _e_smart_monitor_rotation_get(sd->current.orient);
/* record starting refresh rate */
sd->current.refresh_rate = (int)sd->crtc.refresh_rate;
}
Ecore_X_Randr_Crtc
e_smart_monitor_crtc_get(Evas_Object *obj)
{
E_Smart_Data *sd;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return 0;
return sd->crtc.id;
}
void
e_smart_monitor_output_set(Evas_Object *obj, Ecore_X_Randr_Output output)
e_smart_monitor_output_set(Evas_Object *obj, E_Randr_Output *output)
{
E_Smart_Data *sd;
Ecore_X_Randr_Mode_Info *mode;
Ecore_X_Window root = 0;
Ecore_X_Randr_Output primary = 0;
char *name = NULL;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
@ -337,48 +224,55 @@ e_smart_monitor_output_set(Evas_Object *obj, Ecore_X_Randr_Output output)
sd->max.mode_width = mode->width;
sd->max.mode_height = mode->height;
/* get the root window */
root = ecore_x_window_root_first_get();
/* get the primary output */
primary = ecore_x_randr_primary_output_get(root);
/* get output name */
if (!(name = ecore_x_randr_output_name_get(root, sd->output, NULL)))
{
unsigned char *edid = NULL;
unsigned long edid_length = 0;
/* get the edid for this output */
if ((edid =
ecore_x_randr_output_edid_get(root, sd->output, &edid_length)))
{
/* get output name */
name = ecore_x_randr_edid_display_name_get(edid, edid_length);
/* free any memory allocated from ecore_x_randr */
free(edid);
}
}
/* set if it's primary */
sd->primary = (output == primary);
sd->primary = (output->cfg->xid == e_randr_cfg->primary);
if (sd->primary)
edje_object_signal_emit(sd->o_frame, "e,state,primary,on", "e");
else
edje_object_signal_emit(sd->o_frame, "e,state,primary,off", "e");
/* set monitor name */
edje_object_part_text_set(sd->o_frame, "e.text.name", name);
/* free any memory allocated from ecore_x_randr */
free(name);
edje_object_part_text_set(sd->o_frame, "e.text.name", sd->output->name);
/* get the smallest mode */
mode = eina_list_nth(sd->modes, 0);
sd->min.mode_width = mode->width;
sd->min.mode_height = mode->height;
sd->current.x = output->cfg->geo.x;
sd->current.y = output->cfg->geo.y;
sd->current.w = output->cfg->geo.w;
sd->current.h = output->cfg->geo.h;
/* get current orientation */
sd->current.orient = output->cfg->orient;
/* get possible orientations for this crtc */
if (output->crtc)
{
Ecore_X_Window root;
Ecore_X_Randr_Crtc_Info *crtc_info;
root = ecore_x_window_root_first_get();
crtc_info = ecore_x_randr_crtc_info_get(root, output->crtc->xid);
if (crtc_info->rotations <= ECORE_X_RANDR_ORIENTATION_ROT_0)
edje_object_signal_emit(sd->o_frame, "e,state,rotate,disabled", "e");
free(crtc_info);
}
/* get current mode */
sd->current.mode = output->mode;
/* record current refresh rate */
sd->current.refresh_rate = output->cfg->refresh_rate;
sd->current.enabled = output->cfg->connect;
if (!sd->current.enabled)
edje_object_signal_emit(sd->o_frame, "e,state,disabled", "e");
/* get the degree of rotation */
sd->current.rotation = _e_smart_monitor_rotation_get(sd->current.orient);
/* fill in the refresh rate list
*
* NB: This needs to be done After crtc_set has been called */
@ -445,7 +339,7 @@ e_smart_monitor_background_set(Evas_Object *obj, Evas_Coord dx, Evas_Coord dy)
sd->zone_num = zone->num;
/* get the desk */
if (!(desk = e_desk_at_xy_get(zone, sd->crtc.x, sd->crtc.y)))
if (!(desk = e_desk_at_xy_get(zone, sd->current.x, sd->current.y)))
desk = e_desk_current_get(zone);
/* set the background image */
@ -522,24 +416,17 @@ e_smart_monitor_changes_get(Evas_Object *obj)
return sd->changes;
}
Eina_Bool
void
e_smart_monitor_changes_apply(Evas_Object *obj)
{
E_Smart_Data *sd;
Ecore_X_Window root = 0;
Ecore_X_Randr_Output *outputs;
int noutputs = 0;
/* Ecore_X_Randr_Mode_Info *mode_info; */
Ecore_X_Randr_Mode mode;
Evas_Coord cx, cy, cw, ch;
Ecore_X_Randr_Orientation orient;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return EINA_FALSE;
if (!(sd = evas_object_smart_data_get(obj))) return;
sd->primary = (sd->output == e_randr_cfg->primary);
sd->primary = (sd->output->cfg->xid == e_randr_cfg->primary);
if (sd->primary)
edje_object_signal_emit(sd->o_frame, "e,state,primary,on", "e");
@ -547,94 +434,19 @@ e_smart_monitor_changes_apply(Evas_Object *obj)
edje_object_signal_emit(sd->o_frame, "e,state,primary,off", "e");
/* if we have no changes to apply, get out */
if (sd->changes <= E_SMART_MONITOR_CHANGED_NONE) return EINA_FALSE;
/* grab the root window */
root = ecore_x_window_root_first_get();
/* get the outputs for this crtc */
outputs = ecore_x_randr_crtc_outputs_get(root, sd->crtc.id, &noutputs);
if (noutputs < 1)
{
free(outputs);
if ((outputs = malloc(sizeof(Ecore_X_Randr_Output))))
{
outputs[0] = sd->output;
noutputs = 1;
}
}
/* if this monitor gets re-enabled, we need to set a mode */
if ((sd->current.enabled) && (!sd->crtc.mode))
{
Ecore_X_Randr_Mode_Info *info;
info = _e_smart_monitor_mode_find(sd, sd->current.w,
sd->current.h, EINA_FALSE);
if (info)
sd->current.mode = info->xid;
}
/* if this monitor gets re-enabled, we need to assign a crtc */
if ((sd->current.enabled) && (!sd->crtc.id))
{
/* find a crtc */
sd->crtc.id = _e_smart_monitor_crtc_find(sd->output);
}
/* record current values */
mode = sd->current.mode;
if (!sd->current.enabled)
{
mode = 0;
noutputs = 0;
if (outputs) free(outputs);
outputs = NULL;
sd->current.mode = 0;
}
cx = sd->current.x;
cy = sd->current.y;
cw = sd->current.w;
ch = sd->current.h;
orient = sd->current.orient;
/* try to apply the settings */
printf("Applying Settings: %d %d %d %d\n", sd->crtc.id, cx, cy, mode);
if (!ecore_x_randr_crtc_settings_set(root, sd->crtc.id, outputs,
noutputs, cx, cy, mode, orient))
printf("FAILED TO APPLY MONITOR SETTINGS !!!\n");
/* free any allocated memory from ecore_x_randr */
if (outputs) free(outputs);
outputs = NULL;
if (sd->changes <= E_SMART_MONITOR_CHANGED_NONE) return;
/* update crtc values to match current values */
sd->crtc.x = cx;
sd->crtc.y = cy;
sd->crtc.w = cw;
sd->crtc.h = ch;
sd->crtc.mode = mode;
sd->crtc.orient = orient;
sd->crtc.enabled = sd->current.enabled;
sd->crtc.refresh_rate = sd->current.refresh_rate;
/* if ((sd->crtc.mode) && */
/* (mode_info = ecore_x_randr_mode_info_get(root, sd->crtc.mode))) */
/* { */
/* sd->crtc.refresh_rate = */
/* e_randr_mode_refresh_rate_get(mode_info); */
/* ecore_x_randr_mode_info_free(mode_info); */
/* } */
/* else */
/* sd->crtc.refresh_rate = 60.0; */
sd->output->cfg->geo.x = sd->current.x;
sd->output->cfg->geo.y = sd->current.y;
sd->output->cfg->geo.w = sd->current.w;
sd->output->cfg->geo.h = sd->current.h;
sd->output->cfg->orient = sd->current.orient;
sd->output->cfg->connect = sd->current.enabled;
sd->output->cfg->refresh_rate = sd->current.refresh_rate;
/* reset changes */
sd->changes = E_SMART_MONITOR_CHANGED_NONE;
return EINA_TRUE;
}
const char *
@ -656,7 +468,7 @@ e_smart_monitor_output_get(Evas_Object *obj)
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return 0;
return sd->output;
return sd->output->cfg->xid;
}
void
@ -1009,7 +821,7 @@ _e_smart_monitor_modes_fill(E_Smart_Data *sd)
root = ecore_x_window_root_first_get();
/* try to get the modes for this output from ecore_x_randr */
modes = ecore_x_randr_output_modes_get(root, sd->output, &num, NULL);
modes = ecore_x_randr_output_modes_get(root, sd->output->cfg->xid, &num, NULL);
if (!modes) return;
/* loop the returned modes */
@ -1103,8 +915,8 @@ _e_smart_monitor_background_update(void *data, int type EINA_UNUSED, void *event
((ev->zone < 0) || (ev->zone == (int)sd->zone_num)))
{
/* check this bg event happened on our desktop */
if (((ev->desk_x < 0) || (ev->desk_x == sd->crtc.x)) &&
((ev->desk_y < 0) || (ev->desk_y == sd->crtc.y)))
if (((ev->desk_x < 0) || (ev->desk_x == sd->current.x)) &&
((ev->desk_y < 0) || (ev->desk_y == sd->current.y)))
{
/* set the livethumb preview to the background of this desktop */
_e_smart_monitor_background_set(sd, ev->desk_x, ev->desk_y);
@ -1381,7 +1193,7 @@ _e_smart_monitor_thumb_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Obje
_e_smart_monitor_position_set(sd, sd->current.x, sd->current.y);
/* update changes */
if ((sd->crtc.x != sd->current.x) || (sd->crtc.y != sd->current.y))
if ((sd->output->cfg->geo.x != sd->current.x) || (sd->output->cfg->geo.y != sd->current.y))
sd->changes |= E_SMART_MONITOR_CHANGED_POSITION;
else
sd->changes &= ~(E_SMART_MONITOR_CHANGED_POSITION);
@ -1572,7 +1384,7 @@ _e_smart_monitor_frame_cb_resize_stop(void *data, Evas_Object *obj EINA_UNUSED,
sd->resizing = EINA_FALSE;
/* update changes */
if ((sd->crtc.mode != sd->current.mode))
if ((sd->output->mode != sd->current.mode))
sd->changes |= E_SMART_MONITOR_CHANGED_MODE;
else
sd->changes &= ~(E_SMART_MONITOR_CHANGED_MODE);
@ -1729,7 +1541,7 @@ _e_smart_monitor_frame_cb_rotate_stop(void *data, Evas_Object *obj EINA_UNUSED,
ret:
/* update changes */
if ((sd->crtc.orient != sd->current.orient))
if ((sd->output->cfg->orient != sd->current.orient))
sd->changes |= E_SMART_MONITOR_CHANGED_ORIENTATION;
else
sd->changes &= ~(E_SMART_MONITOR_CHANGED_ORIENTATION);
@ -1769,7 +1581,7 @@ _e_smart_monitor_frame_cb_indicator_toggle(void *data, Evas_Object *obj EINA_UNU
}
/* update changes */
if ((sd->crtc.enabled != sd->current.enabled))
if ((sd->output->cfg->connect != sd->current.enabled))
sd->changes |= E_SMART_MONITOR_CHANGED_ENABLED;
else
sd->changes &= ~(E_SMART_MONITOR_CHANGED_ENABLED);
@ -1825,7 +1637,7 @@ _e_smart_monitor_refresh_rate_cb_changed(void *data, Evas_Object *obj EINA_UNUSE
if (cmode) ecore_x_randr_mode_info_free(cmode);
/* update changes */
if ((sd->crtc.mode != sd->current.mode))
if ((sd->output->mode != sd->current.mode))
sd->changes |= E_SMART_MONITOR_CHANGED_MODE;
else
sd->changes &= ~(E_SMART_MONITOR_CHANGED_MODE);
@ -2151,54 +1963,3 @@ _e_smart_monitor_thumb_map_apply(Evas_Object *o_thumb, int rotation)
evas_object_map_set(o_thumb, map);
evas_object_map_enable_set(o_thumb, EINA_TRUE);
}
static Ecore_X_Randr_Crtc
_e_smart_monitor_crtc_find(Ecore_X_Randr_Output output)
{
Ecore_X_Randr_Crtc ret = 0;
Ecore_X_Window root = 0;
Ecore_X_Randr_Crtc *crtcs;
int ncrtcs = 0;
/* get root window */
root = ecore_x_window_root_first_get();
/* get possible crtcs for this output */
if ((crtcs = ecore_x_randr_output_possible_crtcs_get(root, output, &ncrtcs)))
{
Ecore_X_Randr_Output *outputs;
int i = 0, noutputs = 0;
for (i = 0; i < ncrtcs; i++)
{
int j = 0;
/* get any outputs on this crtc */
if (!(outputs =
ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs)))
ret = crtcs[i];
else if (noutputs == 0)
ret = crtcs[i];
else
{
/* loop the outputs */
for (j = 0; j < noutputs; j++)
{
/* check if it is this output */
if (outputs[j] == output)
{
ret = crtcs[i];
break;
}
}
}
free(outputs);
if (ret) break;
}
free(crtcs);
}
return ret;
}

View File

@ -15,9 +15,7 @@ enum _E_Smart_Monitor_Changes
};
Evas_Object *e_smart_monitor_add(Evas *evas);
void e_smart_monitor_crtc_set(Evas_Object *obj, Ecore_X_Randr_Crtc crtc, Evas_Coord cx, Evas_Coord cy, Evas_Coord cw, Evas_Coord ch);
Ecore_X_Randr_Crtc e_smart_monitor_crtc_get(Evas_Object *obj);
void e_smart_monitor_output_set(Evas_Object *obj, Ecore_X_Randr_Output output);
void e_smart_monitor_output_set(Evas_Object *obj, E_Randr_Output *output);
void e_smart_monitor_grid_set(Evas_Object *obj, Evas_Object *grid, Evas_Coord gx, Evas_Coord gy, Evas_Coord gw, Evas_Coord gh);
void e_smart_monitor_grid_virtual_size_set(Evas_Object *obj, Evas_Coord vw, Evas_Coord vh);
void e_smart_monitor_background_set(Evas_Object *obj, Evas_Coord dx, Evas_Coord dy);
@ -25,7 +23,7 @@ void e_smart_monitor_current_geometry_set(Evas_Object *obj, Evas_Coord x, Evas_C
void e_smart_monitor_current_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
void e_smart_monitor_previous_geometry_get(Evas_Object *obj, Evas_Coord *x, Evas_Coord *y, Evas_Coord *w, Evas_Coord *h);
E_Smart_Monitor_Changes e_smart_monitor_changes_get(Evas_Object *obj);
Eina_Bool e_smart_monitor_changes_apply(Evas_Object *obj);
void e_smart_monitor_changes_apply(Evas_Object *obj);
const char *e_smart_monitor_name_get(Evas_Object *obj);
Ecore_X_Randr_Output e_smart_monitor_output_get(Evas_Object *obj);
void e_smart_monitor_indicator_available_set(Evas_Object *obj, Eina_Bool available);

View File

@ -53,7 +53,6 @@ static void _e_smart_randr_monitor_position_update(E_Smart_Data *sd, Evas_Object
static void _e_smart_randr_monitor_position_normalize(E_Smart_Data *sd);
static void _e_smart_randr_monitor_preferred_mode_size_get(Ecore_X_Randr_Output output, Evas_Coord *mw, Evas_Coord *mh);
static Ecore_X_Randr_Crtc _e_smart_randr_crtc_find(Ecore_X_Randr_Output output);
/* external functions exposed by this widget */
Evas_Object *
@ -85,70 +84,41 @@ e_smart_randr_virtual_size_calc(Evas_Object *obj)
{
E_Smart_Data *sd;
Ecore_X_Window root = 0;
Ecore_X_Randr_Output *routputs;
E_Randr_Output *output;
Eina_List *l;
Evas_Coord vw = 0, vh = 0;
int noutputs = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* NB: The old code here used to get the modes from the e_randr_cfg.
* I changed it to get directly from Xrandr because of attempts to
* run this in Xephyr. Getting the information from e_randr_cfg was not
* practical in those cases */
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* grab the root window */
root = ecore_x_window_root_first_get();
/* get list of outputs */
if ((routputs = ecore_x_randr_outputs_get(root, &noutputs)))
/* loop the outputs and get the largest mode */
EINA_LIST_FOREACH(e_randr->outputs, l, output)
{
int j = 0;
intptr_t *o;
Eina_List *outputs = NULL;
Ecore_X_Randr_Mode *modes;
Evas_Coord mw = 0, mh = 0;
int nmode = 0;
for (j = 0; j < noutputs; j++)
{
Ecore_X_Randr_Connection_Status status =
ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
if (output->status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) continue;
status =
ecore_x_randr_output_connection_status_get(root, routputs[j]);
if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) continue;
/* try to get the list of modes for this output */
modes =
ecore_x_randr_output_modes_get(root, output->cfg->xid,
&nmode, NULL);
if (!modes) continue;
outputs =
eina_list_append(outputs, (intptr_t *)(long)routputs[j]);
}
/* get the size of the largest mode */
ecore_x_randr_mode_size_get(root, modes[0], &mw, &mh);
/* loop the outputs and get the largest mode */
EINA_LIST_FREE(outputs, o)
{
Ecore_X_Randr_Output output;
Ecore_X_Randr_Mode *modes;
Evas_Coord mw = 0, mh = 0;
int nmode = 0;
vw += MAX(mw, mh);
vh += MAX(mw, mh);
output = (int)(long)o;
/* try to get the list of modes for this output */
modes =
ecore_x_randr_output_modes_get(root, output,
&nmode, NULL);
if (!modes) continue;
/* get the size of the largest mode */
ecore_x_randr_mode_size_get(root, modes[0], &mw, &mh);
vw += MAX(mw, mh);
vh += MAX(mw, mh);
/* free any allocated memory from ecore_x_randr */
free(modes);
}
free(routputs);
/* free any allocated memory from ecore_x_randr */
free(modes);
}
if ((vw == 0) && (vh == 0))
@ -168,21 +138,16 @@ void
e_smart_randr_monitors_create(Evas_Object *obj)
{
E_Smart_Data *sd;
E_Randr_Output *output;
Evas *evas;
Ecore_X_Window root = 0;
Evas_Coord gx = 0, gy = 0, gw = 0, gh = 0;
Ecore_X_Randr_Output *outputs;
Evas_Object *mon;
Eina_List *l = NULL;
int noutputs = 0, count = 0;
int cx, cy, cw, ch;
int count = 0;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
/* NB: The old code here used to get the outputs from the e_randr_cfg.
* I changed it to get directly from Xrandr because of attempts to
* run this in Xephyr. Getting the information from e_randr_cfg was not
* practical in those cases */
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
@ -192,115 +157,60 @@ e_smart_randr_monitors_create(Evas_Object *obj)
/* get the geometry of the grid */
evas_object_geometry_get(sd->o_grid, &gx, &gy, &gw, &gh);
/* grab the root window */
root = ecore_x_window_root_first_get();
/* get a list of outputs from X */
if ((outputs = ecore_x_randr_outputs_get(root, &noutputs)))
EINA_LIST_FOREACH(e_randr->outputs, l, output)
{
int i = 0;
Evas_Coord nx = 0;
Eina_List *connected = NULL;
if (output->status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) continue;
/* loop these outputs */
for (i = 0; i < noutputs; i++)
/* for each output, try to create a monitor */
if (!(mon = e_smart_monitor_add(evas)))
continue;
/* hook into monitor changed callback */
evas_object_smart_callback_add(mon, "monitor_changed",
_e_smart_randr_monitor_cb_changed, obj);
evas_object_smart_callback_add(mon, "monitor_moved",
_e_smart_randr_monitor_cb_moved, obj);
evas_object_smart_callback_add(mon, "monitor_resized",
_e_smart_randr_monitor_cb_resized, obj);
/* add this monitor to our list */
sd->monitors = eina_list_append(sd->monitors, mon);
/* tell monitor what the grid's virtual size is */
e_smart_monitor_grid_virtual_size_set(mon, sd->vw, sd->vh);
/* tell monitor what the grid is and it's geometry */
e_smart_monitor_grid_set(mon, sd->o_grid, gx, gy, gw, gh);
/* if the output has no size, find an appropriate */
cx = output->cfg->geo.w;
cy = output->cfg->geo.w;
cw = output->cfg->geo.w;
ch = output->cfg->geo.h;
if ((cw == 0) && (ch == 0))
{
Ecore_X_Randr_Crtc crtc = 0;
Evas_Coord mw = 0, mh = 0;
Evas_Coord cx = 0, cy = 0, cw = 0, ch = 0;
Ecore_X_Randr_Connection_Status status =
ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
Ecore_X_Randr_Mode mode = 0;
/* get the size of the preferred mode for this output */
_e_smart_randr_monitor_preferred_mode_size_get(output->cfg->xid,
&cw, &ch);
/* ask X if this output is connected */
status =
ecore_x_randr_output_connection_status_get(root, outputs[i]);
/* if it's not connected, skip it */
if (status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
continue;
connected =
eina_list_append(connected, (intptr_t *)(long)outputs[i]);
/* for each output, try to create a monitor */
if (!(mon = e_smart_monitor_add(evas)))
continue;
/* hook into monitor changed callback */
evas_object_smart_callback_add(mon, "monitor_changed",
_e_smart_randr_monitor_cb_changed, obj);
evas_object_smart_callback_add(mon, "monitor_moved",
_e_smart_randr_monitor_cb_moved, obj);
evas_object_smart_callback_add(mon, "monitor_resized",
_e_smart_randr_monitor_cb_resized, obj);
/* add this monitor to our list */
sd->monitors = eina_list_append(sd->monitors, mon);
/* tell monitor what the grid's virtual size is */
e_smart_monitor_grid_virtual_size_set(mon, sd->vw, sd->vh);
/* tell monitor what the grid is and it's geometry */
e_smart_monitor_grid_set(mon, sd->o_grid, gx, gy, gw, gh);
/* try to get the crtc of this output. If it does not have one
* we will try to find a usable one */
if (!(crtc = ecore_x_randr_output_crtc_get(root, outputs[i])))
crtc = _e_smart_randr_crtc_find(outputs[i]);
/* get the geometry for this crtc */
ecore_x_randr_crtc_geometry_get(root, crtc,
&cx, &cy, &cw, &ch);
e_smart_monitor_crtc_set(mon, crtc, cx, cy, cw, ch);
mode = ecore_x_randr_crtc_mode_get(root, crtc);
/* if this crtc has no mode, or it's size is 0,
* then it's disabled */
if ((!mode) || ((cw == 0) && (ch == 0)))
/* safety */
if ((cw == 0) && (ch == 0))
{
/* get the size of the preferred mode for this output */
_e_smart_randr_monitor_preferred_mode_size_get(outputs[i],
&mw, &mh);
if ((mw == 0) && (mh == 0))
ecore_x_randr_crtc_size_get(root, crtc, &mw, &mh);
/* safety */
if ((mw == 0) && (mh == 0))
{
mw = 640;
mh = 480;
}
/* tell monitor what it's current position is
* NB: This also packs into the grid */
e_smart_monitor_current_geometry_set(mon, nx, 0, mw, mh);
/* tell monitor to set the background preview */
e_smart_monitor_background_set(mon, nx, 0);
nx += mw;
cw = 640;
ch = 480;
}
else
{
/* tell monitor what it's current position is
* NB: This also packs into the grid */
e_smart_monitor_current_geometry_set(mon, cx, cy,
cw, ch);
/* tell monitor to set the background preview */
e_smart_monitor_background_set(mon, cx, cy);
nx += cw;
}
/* tell monitor what output it uses */
e_smart_monitor_output_set(mon, outputs[i]);
}
free(outputs);
/* tell monitor what it's current position is
* NB: This also packs into the grid */
e_smart_monitor_current_geometry_set(mon, cx, cy, cw, ch);
/* tell monitor to set the background preview */
e_smart_monitor_background_set(mon, cx, cy);
/* tell monitor what output it uses */
e_smart_monitor_output_set(mon, output);
}
/* check if we have only one monitor. If so, we will disable the
@ -359,18 +269,13 @@ e_smart_randr_changes_apply(Evas_Object *obj)
E_Smart_Data *sd;
Eina_List *l = NULL;
Evas_Object *mon;
Eina_Bool need_reset = EINA_FALSE;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* tell each monitor to apply it's changes */
EINA_LIST_FOREACH(sd->monitors, l, mon)
if (e_smart_monitor_changes_apply(mon))
need_reset = EINA_TRUE;
if (need_reset)
ecore_x_randr_screen_reset(ecore_x_window_root_first_get());
e_smart_monitor_changes_apply(mon);
}
Eina_List *
@ -797,54 +702,3 @@ _e_smart_randr_monitor_preferred_mode_size_get(Ecore_X_Randr_Output output, Evas
free(modes);
}
static Ecore_X_Randr_Crtc
_e_smart_randr_crtc_find(Ecore_X_Randr_Output output)
{
Ecore_X_Randr_Crtc ret = 0;
Ecore_X_Window root = 0;
Ecore_X_Randr_Crtc *crtcs;
int ncrtcs = 0;
/* get root window */
root = ecore_x_window_root_first_get();
/* get possible crtcs for this output */
if ((crtcs = ecore_x_randr_output_possible_crtcs_get(root, output, &ncrtcs)))
{
Ecore_X_Randr_Output *outputs;
int i = 0, noutputs = 0;
for (i = 0; i < ncrtcs; i++)
{
int j = 0;
/* get any outputs on this crtc */
if (!(outputs =
ecore_x_randr_crtc_outputs_get(root, crtcs[i], &noutputs)))
ret = crtcs[i];
else if (noutputs == 0)
ret = crtcs[i];
else
{
/* loop the outputs */
for (j = 0; j < noutputs; j++)
{
/* check if it is this output */
if (outputs[j] == output)
{
ret = crtcs[i];
break;
}
}
}
free(outputs);
if (ret) break;
}
free(crtcs);
}
return ret;
}