i'll put in leif's randr code - even though it's buggy, it's the best

way for it to be worked on by people for release.



SVN revision: 64801
This commit is contained in:
Carsten Haitzler 2011-11-06 06:41:39 +00:00
parent 604d72c948
commit 20e8feca2c
22 changed files with 4863 additions and 397 deletions

View File

@ -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

View File

@ -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<br>or you lost permissions to your files.");
erstr = _("The file is not writable. Perhaps the disk is read-only<br>or you lost permissions to your files.");
break;
case EET_ERROR_OUT_OF_MEMORY:
erstr = _("Memory ran out while preparing the write.<br>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;
}

View File

@ -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

View File

@ -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);
}
}
/*

View File

@ -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;