Introduce new RandR dialog which fixes issues that the past one had.

Signed-off-by: Christopher Michael <cp.michael@samsung.com>

SVN revision: 81094
This commit is contained in:
Christopher Michael 2012-12-17 09:20:07 +00:00 committed by Christopher Michael
parent 8ca8923989
commit a23ebcd608
4 changed files with 1436 additions and 294 deletions

View File

@ -10,14 +10,15 @@ struct _E_Config_Dialog_Data
};
/* local function prototypes */
static void *_create_data(E_Config_Dialog *cfd __UNUSED__);
static void _free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata);
static void *_create_data(E_Config_Dialog *cfd EINA_UNUSED);
static void _free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata);
static Evas_Object *_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
static int _basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata);
static int _basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata);
static void _randr_cb_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
/* public functions */
E_Config_Dialog *
e_int_config_randr(E_Container *con, const char *params __UNUSED__)
e_int_config_randr(E_Container *con, const char *params EINA_UNUSED)
{
E_Config_Dialog *cfd;
E_Config_Dialog_View *v;
@ -52,7 +53,7 @@ e_int_config_randr(E_Container *con, const char *params __UNUSED__)
/* local functions */
static void *
_create_data(E_Config_Dialog *cfd __UNUSED__)
_create_data(E_Config_Dialog *cfd EINA_UNUSED)
{
E_Config_Dialog_Data *cfdata;
@ -64,7 +65,7 @@ _create_data(E_Config_Dialog *cfd __UNUSED__)
}
static void
_free_data(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
_free_data(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
/* if we have the randr smart widget, delete it */
if (cfdata->o_randr)
@ -78,6 +79,7 @@ static Evas_Object *
_basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
{
Evas_Object *o;
Evas_Coord cw = 0, ch = 0;
/* create the base list widget */
o = e_widget_list_add(evas, 0, 0);
@ -85,10 +87,20 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
/* try to create randr smart widget */
if ((cfdata->o_randr = e_smart_randr_add(evas)))
{
/* calculate virtual size
*
* NB: Get which size is larger. This is done so that the
* virtual canvas size can be set such that monitors may be
* repositioned easily in a horizontal or vertical layout.
* Without using MAX (and just using current size) than a
* horizontal layout cannot be changed into a vertical layout */
cw = MAX(E_RANDR_12->current_size.width,
E_RANDR_12->current_size.height);
ch = MAX(E_RANDR_12->current_size.width,
E_RANDR_12->current_size.height);
/* set the virtual size for the randr widget */
e_smart_randr_current_size_set(cfdata->o_randr,
E_RANDR_12->current_size.width,
E_RANDR_12->current_size.height);
e_smart_randr_current_size_set(cfdata->o_randr, cw, ch);
/* tell randr widget to create monitors */
e_smart_randr_monitors_create(cfdata->o_randr);
@ -97,7 +109,7 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
e_widget_list_object_append(o, cfdata->o_randr, 1, 1, 0.5);
}
/* set a minimum size */
/* set a minimum size to 1/10th scale */
e_widget_size_min_set(o, (E_RANDR_12->current_size.width / 10),
(E_RANDR_12->current_size.height / 10));
@ -109,7 +121,13 @@ _basic_create(E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata)
}
static int
_basic_apply(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfdata)
_basic_apply(E_Config_Dialog *cfd EINA_UNUSED, E_Config_Dialog_Data *cfdata)
{
return 1;
}
static void
_randr_cb_changed(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
{
}

View File

@ -13,8 +13,14 @@ EAPI E_Module_Api e_modapi =
EAPI void *
e_modapi_init(E_Module *m)
{
/* create Screen configuration category
*
* NB: If the category already exists, this function just returns */
e_configure_registry_category_add("screen", 30, _("Screen"),
NULL, "preferences-desktop-display");
/* add the randr dialog to the screen category and provide
* the configure category with the function to call */
e_configure_registry_item_add("screen/screen_setup", 20, _("Screen Setup"),
NULL,
"preferences-system-screen-resolution",
@ -23,6 +29,7 @@ e_modapi_init(E_Module *m)
/* store the modules working directory for use later */
mod_dir = eina_stringshare_add(m->dir);
/* return the module */
return m;
}
@ -39,9 +46,15 @@ e_modapi_shutdown(E_Module *m __UNUSED__)
if (mod_dir) eina_stringshare_del(mod_dir);
mod_dir = NULL;
/* remove randr dialog from the configuration category */
e_configure_registry_item_del("screen/screen_setup");
/* remove the screen configuration category
*
* NB: If there are other items in 'screen' then this function is a no-op */
e_configure_registry_category_del("screen");
/* return 1 for shutdown success */
return 1;
}

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,15 @@ static void _e_smart_hide(Evas_Object *obj);
static void _e_smart_clip_set(Evas_Object *obj, Evas_Object *clip);
static void _e_smart_clip_unset(Evas_Object *obj);
static void _e_smart_randr_monitor_adjacent_move(E_Smart_Data *sd, Evas_Object *obj, Evas_Object *skip);
/* local callbacks prototypes for monitors */
static void _e_smart_randr_monitor_cb_moving(void *data, Evas_Object *obj, void *event EINA_UNUSED);
static void _e_smart_randr_monitor_cb_moved(void *data, Evas_Object *obj, void *event EINA_UNUSED);
static void _e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void *event EINA_UNUSED);
static void _e_smart_randr_monitor_cb_rotated(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED);
static void _e_smart_randr_monitor_cb_deleted(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED);
/* external functions exposed by this widget */
Evas_Object *
e_smart_randr_add(Evas *evas)
@ -68,6 +77,7 @@ e_smart_randr_current_size_set(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
e_layout_virtual_size_set(sd->o_layout, w, h);
/* resize the layout widget
*
* NB: This is using an arbitrary scale of 1/10th the screen size */
evas_object_resize(sd->o_layout, (w / 10), (h / 10));
}
@ -83,6 +93,7 @@ e_smart_randr_monitors_create(Evas_Object *obj)
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* get the canvas of the layout widget */
evas = evas_object_evas_get(sd->o_layout);
/* loop the crtcs, checking for valid output */
@ -116,16 +127,27 @@ e_smart_randr_monitors_create(Evas_Object *obj)
/* add this monitor to the layout */
e_smart_randr_monitor_add(obj, mon);
/* tell the monitor which layout it references */
e_smart_monitor_layout_set(mon, sd->o_layout);
/* tell the monitor which output it references */
e_smart_monitor_output_set(mon, output);
/* with the layout and output assigned, we can
* tell the monitor to setup
*
* NB: This means filling resolutions, getting
* refresh rates, displaying monitor name, etc...
* all the graphical stuff */
e_smart_monitor_setup(mon);
/* move this monitor to it's current location */
e_smart_monitor_move(mon, crtc->geometry.x,
crtc->geometry.y);
e_layout_child_move(mon, crtc->geometry.x,
crtc->geometry.y);
/* resize this monitor to it's current size */
e_smart_monitor_resize(mon, crtc->geometry.w,
crtc->geometry.h);
e_layout_child_resize(mon, crtc->geometry.w,
crtc->geometry.h);
}
}
@ -163,25 +185,59 @@ e_smart_randr_monitor_add(Evas_Object *obj, Evas_Object *mon)
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* tell the monitor what layout it belongs to
*
* NB: This is needed so we can calculate best thumbnail size */
e_smart_monitor_layout_set(mon, sd->o_layout);
/* add evas callbacks for monitor resize, rotate */
evas_object_smart_callback_add(mon, "monitor_moving",
_e_smart_randr_monitor_cb_moving, 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);
evas_object_smart_callback_add(mon, "monitor_rotated",
_e_smart_randr_monitor_cb_rotated, obj);
/* TODO: Add evas callbacks for monitor resize, rotate, move */
/* TODO: Add listener for delete event */
/* add listener for monitor delete event */
evas_object_event_callback_add(mon, EVAS_CALLBACK_DEL,
_e_smart_randr_monitor_cb_deleted, NULL);
/* add monitor to layout */
e_layout_pack(sd->o_layout, mon);
/* add this monitor to our list */
sd->monitors = eina_list_append(sd->monitors, mon);
/* show the monitor
*
* NB: Needed. Do Not Remove */
evas_object_show(mon);
}
void
e_smart_randr_monitor_del(Evas_Object *obj, Evas_Object *mon)
{
E_Smart_Data *sd;
/* try to get the objects smart data */
if (!(sd = evas_object_smart_data_get(obj))) return;
/* delete evas callbacks for monitor resize, rotate */
evas_object_smart_callback_del(mon, "monitor_moving",
_e_smart_randr_monitor_cb_moving);
evas_object_smart_callback_del(mon, "monitor_moved",
_e_smart_randr_monitor_cb_moved);
evas_object_smart_callback_del(mon, "monitor_resized",
_e_smart_randr_monitor_cb_resized);
evas_object_smart_callback_del(mon, "monitor_rotated",
_e_smart_randr_monitor_cb_rotated);
/* delete listener for monitor delete event */
evas_object_event_callback_del(mon, EVAS_CALLBACK_DEL,
_e_smart_randr_monitor_cb_deleted);
/* remove monitor from layout */
e_layout_unpack(mon);
/* add this monitor to our list */
sd->monitors = eina_list_append(sd->monitors, mon);
sd->monitors = eina_list_remove(sd->monitors, mon);
}
/* local functions */
@ -318,3 +374,243 @@ _e_smart_clip_unset(Evas_Object *obj)
/* unset the clip */
if (sd->o_scroll) evas_object_clip_unset(sd->o_scroll);
}
static void
_e_smart_randr_monitor_adjacent_move(E_Smart_Data *sd, Evas_Object *obj, Evas_Object *skip)
{
Eina_List *l = NULL;
Evas_Object *mon;
Eina_Rectangle o;
/* get the current geometry of the monitor we were passed in */
e_smart_monitor_current_geometry_get(obj, &o.x, &o.y, NULL, NULL);
e_layout_child_geometry_get(obj, NULL, NULL, &o.w, &o.h);
/* loop the list of monitors */
EINA_LIST_FOREACH(sd->monitors, l, mon)
{
Eina_Rectangle m;
/* if this monitor is the one we want to skip, than skip it */
if (((skip) && (mon == skip)) || (mon == obj))
continue;
/* get the current geometry of this monitor */
e_smart_monitor_current_geometry_get(mon, &m.x, &m.y, NULL, NULL);
e_layout_child_geometry_get(mon, NULL, NULL, &m.w, &m.h);
/* check if this monitor is adjacent to the original one,
* if it is, then we need to move it */
if ((m.x == o.x) || (m.y == o.y))
/* if ((m.x == (o.x + o.w)) || (m.y == (o.y + o.h))) */
{
if ((m.x == o.x))
{
if ((m.y >= o.y))
{
/* vertical positioning */
e_layout_child_move(mon, m.x, (o.y + o.h));
}
}
else if ((m.y == o.y))
{
if ((m.x >= o.x))
{
/* horizontal positioning */
e_layout_child_move(mon, (o.x + o.w), m.y);
}
}
}
}
}
/* local callbacks for monitors */
/* callback received from a monitor object to let us know that it is moving,
* and we now have to check for a drop zone */
static void
_e_smart_randr_monitor_cb_moving(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
Evas_Object *o_randr = NULL;
E_Smart_Data *sd;
Eina_List *l = NULL;
Evas_Object *mon;
Eina_Rectangle o;
/* data is the randr object */
if (!(o_randr = data)) return;
/* try to get the RandR objects smart data */
if (!(sd = evas_object_smart_data_get(o_randr))) return;
/* get the current geometry of the monitor we were passed in */
e_layout_child_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
/* loop the list of monitors */
EINA_LIST_FOREACH(sd->monitors, l, mon)
{
Eina_Rectangle m;
/* if this monitor is the one we want to skip, than skip it */
if (mon == obj) continue;
/* get the current geometry of this monitor */
e_layout_child_geometry_get(mon, &m.x, &m.y, &m.w, &m.h);
/* check if the moved monitor is inside an existing one */
if (E_CONTAINS(m.x, m.y, m.w, m.h, o.x, o.y, o.w, o.h))
{
/* turn on the drop zone so tell user they can drop here */
e_smart_monitor_drop_zone_set(mon, EINA_TRUE);
break;
}
else
{
/* moving monitor is outside the drop zone of this monitor.
* turn off drop zone hilighting */
e_smart_monitor_drop_zone_set(mon, EINA_FALSE);
}
}
}
/* callback received from a monitor object to let us know that it was moved,
* and we now have to adjust the position of any adjacent monitors */
static void
_e_smart_randr_monitor_cb_moved(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
Evas_Object *o_randr = NULL;
E_Smart_Data *sd;
Eina_List *l = NULL;
Evas_Object *mon;
Eina_Rectangle o;
/* data is the randr object */
if (!(o_randr = data)) return;
/* try to get the RandR objects smart data */
if (!(sd = evas_object_smart_data_get(o_randr))) return;
/* get the current geometry of the monitor we were passed in */
e_layout_child_geometry_get(obj, &o.x, &o.y, &o.w, &o.h);
/* loop the list of monitors */
EINA_LIST_FOREACH(sd->monitors, l, mon)
{
Eina_Rectangle m;
/* if this monitor is the one we want to skip, than skip it */
if (mon == obj) continue;
/* get the current geometry of this monitor */
e_layout_child_geometry_get(mon, &m.x, &m.y, &m.w, &m.h);
/* check if the moved monitor is inside an existing one */
if (E_CONTAINS(m.x, m.y, m.w, m.h, o.x, o.y, o.w, o.h))
{
/* clone this monitor into the obj monitor */
e_smart_monitor_clone_add(mon, obj);
/* emit signal to turn off drop zone */
e_smart_monitor_drop_zone_set(mon, EINA_FALSE);
break;
}
}
}
/* callback received from a monitor object to let us know that it was resized,
* and we now have to adjust the position of any adjacent monitors */
static void
_e_smart_randr_monitor_cb_resized(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
Evas_Object *o_randr = NULL;
E_Smart_Data *sd;
Eina_List *l = NULL;
Evas_Object *mon;
/* data is the randr object */
if (!(o_randr = data)) return;
/* try to get the RandR objects smart data */
if (!(sd = evas_object_smart_data_get(o_randr))) return;
/* freeze the layout widget from redrawing while we shuffle things around */
e_layout_freeze(sd->o_layout);
/* move any monitors which are adjacent to this one to their new
* positions because of the resize, specifying the resized monitor
* as the one to skip */
_e_smart_randr_monitor_adjacent_move(sd, obj, obj);
/* move any Other monitors to their new positions */
EINA_LIST_FOREACH(sd->monitors, l, mon)
{
/* skip the current monitor */
if (mon == obj) continue;
/* move any monitors which are adjacent to this one to their new
* positions because of the resize, specifying the resized monitor
* as the one to skip */
_e_smart_randr_monitor_adjacent_move(sd, mon, obj);
}
/* thaw the layout widget, allowing redraws again */
e_layout_thaw(sd->o_layout);
}
/* callback received from a monitor object to let us know that it was rotated,
* and we now have to adjust the position of any adjacent monitors */
static void
_e_smart_randr_monitor_cb_rotated(void *data, Evas_Object *obj, void *event EINA_UNUSED)
{
printf("RandR Monitor Rotated\n");
Evas_Object *o_randr = NULL;
E_Smart_Data *sd;
Eina_List *l = NULL;
Evas_Object *mon;
/* data is the randr object */
if (!(o_randr = data)) return;
/* try to get the RandR objects smart data */
if (!(sd = evas_object_smart_data_get(o_randr))) return;
/* freeze the layout widget from redrawing while we shuffle things around */
e_layout_freeze(sd->o_layout);
/* move any monitors which are adjacent to this one to their new
* positions because of the resize, specifying the resized monitor
* as the one to skip */
_e_smart_randr_monitor_adjacent_move(sd, obj, obj);
/* move any Other monitors to their new positions */
EINA_LIST_FOREACH(sd->monitors, l, mon)
{
/* skip the current monitor */
if (mon == obj) continue;
/* move any monitors which are adjacent to this one to their new
* positions because of the resize, specifying the resized monitor
* as the one to skip */
_e_smart_randr_monitor_adjacent_move(sd, mon, obj);
}
/* thaw the layout widget, allowing redraws again */
e_layout_thaw(sd->o_layout);
/* TODO: code me */
}
static void
_e_smart_randr_monitor_cb_deleted(void *data EINA_UNUSED, Evas *evas EINA_UNUSED, Evas_Object *obj, void *event EINA_UNUSED)
{
/* delete the smart callbacks we were listening on */
evas_object_smart_callback_del(obj, "monitor_moving",
_e_smart_randr_monitor_cb_moving);
evas_object_smart_callback_del(obj, "monitor_moved",
_e_smart_randr_monitor_cb_moved);
evas_object_smart_callback_del(obj, "monitor_resized",
_e_smart_randr_monitor_cb_resized);
evas_object_smart_callback_del(obj, "monitor_rotated",
_e_smart_randr_monitor_cb_rotated);
}