diff --git a/configure.ac b/configure.ac
index b93bda440..e9865bd1d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -745,6 +745,7 @@ AC_E_OPTIONAL_MODULE([comp], true)
AC_E_OPTIONAL_MODULE([shot], true)
AC_E_OPTIONAL_MODULE([backlight], true)
AC_E_OPTIONAL_MODULE([tasks], true)
+AC_E_OPTIONAL_MODULE([conf_randr], true)
SUSPEND=""
HIBERNATE=""
@@ -843,6 +844,8 @@ src/modules/conf_interaction/Makefile
src/modules/conf_interaction/module.desktop
src/modules/msgbus/Makefile
src/modules/msgbus/module.desktop
+src/modules/conf_randr/Makefile
+src/modules/conf_randr/module.desktop
src/modules/gadman/Makefile
src/modules/gadman/module.desktop
src/modules/mixer/Makefile
diff --git a/src/bin/e_config.c b/src/bin/e_config.c
index c08a01830..edf43c9c5 100644
--- a/src/bin/e_config.c
+++ b/src/bin/e_config.c
@@ -6,23 +6,9 @@
#define DEF_MENUCLICK 0.25
#endif
-typedef enum _Eet_Union
-{
- EET_SCREEN_INFO_11 = (int)((1 << 16) | 1),
- EET_SCREEN_INFO_12 = (int)((1 << 16) | 2),
- EET_SCREEN_INFO_13 = (int)((1 << 16) | 3),
- EET_UNKNOWN
-} Eet_Union;
-
-struct {
- Eet_Union u;
- const char *name;
-} eet_mapping[] = {
- { EET_SCREEN_INFO_11, "E_Config_Screen_11" },
- { EET_SCREEN_INFO_12, "E_Config_Screen_12" },
- { EET_SCREEN_INFO_12, "E_Config_Screen_13" },
- { EET_UNKNOWN, NULL }
-};
+#define RANDR_SERIALIZED_SETUP_11 ((int)((1 << 16) | 1))
+#define RANDR_SERIALIZED_SETUP_12 ((int)((1 << 16) | 2))
+#define RANDR_SERIALIZED_SETUP_13 ((int)((1 << 16) | 3))
EAPI E_Config *e_config = NULL;
@@ -34,8 +20,6 @@ static void _e_config_free(E_Config *cfg);
static Eina_Bool _e_config_cb_timer(void *data);
static int _e_config_eet_close_handle(Eet_File *ef, char *file);
static void _e_config_acpi_bindings_add(void);
-static const char * _eet_union_type_get(const void *data, Eina_Bool *unknow);
-static Eina_Bool _eet_union_type_set(const char *type, void *data, Eina_Bool unknow);
/* local subsystem globals */
static int _e_config_save_block = 0;
@@ -65,15 +49,16 @@ static E_Config_DD *_e_config_shelf_desk_edd = NULL;
static E_Config_DD *_e_config_mime_icon_edd = NULL;
static E_Config_DD *_e_config_syscon_action_edd = NULL;
static E_Config_DD *_e_config_env_var_edd = NULL;
-static E_Config_DD *_e_config_screen_size_edd = NULL;
-static E_Config_DD *_e_config_screen_size_mm_edd = NULL;
-static E_Config_DD *_e_config_eina_rectangle_edd = NULL;
-static E_Config_DD *_e_config_screen_info_edd = NULL;
-static E_Config_DD *_e_config_screen_restore_info_11_edd = NULL;
-static E_Config_DD *_e_config_screen_restore_info_12_edd = NULL;
-static E_Config_DD *_e_config_screen_output_edid_hash_edd = NULL;
-static E_Config_DD *_e_config_screen_output_restore_info_edd = NULL;
-static E_Config_DD *_e_config_screen_crtc_restore_info_edd = NULL;
+static E_Config_DD *_e_config_randr_size_edd = NULL;
+static E_Config_DD *_e_config_randr_size_mm_edd = NULL;
+static E_Config_DD *_e_config_randr_edid_hash_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_11_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_12_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_output_policy_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_output_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_mode_info_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_crtc_edd = NULL;
EAPI int E_EVENT_CONFIG_ICON_THEME = 0;
@@ -526,107 +511,109 @@ e_config_init(void)
E_CONFIG_VAL(D, T, val, STR);
E_CONFIG_VAL(D, T, unset, UCHAR);
- _e_config_screen_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size);
+ _e_config_randr_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size);
#undef T
#undef D
#define T Ecore_X_Randr_Screen_Size
-#define D _e_config_screen_size_edd
+#define D _e_config_randr_size_edd
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
- _e_config_screen_size_mm_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size_MM", Ecore_X_Randr_Screen_Size_MM);
+ _e_config_randr_size_mm_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size_MM", Ecore_X_Randr_Screen_Size_MM);
#undef T
#undef D
#define T Ecore_X_Randr_Screen_Size_MM
-#define D _e_config_screen_size_mm_edd
+#define D _e_config_randr_size_mm_edd
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
E_CONFIG_VAL(D, T, width_mm, INT);
E_CONFIG_VAL(D, T, height_mm, INT);
- _e_config_screen_restore_info_11_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11", E_Randr_Screen_Restore_Info_11);
+ _e_config_randr_edid_hash_edd = E_CONFIG_DD_NEW("E_Randr_Edid_Hash", E_Randr_Edid_Hash);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info_11
-#define D _e_config_screen_restore_info_11_edd
- E_CONFIG_SUB(D, T, size, _e_config_screen_size_edd);
+#define T E_Randr_Edid_Hash
+#define D _e_config_randr_edid_hash_edd
+ E_CONFIG_VAL(D, T, hash, INT);
+
+ _e_config_randr_serialized_setup_11_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup_11", E_Randr_Serialized_Setup_11);
+#undef T
+#undef D
+#define T E_Randr_Serialized_Setup_11
+#define D _e_config_randr_serialized_setup_11_edd
+ E_CONFIG_SUB(D, T, size, _e_config_randr_size_edd);
E_CONFIG_VAL(D, T, orientation, INT);
E_CONFIG_VAL(D, T, refresh_rate, SHORT);
- _e_config_eina_rectangle_edd = E_CONFIG_DD_NEW("Eina_Rectangle", Eina_Rectangle);
+ _e_config_randr_serialized_output_policy_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Output_Policy", E_Randr_Serialized_Output_Policy);
#undef T
#undef D
-#define T Eina_Rectangle
-#define D _e_config_eina_rectangle_edd
- E_CONFIG_VAL(D, T, x, INT);
- E_CONFIG_VAL(D, T, y, INT);
- E_CONFIG_VAL(D, T, w, INT);
- E_CONFIG_VAL(D, T, h, INT);
+#define T E_Randr_Serialized_Output_Policy
+#define D _e_config_randr_serialized_output_policy_edd
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, name_length, INT);
+ E_CONFIG_VAL(D, T, policy, INT);
- _e_config_screen_output_edid_hash_edd = E_CONFIG_DD_NEW("E_Randr_Output_Edid_Hash", E_Randr_Output_Edid_Hash);
+ _e_config_randr_serialized_output_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Output", E_Randr_Serialized_Output);
#undef T
#undef D
-#define T E_Randr_Output_Edid_Hash
-#define D _e_config_screen_output_edid_hash_edd
- E_CONFIG_VAL(D, T, hash, INT);
-
- // FIXME: need to totally re-do this randr config stuff - remove the
- // union stuff. do this differently to not use unions really. not
- // intended for how it is used here really.
- _e_config_screen_output_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Output_Restore_Info", E_Randr_Output_Restore_Info);
-#undef T
-#undef D
-#define T E_Randr_Output_Restore_Info
-#define D _e_config_screen_output_restore_info_edd
- E_CONFIG_SUB(D, T, edid_hash, _e_config_screen_output_edid_hash_edd);
+#define T E_Randr_Serialized_Output
+#define D _e_config_randr_serialized_output_edd
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, name_length, INT);
+ E_CONFIG_SUB(D, T, edid_hash, _e_config_randr_edid_hash_edd);
E_CONFIG_VAL(D, T, backlight_level, DOUBLE);
- _e_config_screen_crtc_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Crtc_Restore_Info", E_Randr_Crtc_Restore_Info);
+ _e_config_randr_serialized_mode_info_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Mode_Info", Ecore_X_Randr_Mode_Info);
#undef T
#undef D
-#define T E_Randr_Crtc_Restore_Info
-#define D _e_config_screen_crtc_restore_info_edd
- E_CONFIG_SUB(D, T, geometry, _e_config_eina_rectangle_edd);
- E_CONFIG_LIST(D, T, outputs, _e_config_screen_output_restore_info_edd);
+#define T Ecore_X_Randr_Mode_Info
+#define D _e_config_randr_serialized_mode_info_edd
+ E_CONFIG_VAL(D, T, width, INT);
+ E_CONFIG_VAL(D, T, height, INT);
+ E_CONFIG_VAL(D, T, dotClock, LL);
+ E_CONFIG_VAL(D, T, hSyncStart, INT);
+ E_CONFIG_VAL(D, T, hSyncEnd, INT);
+ E_CONFIG_VAL(D, T, hTotal, INT);
+ E_CONFIG_VAL(D, T, hSkew, INT);
+ E_CONFIG_VAL(D, T, vSyncStart, INT);
+ E_CONFIG_VAL(D, T, vSyncEnd, INT);
+ E_CONFIG_VAL(D, T, vTotal, INT);
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, nameLength, INT);
+ E_CONFIG_VAL(D, T, modeFlags, LL);
+
+ _e_config_randr_serialized_crtc_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Crtc", E_Randr_Serialized_Crtc);
+#undef T
+#undef D
+#define T E_Randr_Serialized_Crtc
+#define D _e_config_randr_serialized_crtc_edd
+ E_CONFIG_LIST(D, T, serialized_outputs, _e_config_randr_serialized_output_edd);
+ E_CONFIG_SUB(D, T, mode_info, _e_config_randr_serialized_mode_info_edd);
+ E_CONFIG_VAL(D, T, pos.x, INT);
+ E_CONFIG_VAL(D, T, pos.y, INT);
+ EET_DATA_DESCRIPTOR_ADD_LIST_STRING(D, T, "Crtc_Possible_Outputs_Names", possible_outputs_names);
E_CONFIG_VAL(D, T, orientation, INT);
- _e_config_screen_restore_info_12_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12", E_Randr_Screen_Restore_Info_12);
+ _e_config_randr_serialized_setup_12_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup_12", E_Randr_Serialized_Setup_12);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info_12
-#define D _e_config_screen_restore_info_12_edd
- E_CONFIG_LIST(D, T, crtcs, _e_config_screen_crtc_restore_info_edd);
- E_CONFIG_LIST(D, T, outputs_edid_hashes, _e_config_screen_output_edid_hash_edd);
- E_CONFIG_VAL(D, T, noutputs, INT);
- E_CONFIG_VAL(D, T, output_policy, INT);
- E_CONFIG_VAL(D, T, alignment, INT);
+#define T E_Randr_Serialized_Setup_12
+#define D _e_config_randr_serialized_setup_12_edd
+ E_CONFIG_VAL(D, T, timestamp, DOUBLE);
+ E_CONFIG_LIST(D, T, serialized_crtcs, _e_config_randr_serialized_crtc_edd);
+ E_CONFIG_LIST(D, T, serialized_edid_hashes, _e_config_randr_edid_hash_edd);
+ _e_config_randr_serialized_setup_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup", E_Randr_Serialized_Setup);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info
-#define D _e_config_screen_info_edd
- Eet_Data_Descriptor_Class eddc;
- Eet_Data_Descriptor *unified, *edd_11_info, *edd_12_info;
- EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, T);
- D = eet_data_descriptor_stream_new(&eddc);
- eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
- eddc.func.type_get = _eet_union_type_get;
- eddc.func.type_set = _eet_union_type_set;
- //virtual types to work around EET's inability to differentiate when it
- //comes to pointers (a->b) vs. values (a.b) in union mappings
- edd_11_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11_Struct", E_Randr_Screen_Restore_Info_11);
- E_CONFIG_SUB(edd_11_info, E_Randr_Screen_Restore_Info_Union, restore_info_11, _e_config_screen_restore_info_11_edd);
- edd_12_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12_Struct", E_Randr_Screen_Restore_Info_12);
- E_CONFIG_LIST(edd_12_info, E_Randr_Screen_Restore_Info_Union, restore_info_12, _e_config_screen_restore_info_12_edd);
- unified = eet_data_descriptor_stream_new(&eddc);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_11", edd_11_info);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_12", edd_12_info);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_13", edd_12_info);
-// DISABLE! crashie crashie long time
-// EET_DATA_DESCRIPTOR_ADD_UNION(D, T, "E_Randr_Screen_Restore_Info_Union", rrvd_restore_info, randr_version, unified);
- E_CONFIG_VAL(D, T, randr_version, INT);
+#define T E_Randr_Serialized_Setup
+#define D _e_config_randr_serialized_setup_edd
+ E_CONFIG_SUB(D, T, serialized_setup_11, _e_config_randr_serialized_setup_11_edd);
+ E_CONFIG_LIST(D, T, serialized_setups_12, _e_config_randr_serialized_setup_12_edd);
+ E_CONFIG_LIST(D, T, serialized_outputs_policies, _e_config_randr_serialized_output_policy_edd);
_e_config_edd = E_CONFIG_DD_NEW("E_Config", E_Config);
#undef T
@@ -787,7 +774,8 @@ e_config_init(void)
E_CONFIG_VAL(D, T, desklock_ask_presentation, UCHAR);
E_CONFIG_VAL(D, T, desklock_ask_presentation_timeout, DOUBLE);
- E_CONFIG_LIST(D, T, screen_info, _e_config_screen_info_edd);
+ //randr specifics
+ E_CONFIG_SUB(D, T, randr_serialized_setup, _e_config_randr_serialized_setup_edd);
E_CONFIG_VAL(D, T, screensaver_enable, INT);
E_CONFIG_VAL(D, T, screensaver_timeout, INT);
@@ -959,7 +947,7 @@ e_config_shutdown(void)
E_CONFIG_DD_FREE(_e_config_mime_icon_edd);
E_CONFIG_DD_FREE(_e_config_syscon_action_edd);
E_CONFIG_DD_FREE(_e_config_env_var_edd);
- E_CONFIG_DD_FREE(_e_config_screen_info_edd);
+ E_CONFIG_DD_FREE(_e_config_randr_serialized_setup_edd);
return 1;
}
@@ -1920,10 +1908,13 @@ _e_config_free(E_Config *ecf)
E_Color_Class *cc;
E_Path_Dir *epd;
E_Remember *rem;
- E_Randr_Screen_Restore_Info *screen_info;
- E_Randr_Crtc_Restore_Info *crtc_info;
- E_Randr_Output_Info *output_info;
- E_Randr_Screen_Restore_Info_12 *restore_info_12;
+ E_Randr_Serialized_Setup *serialized_setup;
+ E_Randr_Serialized_Setup_12 *serialized_setup_12;
+ E_Randr_Serialized_Crtc *serialized_crtc;
+ E_Randr_Serialized_Output_Policy *serialized_output_policy;
+ E_Randr_Serialized_Output *serialized_output;
+ E_Randr_Edid_Hash *edid_hash;
+ char *output_name;
E_Config_Env_Var *evr;
@@ -2074,37 +2065,50 @@ _e_config_free(E_Config *ecf)
if (sca->icon) eina_stringshare_del(sca->icon);
E_FREE(sca);
}
- if (ecf->screen_info)
+ if(ecf->randr_serialized_setup)
{
- EINA_LIST_FREE(ecf->screen_info, screen_info)
- {
- switch (screen_info->randr_version)
- {
- case EET_SCREEN_INFO_11:
- free(screen_info->rrvd_restore_info.restore_info_11);
- break;
- case EET_SCREEN_INFO_12:
- case EET_SCREEN_INFO_13:
- EINA_LIST_FREE(screen_info->rrvd_restore_info.restore_info_12, restore_info_12)
- {
- EINA_LIST_FREE(restore_info_12->crtcs, crtc_info)
- {
- EINA_LIST_FREE(crtc_info->outputs, output_info)
- {
- free(output_info->name);
- free(output_info->edid);
- free (output_info);
- }
- free (crtc_info);
- }
- free(restore_info_12);
- }
- eina_list_free(screen_info->rrvd_restore_info.restore_info_12);
- break;
- }
- free(screen_info);
- }
+ if(ecf->randr_serialized_setup->serialized_setup_11)
+ free(serialized_setup->serialized_setup_11);
+ else if(ecf->randr_serialized_setup->serialized_setups_12)
+ {
+ EINA_LIST_FREE(ecf->randr_serialized_setup->serialized_setups_12, serialized_setup_12)
+ {
+ EINA_LIST_FREE(serialized_setup_12->serialized_crtcs, serialized_crtc)
+ {
+ if (!serialized_crtc) continue;
+ EINA_LIST_FREE(serialized_crtc->serialized_outputs, serialized_output)
+ {
+ if (serialized_output)
+ {
+ if (serialized_output->name) free(serialized_output);
+ free(serialized_output);
+ }
+ }
+ EINA_LIST_FREE(serialized_crtc->possible_outputs_names, output_name)
+ {
+ if (output_name) free(output_name);
+ }
+ if (serialized_crtc->mode_info.name)
+ free(serialized_crtc->mode_info.name);
+ free(serialized_crtc);
+ }
+ EINA_LIST_FREE(serialized_setup_12->serialized_edid_hashes, edid_hash)
+ {
+ if (edid_hash) free(edid_hash);
+ }
+ free(serialized_setup_12);
+ }
+ }
+ EINA_LIST_FREE(ecf->randr_serialized_setup->serialized_outputs_policies, serialized_output_policy)
+ {
+ if (!serialized_output) continue;
+ if (serialized_output_policy->name)
+ free(serialized_output_policy->name);
+ free(serialized_output_policy);
+ }
+ free(ecf->randr_serialized_setup);
}
+
EINA_LIST_FREE(ecf->env_vars, evr)
{
if (evr->var) eina_stringshare_del(evr->var);
@@ -2121,14 +2125,14 @@ _e_config_free(E_Config *ecf)
E_FREE(ecf);
}
-static Eina_Bool
+ static Eina_Bool
_e_config_cb_timer(void *data)
{
e_util_dialog_show(_("Settings Upgraded"), "%s", (char *)data);
return 0;
}
-static int
+ static int
_e_config_eet_close_handle(Eet_File *ef, char *file)
{
Eet_Error err;
@@ -2138,16 +2142,16 @@ _e_config_eet_close_handle(Eet_File *ef, char *file)
switch (err)
{
case EET_ERROR_NONE:
- /* all good - no error */
- break;
+ /* all good - no error */
+ break;
case EET_ERROR_BAD_OBJECT:
- erstr = _("The EET file handle is bad.");
- break;
+ erstr = _("The EET file handle is bad.");
+ break;
case EET_ERROR_EMPTY:
- erstr = _("The file data is empty.");
- break;
+ erstr = _("The file data is empty.");
+ break;
case EET_ERROR_NOT_WRITABLE:
- erstr = _("The file is not writable. Perhaps the disk is read-only
or you lost permissions to your files.");
+ erstr = _("The file is not writable. Perhaps the disk is read-only
or you lost permissions to your files.");
break;
case EET_ERROR_OUT_OF_MEMORY:
erstr = _("Memory ran out while preparing the write.
Please free up memory.");
@@ -2285,36 +2289,3 @@ _e_config_acpi_bindings_add(void)
bind->params = eina_stringshare_add("now");
e_config->acpi_bindings = eina_list_append(e_config->acpi_bindings, bind);
}
-
-static const char *
-_eet_union_type_get(const void *data, Eina_Bool *unknow)
-{
- const Eet_Union *u = data;
- int i;
-
- if (unknow) *unknow = EINA_FALSE;
- for (i = 0; eet_mapping[i].name; ++i)
- if (*u == eet_mapping[i].u)
- return eet_mapping[i].name;
-
- if (unknow) *unknow = EINA_TRUE;
- return NULL;
-}
-
-static Eina_Bool
-_eet_union_type_set(const char *type, void *data, Eina_Bool unknow)
-{
- Eet_Union *u = data;
- int i;
-
- if (unknow) return EINA_FALSE;
-
- for (i = 0; eet_mapping[i].name; ++i)
- if (strcmp(eet_mapping[i].name, type) == 0)
- {
- *u = eet_mapping[i].u;
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
diff --git a/src/bin/e_config.h b/src/bin/e_config.h
index 123843b2f..e793cb733 100644
--- a/src/bin/e_config.h
+++ b/src/bin/e_config.h
@@ -33,7 +33,7 @@ typedef struct _E_Event_Config_Icon_Theme E_Event_Config_Icon_Theme;
/* increment this whenever a new set of config values are added but the users
* config doesn't need to be wiped - simply new values need to be put in
*/
-#define E_CONFIG_FILE_GENERATION 0x0145
+#define E_CONFIG_FILE_GENERATION 0x0146
#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION)
#define E_EVAS_ENGINE_DEFAULT 0
@@ -250,7 +250,7 @@ struct _E_Config
int mouse_accel_denominator; // GUI
int mouse_accel_threshold; // GUI
- Eina_List *screen_info; // GUI
+ E_Randr_Serialized_Setup *randr_serialized_setup; // GUI
int border_raise_on_mouse_action; // GUI
int border_raise_on_focus; // GUI
diff --git a/src/bin/e_randr.c b/src/bin/e_randr.c
index bb64ecf14..4b8cc7660 100644
--- a/src/bin/e_randr.c
+++ b/src/bin/e_randr.c
@@ -11,6 +11,13 @@
#define Ecore_X_Randr_Unset -1
/*
+ * Save mechanism:
+ * Single monitor:
+ * - Save monitor using the resolution
+ *
+ * Multiple monitors:
+ * - Use the EDID information to make sure we restore the right monitor.
+ *
* TODO:
* -fix output policies above and left
*/
@@ -57,6 +64,11 @@ static E_Randr_Crtc_Info *_e_randr_crtc_info_new(int nrequested);
static void _e_randr_crtc_info_free(E_Randr_Crtc_Info *crtc_info);
static Eina_Bool _e_randr_screen_outputs_init(void);
static Eina_Bool _e_randr_screen_crtcs_init(void);
+
+static Eina_Bool _e_randr_try_restore_11(E_Randr_Screen_Info_11 *si_11);
+static Eina_Bool _e_randr_try_restore_12(E_Randr_Screen_Info_12 *si_12);
+EAPI void e_randr_store_configuration(E_Randr_Screen_Info *screen_info);
+EAPI Eina_Bool e_randr_try_restore_configuration(E_Randr_Screen_Info *screen_info);
static Eina_Bool _e_randr_output_modes_add(E_Randr_Output_Info *output_info);
static void _e_randr_notify_crtc_mode_change(E_Randr_Crtc_Info *crtc_info);
static void _e_randr_notify_output_change(E_Randr_Output_Info *output_info);
@@ -66,12 +78,8 @@ static E_Randr_Output_Info *_e_randr_output_info_get(Ecore_X_Randr_Output output
static void _e_randr_output_info_set(E_Randr_Output_Info *output_info);
static void _e_randr_crtc_info_set(E_Randr_Crtc_Info *crtc_info);
static const E_Randr_Crtc_Info *_e_randr_policy_crtc_get(E_Randr_Crtc_Info* but, E_Randr_Crtc_Info *hint, Ecore_X_Randr_Output_Policy policy);
-//static Eina_Bool _e_randr_outputs_connected(Eina_List *outputs_info);
static Ecore_X_Randr_Output *_e_randr_outputs_to_array(Eina_List *outputs_info);
-//static int _e_randr_config_find_suiting_config_11(E_Randr_Screen_Restore_Info_11** restore_info);
-static E_Randr_Screen_Restore_Info_12 * _e_randr_config_find_suiting_config_12(void);
-//static Eina_Bool _e_randr_config_enable_11(int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation);
-//static Eina_Bool _e_randr_config_enable_12(const E_Randr_Screen_Restore_Info_12 *restore_info);
+static E_Randr_Serialized_Setup_12 * _e_randr_config_find_suiting_config_12(void);
static Eina_Bool _e_randr_try_enable_output(E_Randr_Output_Info *output_info, Eina_Bool force);
static void _e_randr_crtcs_possible_output_update(E_Randr_Output_Info *output_info);
static void _e_randr_crtc_outputs_refs_update(E_Randr_Crtc_Info *crtc_info);
@@ -90,7 +98,7 @@ static void _e_randr_output_info_hw_info_set(E_Randr_Output_Info *output_info);
static void _e_randr_output_hw_info_free(E_Randr_Output_Info *output_info);
static Eina_Bool _e_randr_outputs_are_clones(E_Randr_Output_Info *output_info, Eina_List *outputs);
-E_Randr_Screen_Info *e_randr_screen_info = NULL;
+EAPI E_Randr_Screen_Info *e_randr_screen_info = NULL;
static Eina_List *_e_randr_event_handlers = NULL;
EINTERN Eina_Bool
@@ -270,7 +278,6 @@ _e_randr_screen_info_12_new(void)
.crtcs = NULL,
.outputs = NULL,
.primary_output = NULL,
- .output_policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE,
.alignment = ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE
};
@@ -459,7 +466,8 @@ _e_randr_output_info_new(int nrequested)
.connector_type = Ecore_X_Randr_Unset,
.connection_status = ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED,
.subpixel_order= Ecore_X_Randr_Unset,
- .compatible_outputs = NULL
+ .compatible_outputs = NULL,
+ .policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE
};
if (!(ret = malloc(sizeof(E_Randr_Output_Info) * nrequested))) return NULL;
@@ -760,7 +768,7 @@ _e_randr_event_cb(void *data __UNUSED__, int type, void *ev)
else if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE)
{
Ecore_X_Event_Randr_Output_Change *event = ev;
- const E_Randr_Screen_Restore_Info_12 *restore_info;
+ const E_Randr_Serialized_Setup_12 *restore_info;
E_Randr_Output_Info* output_info = NULL;
/* available information:
struct _Ecore_X_Event_Randr_Output_Change
@@ -807,11 +815,13 @@ _e_randr_event_cb(void *data __UNUSED__, int type, void *ev)
_e_randr_output_info_hw_info_set(output_info);
//make the crtcs aware of their possibly new output
_e_randr_crtcs_possible_output_update(output_info);
+ /*
if ((restore_info = _e_randr_config_find_suiting_config_12()))
//maybe we have a suiting configuration
//_e_randr_config_enable_12(restore_info);
;
else
+ */
enabled = _e_randr_try_enable_output(output_info, EINA_FALSE); //maybe give a success message?
}
_e_randr_notify_output_change(output_info);
@@ -841,11 +851,13 @@ _e_randr_event_cb(void *data __UNUSED__, int type, void *ev)
_e_randr_screen_primary_output_assign(output_info);
//let's try to get a proper config for the new setup and crop the
//screen afterwards.
+ /*
if ((restore_info = _e_randr_config_find_suiting_config_12()))
{
//in case we didn't have, init it anyway...
//_e_randr_config_enable_12(restore_info);
}
+ */
}
_e_randr_notify_output_change(output_info);
_e_randr_output_hw_info_free(output_info);
@@ -865,6 +877,7 @@ _e_randr_event_cb(void *data __UNUSED__, int type, void *ev)
};
*/
}
+ e_randr_try_restore_configuration(e_randr_screen_info);
on_exit:
return ECORE_CALLBACK_RENEW;
}
@@ -999,146 +1012,602 @@ _e_randr_policy_crtc_get(E_Randr_Crtc_Info *but, E_Randr_Crtc_Info *hint __UNUSE
return ret;
}
-/*
-static Eina_Bool
-_e_randr_outputs_connected(Eina_List *outputs_info)
+// Setup store functions
+ Eina_Bool
+_e_randr_copy_mode_info(Ecore_X_Randr_Mode_Info *dest, Ecore_X_Randr_Mode_Info *src)
{
- Eina_List *iter;
- E_Randr_Output_Info *output_info;
- EINA_LIST_FOREACH(outputs_info, iter, output_info)
- if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) return EINA_TRUE;
- return EINA_FALSE;
-}
+ if (!dest || !src) return EINA_FALSE;
-static Eina_Bool
-_e_randr_config_enable_11(int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation)
-{
- E_Randr_Screen_Info_11 *current_info_11;
-
- if (E_RANDR_NO_11 || (size_index < 0) || (refresh_rate < 0) ||
- (orientation < 0)) return EINA_FALSE;
-
- if (!ecore_x_randr_screen_primary_output_size_set(e_randr_screen_info->root, size_index)
- || !ecore_x_randr_screen_primary_output_orientation_set(e_randr_screen_info->root, orientation)
- || !ecore_x_randr_screen_primary_output_refresh_rate_set(e_randr_screen_info->root, size_index, refresh_rate)) return EINA_FALSE;
-
- //TODO: move this to the screen event later.
- current_info_11 = e_randr_screen_info->rrvd_info.randr_info_11;
-
- current_info_11->csize_index = size_index;
- current_info_11->corientation = orientation;
- current_info_11->current_rate = refresh_rate;
+ dest->width = src->width;
+ dest->height = src->height;
+ dest->dotClock = src->dotClock;
+ dest->hSyncStart = src->hSyncStart;
+ dest->hSyncEnd = src->hSyncEnd;
+ dest->hTotal = src->hTotal;
+ dest->hSkew = src->hSkew;
+ dest->vSyncStart = src->vSyncStart;
+ dest->vSyncEnd = src->vSyncEnd;
+ dest->vTotal = src->vTotal;
+ if (src->nameLength > 0)
+ {
+ if (!(dest->name = malloc(src->nameLength + 1))) return EINA_FALSE;
+ if (!strncpy(dest->name, src->name, src->nameLength)) goto _e_randr_copy_mode_info_fail_free_name;
+ }
+ dest->nameLength = src->nameLength;
+ dest->modeFlags = src->modeFlags;
return EINA_TRUE;
-}
-static Eina_Bool
-_e_randr_config_enable_12(const E_Randr_Screen_Restore_Info_12 *restore_info __UNUSED__)
-{
- if (E_RANDR_NO_12 || !restore_info) return EINA_FALSE;
- E_Randr_Screen_Info_12 *current_info_12;
- E_Randr_Screen_Restore_Info_12 *restore_info_12 = NULL;
- E_Randr_Crtc_Restore_Info *crtc_restore_info = NULL;
- E_Randr_Crtc_Info *crtc_info;
- E_Randr_Output_Info *output_info;
- Eina_List *crtc_restore_iter;
-
- current_info_12 = (e_randr_screen_info->rrvd_info).randr_info_12;
- EINA_LIST_FOREACH(restore_info_12->crtcs, crtc_restore_iter, crtc_restore_info)
- {
- ;
- }
- current_info_12->alignment = restore_info_12->alignment;
- current_info_12->output_policy = restore_info_12->output_policy;
- return EINA_TRUE;
+_e_randr_copy_mode_info_fail_free_name:
+ free(dest->name);
return EINA_FALSE;
}
-static int
-_e_randr_config_find_suiting_config_11(E_Randr_Screen_Restore_Info_11 **restore_info)
+ void
+_e_randr_free_serialized_mode_info(Ecore_X_Randr_Mode_Info *mode_info)
{
- E_RANDR_NO_11_RET(Ecore_X_Randr_None);
- Eina_List *cfg_screen_restore_info_iter;
- E_Randr_Screen_Restore_Info *screen_restore_info;
-
- E_Randr_Screen_Restore_Info_11 *restore_info_11;
- Ecore_X_Randr_Screen_Size_MM *sizes;
- Ecore_X_Randr_Refresh_Rate *rates = NULL;
- int i = 0, j = 0, nsizes = 0, nrates = 0;
-
- EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info)
- {
- // 'screen_restore_info' should _never_ be NULL, since this functions shouldn't be called due to randr init failing.
- if (!screen_restore_info) continue;
- if (screen_restore_info->randr_version != ECORE_X_RANDR_1_1) continue;
- restore_info_11 = screen_restore_info->rrvd_restore_info.restore_info_11;
- if((sizes = ecore_x_randr_screen_primary_output_sizes_get(e_randr_screen_info->root, &nsizes)))
- {
- for (i = 0; i < nsizes; i++)
- {
- if ((restore_info_11->size.width == sizes[i].width)
- && (restore_info_11->size.height == sizes[i].height))
- {
- if ((rates = ecore_x_randr_screen_primary_output_refresh_rates_get(e_randr_screen_info->root, i, &nrates)))
- {
- for (j = 0; j < nrates; j++)
- if (rates[j] == restore_info_11->refresh_rate)
- {
- if (restore_info) *restore_info = restore_info_11;
- free(rates);
- free(sizes);
- return i;
- }
- free(rates);
- }
- }
- }
- if (sizes) free(sizes);
- }
- }
- return Ecore_X_Randr_Unset;
+ if (mode_info->name) free(mode_info->name);
}
-*/
-/**
- * @Brief find configuration with the most hardware currently available
- */
-static E_Randr_Screen_Restore_Info_12 *
-_e_randr_config_find_suiting_config_12(void)
+ Eina_List
+*_e_randr_create_outputs_policies_list(Eina_List *outputs)
{
- //TODO: write geometry based loading
- /*
- Eina_List *cfg_screen_restore_info_iter;
- E_Randr_Screen_Restore_Info *screen_restore_info;
+ Eina_List *iter, *list = NULL;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Output_Policy *sop;
+ char *name;
- E_Randr_Screen_Info_12 *current_info_12;
- E_Randr_Screen_Restore_Info_12 *restore_info_12, *most_matches = NULL;
- E_Randr_Output_Info *output_info;
- E_Randr_Crtc_Restore_Info *crtc_restore_info;
- Ecore_X_Randr_Output *outputs_xids;
- Ecore_X_Randr_Crtc *crtcs_xids;
- Eina_List *restore_info_12_iter, *output_iter, *restore_crtcs_iter;
+ EINA_LIST_FOREACH(outputs, iter, oi)
+ {
+ if (!oi->name || (oi->name_length <= 0)) continue;
+ if (!(sop = E_NEW(E_Randr_Serialized_Output_Policy, 1))
+ || !(sop->name = malloc(oi->name_length + 1))
+ || !(strncpy(sop->name, oi->name, oi->name_length)))
+ goto _e_randr_create_outputs_policies_list_fail_free_list;
+ sop->name_length = oi->name_length;
+ sop->policy = oi->policy;
+ if (!(list = eina_list_append(list, sop)))
+ goto _e_randr_create_outputs_policies_list_fail_free_list;
+ }
- if (e_randr_screen_info && e_config && e_config->screen_info)
- {
-
- EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info)
- {
- if (screen_restore_info->randr_version < ECORE_X_RANDR_1_2) continue;
-
- //HINT: use eina_list_clone and a sort callback to find proper
- //crtcs and outputs
-
- //current_info_12 = e_randr_screen_info->rrvd_info.randr_info_12;
- }
-
- }
- */
+ return list;
+_e_randr_create_outputs_policies_list_fail_free_list:
+ EINA_LIST_FREE(list, sop)
+ {
+ if (sop->name) free(sop->name);
+ free(sop);
+ }
return NULL;
}
-static Ecore_X_Randr_Output *
+void
+_e_randr_free_serialized_output_policy(E_Randr_Serialized_Output_Policy *sop)
+{
+ if (!sop) return;
+ if (sop->name) free(sop->name);
+ free(sop);
+}
+
+ Eina_List
+*_e_randr_update_serialized_outputs_policies(E_Randr_Screen_Info_12 *si_12, Eina_List *sops)
+{
+ E_Randr_Serialized_Output_Policy *sop;
+
+ EINA_LIST_FREE(sops, sop)
+ {
+ _e_randr_free_serialized_output_policy(sop);
+ }
+
+ return _e_randr_create_outputs_policies_list(si_12->outputs);
+}
+
+ Eina_List
+*_e_randr_create_possible_outputs_names_list(Eina_List *outputs)
+{
+ Eina_List *iter, *list = NULL;
+ E_Randr_Output_Info *oi;
+ char *name;
+
+ if (!outputs) return NULL;
+
+ EINA_LIST_FOREACH(outputs, iter, oi)
+ {
+ if (!oi->name || (oi->name_length <= 0)) continue;
+ if (!(name = malloc(oi->name_length))
+ || !strncpy(name, oi->name, oi->name_length)
+ || !(list = eina_list_append(list, name))) goto _e_randr_create_possible_outputs_names_list_fail_free_list;
+ }
+ return list;
+
+_e_randr_create_possible_outputs_names_list_fail_free_list:
+ EINA_LIST_FREE(list, name)
+ {
+ if(name) free(name);
+ }
+ return NULL;
+}
+
+ E_Randr_Edid_Hash
+*_e_randr_create_edid_hash(E_Randr_Output_Info *output_info)
+{
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (!output_info || (output_info->edid_hash.hash == 0) || !(edid_hash = malloc(sizeof(E_Randr_Edid_Hash)))) return NULL;
+
+ edid_hash->hash = output_info->edid_hash.hash;
+
+ return edid_hash;
+}
+
+ E_Randr_Serialized_Output
+*_e_randr_create_serialized_output(E_Randr_Output_Info *output_info)
+{
+ E_Randr_Serialized_Output *so;
+ char *name;
+
+ if (!output_info || !output_info->name || (output_info->name_length <= 0) || !(so = malloc(sizeof(E_Randr_Serialized_Output)))) return NULL;
+
+ if (!(name = malloc(output_info->name_length))
+ || !strncpy(so->name, output_info->name, output_info->name_length))
+ goto _e_randr_create_serialized_outputs_fail_free_so;
+ so->name_length = output_info->name_length;
+ so->edid_hash.hash = output_info->edid_hash.hash;
+ so->backlight_level = output_info->backlight_level;
+
+ return so;
+
+_e_randr_create_serialized_outputs_fail_free_so:
+ free(so);
+ return NULL;
+}
+
+ void
+_e_randr_free_serialized_output(E_Randr_Serialized_Output *so)
+{
+ if (so->name) free(so->name);
+ free(so);
+}
+
+ E_Randr_Serialized_Crtc
+*_e_randr_create_serialized_crtc(E_Randr_Crtc_Info *crtc_info)
+{
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Serialized_Output *so;
+ E_Randr_Output_Info *output_info;
+ Eina_List *iter;
+ char *output_name;
+ size_t len;
+
+ if (!(sc = E_NEW(E_Randr_Serialized_Crtc, 1))) return NULL;
+ if(!_e_randr_copy_mode_info(&sc->mode_info, crtc_info->current_mode)) goto _e_randr_create_serialized_crtc_free_sc;
+ if(!(sc->possible_outputs_names = _e_randr_create_possible_outputs_names_list(crtc_info->possible_outputs))) goto _e_randr_create_serialized_crtc_free_mode_sc;
+ //Create list of serialized outputs
+ EINA_LIST_FOREACH(crtc_info->outputs, iter, output_info)
+ {
+ if(!(so = _e_randr_create_serialized_output(output_info))
+ || !(sc->serialized_outputs = eina_list_append(sc->serialized_outputs, so))) goto _e_randr_create_serialized_crtc_free_outputs_list_sc;
+ }
+ sc->pos.x = crtc_info->geometry.x;
+ sc->pos.y = crtc_info->geometry.y;
+ sc->orientation = crtc_info->current_orientation;
+
+ return sc;
+
+_e_randr_create_serialized_crtc_free_outputs_list_sc:
+ EINA_LIST_FREE(sc->possible_outputs_names, output_name)
+ {
+ if (output_name) free(output_name);
+ }
+ EINA_LIST_FREE(sc->serialized_outputs, so)
+ {
+ if (so) _e_randr_free_serialized_output(so);
+ }
+_e_randr_create_serialized_crtc_free_mode_sc:
+ _e_randr_free_serialized_mode_info(&sc->mode_info);
+_e_randr_create_serialized_crtc_free_sc:
+ E_FREE(sc);
+
+ return NULL;
+}
+
+ void
+_e_randr_free_serialized_crtc(E_Randr_Serialized_Crtc *sc)
+{
+ E_Randr_Serialized_Output *so;
+ char *name;
+
+ EINA_LIST_FREE(sc->serialized_outputs, so)
+ _e_randr_free_serialized_output(so);
+ _e_randr_free_serialized_mode_info(&sc->mode_info);
+ EINA_LIST_FREE(sc->possible_outputs_names, name)
+ free(name);
+ free(sc);
+}
+
+ E_Randr_Serialized_Setup_11
+*_e_randr_create_serialized_setup_11(E_Randr_Screen_Info_11 *screen_info_11)
+{
+ E_Randr_Serialized_Setup_11 *ss;
+ Ecore_X_Randr_Screen_Size_MM* size;
+
+ if (!(ss = malloc(sizeof(*ss)))) return NULL;
+ if(!(size = (Ecore_X_Randr_Screen_Size_MM*)eina_list_data_get(eina_list_nth(screen_info_11->sizes, screen_info_11->csize_index)))) goto _e_randr_create_serialized_setup_11_failed_free_ss;
+ ss->size.width = size->width;
+ ss->size.height = size->height;
+ ss->refresh_rate = screen_info_11->current_rate;
+ ss->orientation = screen_info_11->corientation;
+
+ return ss;
+
+_e_randr_create_serialized_setup_11_failed_free_ss:
+ free(ss);
+}
+
+ E_Randr_Serialized_Setup_11
+*_e_randr_update_serialized_setup_11(E_Randr_Serialized_Setup_11 *ss_11, E_Randr_Screen_Info_11 *si_11)
+{
+ Ecore_X_Randr_Screen_Size_MM* size;
+
+ if (ss_11)
+ {
+ if(!(size = (Ecore_X_Randr_Screen_Size_MM*)eina_list_data_get(eina_list_nth(si_11->sizes, si_11->csize_index)))) return NULL;
+ if (!memcpy(&ss_11->size, size, sizeof(Ecore_X_Randr_Screen_Size_MM)))
+ goto _e_randr_update_serialized_setup_11_failed_free_ss;
+ ss_11->refresh_rate = si_11->current_rate;
+ ss_11->orientation = si_11->corientation;
+ }
+ else
+ ss_11 = _e_randr_create_serialized_setup_11(si_11);
+
+ return ss_11;
+
+_e_randr_update_serialized_setup_11_failed_free_ss:
+ free(ss_11);
+ return NULL;
+}
+
+ E_Randr_Serialized_Setup_12
+*_e_randr_create_serialized_setup_12(E_Randr_Screen_Info_12 *screen_info_12)
+{
+ E_Randr_Serialized_Setup_12 *ss;
+ Eina_List *iter;
+ E_Randr_Crtc_Info *ci;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (!(ss = E_NEW(E_Randr_Serialized_Setup_12, 1))) return NULL;
+
+ ss->timestamp = ecore_time_get();
+
+ //Add CRTCs and their configuration
+ EINA_LIST_FOREACH(screen_info_12->crtcs, iter, ci)
+ {
+ //ignore disabled crtcs for now
+ if (!ci->current_mode) continue;
+
+ if (!(sc = _e_randr_create_serialized_crtc(ci))
+ || !(ss->serialized_crtcs = eina_list_append(ss->serialized_crtcs, sc)))
+ goto _e_randr_create_serialized_setup_12_failed_free_list_ss;
+ }
+
+ /*
+ * Add EDID hashes of connected and enabled
+ * outputs for easier comparison during
+ * setup restoration
+ */
+ EINA_LIST_FOREACH(screen_info_12->outputs, iter, oi)
+ {
+ if ((oi->connection_status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) || !oi->crtc || !oi->crtc->current_mode)
+ continue;
+ if (!(edid_hash = _e_randr_create_edid_hash(oi)) || !(ss->serialized_edid_hashes = eina_list_append(ss->serialized_edid_hashes, edid_hash)))
+ goto _e_randr_create_serialized_setup_12_failed_free_output_list_crtc_list_ss;
+ }
+
+ return ss;
+
+_e_randr_create_serialized_setup_12_failed_free_output_list_crtc_list_ss:
+ EINA_LIST_FREE(ss->serialized_edid_hashes, edid_hash)
+ {
+ if (edid_hash) free(edid_hash);
+ }
+_e_randr_create_serialized_setup_12_failed_free_list_ss:
+ EINA_LIST_FREE(ss->serialized_crtcs, sc)
+ {
+ _e_randr_free_serialized_crtc(sc);
+ }
+_e_randr_create_serialized_setup_12_failed_free_ss:
+ free(ss);
+}
+
+E_Randr_Serialized_Setup_12
+*_e_randr_find_matching_serialized_setup(Eina_List *setups_12, E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ Eina_List *setups_iter, *r_iter, *s_iter;
+ Eina_Bool found = EINA_FALSE;
+ E_Randr_Edid_Hash *edid_hash;
+ E_Randr_Output_Info *oi;
+
+ if (!setups_12 || !si_12) return NULL;
+
+ EINA_LIST_FOREACH(setups_12, setups_iter, ss_12)
+ {
+ EINA_LIST_FOREACH(si_12->outputs, r_iter, oi)
+ {
+ //skip disconnected/-abled monitors
+ if ((oi->connection_status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) || !oi->crtc || !oi->crtc->current_mode)
+ continue;
+ found = EINA_FALSE;
+ EINA_LIST_FOREACH(ss_12->serialized_edid_hashes, s_iter, edid_hash)
+ {
+ if (oi->edid_hash.hash == edid_hash->hash)
+ {
+ found = EINA_TRUE;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+ if (found)
+ break;
+ }
+ if (found)
+ return ss_12;
+
+ return NULL;
+}
+
+ void
+_e_randr_free_serialized_setup_12(E_Randr_Serialized_Setup_12 *ss_12)
+{
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (!ss_12) return;
+
+ EINA_LIST_FREE(ss_12->serialized_crtcs, sc)
+ {
+ if (!sc) continue;
+ _e_randr_free_serialized_crtc(sc);
+ }
+ EINA_LIST_FREE(ss_12->serialized_edid_hashes, edid_hash)
+ if (edid_hash) free(edid_hash);
+
+ free(ss_12);
+}
+
+ Eina_List
+*_e_randr_update_serialized_setup_12(Eina_List *setups_12, E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ E_Randr_Serialized_Output *so;
+ E_Randr_Output_Info *oi;
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (setups_12)
+ {
+ /*
+ * try to find the setup with the same monitors
+ * connected in order to replace it
+ */
+ if((ss_12 = _e_randr_find_matching_serialized_setup(setups_12, si_12)))
+ _e_randr_free_serialized_setup_12(ss_12);
+ }
+ ss_12 = _e_randr_create_serialized_setup_12(si_12);
+ setups_12 = eina_list_append(setups_12, ss_12);
+
+ return setups_12;
+}
+
+ E_Randr_Serialized_Setup
+*_e_randr_create_serialized_setup(E_Randr_Screen_Info *screen_info)
+{
+ E_Randr_Serialized_Setup *ss;
+ E_Randr_Serialized_Setup_12 *ss_12;
+
+ if (!(ss = E_NEW(E_Randr_Serialized_Setup, 1))) return NULL;
+ if ((screen_info->randr_version == ECORE_X_RANDR_1_1) && !(ss->serialized_setup_11 = _e_randr_create_serialized_setup_11(screen_info->rrvd_info.randr_info_11))) goto _e_randr_create_serialized_setup_failed_free_ss;
+ if ((screen_info->randr_version >= ECORE_X_RANDR_1_2))
+ {
+ if (!(ss_12 = _e_randr_create_serialized_setup_12(screen_info->rrvd_info.randr_info_12))
+ || !(ss->serialized_setups_12 = eina_list_append(ss->serialized_setups_12, ss_12)))
+ goto _e_randr_create_serialized_setup_failed_free_ss;
+ }
+
+ return ss;
+
+_e_randr_create_serialized_setup_failed_free_ss:
+ free(ss);
+}
+
+ EAPI void
+e_randr_store_configuration(E_Randr_Screen_Info *screen_info)
+{
+ if (E_RANDR_NO_11) return;
+
+ if (!e_config->randr_serialized_setup)
+ {
+ e_config->randr_serialized_setup = _e_randr_create_serialized_setup(screen_info);
+ e_config_save_queue();
+ return;
+ }
+
+ if (screen_info->randr_version == ECORE_X_RANDR_1_1)
+ {
+ e_config->randr_serialized_setup->serialized_setup_11 = _e_randr_update_serialized_setup_11(e_config->randr_serialized_setup->serialized_setup_11, screen_info->rrvd_info.randr_info_11);
+ }
+ else if (screen_info->randr_version >= ECORE_X_RANDR_1_2)
+ {
+ e_config->randr_serialized_setup->serialized_setups_12 = _e_randr_update_serialized_setup_12(e_config->randr_serialized_setup->serialized_setups_12, screen_info->rrvd_info.randr_info_12);
+
+ //Also, update output policies
+ e_config->randr_serialized_setup->serialized_outputs_policies = _e_randr_update_serialized_outputs_policies(screen_info->rrvd_info.randr_info_12, e_config->randr_serialized_setup->serialized_outputs_policies);
+ }
+ e_config_save_queue();
+}
+
+//setup restore functions
+ EAPI Eina_Bool
+e_randr_try_restore_configuration(E_Randr_Screen_Info *si)
+{
+ if (!e_config || !e_config->randr_serialized_setup) return EINA_FALSE;
+
+ if (si->randr_version == ECORE_X_RANDR_1_1)
+ return _e_randr_try_restore_11(si->rrvd_info.randr_info_11);
+ else if (si->randr_version >= ECORE_X_RANDR_1_2)
+ return _e_randr_try_restore_12(si->rrvd_info.randr_info_12);
+
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+_e_randr_try_restore_11(E_Randr_Screen_Info_11 *si_11)
+{
+ E_Manager *man;
+ Eina_List *iter;
+ Ecore_X_Randr_Screen_Size_MM *stored_size, *size;
+ int i = 0;
+
+ if (!e_config->randr_serialized_setup->serialized_setup_11) return EINA_FALSE;
+ stored_size = &e_config->randr_serialized_setup->serialized_setup_11->size;
+ EINA_LIST_FOREACH(si_11->sizes, iter, size)
+ {
+ if ((stored_size->width == size->width)
+ && (stored_size->height == size->height)
+ && (stored_size->width_mm == size->width_mm)
+ && (stored_size->height_mm == size->height_mm))
+ {
+ man = e_manager_current_get();
+ return ecore_x_randr_screen_primary_output_size_set(man->root, i);
+ }
+ i++;
+ }
+
+ return EINA_FALSE;
+}
+
+ E_Randr_Crtc_Info
+*_e_randr_find_matching_crtc(Eina_List *crtcs, E_Randr_Serialized_Crtc *sc)
+{
+ Eina_List *iter, *s_name_iter, *p_output_iter;
+ E_Randr_Crtc_Info *ci;
+ E_Randr_Output_Info *oi;
+ char *s_output_name;
+ Eina_Bool name_found;
+
+ EINA_LIST_FOREACH(crtcs, iter, ci)
+ {
+ if (eina_list_count(ci->possible_outputs) != eina_list_count(sc->possible_outputs_names))
+ continue;
+ EINA_LIST_FOREACH(sc->possible_outputs_names, s_name_iter, s_output_name)
+ {
+ name_found = EINA_FALSE;
+ EINA_LIST_FOREACH(ci->possible_outputs, p_output_iter, oi)
+ {
+ if (!strncmp(s_output_name, oi->name, oi->name_length))
+ {
+ name_found = EINA_TRUE;
+ break;
+ }
+ }
+ if (!name_found)
+ break;
+ }
+ if (name_found)
+ break;
+ }
+ if (name_found)
+ return ci;
+ else
+ return NULL;
+}
+
+ Eina_List
+*_e_randr_find_matching_outputs(Eina_List *sois, Eina_List *ois)
+{
+ Eina_List *r_output_iter, *s_output_iter, *list = NULL;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Output *so;
+
+ EINA_LIST_FOREACH(sois, s_output_iter, so)
+ {
+ EINA_LIST_FOREACH(ois, r_output_iter, oi)
+ {
+ if (so->edid_hash.hash == oi->edid_hash.hash)
+ {
+ list = eina_list_append(list, oi);
+ break;
+ }
+ }
+ }
+ if (list && (eina_list_count(sois) != eina_list_count(list)))
+ {
+ eina_list_free(list);
+ list = NULL;
+ }
+
+ return list;
+}
+
+ Ecore_X_Randr_Mode_Info
+*_e_randr_find_matching_mode_info(Eina_List *modes, Ecore_X_Randr_Mode_Info *mode)
+{
+ Eina_List *iter;
+ Ecore_X_Randr_Mode_Info *mi = NULL;
+
+ EINA_LIST_FOREACH(modes, iter, mi)
+ {
+ if ((mode->width == mi->width)
+ && (mode->height == mi->height)
+ && (mode->dotClock == mi->dotClock)
+ && (mode->hSyncStart == mi->hSyncStart)
+ && (mode->hSyncEnd == mi->hSyncEnd)
+ && (mode->hTotal == mi->hTotal)
+ && (mode->hSkew == mi->hSkew)
+ && (mode->vSyncStart == mi->vSyncStart)
+ && (mode->vSyncEnd == mi->vSyncEnd)
+ && (mode->vTotal == mi->vTotal)
+ && (mode->nameLength == mi->nameLength)
+ && !strncpy(mode->name, mi->name, mode->nameLength)
+ && (mode->modeFlags == mi->modeFlags))
+ return mi;
+ }
+ return NULL;
+}
+
+ Eina_Bool
+_e_randr_try_restore_12(E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Crtc_Info *ci;
+ Ecore_X_Randr_Output *outputs_array;
+ Ecore_X_Randr_Mode_Info *mi;
+ Eina_List *iter, *outputs_list;
+ Eina_Bool ret = EINA_TRUE;
+ E_Manager *man;
+
+ if(!(ss_12 = _e_randr_find_matching_serialized_setup(e_config->randr_serialized_setup->serialized_setups_12, si_12))) return EINA_FALSE;
+
+ man = e_manager_current_get();
+
+ EINA_LIST_FOREACH(ss_12->serialized_crtcs, iter, sc)
+ {
+ ci = _e_randr_find_matching_crtc(si_12->crtcs, sc);
+ outputs_list = _e_randr_find_matching_outputs(si_12->outputs, sc->serialized_outputs);
+ outputs_array = _e_randr_outputs_to_array(outputs_list);
+ mi = _e_randr_find_matching_mode_info(si_12->modes, &sc->mode_info);
+ ret &= ecore_x_randr_crtc_mode_set(man->root, ci->xid, outputs_array, eina_list_count(outputs_list), mi->xid);
+ ret &= ecore_x_randr_crtc_pos_set(man->root, ci->xid, sc->pos.x, sc->pos.y);
+ }
+ return ret;
+}
+
+//Utility functions
+ static Ecore_X_Randr_Output *
_e_randr_outputs_to_array(Eina_List *outputs_info)
{
Ecore_X_Randr_Output *ret = NULL;
@@ -1148,7 +1617,7 @@ _e_randr_outputs_to_array(Eina_List *outputs_info)
if (!outputs_info || !(ret = malloc(sizeof(Ecore_X_Randr_Output) * eina_list_count(outputs_info)))) return NULL;
EINA_LIST_FOREACH(outputs_info, output_iter, output_info)
- /* output_info == NULL should _not_ be possible! */
+ /* output_info == NULL should _not_ be possible! */
ret[i++] = output_info ? output_info->xid : Ecore_X_Randr_None;
return ret;
}
@@ -1191,7 +1660,7 @@ _e_randr_try_enable_output(E_Randr_Output_Info *output_info, Eina_Bool force)
if (!usable_crtc) return EINA_FALSE;
//get the CRTC we will refer to, dependend on policy
- switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy)
+ switch (output_info->policy)
{
case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
return EINA_TRUE;
@@ -1386,15 +1855,19 @@ static Eina_Bool
_e_randr_crtc_move_policy(E_Randr_Crtc_Info *new_crtc)
{
const E_Randr_Crtc_Info *crtc_rel;
+ E_Randr_Output_Info *last_output = NULL;
int dx = Ecore_X_Randr_None, dy = Ecore_X_Randr_None;
Eina_Bool ret = EINA_TRUE;
+ //use the policy of the new crtc's last output
+ last_output = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(new_crtc->outputs));
+ if (!last_output) return EINA_FALSE;
//get the crtc we will place our's relative to. If it's NULL, this is the
//only output attached, work done.
- if(!(crtc_rel = _e_randr_policy_crtc_get(new_crtc, NULL, e_randr_screen_info->rrvd_info.randr_info_12->output_policy))) return EINA_TRUE;
+ if(!(crtc_rel = _e_randr_policy_crtc_get(new_crtc, NULL, last_output->policy))) return EINA_TRUE;
//following is policy dependend.
- switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy)
+ switch (last_output->policy)
{
case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
dy = (crtc_rel->geometry.y - new_crtc->geometry.h);
@@ -1425,7 +1898,7 @@ _e_randr_crtc_move_policy(E_Randr_Crtc_Info *new_crtc)
default:
break;
}
- ret &= ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, new_crtc->xid, crtc_rel->xid, e_randr_screen_info->rrvd_info.randr_info_12->output_policy, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
+ ret &= ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, new_crtc->xid, crtc_rel->xid, last_output->policy, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
return ret;
}
@@ -1686,6 +2159,8 @@ _e_randr_output_info_hw_info_set(E_Randr_Output_Info *output_info)
_e_randr_output_modes_add(output_info);
output_info->edid = ecore_x_randr_output_edid_get(e_randr_screen_info->root, output_info->xid, &output_info->edid_length);
+ if (output_info->edid_length > 0)
+ output_info->edid_hash.hash = eina_hash_superfast(output_info->edid, output_info->edid_length);
//get the outputs we can use on the same CRTC alongside this one.
if ((outputs = ecore_x_randr_output_clones_get(e_randr_screen_info->root, output_info->xid, &num)))
{
@@ -1711,6 +2186,10 @@ _e_randr_output_info_hw_info_set(E_Randr_Output_Info *output_info)
}
free(crtcs);
}
+ else
+ {
+ fprintf(stderr, "E_RANDR: Output %x does not have a single possible CRTC.\n", output_info->xid);
+ }
}
/*
diff --git a/src/bin/e_randr.h b/src/bin/e_randr.h
index 448fc8901..7f04d0283 100644
--- a/src/bin/e_randr.h
+++ b/src/bin/e_randr.h
@@ -1,24 +1,26 @@
#ifdef E_TYPEDEFS
typedef struct _E_Randr_Crtc_Info E_Randr_Crtc_Info;
+typedef struct _E_Randr_Edid_Hash E_Randr_Edid_Hash;
typedef struct _E_Randr_Output_Info E_Randr_Output_Info;
typedef struct _E_Randr_Screen_Info_11 E_Randr_Screen_Info_11;
typedef struct _E_Randr_Screen_Info_12 E_Randr_Screen_Info_12;
typedef union _E_Randr_Screen_RRVD_Info E_Randr_Screen_RRVD_Info;
typedef struct _E_Randr_Screen_Info E_Randr_Screen_Info;
-typedef struct _E_Randr_Output_Edid_Hash E_Randr_Output_Edid_Hash;
-typedef struct _E_Randr_Output_Restore_Info E_Randr_Output_Restore_Info;
-typedef struct _E_Randr_Crtc_Restore_Info E_Randr_Crtc_Restore_Info;
-typedef struct _E_Randr_Screen_Restore_Info_11 E_Randr_Screen_Restore_Info_11;
-typedef struct _E_Randr_Screen_Restore_Info_12 E_Randr_Screen_Restore_Info_12;
-typedef union _E_Randr_Screen_Restore_Info_Union E_Randr_Screen_Restore_Info_Union;
-typedef struct _E_Randr_Screen_Restore_Info E_Randr_Screen_Restore_Info;
+typedef struct _E_Randr_Serialized_Output_Policy E_Randr_Serialized_Output_Policy;
+typedef struct _E_Randr_Serialized_Output E_Randr_Serialized_Output;
+typedef struct _E_Randr_Serialized_Crtc E_Randr_Serialized_Crtc;
+typedef struct _E_Randr_Serialized_Setup_11 E_Randr_Serialized_Setup_11;
+typedef struct _E_Randr_Serialized_Setup_12 E_Randr_Serialized_Setup_12;
+typedef struct _E_Randr_Serialized_Setup E_Randr_Serialized_Setup;
+
+EAPI void e_randr_store_configuration(E_Randr_Screen_Info *screen_info);
#else
#ifndef E_RANDR_H
#define E_RANDR_H
-struct _E_Randr_Crtc_Info
+struct _E_Randr_Crtc_Info
{
Ecore_X_ID xid;
Eina_Rectangle geometry;
@@ -35,7 +37,12 @@ struct _E_Randr_Crtc_Info
Ecore_X_Randr_Mode_Info *current_mode;
};
-struct _E_Randr_Output_Info
+struct _E_Randr_Edid_Hash
+{
+ int hash;
+};
+
+struct _E_Randr_Output_Info
{
Ecore_X_ID xid;
char *name;
@@ -47,6 +54,7 @@ struct _E_Randr_Output_Info
int connector_number;
Ecore_X_Randr_Connector_Type connector_type;
Ecore_X_Randr_Connection_Status connection_status;
+ Ecore_X_Randr_Output_Policy policy;
/*
* Attached Monitor specific:
*/
@@ -57,6 +65,7 @@ struct _E_Randr_Output_Info
Ecore_X_Randr_Screen_Size size_mm;
unsigned char *edid;
unsigned long edid_length;
+ E_Randr_Edid_Hash edid_hash;
int max_backlight;
double backlight_level;
Ecore_X_Render_Subpixel_Order subpixel_order;
@@ -75,7 +84,7 @@ struct _E_Randr_Screen_Info_11
Ecore_X_Randr_Refresh_Rate current_rate;
};
-struct _E_Randr_Screen_Info_12
+struct _E_Randr_Screen_Info_12
{
Ecore_X_Randr_Screen_Size min_size;
Ecore_X_Randr_Screen_Size max_size;
@@ -84,18 +93,17 @@ struct _E_Randr_Screen_Info_12
Eina_List *crtcs;
Eina_List *outputs;
E_Randr_Output_Info *primary_output;
- Ecore_X_Randr_Output_Policy output_policy;
Ecore_X_Randr_Relative_Alignment alignment;
};
//RRVD == RandR(R) Version Depended
-union _E_Randr_Screen_RRVD_Info
+union _E_Randr_Screen_RRVD_Info
{
E_Randr_Screen_Info_11 *randr_info_11;
E_Randr_Screen_Info_12 *randr_info_12;
};
-struct _E_Randr_Screen_Info
+struct _E_Randr_Screen_Info
{
Ecore_X_Window root;
int randr_version;
@@ -103,56 +111,67 @@ struct _E_Randr_Screen_Info
};
//Following stuff is just for configuration purposes
-struct _E_Randr_Output_Edid_Hash {
- int hash;
+
+struct _E_Randr_Serialized_Output_Policy
+{
+ char *name;
+ int name_length;
+ Ecore_X_Randr_Output_Policy policy;
};
-struct _E_Randr_Output_Restore_Info
+struct _E_Randr_Serialized_Output
{
- E_Randr_Output_Edid_Hash edid_hash;
+ char *name;
+ int name_length;
+ E_Randr_Edid_Hash edid_hash;
double backlight_level;
};
-struct _E_Randr_Crtc_Restore_Info
+struct _E_Randr_Serialized_Crtc
{
- Eina_Rectangle geometry;
+ //List of E_Randr_Serialized_Output objects that were used on the same output
+ Eina_List *serialized_outputs;
+ //the serialized mode_info misses its xid value
+ Ecore_X_Randr_Mode_Info mode_info;
+ Evas_Coord_Point pos;
+ //List of all possible outputs' names
+ //e.g. "LVDS", "CRT-0", "VGA"
+ Eina_List *possible_outputs_names;
Ecore_X_Randr_Orientation orientation;
- //list of the outputs;
- Eina_List *outputs;
};
-struct _E_Randr_Screen_Restore_Info_11
+struct _E_Randr_Serialized_Setup_12
{
- Ecore_X_Randr_Screen_Size size;
+ double timestamp;
+ //List of E_Randr_Serialized_Crtc objects
+ Eina_List *serialized_crtcs;
+ /*
+ * List of E_Randr_Edid_Hash elements of monitors,
+ * that were enabled, when the setup was stored
+ */
+ Eina_List *serialized_edid_hashes;
+};
+
+struct _E_Randr_Serialized_Setup_11
+{
+ Ecore_X_Randr_Screen_Size_MM size;
Ecore_X_Randr_Refresh_Rate refresh_rate;
Ecore_X_Randr_Orientation orientation;
};
-struct _E_Randr_Screen_Restore_Info_12
+struct _E_Randr_Serialized_Setup
{
- Eina_List *outputs_edid_hashes;
- int noutputs;
- Eina_List *crtcs;
- Ecore_X_Randr_Output_Policy output_policy;
- Ecore_X_Randr_Relative_Alignment alignment;
-};
-
-union _E_Randr_Screen_Restore_Info_Union
-{
- E_Randr_Screen_Restore_Info_11 *restore_info_11;
- Eina_List *restore_info_12;
-};
-
-struct _E_Randr_Screen_Restore_Info
-{
- int randr_version;
- E_Randr_Screen_Restore_Info_Union rrvd_restore_info;
+ E_Randr_Serialized_Setup_11 *serialized_setup_11;
+ //List of E_Randr_Serialized_Setup_12 objects
+ Eina_List *serialized_setups_12;
+ //List of E_Randr_Serialized_Output_Policy objects
+ Eina_List *serialized_outputs_policies;
};
EINTERN Eina_Bool e_randr_init(void);
EINTERN int e_randr_shutdown(void);
-extern E_Randr_Screen_Info *e_randr_screen_info;
+EAPI extern E_Randr_Screen_Info *e_randr_screen_info;
#endif
#endif
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index 7eadd76a1..56498e786 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -126,6 +126,10 @@ if USE_MODULE_CONF_INTERACTION
SUBDIRS += conf_interaction
endif
+if USE_MODULE_CONF_RANDR
+SUBDIRS += conf_randr
+endif
+
if USE_MODULE_GADMAN
SUBDIRS += gadman
endif
diff --git a/src/modules/conf_display/e_int_config_display.c b/src/modules/conf_display/e_int_config_display.c
index 27b62844b..6733c9429 100644
--- a/src/modules/conf_display/e_int_config_display.c
+++ b/src/modules/conf_display/e_int_config_display.c
@@ -23,8 +23,6 @@ static int _sort_resolutions (const void *d1, const void *d2);
typedef struct _Resolution Resolution;
typedef struct _SureBox SureBox;
-static E_Randr_Screen_Restore_Info_11 *e_screen_config_11 = NULL;
-
struct _Resolution
{
int id;
@@ -96,13 +94,8 @@ _surebox_dialog_cb_yes(void *data, E_Dialog *dia)
ecore_x_randr_screen_primary_output_current_size_get(man->root, &c_size.width, &c_size.height, NULL, NULL, NULL);
c_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
- if (e_screen_config_11)
- {
- e_screen_config_11->size.width = c_size.width;
- e_screen_config_11->size.height = c_size.height;
- e_screen_config_11->refresh_rate = c_rate;
- e_config_save_queue();
- }
+ e_randr_store_configuration(e_randr_screen_info);
+
_fill_data(sb->cfdata);
_load_resolutions(sb->cfdata);
/* No need to load rates as the currently selected resolution has not been
@@ -242,7 +235,6 @@ static void
_fill_data(E_Config_Dialog_Data *cfdata)
{
E_Manager *man;
- E_Randr_Screen_Restore_Info *restore_info;
Eina_List *iter;
int rots;
@@ -250,36 +242,6 @@ _fill_data(E_Config_Dialog_Data *cfdata)
ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index);
cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
- EINA_LIST_FOREACH(e_config->screen_info, iter, restore_info)
- {
- if (restore_info->randr_version == RANDR_11)
- {
- e_screen_config_11 = restore_info->rrvd_restore_info.restore_info_11;
- break;
- }
- }
-
- if(!e_screen_config_11)
- {
- if ((restore_info = E_NEW(E_Randr_Screen_Restore_Info, 1)))
- {
- restore_info->randr_version = RANDR_11;
- if ((e_screen_config_11 = E_NEW(E_Randr_Screen_Restore_Info_11, 1)))
- {
- restore_info->rrvd_restore_info.restore_info_11 = e_screen_config_11;
- if (!(e_config->screen_info = eina_list_append(e_config->screen_info, restore_info)))
- {
- free(e_screen_config_11);
- free(restore_info);
- }
- }
- else
- {
- free (restore_info);
- }
- }
- }
-
rots = ecore_x_randr_screen_primary_output_orientations_get(man->root);
if ((rots) && (rots != ECORE_X_RANDR_ORIENTATION_ROT_0))
{
@@ -352,7 +314,6 @@ _basic_check_changed(E_Config_Dialog *cfd __UNUSED__, E_Config_Dialog_Data *cfda
rt = eina_list_nth(res->rates, r);
if (!rt) return 0;
- if (!e_screen_config_11) return EINA_FALSE;
return ((res->size.width != cfdata->orig_size.width) ||
(res->size.height != cfdata->orig_size.height) ||
(cfdata->has_rates && (*rt != cfdata->orig_rate)) ||
@@ -414,14 +375,7 @@ _basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
(cfdata->orientation | cfdata->flip));
cfdata->orig_orientation = cfdata->orientation;
cfdata->orig_flip = cfdata->flip;
- if (e_screen_config_11)
- e_screen_config_11->orientation = (cfdata->orientation | cfdata->flip);
}
- else
- if (e_screen_config_11)
- e_screen_config_11->orientation = 0;
-
- e_config_save_queue();
return 1;
}
diff --git a/src/modules/conf_randr/Makefile.am b/src/modules/conf_randr/Makefile.am
new file mode 100644
index 000000000..f54929fda
--- /dev/null
+++ b/src/modules/conf_randr/Makefile.am
@@ -0,0 +1,51 @@
+MAINTAINERCLEANFILES = Makefile.in module.desktop
+MODULE = conf_randr
+
+EDJE_CC = @edje_cc@
+EDJE_FLAGS = -v \
+ -id $(top_srcdir)/src/modules/$(MODULE)/images \
+ @EDJE_DEF@
+
+# data files for the module
+filesdir = $(libdir)/enlightenment/modules/$(MODULE)
+files_DATA = \
+ e-module-$(MODULE).edj \
+ module.desktop
+
+EXTRA_DIST = \
+ e-module-$(MODULE).edc \
+ module.desktop.in
+
+# the module .so file
+INCLUDES = -I. \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/modules/$(MODULE) \
+ -I$(top_srcdir)/src/bin \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/modules \
+ @e_cflags@
+pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+module_la_SOURCES = e_mod_main.c \
+ e_mod_main.h \
+ e_int_config_randr_orientation.c \
+ e_int_config_randr_resolutions.c \
+ e_int_config_randr_arrangement.c \
+ e_int_config_randr_policies.c \
+ e_int_config_randr.c \
+ e_int_config_randr.h
+
+module_la_LIBADD = @e_libs@ @dlopen_libs@
+module_la_LDFLAGS = -module -avoid-version
+module_la_DEPENDENCIES = $(top_builddir)/config.h
+
+e-module-$(MODULE).edj: Makefile $(EXTRA_DIST)
+ $(EDJE_CC) $(EDJE_FLAGS) \
+ $(top_srcdir)/src/modules/$(MODULE)/e-module-$(MODULE).edc \
+ $(top_builddir)/src/modules/$(MODULE)/e-module-$(MODULE).edj
+
+clean-local:
+ rm -f *.edj
+
+uninstall:
+ rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)
diff --git a/src/modules/conf_randr/e-module-conf_randr.edc b/src/modules/conf_randr/e-module-conf_randr.edc
new file mode 100644
index 000000000..61f2e219f
--- /dev/null
+++ b/src/modules/conf_randr/e-module-conf_randr.edc
@@ -0,0 +1,945 @@
+#define BORDERSIZE 1
+#define SUGGESTION_TIMEOUT 2.5
+
+images {
+ image: "icon.png" COMP;
+ image: "video-display.svg" COMP;
+ image: "display.png" COMP;
+ image: "display-glass-shine.png" COMP;
+}
+
+collections {
+
+ // The icon used in the settings dialog
+ group {
+ name: "icon";
+ parts {
+ part {
+ name: "image";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.normal: "icon.png";
+ }
+ }
+ }
+ }
+
+ /**********************************************/
+ /*********Subdialog - Arrangement**************/
+ /**********************************************/
+
+ //The graphical representation of a single monitor, including its decorations
+ group {
+ name: "e/conf/randr/dialog/subdialog/arrangement/output";
+
+ styles {
+ style {
+ name: "display_name_text";
+ base: "font=Sans:style=Bold font_size=10 text_class=tb_plain align=center valign=center color=#fff style=soft_shadow shadow_color=#0000001f wrap=word";
+ tag: "br" "\n";
+ tag: "hilight" "+ font=Sans:style=Bold text_class=tb_light";
+ }
+ }
+
+
+ parts {
+
+ part {
+ name: "display";
+ type: IMAGE;
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ image.normal: "display.png";
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+
+ part {
+ name: "e.swallow.content";
+ type: SWALLOW; // background of CRTC's zone
+
+ description {
+ state: "default" 0.0;
+ aspect_preference: BOTH;
+ color: 255 255 255 255;
+ rel1 {
+ to: "display";
+ relative: 0.047379 0.049303;
+ }
+ rel2 {
+ to: "display";
+ //relative: 0.97 0.657804;
+ relative: 0.975 0.66;
+ }
+ }
+
+ description {
+ state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 128;
+ }
+ }
+
+ part {
+ name: "output_selected_frame_clip";
+ type: RECT;
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_top";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 0 2;
+ fixed: 0 1;
+ align: 0.5 0.0;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ relative: 1.0 0.0;
+ offset: 0 BORDERSIZE;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_right";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 1 0;
+ fixed: 1 0;
+ align: 1.0 0.5;
+
+ rel1 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_top";
+ relative: 1.0 1.0;
+ offset: (-BORDERSIZE-1) 0;
+ }
+ rel2 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_bottom";
+ relative: 1.0 0.0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_bottom";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 0 2;
+ fixed: 0 1;
+ align: 0.5 1.0;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ relative: 0.0 1.0;
+ offset: 0 (-BORDERSIZE-1);
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ relative: 1.0 1.0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_left";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 1 0;
+ fixed: 1 0;
+ align: 0.0 0.5;
+
+ rel1 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_top";
+ relative: 0.0 1.0;
+ }
+ rel2 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_bottom";
+ relative: 0.0 0.0;
+ offset: BORDERSIZE 0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frm_inside";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 120;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ offset: BORDERSIZE BORDERSIZE;
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ offset: -BORDERSIZE -BORDERSIZE;
+ }
+ }
+ }
+
+ part {
+ name: "output_txt_bg";
+ type: RECT;
+ //clip_to: "output_txt_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 128;
+ align: 0.5 0.5;
+
+ rel1 {
+ to: "output_txt";
+ relative: 0.0 0.0;
+ offset: -5 -5;
+ }
+ rel2 {
+ to: "output_txt";
+ relative: 1.0 1.0;
+ offset: 5 5;
+ }
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 255;
+ }
+ }
+
+ part {
+ name: "output_txt";
+ type: TEXTBLOCK;
+ //clip_to: "output_txt_clip";
+ mouse_events: 0;
+
+ description {
+ align: 0.5 0.5;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ // define part coordinates:
+ //rel1.to: "output_txt_clip";
+ //rel2.to: "output_txt_clip";
+ rel1.to: "e.swallow.content";
+ rel2.to: "e.swallow.content";
+
+ text {
+ style: "display_name_text";
+ text: "output name";
+ min: 1.0 1.0;
+ max: 1.0 1.0;
+ }
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+
+ part {
+ name: "selected_toggle_on";
+ type: RECT;
+ mouse_events: 1;
+
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 1;
+
+ rel1 {
+ to: "e.swallow.content";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "e.swallow.content";
+ relative: 1.0 1.0;
+ }
+ }
+
+ description {
+ state: "disable" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+
+ part {
+ name: "selected_toggle_off";
+ type: RECT;
+ mouse_events: 1;
+
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 0;
+
+ rel1 {
+ to: "selected_toggle_on";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "selected_toggle_on";
+ relative: 1.0 1.0;
+ }
+ }
+
+ description {
+ state: "disable" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+
+ part {
+ name: "display-glass-shine";
+ type: IMAGE;
+
+ description {
+ state: "default" 0.0;
+ image.normal: "display-glass-shine.png";
+ }
+ }
+
+ programs {
+ program {
+ name: "highlight";
+ signal: "mouse,down,1";
+ source: "selected_toggle_on";
+
+ action: STATE_SET "selected" 0.0;
+ transition: LINEAR 0.1;
+ //target: "e.swallow.content";
+ //target: "output_selected_clip";
+ target: "output_txt";
+ target: "output_txt_bg";
+ target: "output_selected_frame_clip";
+ }
+
+ program {
+ name: "normal";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_off";
+
+ action: STATE_SET "default" 0.0;
+ transition: LINEAR 0.1;
+ //target: "e.swallow.content";
+ //target: "output_selected_clip";
+ target: "output_txt";
+ target: "output_txt_bg";
+ target: "output_selected_frame_clip";
+ }
+
+ program {
+ name: "selected_toggle_off_on";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_on";
+ action: STATE_SET "disable" 1.0;
+ target: "selected_toggle_on";
+ target: "selected_toggle_off";
+ }
+
+ program {
+ name: "selected_toggle_on_off";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_off";
+ action: STATE_SET "default" 1.0;
+ target: "selected_toggle_on";
+ target: "selected_toggle_off";
+ }
+
+ program {
+ name: "emit_highlight";
+ signal: "select";
+ source: "e";
+ after: "highlight";
+ }
+
+ program {
+ name: "emit_normal";
+ signal: "deselect";
+ source: "e";
+ after: "normal";
+ }
+
+ program {
+ name: "disable";
+ signal: "disabled";
+ source: "e";
+ action: STATE_SET "disabled" 0.0;
+ target: "e.swallow.content";
+ }
+
+ program {
+ name: "enable";
+ signal: "enabled";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "e.swallow.content";
+ }
+
+ program {
+ name: "init";
+ after: "normal";
+ }
+ }
+ }
+ }
+
+ //This group describes the look of the suggestion entity used, when a monitor
+ //representation is dragged. Its size matches the size of the monitor
+ //dragged.
+ group{
+ name: "e/conf/randr/dialog/subdialog/arrangement/suggestion";
+ data {
+ item: "distance_min" "20";
+ }
+
+ /*
+ script {
+ public fade_out_timer_id = 0;
+
+ public suggestion_fade_out ()
+ {
+ cancel_timer(get_int(fade_out_timer_id));
+ run_program(PROGRAM:"hide");
+ }
+ }
+ */
+
+ parts {
+ part {
+ name: "shape_clip";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "shape";
+ type: RECT;
+ mouse_events: 0;
+ clip_to: "shape_clip";
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 100;
+ rel1.to: "shape_clip";
+ rel2.to: "shape_clip";
+ }
+ }
+ }
+ programs {
+ program {
+ name: "show_transition";
+ signal: "show";
+ source: "e";
+ action: STATE_SET "visible" 0.0;
+ target: "shape_clip";
+ transition: LINEAR 0.2;
+ }
+ /*
+ program {
+ name: "set_timeout";
+ signal: "show";
+ source: "e";
+ script {
+ new i = timer(SUGGESTION_TIMEOUT, "suggestion_fade_out", 0);
+ set_int(fade_out_timer_id, i);
+ }
+ }
+ */
+ program {
+ name: "hide";
+ signal: "hide";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "shape_clip";
+ transition: LINEAR 0.2;
+ }
+ }
+ }
+
+ /**********************************************/
+ /************Subdialog - Policies**************/
+ /**********************************************/
+ group{
+ name: "e/conf/randr/dialog/subdialog/policies";
+ parts {
+ part {
+ name: "current_displays_setup/clipper";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.25;
+ rel2.relative: 0.75 0.75;
+ }
+ description {
+ state: "above" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.25 0.5;
+ rel2.relative: 0.75 1.0;
+ }
+ description {
+ state: "right" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.0 0.25;
+ rel2.relative: 0.5 0.75;
+ }
+ description {
+ state: "below" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.25 0.0;
+ rel2.relative: 0.75 0.5;
+ }
+ description {
+ state: "left" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.5 0.25;
+ rel2.relative: 1.0 0.75;
+ }
+ description {
+ state: "clone" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "none" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "current_displays_setup.swallow.content";
+ type: SWALLOW;
+ clip_to: "current_displays_setup/clipper";
+ description {
+ state: "default" 0.0;
+ rel1.to: "current_displays_setup/clipper";
+ rel2.to: "current_displays_setup/clipper";
+ }
+ }
+ part {
+ name: "new_display/clipper";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.25;
+ rel2.relative: 0.75 0.75;
+ }
+ description {
+ state: "above" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.0;
+ rel2.relative: 0.75 0.5;
+ }
+ description {
+ state: "above_visible" 0.0;
+ inherit: "above" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "right" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.5 0.25;
+ rel2.relative: 1.0 0.75;
+ }
+ description {
+ state: "right_visible" 0.0;
+ inherit: "right" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "below" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.5;
+ rel2.relative: 0.75 1.0;
+ }
+ description {
+ state: "below_visible" 0.0;
+ inherit: "below" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "left" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.0 0.25;
+ rel2.relative: 0.5 0.75;
+ }
+ description {
+ state: "left_visible" 0.0;
+ inherit: "left" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "clone" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ description {
+ state: "clone_visible" 0.0;
+ inherit: "clone" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "none" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ description {
+ state: "none_visible" 0.0;
+ inherit: "none" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "new_display.swallow.content";
+ type: SWALLOW;
+ clip_to: "new_display/clipper";
+ description {
+ state: "default" 0.0;
+ rel1.to: "new_display/clipper";
+ rel2.to: "new_display/clipper";
+ }
+ }
+ }
+ /*
+ * The signals emitted to the UI are encoded as their corresponding value
+ * in Ecore_X
+ *
+ * Policy = Signal emitted
+ * ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1
+ * ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2
+ * ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3
+ * ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4
+ * ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5
+ * ECORE_X_RANDR_OUTPUT_POLICY_NONE = 6
+ */
+ programs {
+ program {
+ name: "new_display_hide";
+ signal: "conf,randr,dialog,policies,*";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "new_display/clipper";
+ }
+ program {
+ name: "current_displays_setup_clipper_above";
+ signal: "conf,randr,dialog,policies,1";
+ source: "e";
+ action: STATE_SET "above" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_above_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_above_visible_set";
+ action: STATE_SET "above_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_right";
+ signal: "conf,randr,dialog,policies,2";
+ source: "e";
+ action: STATE_SET "right" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_right_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_right_visible_set";
+ action: STATE_SET "right_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_below";
+ signal: "conf,randr,dialog,policies,3";
+ source: "e";
+ action: STATE_SET "below" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_below_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_below_visible_set";
+ action: STATE_SET "below_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_left";
+ signal: "conf,randr,dialog,policies,4";
+ source: "e";
+ action: STATE_SET "left" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_left_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_left_visible_set";
+ action: STATE_SET "left_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_clone";
+ signal: "conf,randr,dialog,policies,5";
+ source: "e";
+ action: STATE_SET "clone" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_clone_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_clone_visible_set";
+ action: STATE_SET "clone_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_none";
+ signal: "conf,randr,dialog,policies,6";
+ source: "e";
+ action: STATE_SET "none" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ //after: "new_display_none_visible_set";
+ transition: LINEAR 0.5;
+ }
+ /*
+ * following is an analog program for none, but we don't want to show
+ * it anyway.
+ program {
+ name: "new_display_none_visible_set";
+ action: STATE_SET "none_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ */
+ }
+ }
+
+ // Text objects for rotation and reflection
+ group {
+ name: "e/conf/randr/dialog/subdialog/orientation";
+
+ parts {
+ part {
+ name: "clip";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+ part {
+ name: "display";
+ clip_to: "clip";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.normal: "video-display.svg";
+ }
+ }
+ part {
+ name: "orientation_text";
+ clip_to: "clip";
+ type: TEXT;
+ mouse_events: 0;
+ scale: 1;
+ description {
+ state: "default" 0.0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 0.8;
+ color: 0 0 0 255;
+ text {
+ //Maybe use some default theme label text style later
+ text: "Orientation";
+ font: "Sans:style=Bold";
+ /* Use the Bold style
+ * of the Sans font from
+ * fontconfig */
+ size: 10;
+ /* size in pixels - 10 */
+ min: 0 1;
+ /* the text will not determine minimum horizontal
+ * size but WILL determine minimal vertical size
+ * (thus 0 1 - horiz then vert flags) */
+ /* align text to top-left of the region
+ * given */
+ text_class: "title_bar";
+ /* text class - so font and size
+ * can be changed by users */
+ }
+ map {
+ on: 1;
+ rotation {
+ x: 0.0;
+ y: 0.0;
+ z: 0.0;
+ }
+ }
+ }
+ description {
+ state: "rotate" 0.90;
+ inherit: "default" 0.0;
+ map.rotation.z: 270.0;
+ }
+ description {
+ state: "rotate" 0.180;
+ inherit: "default" 0.0;
+ map.rotation.z: 180.0;
+ }
+ description {
+ state: "rotate" 0.270;
+ inherit: "default" 0.0;
+ map.rotation.z: 90.0;
+ }
+ description {
+ state: "reflect_horizontal" 0.0;
+ inherit: "default" 0.0;
+ map.rotation.y: 180.0;
+ }
+ description {
+ state: "reflect_vertical" 0.0;
+ inherit: "default" 0.0;
+ map.rotation.x: 180.0;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "rot0";
+ signal: "conf,randr,dialog,orientation,current,1";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot90";
+ signal: "conf,randr,dialog,orientation,current,2";
+ source: "e";
+ action: STATE_SET "rotate" 0.90;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot180";
+ signal: "conf,randr,dialog,orientation,current,4";
+ source: "e";
+ action: STATE_SET "rotate" 0.180;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot270";
+ signal: "conf,randr,dialog,orientation,current,8";
+ source: "e";
+ action: STATE_SET "rotate" 0.270;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "ref_x";
+ signal: "conf,randr,dialog,orientation,current,16";
+ source: "e";
+ action: STATE_SET "reflect_horizontal" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "ref_y";
+ signal: "conf,randr,dialog,orientation,current,32";
+ source: "e";
+ action: STATE_SET "reflect_vertical" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ }
+
+ }
+
+}
diff --git a/src/modules/conf_randr/e_int_config_randr.c b/src/modules/conf_randr/e_int_config_randr.c
new file mode 100644
index 000000000..3a525e708
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr.c
@@ -0,0 +1,424 @@
+#include "e_int_config_randr.h"
+#include "e_widget_toolbook.h"
+#include "e.h"
+#include "e_randr.h"
+
+/*
+ * BUGS:
+ * - ethumb sometimes returns garbage objects leading to a segv
+ *
+ * TODO:
+ * - write 1.2 per monitor configuration
+ * - write Smart object, so crtcs representations can be properly freed (events,
+ * etc.)
+ *
+ * IMPROVABLE:
+ * See comments starting with 'IMPROVABLE'
+ */
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+
+#ifdef Ecore_X_Randr_None
+#undef Ecore_X_Randr_None
+#define Ecore_X_Randr_None 0
+#else
+#define Ecore_X_Randr_None 0
+#endif
+#ifdef Ecore_X_Randr_Unset
+#undef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#else
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define THEME_FILENAME "/e-module-conf_randr.edj"
+#define TOOLBAR_ICONSIZE 16
+
+static void *create_data (E_Config_Dialog *cfd);
+static void free_cfdata (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static int basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static int basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static Evas_Object *basic_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
+static Eina_Bool _deferred_noxrandr_error (void *data);
+static Eina_Bool _deferred_norates_error (void *data);
+
+// Functions for the arrangement subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_arrangement_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the policies subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_policies_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_policies_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_policies_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the resolutions subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_resolutions_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_resolutions_update_list (Evas *canvas, Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_resolutions_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_resolutions_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the orientation subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_orientation_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_orientation_update_radio_buttons (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_update_edje (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_orientation_discard_changes (E_Config_Dialog_Data *cfdata);
+
+/* actual module specifics */
+E_Config_Dialog_Data *e_config_runtime_info = NULL;
+extern E_Module *conf_randr_module;
+char _theme_file_path[PATH_MAX];
+
+ E_Config_Randr_Dialog_Output_Dialog_Data *
+_e_config_randr_dialog_output_dialog_data_new(E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ if ((!crtc_info && !output_info) || !(dialog_data = E_NEW(E_Config_Randr_Dialog_Output_Dialog_Data, 1))) return NULL;
+ if (crtc_info)
+ {
+ //already enabled screen
+ dialog_data->crtc = crtc_info;
+ }
+ else if (output_info)
+ {
+ //disabled monitor
+ dialog_data->output = output_info;
+ }
+ return dialog_data;
+
+_e_conf_randr_dialog_create_output_data_failed:
+ free(dialog_data);
+ return NULL;
+}
+
+
+ static void *
+create_data(E_Config_Dialog *cfd)
+{
+ Eina_List *iter;
+ E_Randr_Output_Info *output_info;
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+
+ // Prove we got all things to get going
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2), NULL);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!(e_config_runtime_info = E_NEW(E_Config_Dialog_Data, 1)), NULL);
+
+ e_config_runtime_info->cfd = cfd;
+
+ //Compose theme's file path and name
+ snprintf(_theme_file_path, sizeof(_theme_file_path), "%s%s", conf_randr_module->dir, THEME_FILENAME);
+
+ e_config_runtime_info->manager = e_manager_current_get();
+ EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info)
+ {
+ //Create basic data struct for every connected output.
+ //Data would have to be recreated if a monitor is connected while dialog
+ //is open.
+ if (output_info->connection_status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
+ continue;
+ if ((odd = _e_config_randr_dialog_output_dialog_data_new(output_info->crtc, output_info)))
+ EINA_SAFETY_ON_FALSE_GOTO((e_config_runtime_info->output_dialog_data_list = eina_list_append(e_config_runtime_info->output_dialog_data_list, odd)), _e_conf_randr_create_data_failed_free_data);
+ }
+
+ fprintf(stderr, "CONF_RANDR: Added %d output data structs.\n", eina_list_count(e_config_runtime_info->output_dialog_data_list));
+ //FIXME: Properly (stack-like) free data when creation fails
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_arrangement_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_resolutions_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_policies_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_orientation_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+
+ return e_config_runtime_info;
+
+_e_conf_randr_create_data_failed_free_data:
+ free(e_config_runtime_info);
+ return NULL;
+}
+
+ static void
+free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ EINA_SAFETY_ON_TRUE_RETURN(!e_randr_screen_info);
+ e_config_randr_dialog_subdialog_arrangement_free_data(cfd, cfdata);
+
+ if (cfdata) free(cfdata);
+ cfdata = NULL;
+}
+
+ static Eina_Bool
+_e_conf_randr_confirmation_dialog_timer_cb(void *data)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+ char buf[4096];
+
+ if (!cdd) return ECORE_CALLBACK_CANCEL;
+
+ --cdd->countdown;
+
+ if (cdd->countdown > 0)
+ {
+ snprintf(buf, sizeof(buf),
+ _("Does this look OK? Click Keep if it does, or Restore if not.
"
+ "If you do not press a button, the previous settings will be restored in %d seconds."), cdd->countdown);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf),
+ _("Does this look OK? Click Keep if it does, or Restore if not.
"
+ "If you do not press a button, the previous settings will be restored IMMEDIATELY."));
+ }
+
+ e_dialog_text_set(cdd->dialog, buf);
+
+ return (cdd->countdown > 0) ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL;
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_delete_cb(E_Win *win)
+{
+ E_Dialog *dia;
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd;
+ E_Config_Dialog *cfd;
+
+ dia = win->data;
+ cd = dia->data;
+ cd->cfdata->gui.confirmation_dialog = NULL;
+ cfd = cd->cfdata->cfd;
+ if (cd->timer) ecore_timer_del(cd->timer);
+ cd->timer = NULL;
+ free(cd);
+ e_object_del(E_OBJECT(dia));
+ e_object_unref(E_OBJECT(cfd));
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_keep_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ e_config_randr_dialog_subdialog_arrangement_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_orientation_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_policies_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_resolutions_keep_changes(cdd->cfdata);
+ _e_conf_randr_confirmation_dialog_delete_cb(dia->win);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_discard_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ e_config_randr_dialog_subdialog_arrangement_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_orientation_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_policies_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_resolutions_discard_changes(cdd->cfdata);
+ _e_conf_randr_confirmation_dialog_delete_cb(dia->win);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_store_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ _e_conf_randr_confirmation_dialog_keep_cb(data, dia);
+ e_randr_store_configuration(e_randr_screen_info);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_new(E_Config_Dialog *cfd)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd = E_NEW(E_Config_Randr_Dialog_Confirmation_Dialog_Data, 1);
+
+ if (!cd) return;
+
+ cd->cfd = cfd;
+
+ if((cd->dialog = e_dialog_new(cfd->con, "E", "e_randr_confirmation_dialog")))
+ {
+ e_dialog_title_set(cd->dialog, _("New settings confirmation"));
+ cd->cfdata = cfd->cfdata;
+ cd->timer = ecore_timer_add(1.0, _e_conf_randr_confirmation_dialog_timer_cb, cd);
+ cd->countdown = 15;
+ cd->dialog->data = cd;
+ e_dialog_icon_set(cd->dialog, "preferences-system-screen-resolution", 48);
+ e_win_delete_callback_set(cd->dialog->win, _e_conf_randr_confirmation_dialog_delete_cb);
+ e_dialog_button_add(cd->dialog, _("Keep"), NULL, _e_conf_randr_confirmation_dialog_keep_cb, cd);
+ e_dialog_button_add(cd->dialog, _("Store Permanently"), NULL, _e_conf_randr_confirmation_dialog_store_cb, cd);
+ e_dialog_button_add(cd->dialog, _("Restore"), NULL, _e_conf_randr_confirmation_dialog_discard_cb, cd);
+ e_dialog_button_focus_num(cd->dialog, 1);
+ e_win_centered_set(cd->dialog->win, 1);
+ e_win_borderless_set(cd->dialog->win, 1);
+ e_win_layer_set(cd->dialog->win, 6);
+ e_win_sticky_set(cd->dialog->win, 1);
+ e_dialog_show(cd->dialog);
+ e_object_ref(E_OBJECT(cfd));
+ }
+
+}
+
+ static Evas_Object *
+basic_create_widgets (E_Config_Dialog *cfd, Evas *canvas, E_Config_Dialog_Data *cfdata)
+{
+ Evas_Object *table = NULL, *wl = NULL;
+
+ EINA_SAFETY_ON_TRUE_RETURN_VAL (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2), NULL);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL((!canvas || !cfdata), NULL);
+
+ if(!(cfdata->gui.subdialogs.arrangement.dialog = e_config_randr_dialog_subdialog_arrangement_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_arrangement_fail;
+ if(!(cfdata->gui.subdialogs.policies.dialog = e_config_randr_dialog_subdialog_policies_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_policies_fail;
+ if(!(cfdata->gui.subdialogs.resolutions.dialog = e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_resolutions_fail;
+ if(!(cfdata->gui.subdialogs.orientation.dialog = e_config_randr_dialog_subdialog_orientation_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_orientation_fail;
+
+ EINA_SAFETY_ON_FALSE_GOTO((table = e_widget_table_add(canvas, EINA_FALSE)), _e_config_randr_dialog_create_widgets_fail);
+ EINA_SAFETY_ON_FALSE_GOTO((wl = e_widget_list_add(canvas, EINA_FALSE, EINA_TRUE)), _e_config_randr_dialog_create_widget_list_fail);
+
+ //e_widget_table_object_append(Evas_Object *obj, Evas_Object *sobj, int col, int row, int colspan, int rowspan, int fill_w, int fill_h, int expand_w, int expand_h);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.arrangement.dialog, 1, 1, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ /*
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.policies.dialog, 1, 2, 1, 1, 0, 0, 0, 0);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.orientation.dialog, 2, 2, 1, 1, 0, 0, 0, 0);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.resolutions.dialog, 3, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ */
+ //e_widget_list_object_append(Evas_Object *obj, Evas_Object *sobj, int fill, int expand, double align);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.policies.dialog, 0, 0, 0.0);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.orientation.dialog, 0, 0, 0.0);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.resolutions.dialog, EVAS_HINT_FILL, EVAS_HINT_EXPAND, 1.0);
+ e_widget_table_object_append(table, wl, 1, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ cfdata->gui.widget_list = wl;
+
+ cfdata->gui.dialog = table;
+
+ e_dialog_resizable_set(cfd->dia, EINA_TRUE);
+
+ return cfdata->gui.dialog;
+
+_e_config_randr_dialog_create_widget_list_fail:
+ evas_object_del(table);
+_e_config_randr_dialog_create_widgets_fail:
+ evas_object_del(cfdata->gui.subdialogs.orientation.dialog);
+_e_config_randr_dialog_create_subdialog_orientation_fail:
+ evas_object_del(cfdata->gui.subdialogs.resolutions.dialog);
+_e_config_randr_dialog_create_subdialog_resolutions_fail:
+ evas_object_del(cfdata->gui.subdialogs.policies.dialog);
+_e_config_randr_dialog_create_subdialog_policies_fail:
+ evas_object_del(cfdata->gui.subdialogs.arrangement.dialog);
+_e_config_randr_dialog_create_subdialog_arrangement_fail:
+ return NULL;
+}
+
+static int
+ basic_apply_data
+(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_Bool ret = EINA_TRUE;
+
+ fprintf(stderr, "CONF_RANDR: New configuration is beeing applied.\n");
+ //this is a special case, where the function is called, before the
+ //configuration data is created.
+ if (!cfdata) return EINA_FALSE;
+
+ //the order matters except for policies!
+ if (e_config_randr_dialog_subdialog_policies_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_policies_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_resolutions_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_resolutions_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_arrangement_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_arrangement_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_orientation_basic_check_changed(cfd, cfdata))
+ ret &= e_config_randr_dialog_subdialog_orientation_basic_apply_data(cfd, cfdata);
+
+ _e_conf_randr_confirmation_dialog_new(cfd);
+
+ return ret;
+}
+
+E_Config_Dialog *
+e_int_config_randr(E_Container *con, const char *params __UNUSED__){
+ E_Config_Dialog *cfd;
+ E_Config_Dialog_View *v;
+
+ if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2))
+ {
+ ecore_timer_add(0.5, _deferred_noxrandr_error, NULL);
+ fprintf(stderr, "CONF_RANDR: XRandR version >= 1.2 necessary to work.\n");
+ return NULL;
+ }
+
+ //Dialog already opened?
+ if (e_config_dialog_find("E", "screen/screen_setup")) return NULL;
+
+ v = E_NEW(E_Config_Dialog_View, 1);
+ v->create_cfdata = create_data;
+ v->free_cfdata = free_cfdata;
+ v->basic.apply_cfdata = basic_apply_data;
+ v->basic.create_widgets = basic_create_widgets;
+ v->basic.check_changed = basic_check_changed;
+ //v->override_auto_apply = 0;
+
+ cfd = e_config_dialog_new(con, _("Screen Setup"),
+ "E", "screen/screen_setup",
+ "preferences-system-screen-setup", 0, v, NULL);
+ return cfd;
+}
+
+ static Eina_Bool
+_deferred_noxrandr_error(void *data __UNUSED__)
+{
+ e_util_dialog_show(_("Missing Features"),
+ _("Your X Display Server is missing support for
"
+ "the XRandR (X Resize and Rotate) extension version 1.2 or above.
"
+ "You cannot change screen resolutions without
"
+ "the support of this extension. It could also be
"
+ "that at the time ecore was built, there
"
+ "was no XRandR support detected."));
+ return ECORE_CALLBACK_CANCEL;
+}
+
+ static int
+basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ if (!cfdata) return EINA_FALSE;
+ else
+ return (e_config_randr_dialog_subdialog_arrangement_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_policies_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_orientation_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_resolutions_basic_check_changed(cfd, cfdata));
+}
+
diff --git a/src/modules/conf_randr/e_int_config_randr.h b/src/modules/conf_randr/e_int_config_randr.h
new file mode 100644
index 000000000..5356e2494
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr.h
@@ -0,0 +1,73 @@
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_INT_CONFIG_RANDR_H
+#define E_INT_CONFIG_RANDR_H
+
+#include "e.h"
+
+typedef struct _E_Config_Randr_Dialog_Output_Dialog_Data E_Config_Randr_Dialog_Output_Dialog_Data;
+typedef struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data E_Config_Randr_Dialog_Confirmation_Dialog_Data;
+
+struct _E_Config_Dialog_Data
+{
+ E_Config_Dialog *cfd;
+
+ //list of E_Config_Randr_Dialog_Output_Dialog_Data
+ Eina_List *output_dialog_data_list;
+ E_Manager *manager;
+ struct {
+ Evas_Object *dialog, *widget_list, *selected_eo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *selected_output_dd;
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *confirmation_dialog;
+ struct {
+ struct {
+ Evas_Object *dialog, *swallowing_edje, *smart_parent, *suggestion, *clipper;
+ Evas_Coord_Point previous_pos, relative_zero;
+ int suggestion_dist_min;
+ } arrangement;
+ struct {
+ Evas_Object *dialog;
+ //Evas_Object *swallowing_edje;
+ Evas_Object *radio_above, *radio_right, *radio_below, *radio_left, *radio_clone, *radio_none;
+ int radio_val;
+ //Evas_Object *current_displays_setup, *current_displays_setup_background, *new_display, *new_display_background;
+ } policies;
+ struct {
+ Evas_Object *dialog;
+ } resolutions;
+ struct {
+ Evas_Object *dialog;
+ //Evas_Object *swallowing_edje;
+ Evas_Object *radio_normal, *radio_rot90, *radio_rot180, *radio_rot270, *radio_reflect_horizontal, *radio_reflect_vertical;
+ int radio_val;
+ } orientation;
+ } subdialogs;
+ } gui;
+ Ecore_X_Randr_Screen_Size screen_size;
+
+};
+
+struct _E_Config_Randr_Dialog_Output_Dialog_Data
+{
+ E_Randr_Crtc_Info *crtc;
+ E_Randr_Output_Info *output;
+ Evas_Coord_Point previous_pos, new_pos;
+ Ecore_X_Randr_Mode_Info *previous_mode, *new_mode, *preferred_mode;
+ Ecore_X_Randr_Orientation previous_orientation, new_orientation;
+ Ecore_X_Randr_Output_Policy previous_policy, new_policy;
+ Evas_Object *bg;
+};
+
+struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data
+{
+ E_Config_Dialog *cfd;
+ E_Config_Dialog_Data *cfdata;
+ E_Dialog *dialog;
+ Ecore_Timer *timer;
+ int countdown;
+};
+
+E_Config_Dialog *e_int_config_randr(E_Container *con, const char *params __UNUSED__);
+
+#endif
+#endif
diff --git a/src/modules/conf_randr/e_int_config_randr_arrangement.c b/src/modules/conf_randr/e_int_config_randr_arrangement.c
new file mode 100644
index 000000000..d30260ace
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr_arrangement.c
@@ -0,0 +1,806 @@
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+#include "Ecore_X.h"
+
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define DOUBLECLICK_TIMEOUT 0.2
+#define CRTC_THUMB_SIZE_W 300
+#define CRTC_THUMB_SIZE_H 300
+
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_create_data (E_Config_Dialog_Data *e_config_runtime_info);
+Evas_Object *e_config_randr_dialog_subdialog_arrangement_basic_create_widgets (Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_arrangement_free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static inline Eina_List *_e_config_randr_dialog_subdialog_arrangement_neighbors_get (Evas_Object *obj);
+static void _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive (Evas_Object *obj);
+
+static inline E_Config_Randr_Dialog_Output_Dialog_Data *_e_config_randr_dialog_subdialog_arrangement_output_dialog_data_new (E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info);
+static inline void _e_config_randr_dialog_subdialog_arrangement_suggestion_add (Evas *evas);
+static inline void _e_config_randr_dialog_subdialog_arrangement_make_suggestion (Evas_Object *obj);
+static void _e_config_randr_dialog_subdialog_arrangement_smart_class_resize (Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static Evas_Object *_e_config_randr_dialog_subdialog_arrangement_output_add (Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+// Function for the resolutions subdialog interaction
+extern void e_config_randr_dialog_subdialog_resolutions_update_list (Evas_Object *crtc);
+// Function for the orientation subdialog interaction
+extern void e_config_randr_dialog_subdialog_orientation_update_radio_buttons (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_update_edje (Evas_Object *crtc);
+// Functions for the orientation subdialog interaction
+extern void e_config_randr_dialog_subdialog_policies_update_radio_buttons (Evas_Object *crtc);
+
+Evas_Smart_Class screen_setup_smart_class = EVAS_SMART_CLASS_INIT_NAME_VERSION("EvasObjectSmartScreenSetup");
+Evas_Smart *screen_setup_smart;
+
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_dialog_data_fill(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
+{
+ if (!odd) return;
+
+ if (odd->crtc)
+ {
+ //already enabled screen
+ odd->previous_pos.x = odd->crtc->geometry.x;
+ odd->previous_pos.y = odd->crtc->geometry.y;
+ odd->previous_mode = odd->crtc->current_mode;
+ }
+ else if (odd->output)
+ {
+ //disabled monitor
+ //try to get a mode from the preferred list, else use default list
+ if(!(odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->preferred_modes))))
+ odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->modes));
+ odd->previous_pos.x = Ecore_X_Randr_Unset;
+ odd->previous_pos.y = Ecore_X_Randr_Unset;
+ }
+
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_create_data(E_Config_Dialog_Data *data)
+{
+ Eina_List *iter;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ EINA_LIST_FOREACH(data->output_dialog_data_list, iter, dialog_data)
+ {
+ _e_config_randr_dialog_subdialog_arrangement_output_dialog_data_fill(dialog_data);
+ }
+
+ return EINA_TRUE;
+}
+
+//IMPROVABLE: Clean up properly if instances can't be created
+ Evas_Object *
+e_config_randr_dialog_subdialog_arrangement_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog, *crtc;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Eina_List *iter;
+
+ if (!canvas || !e_config_runtime_info || !e_config_runtime_info->output_dialog_data_list) return NULL;
+
+ //initialize smart object
+ evas_object_smart_clipped_smart_set(&screen_setup_smart_class);
+ screen_setup_smart_class.resize = _e_config_randr_dialog_subdialog_arrangement_smart_class_resize;
+ screen_setup_smart = evas_smart_class_new(&screen_setup_smart_class);
+
+ subdialog = evas_object_smart_add(canvas, screen_setup_smart);
+ e_config_runtime_info->gui.subdialogs.arrangement.clipper = evas_object_smart_clipped_clipper_get(subdialog);
+ fprintf(stderr, "CONF_RANDR: Arrangement subdialog added (%p).\n", subdialog);
+
+
+ //only use information we can restore.
+ EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, output_dialog_data)
+ {
+ if ((!output_dialog_data->crtc && !output_dialog_data->output))
+ continue;
+ crtc = _e_config_randr_dialog_subdialog_arrangement_output_add(canvas, output_dialog_data);
+
+ if (!crtc) continue;
+ evas_object_show(crtc);
+
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_DOWN, _e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb, NULL);
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_MOVE, _e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb, NULL);
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb, NULL);
+
+
+ evas_object_smart_member_add(crtc, subdialog);
+ fprintf(stderr, "CONF_RANDR: CRTC representation (%p) added to arrangement subdialog (%p).\n", crtc, subdialog);
+ }
+
+ e_config_runtime_info->gui.subdialogs.arrangement.smart_parent = subdialog;
+
+ return subdialog;
+}
+
+ static Evas_Object *
+_e_config_randr_dialog_subdialog_arrangement_output_add(Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data)
+{
+ E_Randr_Output_Info *output_info;
+ Evas_Object *output, *bg;
+ const char* output_name = NULL;
+
+ if (!canvas || !output_dialog_data || !e_config_runtime_info) return NULL;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((output = edje_object_add(canvas)), NULL);
+
+ //set instance data for output
+ evas_object_data_set(output, "output_info", output_dialog_data);
+
+ //set theme for monitor representation
+ EINA_SAFETY_ON_FALSE_GOTO(edje_object_file_set(output, _theme_file_path, "e/conf/randr/dialog/subdialog/arrangement/output"), _e_config_randr_dialog_subdialog_arrangement_output_add_edje_set_fail);
+ //indicate monitor state
+ if (!output_dialog_data->crtc || (output_dialog_data->crtc && !output_dialog_data->previous_mode))
+ edje_object_signal_emit(output, "disabled", "e");
+ else
+ edje_object_signal_emit(output, "enabled", "e");
+ //for now use deskpreview widget as background of output, maybe change this to
+ //live image from comp module
+ output_dialog_data->bg = e_widget_deskpreview_add(canvas, 1, 1);
+ edje_object_part_swallow(output, "e.swallow.content", output_dialog_data->bg);
+
+ //Try to get the name of the monitor connected to the output's last output via edid
+ //else use the output's name
+ if (output_dialog_data->crtc)
+ output_info = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(output_dialog_data->crtc->outputs));
+ else
+ output_info = output_dialog_data->output;
+ if (output_info)
+ {
+ if (ecore_x_randr_edid_has_valid_header(output_info->edid, output_info->edid_length))
+ output_name = ecore_x_randr_edid_display_name_get(output_info->edid, output_info->edid_length);
+ else if (output_info->name)
+ output_name = output_info->name;
+ }
+ if (output_name)
+ edje_object_part_text_set(output, "output_txt", output_name);
+
+ //set output orientation
+ e_config_randr_dialog_subdialog_orientation_update_edje(output);
+ return output;
+
+_e_config_randr_dialog_subdialog_arrangement_output_add_edje_set_fail:
+ evas_object_del(output);
+ return NULL;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_smart_class_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Object *output;
+ Evas_Coord real_sum_w = 0 , real_sum_h = 0;
+ Eina_Rectangle parent_geo, new_geo;
+ Evas_Coord_Point offset = {.x = 0, .y = 0};
+ Evas_Coord offset_x_max = 0;
+ float scaling_factor = 0.1;
+ Eina_List *lst, *itr;
+ const E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ evas_object_geometry_get(obj, &parent_geo.x, &parent_geo.y, &parent_geo.w, &parent_geo.h);
+ fprintf(stderr, "CONF_RANDR: Arrangement dialog shall be resized to %d x %d\n", w, h);
+ fprintf(stderr, "CONF_RANDR: Arrangement dialog Smart object geo: %d x %d, %d x %d\n", parent_geo.x, parent_geo.y, parent_geo.w, parent_geo.h);
+ if ((w < 1) || (h < 1)) return;
+
+ lst = evas_object_smart_members_get(obj);
+ //Calc average aspect ratio from all available monitors
+ EINA_LIST_FOREACH(lst, itr, output)
+ {
+ if ((output == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(output_dialog_data = evas_object_data_get(output, "output_info")) || (!output_dialog_data->previous_mode && !output_dialog_data->preferred_mode)) continue;
+ if (output_dialog_data->previous_mode)
+ {
+ real_sum_w += output_dialog_data->previous_mode->width;
+ real_sum_h += output_dialog_data->previous_mode->height;
+ }
+ else
+ {
+ real_sum_w += output_dialog_data->preferred_mode->width;
+ real_sum_h += output_dialog_data->preferred_mode->height;
+ }
+ }
+
+ scaling_factor = (((float)parent_geo.w / (float)real_sum_w) < ((float)parent_geo.h / (float)real_sum_h)) ? ((float)parent_geo.w / (float)real_sum_w) : ((float)parent_geo.h / (float)real_sum_h);
+ scaling_factor *= e_scale;
+
+ EINA_LIST_FOREACH(lst, itr, output)
+ {
+ //Skip elements that are either the clipped smart object or falsely added
+ //to the list of outputs (which should not happen)
+ if ((output == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(output_dialog_data = evas_object_data_get(output, "output_info"))) continue;
+ if (output_dialog_data->previous_mode)
+ {
+ new_geo.w = (int)((float)output_dialog_data->previous_mode->width * scaling_factor);
+ new_geo.h = (int)((float)output_dialog_data->previous_mode->height * scaling_factor);
+ }
+ else if (output_dialog_data->preferred_mode)
+ {
+ new_geo.w = (int)((float)output_dialog_data->preferred_mode->width * scaling_factor);
+ new_geo.h = (int)((float)output_dialog_data->preferred_mode->height * scaling_factor);
+ }
+ else
+ {
+ fprintf(stderr, "CONF_RANDR: Can't resize thumb, as neither mode nor preferred mode are avavailable for %x\n", (output_dialog_data->crtc ? output_dialog_data->crtc->xid : output_dialog_data->output->xid));
+ continue;
+ }
+ if ((new_geo.w <= 0) || (new_geo.h <= 0))
+ {
+ //this is an effect, occuring during dialog closing.
+ //If we don't return here, e_thumb will segfault!
+ return;
+ }
+ if ((output_dialog_data->previous_pos.x == Ecore_X_Randr_Unset) || (output_dialog_data->previous_pos.y == Ecore_X_Randr_Unset))
+ {
+ //this is a non enabled monitor
+ new_geo.x = parent_geo.x + parent_geo.w - new_geo.w - offset.x;
+ new_geo.y = parent_geo.y + offset.y;
+ offset.y = new_geo.y + new_geo.h;
+ if (offset_x_max < new_geo.w)
+ {
+ //adopt new max value for x
+ offset_x_max = new_geo.w;
+ }
+ if ((offset.y + new_geo.h) > (parent_geo.y + parent_geo.h))
+ {
+ //reset offset.y and adjust offset.x
+ offset.y = 0;
+ offset.x += offset_x_max;
+ }
+ }
+ else
+ {
+ new_geo.x = ((int)((float)output_dialog_data->previous_pos.x * scaling_factor)) + parent_geo.x;
+ new_geo.y = ((int)((float)output_dialog_data->previous_pos.y * scaling_factor)) + parent_geo.y;
+ }
+ //resize edje element
+ evas_object_resize(output, new_geo.w, new_geo.h);
+ //also resize bg
+ e_thumb_icon_size_set(output_dialog_data->bg, new_geo.w, new_geo.h); //need to clarify the usage of e_thumb. Usable without e_thumb_icon_file_set??!!
+ evas_object_move(output, new_geo.x, new_geo.y);
+ fprintf(stderr, "CONF_RANDR: output representation %p was resized to %d x %d\n", output, new_geo.w, new_geo.h);
+ fprintf(stderr, "CONF_RANDR: output representation %p was moved to %d x %d\n", output, new_geo.x, new_geo.y);
+ }
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*)event_info;
+ Evas_Object *element = NULL;
+ Eina_List *iter;
+ Eina_Bool crtc_selected = EINA_FALSE;
+
+ EINA_LIST_FOREACH(evas_object_smart_members_get(evas_object_smart_parent_get(obj)), iter, element)
+ {
+ if (e_config_runtime_info->gui.subdialogs.arrangement.clipper == obj) continue;
+ if (element != obj)
+ edje_object_signal_emit(element, "deselect", "e");
+ else
+ {
+ edje_object_signal_emit(element, "select", "e");
+ //update data for other dialogs
+ e_config_runtime_info->gui.selected_eo = obj;
+
+ //update resolutions list
+ e_config_randr_dialog_subdialog_resolutions_update_list(obj);
+
+ //update orientation radio buttons
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(obj);
+
+ //update policy radio buttons
+ e_config_randr_dialog_subdialog_policies_update_radio_buttons(obj);
+
+ crtc_selected = EINA_TRUE;
+ }
+ }
+ if (!crtc_selected)
+ {
+ //update data for other dialogs
+ e_config_runtime_info->gui.selected_eo = NULL;
+
+ //update resolutions list
+ e_config_randr_dialog_subdialog_resolutions_update_list(NULL);
+
+ //update orientation radio buttons
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(NULL);
+
+ //update policy radio buttons
+ e_config_randr_dialog_subdialog_policies_update_radio_buttons(NULL);
+ }
+
+ evas_object_geometry_get(obj, &e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.x, &e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.y, NULL, NULL);
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Move *ev = event_info;
+ Eina_Rectangle geo, parent;
+ Evas_Coord_Point delta, new;
+
+ if (ev->buttons == 1)
+ {
+ evas_object_geometry_get (obj, &geo.x, &geo.y, &geo.w, &geo.h);
+ evas_object_geometry_get (evas_object_smart_parent_get(obj), &parent.x, &parent.y, &parent.w, &parent.h);
+ delta.x = ev->cur.canvas.x - ev->prev.canvas.x;
+ delta.y = ev->cur.canvas.y - ev->prev.canvas.y;
+
+ new.x = geo.x + delta.x;
+ new.y = geo.y + delta.y;
+ //respect container borders
+ if (new.x < parent.x + 1)
+ new.x = parent.x + 1;
+ else if (new.x > parent.x + parent.w - geo.w)
+ new.x = parent.x + parent.w - geo.w;
+ if (new.y < parent.y + 1)
+ new.y = parent.y + 1;
+ else if (new.y > parent.y + parent.h - geo.h)
+ new.y = parent.y + parent.h - geo.h;
+ //only take action if position changed
+ if ((geo.x != new.x) || (geo.y != new.y))
+ {
+ evas_object_move(obj, new.x, new.y);
+ _e_config_randr_dialog_subdialog_arrangement_make_suggestion(obj);
+ }
+ }
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Coord_Point coords;
+
+ if (evas_object_visible_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion))
+ {
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "hide", "e");
+ evas_object_geometry_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, &coords.x, &coords.y, NULL, NULL);
+ evas_object_move(obj, coords.x, coords.y);
+ }
+ else
+ {
+ evas_object_move(obj, e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.x, e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.y);
+ }
+
+}
+
+void
+_e_config_randr_dialog_subdialog_arrangement_suggestion_add(Evas *evas)
+{
+ const char *theme_data_item = NULL;
+
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion = edje_object_add(evas);
+ edje_object_file_set(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, _theme_file_path, "e/conf/randr/dialog/subdialog/arrangement/suggestion");
+ if ((theme_data_item = edje_object_data_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "distance_min")))
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min = MIN(MAX(atoi(theme_data_item), 0), 100);
+ else
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min = 20;
+}
+
+ void
+_e_config_randr_dialog_subdialog_arrangement_make_suggestion (Evas_Object *obj)
+{
+ Eina_List *li, *crtcs = evas_object_smart_members_get(evas_object_smart_parent_get(obj));
+ Evas_Object *crtc = NULL;
+ Eina_Rectangle p_geo, geo, crtc_geo, s_geo;
+ int dxa = 10000, dya = 10000, tmp, min_dist;
+
+ if (!obj) return;
+
+ if (!e_config_runtime_info->gui.subdialogs.arrangement.suggestion)
+ {
+ _e_config_randr_dialog_subdialog_arrangement_suggestion_add(evas_object_evas_get(obj));
+ evas_object_show(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ }
+
+ min_dist = e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min;
+
+ evas_object_geometry_get(evas_object_smart_parent_get(obj), &p_geo.x, &p_geo.y, &p_geo.w, &p_geo.h);
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+
+ s_geo.x = geo.x;
+ s_geo.y = geo.y;
+ s_geo.w = geo.w;
+ s_geo.h = geo.h;
+
+ //compare possible positions
+ //aritifical (relative) 0x0 element
+ tmp = s_geo.x;
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = p_geo.x;
+ dxa = tmp;
+ }
+ tmp = s_geo.y;
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = p_geo.y;
+ dya = tmp;
+ }
+ //iterate crtc list
+ EINA_LIST_FOREACH(crtcs, li, crtc)
+ {
+ if ((crtc == obj) || (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper)) continue;
+ evas_object_geometry_get(crtc, &crtc_geo.x, &crtc_geo.y, &crtc_geo.w, &crtc_geo.h);
+ //X-Axis
+ tmp = abs(s_geo.x - crtc_geo.x);
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = crtc_geo.x;
+ dxa = abs(s_geo.x - crtc_geo.x);
+ }
+
+ tmp = abs(s_geo.x - (crtc_geo.x + crtc_geo.w));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x + crtc_geo.w);
+ dxa = tmp;
+ }
+
+ tmp = abs((s_geo.x + s_geo.w) - (crtc_geo.x - 1));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x - s_geo.w);
+ dxa = tmp;
+ }
+
+ tmp = abs((s_geo.x + s_geo.w) - (crtc_geo.x + crtc_geo.w));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x + crtc_geo.w - s_geo.w);
+ dxa = tmp;
+ }
+
+ //Y-Axis
+ tmp = abs(s_geo.y - crtc_geo.y);
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = crtc_geo.y;
+ dya = abs(s_geo.y - crtc_geo.y);
+ }
+
+ tmp = abs(s_geo.y - (crtc_geo.y + crtc_geo.h));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y + crtc_geo.h);
+ dya = tmp;
+ }
+
+ tmp = abs((s_geo.y + s_geo.h) - (crtc_geo.y - 1));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y - s_geo.h);
+ dya = tmp;
+ }
+
+ tmp = abs((s_geo.y + s_geo.h) - (crtc_geo.y + crtc_geo.h));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y + crtc_geo.h - s_geo.h);
+ dya = tmp;
+ }
+
+ }
+
+
+ if ((s_geo.x != geo.x) && (s_geo.y != geo.y))
+ {
+ if (s_geo.x < p_geo.x) s_geo.x = p_geo.x;
+ if ((s_geo.x + s_geo.w) > (p_geo.x + p_geo.w)) s_geo.x = ((p_geo.x + p_geo.w) - s_geo.w);
+ if (s_geo.y < p_geo.y) s_geo.y = p_geo.y;
+ if ((s_geo.y + s_geo.h) > (p_geo.y + p_geo.h)) s_geo.y = ((p_geo.y + p_geo.h) - s_geo.h);
+
+ if (!evas_object_visible_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion))
+ {
+ evas_object_show(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "show", "e");
+ }
+
+ evas_object_resize(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, s_geo.w, s_geo.h);
+ evas_object_move(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, s_geo.x, s_geo.y);
+ }
+ else
+ {
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "hide", "e");
+ evas_object_hide(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ EINA_SAFETY_ON_NULL_RETURN(cfdata);
+
+ EINA_LIST_FREE(cfdata->output_dialog_data_list, dialog_data)
+ {
+ if (dialog_data)
+ {
+ if (dialog_data->bg)
+ {
+ evas_object_del(dialog_data->bg);
+ dialog_data->bg = NULL;
+ }
+ free(dialog_data);
+ dialog_data = NULL;
+ }
+ }
+}
+
+ static Eina_List
+*_e_config_randr_dialog_subdialog_arrangement_neighbors_get(Evas_Object *obj)
+{
+ Evas_Object *smart_parent, *crtc;
+ Eina_List *crtcs, *iter, *neighbors = NULL;
+ Eina_Rectangle geo, neighbor_geo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data, *neighbor_info;
+
+ smart_parent = evas_object_smart_parent_get(obj);
+ crtcs = evas_object_smart_members_get(smart_parent);
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((dialog_data = evas_object_data_get(obj, "output_info")), NULL);
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if ((crtc == obj)
+ || (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper)) continue;
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+ if(!(neighbor_info = evas_object_data_get(crtc, "output_info"))) continue;
+
+ if (((geo.x + geo.w) == neighbor_geo.x)
+ || (geo.x == (neighbor_geo.x + neighbor_geo.w))
+ || (geo.x == neighbor_geo.x)
+ || ((geo.x + geo.w) == (neighbor_geo.x + neighbor_geo.w))
+ || ((geo.y + geo.h) == neighbor_geo.y)
+ || (geo.y == (neighbor_geo.y + neighbor_geo.h))
+ || (geo.y == neighbor_geo.y)
+ || ((geo.y + geo.h) == (neighbor_geo.y + neighbor_geo.h)))
+ {
+ neighbors = eina_list_append(neighbors, crtc);
+ }
+ }
+
+ return neighbors;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(Evas_Object *obj)
+{
+ Eina_List *neighbors, *iter;
+ Evas_Object *smart_parent, *crtc;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data, *neighbor_info;
+ Eina_Rectangle geo, neighbor_geo, smart_geo;
+
+ // Each object is seen as a tree. All its edges are compared to their
+ // neighbors and wandered recusively.
+ EINA_SAFETY_ON_NULL_RETURN(obj);
+
+ smart_parent = e_config_runtime_info->gui.subdialogs.arrangement.smart_parent;
+ evas_object_geometry_get(smart_parent, &smart_geo.x, &smart_geo.y, &smart_geo.w, &smart_geo.h);
+ //fprintf(stderr, "CONF_RANDR: Smart Parent is at %dx%d\n", smart_geo.x, smart_geo.y);
+ neighbors = _e_config_randr_dialog_subdialog_arrangement_neighbors_get(obj);
+
+ EINA_SAFETY_ON_FALSE_RETURN((dialog_data = evas_object_data_get(obj, "output_info")));
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+
+ //fprintf(stderr, "CONF_RANDR: Traversed element (%p) is at %dx%d\n", obj, geo.x, geo.y);
+ if (geo.x == e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.x) dialog_data->new_pos.x = 0;
+ if (geo.y == e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.y) dialog_data->new_pos.y = 0;
+
+ if ((dialog_data->new_pos.x != 0) || (dialog_data->new_pos.y != 0))
+ {
+ // Find neighbor object we can calculate our own coordinates from
+ EINA_LIST_FOREACH(neighbors, iter, crtc)
+ {
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+ if (!(neighbor_info = evas_object_data_get(crtc, "output_info"))) continue;
+
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+
+ if ((dialog_data->new_pos.x == Ecore_X_Randr_Unset) && (neighbor_info->new_pos.x != Ecore_X_Randr_Unset))
+ {
+ if ((geo.x + geo.w) == neighbor_geo.x)
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x - dialog_data->previous_mode->width;
+ }
+
+ if (geo.x == (neighbor_geo.x + neighbor_geo.w))
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x + neighbor_info->previous_mode->width;
+ }
+
+ if (geo.x == neighbor_geo.x)
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x;
+ }
+
+ if ((geo.x + geo.w) == (neighbor_geo.x + neighbor_geo.w))
+ {
+ dialog_data->new_pos.x = (neighbor_info->new_pos.x + neighbor_info->previous_mode->width) - dialog_data->previous_mode->width;
+ }
+ }
+
+ if ((dialog_data->new_pos.y == Ecore_X_Randr_Unset) && (neighbor_info->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ if ((geo.y + geo.h) == neighbor_geo.y)
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y - dialog_data->previous_mode->height;
+ }
+
+ if (geo.y == (neighbor_geo.y + neighbor_geo.h))
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y + neighbor_info->previous_mode->height;
+ }
+
+ if (geo.y == neighbor_geo.y)
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y;
+ }
+
+ if ((geo.y + geo.h) == (neighbor_geo.y + neighbor_geo.h))
+ {
+ dialog_data->new_pos.y = (neighbor_info->new_pos.y + neighbor_info->previous_mode->height) - dialog_data->previous_mode->height;
+ }
+ }
+ if ((dialog_data->new_pos.x != Ecore_X_Randr_Unset)
+ && (dialog_data->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ //fprintf(stderr, "CONF_RANDR: Determined position for %p: %dx%d\n", obj, dialog_data->new_pos.x, dialog_data->new_pos.y);
+ break;
+ }
+ }
+ }
+ if ((dialog_data->new_pos.x != Ecore_X_Randr_Unset) || (dialog_data->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ //Only wander all neighbors recursively, if they can use the current
+ //element as reference for their position
+ EINA_LIST_FOREACH(neighbors, iter, crtc)
+ {
+ neighbor_info = evas_object_data_get(crtc, "output_info");
+ if ((neighbor_info->new_pos.x == Ecore_X_Randr_Unset)
+ || (neighbor_info->new_pos.y == Ecore_X_Randr_Unset))
+ {
+ //fprintf(stderr, "CONF_RANDR: Now going to travel %p.\n", crtc);
+ _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(crtc);
+ }
+ }
+ }
+ eina_list_free(neighbors);
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_List *crtcs, *iter;
+ Evas_Object *smart_parent, *crtc, *top_left = NULL;
+ Eina_Rectangle geo, smart_geo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Evas_Coord_Point relz = { .x = 10000, .y = 10000};
+ Eina_Bool arrangement_failed = EINA_FALSE;
+
+ smart_parent = e_config_runtime_info->gui.subdialogs.arrangement.smart_parent;
+ evas_object_geometry_get(smart_parent, &smart_geo.x, &smart_geo.y, &smart_geo.w, &smart_geo.h);
+ crtcs = evas_object_smart_members_get(smart_parent);
+
+ //Create virtual borders around the displayed representations by finding
+ //relative x and y as virtual 0x0
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper) continue;
+ //Already reset values for upcoming calculation
+ if (!(odd = evas_object_data_get(crtc, "output_info"))) continue;
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+ odd = NULL;
+
+ //See whether this element is closer to 0x0 than any before
+ evas_object_geometry_get(crtc, &geo.x, &geo.y, &geo.w, &geo.h);
+ if (geo.x < relz.x)
+ {
+ relz.x = geo.x;
+ top_left = crtc;
+ }
+ if (geo.y < relz.y)
+ {
+ relz.y = geo.y;
+ top_left = crtc;
+ }
+ }
+ e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.x = relz.x;
+ e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.y = relz.y;
+ if (top_left) _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(top_left);
+
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if ((crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(odd = evas_object_data_get(crtc, "output_info")) || !odd->crtc
+ || ((odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))) continue;
+ if ((odd->previous_pos.x != odd->new_pos.x) || (odd->previous_pos.y != odd->new_pos.y))
+ {
+ fprintf(stderr, "CONF_RANDR: CRTC %x is moved to %dx%d\n", odd->crtc->xid, odd->new_pos.x, odd->new_pos.y);
+ if (!ecore_x_randr_crtc_pos_set(cfd->con->manager->root, odd->crtc->xid, odd->new_pos.x, odd->new_pos.y))
+ {
+ arrangement_failed = EINA_TRUE;
+ break;
+ }
+ }
+ }
+ if (arrangement_failed)
+ return EINA_FALSE;
+ else
+ {
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ return EINA_TRUE;
+ }
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_List *iter;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, output_dialog_data)
+ {
+ if ((output_dialog_data->previous_pos.x != output_dialog_data->new_pos.x)
+ || (output_dialog_data->previous_pos.y != output_dialog_data->new_pos.y)
+ ) return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || ((odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))) continue;
+ odd->previous_pos.x = odd->new_pos.x;
+ odd->previous_pos.y = odd->new_pos.y;
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || ((odd->previous_pos.x == Ecore_X_Randr_Unset) || (odd->previous_pos.y == Ecore_X_Randr_Unset))) continue;
+ if (ecore_x_randr_crtc_pos_set(cfdata->manager->root, odd->crtc->xid, odd->previous_pos.x, odd->previous_pos.y))
+ {
+ odd->new_pos.x = odd->previous_pos.x;
+ odd->new_pos.y = odd->previous_pos.y;
+ odd->previous_pos.x = Ecore_X_Randr_Unset;
+ odd->previous_pos.y = Ecore_X_Randr_Unset;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
diff --git a/src/modules/conf_randr/e_int_config_randr_orientation.c b/src/modules/conf_randr/e_int_config_randr_orientation.c
new file mode 100644
index 000000000..3a0121baf
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr_orientation.c
@@ -0,0 +1,336 @@
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define RANDR_DIALOG_ORIENTATION_ALL (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 | ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y)
+
+Eina_Bool e_config_randr_dialog_subdialog_orientation_create_data (E_Config_Dialog_Data *cfdata);
+Evas_Object *e_config_randr_dialog_subdialog_orientation_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_orientation_update_radio_buttons(Evas_Object *crtc);
+void e_config_randr_dialog_subdialog_orientation_update_edje(Evas_Object *crtc);
+
+static void _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+/*
+static void
+_e_config_randr_dialog_subdialog_orientation_radio_add_callbacks(void)
+{
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+}
+*/
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_create_data(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Crtc_Info *ci;
+ Eina_List *iter;
+
+ if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!ci || !ci->current_mode) continue;
+ odd->new_orientation = Ecore_X_Randr_Unset;
+ odd->previous_orientation = ci->current_orientation;
+ }
+
+ return EINA_TRUE;
+}
+
+Evas_Object *
+e_config_randr_dialog_subdialog_orientation_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+ E_Radio_Group *rg;
+ //char signal[29];
+
+ if (!canvas || !e_config_runtime_info) return NULL;
+ if (e_config_runtime_info->gui.subdialogs.orientation.dialog) return e_config_runtime_info->gui.subdialogs.orientation.dialog;
+
+ if (!(subdialog = e_widget_framelist_add(canvas, _("Display Orientation"), EINA_FALSE))) return NULL;
+
+ // Add radio buttons
+ if(!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.subdialogs.orientation.radio_val))) goto _e_config_randr_dialog_subdialog_orientation_radio_add_fail;
+
+ //IMPROVABLE: use enum to determine objects via 'switch'-statement
+ e_config_runtime_info->gui.subdialogs.orientation.radio_normal = e_widget_radio_add(canvas, _("Normal"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_normal);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot90 = e_widget_radio_add(canvas, _("Rotated, 90°"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot90);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot180 = e_widget_radio_add(canvas, _("Rotated, 180°"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot180);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot270 = e_widget_radio_add(canvas, _("Rotated, 270°"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot270);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal = e_widget_radio_add(canvas, _("Flipped, horizontally"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical = e_widget_radio_add(canvas, _("Flipped, vertically"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical);
+
+ //_e_config_randr_dialog_subdialog_orientation_radio_add_callbacks();
+
+ /*
+ // Add orientation demonstration edje
+ if (!(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje = edje_object_add(canvas)))
+ goto _e_config_randr_dialog_subdialog_orientation_edje_add_fail;
+ if (!edje_object_file_set(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/subdialog/orientation"))
+ goto _e_config_randr_dialog_subdialog_orientation_edje_set_fail;
+
+ e_widget_table_object_align_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
+ */
+
+ //disable widgets, if no CRTC is selected
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(e_config_runtime_info->gui.selected_eo);
+
+ //evas_object_show(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje);
+
+ return subdialog;
+
+ /*
+_e_config_randr_dialog_subdialog_orientation_edje_set_fail:
+ evas_object_del(ol);
+ evas_object_del(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje);
+_e_config_randr_dialog_subdialog_orientation_edje_add_fail:
+ fprintf(stderr, "CONF_RANDR: Couldn't set edj for orientation subdialog!\n");
+ evas_object_del(subdialog);
+ return NULL;
+ */
+_e_config_randr_dialog_subdialog_orientation_radio_add_fail:
+ evas_object_del(subdialog);
+ fprintf(stderr, "CONF_RANDR: Could not add radio group!\n");
+ return NULL;
+}
+
+/*
+ static void
+_e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ char signal[40];
+ int orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+
+ /*
+ * IMPROVABLE:
+ * "sadly" the evas callbacks are called before radio_val is set to its new
+ * value. If that is ever changed, remove the used code below and just use the
+ * 1-liner below.
+ * snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,%d", e_config_runtime_info->gui.subdialogs.orientation.radio_val);
+ * /
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_normal) orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot90) orientation = ECORE_X_RANDR_ORIENTATION_ROT_90;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot180) orientation = ECORE_X_RANDR_ORIENTATION_ROT_180;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot270) orientation = ECORE_X_RANDR_ORIENTATION_ROT_270;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_X;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_Y;
+
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,%d", orientation);
+
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, signal, "e");
+
+ fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to orientation: %s\n", signal);
+}
+*/
+
+ void
+e_config_randr_dialog_subdialog_orientation_update_radio_buttons(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Orientation supported_oris, ori;
+ char signal[40];
+
+ //disable widgets, if no crtc is selected
+ if (!crtc)
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+ return;
+ }
+
+ if (!(output_dialog_data = evas_object_data_get(crtc, "output_info"))) return;
+
+ if (output_dialog_data->crtc)
+ {
+ //enabled monitor
+ supported_oris = output_dialog_data->crtc->orientations;
+ ori = output_dialog_data->crtc->current_orientation;
+ }
+ else
+ {
+ //disabled monitor
+ //assume all orientations are supported
+ supported_oris = RANDR_DIALOG_ORIENTATION_ALL;
+ ori = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ }
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_0)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_90)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_180)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_270)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_X)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_Y)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+
+ //toggle the switch of the currently used orientation
+ switch (ori)
+ {
+ case ECORE_X_RANDR_ORIENTATION_ROT_90:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_ROT_180:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_ROT_270:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_FLIP_X:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_FLIP_Y:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+ break;
+ default: //== ECORE_X_RANDR_ORIENTATION_ROT_0:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_update_edje(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Orientation supported_oris, ori;
+ char signal[40];
+
+ if (!e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(crtc, "output_info"))) return;
+
+ if (output_dialog_data->crtc)
+ {
+ //enabled monitor
+ supported_oris = output_dialog_data->crtc->orientations;
+ ori = output_dialog_data->crtc->current_orientation;
+ }
+ else
+ {
+ //disabled monitor
+ //assume all orientations are supported
+ supported_oris = RANDR_DIALOG_ORIENTATION_ALL;
+ ori = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ }
+ //Send signal to the edje, to represent the supported and current set orientation
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,supported,%d", supported_oris);
+ edje_object_signal_emit(crtc, signal, "e");
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,current,%d", ori);
+ edje_object_signal_emit(crtc, signal, "e");
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Orientation orientation;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.subdialogs.orientation.dialog || !e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info")) || !output_dialog_data->crtc) return EINA_FALSE;
+
+ orientation = e_config_runtime_info->gui.subdialogs.orientation.radio_val;
+
+ fprintf(stderr, "CONF_RANDR: Change orientation of crtc %x to %d.\n", output_dialog_data->crtc->xid, orientation);
+
+ if (ecore_x_randr_crtc_orientation_set(cfd->con->manager->root, output_dialog_data->crtc->xid, orientation))
+ {
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ output_dialog_data->previous_orientation = output_dialog_data->new_orientation;
+ output_dialog_data->new_orientation = orientation;
+ return EINA_TRUE;
+ }
+ else
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Orientation orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.subdialogs.orientation.dialog || !e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info"))) return EINA_FALSE;
+
+ return (output_dialog_data->previous_orientation != e_config_runtime_info->gui.subdialogs.orientation.radio_val);
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd || (odd->previous_orientation == Ecore_X_Randr_Unset)) continue;
+ odd->previous_orientation = odd->new_orientation;
+ odd->new_orientation = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || (odd->previous_orientation == Ecore_X_Randr_Unset)) continue;
+ if (ecore_x_randr_crtc_orientation_set(cfdata->manager->root, odd->crtc->xid, odd->previous_orientation))
+ {
+ odd->new_orientation = odd->previous_orientation;
+ odd->previous_orientation = Ecore_X_Randr_Unset;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
diff --git a/src/modules/conf_randr/e_int_config_randr_policies.c b/src/modules/conf_randr/e_int_config_randr_policies.c
new file mode 100644
index 000000000..77b204c5e
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr_policies.c
@@ -0,0 +1,302 @@
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+Evas_Object *e_config_randr_dialog_subdialog_policies_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_policies_update_radio_buttons(Evas_Object *crtc);
+
+static void _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+/*
+static void
+_e_config_randr_dialog_subdialog_policies_radio_add_callbacks(void)
+{
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_none, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_left, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_below, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_above, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_right, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+}
+*/
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_create_data(E_Config_Dialog_Data *e_config_runtime_info)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Output_Info *oi;
+ Eina_List *iter;
+
+ if (!e_config_runtime_info || !e_config_runtime_info->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, odd)
+ {
+ if (odd->crtc)
+ oi = eina_list_data_get(eina_list_last(odd->crtc->outputs));
+ else if (odd->output)
+ oi = odd->output;
+ if (!oi) continue;
+ odd->previous_policy = oi->policy;
+ odd->new_policy = Ecore_X_Randr_Unset;
+ }
+
+ return EINA_TRUE;
+}
+
+Evas_Object *
+e_config_randr_dialog_subdialog_policies_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+ E_Radio_Group *rg;
+ //char signal[29];
+
+ if (!canvas || !e_config_runtime_info) return NULL;
+
+ if (e_config_runtime_info->gui.subdialogs.policies.dialog) return e_config_runtime_info->gui.subdialogs.policies.dialog;
+
+ if(!(subdialog = e_widget_framelist_add(canvas, _("Screen attachement policy"), EINA_FALSE))) return NULL;
+
+ // Add radio buttons
+ if (!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.subdialogs.policies.radio_val))) goto _e_config_randr_dialog_subdialog_policies_radio_add_fail;
+
+ //IMPROVABLE: use enum to determine objects via 'switch'-statement
+ e_config_runtime_info->gui.subdialogs.policies.radio_above = e_widget_radio_add(canvas, _("Above"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_above);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_right = e_widget_radio_add(canvas, _("Right"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_right);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_below = e_widget_radio_add(canvas, _("Below"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_below);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_left = e_widget_radio_add(canvas, _("Left"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_left);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_clone = e_widget_radio_add(canvas, _("Clone display content"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_clone);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_none = e_widget_radio_add(canvas, _("No reaction"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_none);
+
+ //_e_config_randr_dialog_subdialog_policies_radio_add_callbacks();
+
+ /*
+ // Add policies demonstration edje
+ if (!(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje = edje_object_add(canvas)))
+ {
+ goto _e_config_randr_dialog_subdialog_policies_edje_add_fail;
+
+ }
+ if (!edje_object_file_set(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/subdialog/policies"))
+ {
+ goto _e_config_randr_dialog_subdialog_policies_edje_set_fail;
+ }
+
+ e_widget_table_object_align_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
+ */
+
+ /*
+ evas_object_show(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje);
+
+ //emit signal to edje so a demonstration can be shown
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_randr_screen_info->rrvd_info.randr_info_12->output_policy);
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, signal, "e");
+ fprintf(stderr, "CONF_RANDR: Initial signal emitted to policy dialog: %s\n", signal);
+
+ //Use theme's background as screen representation
+ e_config_runtime_info->gui.subdialogs.policies.new_display = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.new_display, "base/theme/widgets", "e/widgets/frame");
+ e_config_runtime_info->gui.subdialogs.policies.new_display_background = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.new_display_background, "base/theme/background", "e/desktop/background");
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.new_display, "e.swallow.content", e_config_runtime_info->gui.subdialogs.policies.new_display_background);
+ edje_object_part_text_set(e_config_runtime_info->gui.subdialogs.policies.new_display, "e.text.label", _("New display"));
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, "new_display.swallow.content", e_config_runtime_info->gui.subdialogs.policies.new_display);
+ //add theme's frame
+ //for now use the theme's background for the new display as well
+ e_config_runtime_info->gui.subdialogs.policies.current_displays_setup = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "base/theme/widgets", "e/widgets/frame");
+ e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background, "base/theme/background", "e/desktop/background");
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "e.swallow.content", e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background);
+ edje_object_part_text_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "e.text.label", _("Used display"));
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, "current_displays_setup.swallow.content", e_config_runtime_info->gui.subdialogs.policies.current_displays_setup);
+ */
+
+ evas_object_show(subdialog);
+
+ return subdialog;
+
+ /*
+_e_config_randr_dialog_subdialog_policies_edje_set_fail:
+ evas_object_del(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje);
+_e_config_randr_dialog_subdialog_policies_edje_add_fail:
+ fprintf(stderr, "CONF_RANDR: Couldn't set edj for policies subdialog!\n");
+ evas_object_del(subdialog);
+ return NULL;
+ */
+_e_config_randr_dialog_subdialog_policies_radio_add_fail:
+ evas_object_del(subdialog);
+ return NULL;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ char signal[29];
+ int policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
+
+ /*
+ * IMPROVABLE:
+ * "sadly" the evas callbacks are called before radio_val is set to its new
+ * value. If that is ever changed, remove the used code below and just use the
+ * 1-liner below.
+ * snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_config_runtime_info->gui.subdialogs.policies.radio_val);
+ */
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_above) policy = ECORE_X_RANDR_OUTPUT_POLICY_ABOVE;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_right) policy = ECORE_X_RANDR_OUTPUT_POLICY_RIGHT;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_below) policy = ECORE_X_RANDR_OUTPUT_POLICY_BELOW;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_left) policy = ECORE_X_RANDR_OUTPUT_POLICY_LEFT;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_clone) policy = ECORE_X_RANDR_OUTPUT_POLICY_CLONE;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_none) policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
+
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", policy);
+
+ //edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, signal, "e");
+
+ fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to policy: %s\n", signal);
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ E_Randr_Output_Info *output_info;
+
+ if (!e_randr_screen_info || !e_config_runtime_info->gui.selected_output_dd) return EINA_FALSE;
+
+ //policy update
+ e_config_runtime_info->gui.selected_output_dd->previous_policy = e_config_runtime_info->gui.selected_output_dd->new_policy;
+ e_config_runtime_info->gui.selected_output_dd->new_policy = e_config_runtime_info->gui.subdialogs.policies.radio_val;
+ fprintf(stderr, "CONF_RANDR: 'New display attached'-policy set to %d\n", e_config_runtime_info->gui.selected_output_dd->new_policy);
+
+ return EINA_TRUE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ if (!e_randr_screen_info || !cfdata || !cfdata->gui.selected_output_dd) return EINA_FALSE;
+
+ return (cfdata->gui.selected_output_dd->previous_policy != cfdata->gui.subdialogs.policies.radio_val);
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_update_radio_buttons(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ E_Randr_Output_Info *output;
+ Ecore_X_Randr_Output_Policy policy;
+ char signal[40];
+
+ //disable widgets, if no crtc is selected
+ if (!crtc || !(output_dialog_data = evas_object_data_get(crtc, "output_info")))
+ {
+ //Evas_Object *radio_above, *radio_right, *radio_below, *radio_left, *radio_clone, *radio_none;
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_TRUE);
+ return;
+ }
+ else
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_FALSE);
+ }
+
+ if (output_dialog_data->crtc && output_dialog_data->crtc->outputs)
+ {
+ output = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(output_dialog_data->crtc->outputs));
+ }
+ else if (output_dialog_data->output)
+ {
+ output = output_dialog_data->output;
+ }
+
+ if (!output) return;
+ policy = output->policy;
+ e_config_runtime_info->gui.selected_output_dd = output_dialog_data;
+ //toggle the switch of the currently used policies
+ switch (policy)
+ {
+ case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_TRUE);
+ break;
+ default: //== ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_TRUE);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd || (odd->previous_policy == Ecore_X_Randr_Unset)) continue;
+ odd->previous_policy = odd->new_policy;
+ odd->new_policy = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || (odd->previous_policy == Ecore_X_Randr_Unset)) continue;
+ odd->new_policy = odd->previous_policy;
+ odd->previous_policy = Ecore_X_Randr_Unset;
+ }
+}
diff --git a/src/modules/conf_randr/e_int_config_randr_resolutions.c b/src/modules/conf_randr/e_int_config_randr_resolutions.c
new file mode 100644
index 000000000..ea3bb9362
--- /dev/null
+++ b/src/modules/conf_randr/e_int_config_randr_resolutions.c
@@ -0,0 +1,265 @@
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+#include "e_widget_ilist.h"
+
+#ifdef Ecore_X_Randr_Unset
+#undef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#else
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#ifdef Ecore_X_Randr_None
+#undef Ecore_X_Randr_None
+#endif
+#define Ecore_X_Randr_None 0
+
+#define ICON_WIDTH 10
+#define ICON_HEIGHT 10
+#define RESOLUTION_TXT_MAX_LENGTH 50
+
+Evas_Object *e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_resolutions_update_list(Evas_Object *crtc);
+void e_config_randr_dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata);
+
+extern E_Config_Dialog_Data *e_config_runtime_info;
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_create_data(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Crtc_Info *ci;
+ Ecore_X_Randr_Mode_Info *mi;
+ Eina_List *iter;
+
+ if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (odd->previous_mode || odd->preferred_mode)
+ {
+ //this means, that mode info is already filled
+ //(by the display arrangement code)
+ break;
+ }
+ if (odd->crtc)
+ {
+ if(!(mi = odd->crtc->current_mode))
+ mi = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->crtc->outputs_common_modes));
+ odd->previous_mode = mi;
+ }
+ else if (odd->output)
+ {
+ odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->preferred_modes));
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+ Evas_Object *
+e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+
+ if (!canvas || !e_config_runtime_info || e_config_runtime_info->gui.subdialogs.resolutions.dialog || !(subdialog = e_widget_ilist_add(canvas, ICON_WIDTH * e_scale, ICON_HEIGHT * e_scale, NULL))) return NULL;
+
+ e_widget_ilist_multi_select_set(subdialog, EINA_FALSE);
+ e_widget_disabled_set(subdialog, EINA_TRUE);
+
+ evas_object_show(subdialog);
+
+ return subdialog;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ //Apply new mode
+ Ecore_X_Randr_Mode_Info* selected_mode;
+ Ecore_X_ID selected_mode_xid;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Output *output = NULL;
+ E_Randr_Crtc_Info *crtc_info = NULL, *crtc_iter;
+ Eina_List *iter;
+ int noutputs = Ecore_X_Randr_Unset;
+
+ if (!e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info")))
+ {
+ fprintf(stderr, "CONF_RADNR: no crtc was selected or no output info could be retrieved for the selected crtc element (%p).\n", e_config_runtime_info->gui.selected_eo);
+ return EINA_FALSE;
+ }
+
+ if (output_dialog_data->crtc)
+ {
+ //CRTC is already asssigned, easy one!
+ crtc_info = output_dialog_data->crtc;
+ }
+ else if (output_dialog_data->output)
+ {
+ //CRTC not assigned yet. Let's try to find a non occupied one.
+ fprintf(stderr, "CONF_RANDR: Trying to find a CRTC for output %x, %d crtcs are possible.\n", output_dialog_data->output->xid, eina_list_count(output_dialog_data->output->possible_crtcs));
+ output = &output_dialog_data->output->xid;
+ noutputs = 1;
+ EINA_LIST_FOREACH(output_dialog_data->output->possible_crtcs, iter, crtc_iter)
+ {
+ if (!crtc_iter->outputs)
+ {
+ //CRTC is not occupied yet
+ crtc_info = crtc_iter;
+ break;
+ }
+ }
+ }
+ if (!crtc_info)
+ {
+ fprintf(stderr, "CONF_RANDR: Changing mode failed, no unoccupied CRTC found!\n");
+ return EINA_FALSE;
+ }
+ //get selected mode
+ if ((selected_mode = (Ecore_X_Randr_Mode_Info*)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)))
+ {
+ selected_mode_xid = selected_mode->xid;
+ }
+ else
+ {
+ selected_mode_xid = Ecore_X_Randr_None;
+ }
+
+ fprintf(stderr, "CONF_RANDR: Change mode of crtc %x to %x.\n", crtc_info->xid, selected_mode_xid);
+
+ if (ecore_x_randr_crtc_mode_set(cfd->con->manager->root, crtc_info->xid, output, noutputs, selected_mode_xid))
+ {
+ //remove unused space
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ //update information
+ if (!output_dialog_data->crtc)
+ output_dialog_data->crtc = crtc_info;
+ output_dialog_data->new_mode = selected_mode;
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Mode_Info* selected_mode;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.selected_eo || !(selected_mode = (Ecore_X_Randr_Mode_Info*)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)) || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info"))) return EINA_FALSE;
+
+ return (selected_mode != output_dialog_data->previous_mode);
+}
+
+ void
+e_config_randr_dialog_subdialog_resolutions_update_list(Evas_Object *crtc)
+{
+ Eina_List *iter, *modelist = NULL;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Mode_Info *mode_info, *current_mode;
+ char resolution_text[RESOLUTION_TXT_MAX_LENGTH];
+ float rate;
+ int str_ret, i = 0;
+
+ e_widget_ilist_freeze(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ e_widget_ilist_clear(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ if (!crtc)
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_TRUE);
+ return;
+ }
+ if (!(output_dialog_data = evas_object_data_get(crtc, "output_info")))
+ return;
+
+ //select correct mode list
+ if (output_dialog_data->crtc)
+ {
+ current_mode = output_dialog_data->crtc->current_mode;
+ modelist = output_dialog_data->crtc->outputs_common_modes;
+ }
+ else if (output_dialog_data->output)
+ {
+ current_mode = NULL;
+ if (output_dialog_data->output->modes)
+ modelist = output_dialog_data->output->modes;
+ else
+ modelist = output_dialog_data->output->modes;
+ }
+ EINA_LIST_FOREACH(modelist, iter, mode_info)
+ {
+ //calculate refresh rate
+ if (!mode_info) continue;
+ if (mode_info->hTotal && mode_info->vTotal)
+ rate = ((float) mode_info->dotClock /
+ ((float) mode_info->hTotal * (float) mode_info->vTotal));
+ else
+ rate = 0.0;
+
+ str_ret = snprintf(resolution_text, RESOLUTION_TXT_MAX_LENGTH, "%dx%d@%.1fHz", mode_info->width, mode_info->height, rate);
+ if (str_ret < 0 || str_ret > (RESOLUTION_TXT_MAX_LENGTH - 1))
+ {
+ fprintf(stderr, "CONF_RANDR: Resolution text could not be created.");
+ continue;
+ }
+ e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, resolution_text, NULL, mode_info, NULL);
+
+ //select currently enabled mode
+ if (mode_info == current_mode)
+ e_widget_ilist_selected_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, i);
+ i++;
+ }
+
+ //append 'disabled' mode
+ e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, _("Disabled"), NULL, NULL, NULL);
+
+ //reenable widget
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_FALSE);
+ e_widget_ilist_go(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ e_widget_ilist_thaw(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+}
+
+
+void
+e_config_randr_dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (odd && odd->new_mode && (odd->new_mode != odd->previous_mode))
+ {
+ odd->previous_mode = odd->new_mode;
+ odd->new_mode = NULL;
+ }
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ //for now, there is no way to redisable an output during discartion
+ if (!odd->crtc || !odd->previous_mode) continue;
+ //use currently used outputs (noutputs == Ecore_X_Randr_Unset)
+ if (ecore_x_randr_crtc_mode_set(cfdata->manager->root, odd->crtc->xid, NULL, Ecore_X_Randr_Unset, odd->previous_mode->xid))
+ {
+ odd->new_mode = odd->previous_mode;
+ odd->previous_mode = NULL;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
diff --git a/src/modules/conf_randr/e_mod_main.c b/src/modules/conf_randr/e_mod_main.c
new file mode 100644
index 000000000..6358594d7
--- /dev/null
+++ b/src/modules/conf_randr/e_mod_main.c
@@ -0,0 +1,42 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+#include "e.h"
+#include "e_mod_main.h"
+
+/* actual module specifics */
+E_Module *conf_randr_module = NULL;
+
+/* module setup */
+EAPI E_Module_Api e_modapi =
+{
+ E_MODULE_API_VERSION,
+ "Settings - Screen Setup"
+};
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+ e_configure_registry_category_add("screen", 30, _("Screen"), NULL, "preferences-desktop-display");
+ e_configure_registry_item_add("screen/randr", 20, _("Screen Setup"), NULL, "preferences-system-screen-resolution", e_int_config_randr);
+ conf_randr_module = m;
+ e_module_delayed_set(m, 1);
+ return m;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m)
+{
+ E_Config_Dialog *cfd;
+ while ((cfd = e_config_dialog_get("E", "screen/randr"))) e_object_del(E_OBJECT(cfd));
+ e_configure_registry_item_del("screen/randr");
+ e_configure_registry_category_del("screen");
+ conf_randr_module = NULL;
+ return 1;
+}
+
+EAPI int
+e_modapi_save(E_Module *m)
+{
+ return 1;
+}
diff --git a/src/modules/conf_randr/e_mod_main.h b/src/modules/conf_randr/e_mod_main.h
new file mode 100644
index 000000000..8735ba71d
--- /dev/null
+++ b/src/modules/conf_randr/e_mod_main.h
@@ -0,0 +1,19 @@
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef E_MOD_MAIN_H
+#define E_MOD_MAIN_H
+
+#define E_TYPEDEFS 1
+#include "e_int_config_randr.h"
+
+#undef E_TYPEDEFS
+#include "e_int_config_randr.h"
+
+EAPI extern E_Module_Api e_modapi;
+
+EAPI void *e_modapi_init (E_Module *m);
+EAPI int e_modapi_shutdown (E_Module *m);
+EAPI int e_modapi_save (E_Module *m);
+
+#endif
diff --git a/src/modules/conf_randr/images/display-glass-shine.png b/src/modules/conf_randr/images/display-glass-shine.png
new file mode 100644
index 000000000..0f299a631
Binary files /dev/null and b/src/modules/conf_randr/images/display-glass-shine.png differ
diff --git a/src/modules/conf_randr/images/display.png b/src/modules/conf_randr/images/display.png
new file mode 100644
index 000000000..589385f5c
Binary files /dev/null and b/src/modules/conf_randr/images/display.png differ
diff --git a/src/modules/conf_randr/images/icon.png b/src/modules/conf_randr/images/icon.png
new file mode 100644
index 000000000..11aa540be
Binary files /dev/null and b/src/modules/conf_randr/images/icon.png differ
diff --git a/src/modules/conf_randr/images/video-display.svg b/src/modules/conf_randr/images/video-display.svg
new file mode 100644
index 000000000..3c29c6683
--- /dev/null
+++ b/src/modules/conf_randr/images/video-display.svg
@@ -0,0 +1,741 @@
+
+
+
+
diff --git a/src/modules/conf_randr/module.desktop.in b/src/modules/conf_randr/module.desktop.in
new file mode 100644
index 000000000..e0b1c0773
--- /dev/null
+++ b/src/modules/conf_randr/module.desktop.in
@@ -0,0 +1,32 @@
+[Desktop Entry]
+Type=Link
+Name=Settings - Screen Setup
+Name[cs]=Nastavení - rozlišení obrazovky
+Name[de]=Konfiguration - Bildschirm
+Name[eo]=Agordo - Ekrandistingivo
+Name[es]=Configuración - Resolución de pantalla
+Name[fr]=Configuration - Résolution de l'écran
+Name[hu]=Beállítások - Képernyő felbontása
+Name[it]=Configurazione - Risoluzione schermo
+Name[ja]=
+Name[pt]=
+Name[pt_BR]=
+Name[tr]=Ayarlar - Ekran Çözünürlüğü
+Name[zh_CN]=
+Name[zh_TW]=
+Icon=e-module-conf_randr
+Comment=Used to configure your screen's resolution.
+Comment[cs]=Použit k nastavení rozlišení obrazovky.
+Comment[de]=
+Comment[eo]=Agordi sian ekrandistingivon.
+Comment[es]=Usado para configurar su resolución de pantalla.
+Comment[fr]=Permet de configurer la résolution de l'écran.
+Comment[hu]=Segítségével beállíthatod a képernyőd felbontását.
+Comment[it]=Usato per configurare la risoluzione del vostro schermo.
+Comment[ja]=
+Comment[pt]=
+Comment[pt_BR]=
+Comment[tr]=Ekranınızın çözünürlüğünü yapılandırır.
+Comment[zh_CN]=
+Comment[zh_TW]=
+X-Enlightenment-ModuleType=settings