diff --git a/src/bin/e_config.c b/src/bin/e_config.c
index 3592bf886..e62d3c1bf 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;
}
@@ -1915,10 +1903,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;
@@ -2069,37 +2060,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);
@@ -2116,14 +2120,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;
@@ -2133,16 +2137,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.");
@@ -2280,36 +2284,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_gadcon.c b/src/bin/e_gadcon.c
index 289715120..e300a428e 100644
--- a/src/bin/e_gadcon.c
+++ b/src/bin/e_gadcon.c
@@ -1466,10 +1466,10 @@ e_gadcon_client_util_menu_items_append(E_Gadcon_Client *gcc, E_Menu *menu_gadget
{
mi = e_menu_item_new(menu_main);
if (gcc->client_class->func.label)
- snprintf(buf, sizeof(buf), "Gadget %s",
+ snprintf(buf, sizeof(buf), "%s",
gcc->client_class->func.label((E_Gadcon_Client_Class *)gcc->client_class));
else
- snprintf(buf, sizeof(buf), "Gadget %s", gcc->name);
+ snprintf(buf, sizeof(buf), "%s", gcc->name);
e_menu_item_label_set(mi, _(buf));
e_menu_item_realize_callback_set(mi, _e_gadcon_client_cb_menu_pre, gcc);
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