Hi all,
this is a major rework of the e_randr code.
What has been done:
-Split up into several logical parts:
-Generic
-RandRR 1.1
-RandRR >= 1.2
-Each part has subparts as necessary e.g. (de)serialization
What works (for me):
-Save setup (including disabled CRTCs, etc.) using EDIDs of connected monitors.
-Restore setup that matching connected monitors
-Change resolution, etc. in dialog
Known bugs:
-E crashes, when e_config_save is triggered. Sadly I don't get too
much information why this is happening. Avoid it by not storing the
configuration.
2012/2/18 Enlightenment SVN <no-reply@...>:
> Log:
> Refactoring e_randr, big time.
>
> Author: leif
> Date: 2012-02-18 08:49:07 -0800 (Sat, 18 Feb 2012)
> New Revision: 68114
> Trac: http://trac.enlightenment.org/e/changeset/68114
>
> Added:
> trunk/e/src/bin/e_randr_11.c trunk/e/src/bin/e_randr_11_serialization.c trunk/e/src/bin/e_randr_12.c trunk/e/src/bin/e_randr_12_crtc.c trunk/e/src/bin/e_randr_12_output.c trunk/e/src/bin/e_randr_12_serialization.c trunk/e/src/bin/e_randr_private.h trunk/e/src/bin/e_randr_serialization.c
> Modified:
> trunk/e/src/bin/Makefile.am trunk/e/src/bin/e_config.c trunk/e/src/bin/e_randr.c trunk/e/src/bin/e_randr.h
>
> Modified: trunk/e/src/bin/Makefile.am
> ===================================================================
> --- trunk/e/src/bin/Makefile.am 2012-02-18 15:56:00 UTC (rev 68113)
> +++ trunk/e/src/bin/Makefile.am 2012-02-18 16:49:07 UTC (rev 68114)
> @@ -276,6 +276,13 @@
> e_powersave.c \
> e_prefix.c \
> e_randr.c \
> +e_randr_serialization.c \
> +e_randr_11.c \
> +e_randr_11_serialization.c \
> +e_randr_12.c \
> +e_randr_12_output.c \
> +e_randr_12_crtc.c \
> +e_randr_12_serialization.c \
> e_remember.c \
> e_resist.c \
> e_scale.c \
>
> Modified: trunk/e/src/bin/e_config.c
> ===================================================================
> --- trunk/e/src/bin/e_config.c 2012-02-18 15:56:00 UTC (rev 68113)
> +++ trunk/e/src/bin/e_config.c 2012-02-18 16:49:07 UTC (rev 68114)
> @@ -57,7 +57,7 @@
> 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_mode_info_edd = NULL;
> static E_Config_DD *_e_config_randr_serialized_crtc_edd = NULL;
>
>
> @@ -555,7 +555,6 @@
> #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_randr_serialized_output_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Output", E_Randr_Serialized_Output);
> @@ -564,15 +563,14 @@
> #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_VAL(D, T, edid_hash.hash, INT);
> E_CONFIG_VAL(D, T, backlight_level, DOUBLE);
>
> - _e_config_randr_serialized_mode_info_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Mode_Info", Ecore_X_Randr_Mode_Info);
> + _e_config_randr_mode_info_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Mode_Info", Ecore_X_Randr_Mode_Info);
> #undef T
> #undef D
> #define T Ecore_X_Randr_Mode_Info
> -#define D _e_config_randr_serialized_mode_info_edd
> +#define D _e_config_randr_mode_info_edd
> + E_CONFIG_VAL(D, T, xid, INT);
> E_CONFIG_VAL(D, T, width, INT);
> E_CONFIG_VAL(D, T, height, INT);
> E_CONFIG_VAL(D, T, dotClock, LL);
> @@ -592,11 +590,10 @@
> #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_LIST(D, T, outputs, _e_config_randr_serialized_output_edd);
> + E_CONFIG_SUB(D, T, mode_info, _e_config_randr_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_randr_serialized_setup_12_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup_12", E_Randr_Serialized_Setup_12);
> @@ -605,8 +602,8 @@
> #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_LIST(D, T, crtcs, _e_config_randr_serialized_crtc_edd);
> + E_CONFIG_LIST(D, T, 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
> @@ -615,7 +612,7 @@
> #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_LIST(D, T, outputs_policies, _e_config_randr_serialized_output_policy_edd);
>
> _e_config_edd = E_CONFIG_DD_NEW("E_Config", E_Config);
> #undef T
> @@ -936,7 +933,7 @@
> 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_randr_serialized_setup_edd);
> + //E_CONFIG_DD_FREE(_e_config_randr_serialized_setup_edd);
> return 1;
> }
>
> @@ -1881,15 +1878,8 @@
> E_Color_Class *cc;
> E_Path_Dir *epd;
> E_Remember *rem;
> - 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;
>
> -
> if (!ecf) return;
>
> EINA_LIST_FREE(ecf->modules, em)
> @@ -2039,44 +2029,8 @@
> }
> if(ecf->randr_serialized_setup)
> {
> - free (ecf->randr_serialized_setup->serialized_setup_11);
> - 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) continue;
> - free(serialized_output->name);
> - 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_policy) continue;
> - free(serialized_output_policy->name);
> - free(serialized_output_policy);
> - }
> - free(ecf->randr_serialized_setup);
> + e_randr_serialized_setup_free(ecf->randr_serialized_setup);
> }
> -
> EINA_LIST_FREE(ecf->env_vars, evr)
> {
> if (evr->var) eina_stringshare_del(evr->var);
>
> Modified: trunk/e/src/bin/e_randr.c
> ===================================================================
> --- trunk/e/src/bin/e_randr.c 2012-02-18 15:56:00 UTC (rev 68113)
> +++ trunk/e/src/bin/e_randr.c 2012-02-18 16:49:07 UTC (rev 68114)
> @@ -2,16 +2,15 @@
> * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
> */
> #include "e.h"
> +#include "e_randr_private.h"
>
> #define ECORE_X_RANDR_1_1 ((1 << 16) | 1)
> #define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
> #define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
>
> -#define Ecore_X_Randr_None 0
> +#define Ecore_X_Randr_None 0
> #define Ecore_X_Randr_Unset -1
>
> -#define POLLINTERVAL 128
> -
> /*
> * Save mechanism:
> * Single monitor:
> @@ -19,2404 +18,150 @@
> *
> * Multiple monitors:
> * - Use the EDID information to make sure we restore the right monitor.
> + * - Depend on the sequence in which the XIDs are returned provided by the X
> + * server. This means that relative indexes are used for setup store/restore.
> *
> - * TODO:
> - * -fix output policies above and left
> */
>
> -//following macro namescheme follows cardinal relation
> -//1 : M
> -#define E_RANDR_NO_SCREEN_RET(ret) if (!e_randr_screen_info) \
> - return ret
> -#define E_RANDR_NO_11_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1) || !e_randr_screen_info->rrvd_info.randr_info_11) \
> - return ret
> -#define E_RANDR_NO_12_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12) \
> - return ret
> -#define E_RANDR_NO_CRTCS_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs) \
> - return ret
> -#define E_RANDR_NO_OUTPUTS_RET(ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs) \
> - return ret
> -#define E_RANDR_NO_CRTC_RET(crtc, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc) \
> - return ret
> -#define E_RANDR_NO_OUTPUT_RET(output, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) \
> - return ret
> -#define E_RANDR_NO_MODE_RET(mode, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode) \
> - return ret
> -#define E_RANDR_NO_CRTC_OUTPUT_RET(crtc, output, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output) \
> - return ret
> -#define E_RANDR_NO_CRTC_OUTPUT_MODE_RET(crtc, output, mode, ret) if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode) \
> - return ret
> +static Eina_Bool _init(void);
> +static void _shutdown(void);
> +static void _screen_info_refresh(void);
> +static Eina_Bool _e_event_config_loaded_cb(void *data, int type, void *e);
> +static void _try_restore_configuration(void);
> +static void _event_listeners_add(void);
> +static void _event_listeners_remove(void);
>
> -#define E_RANDR_NO_11 (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1) || !e_randr_screen_info->rrvd_info.randr_info_11)
> -#define E_RANDR_NO_12 (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12)
> -#define E_RANDR_NO_CRTCS (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs)
> -#define E_RANDR_NO_OUTPUTS (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs)
> -#define E_RANDR_NO_MODES (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->modes)
> -#define E_RANDR_NO_CRTC(crtc) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc)
> -#define E_RANDR_NO_OUTPUT(output) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output)
> -#define E_RANDR_NO_CRTC_OUTPUT(crtc, output) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output)
> -#define E_RANDR_NO_CRTC_OUTPUT_MODE(crtc, output, mode) (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2) || !e_randr_screen_info->rrvd_info.randr_info_12 || !e_randr_screen_info->rrvd_info.randr_info_12->crtcs || !crtc || !e_randr_screen_info->rrvd_info.randr_info_12->outputs || !output || !e_randr_screen_info->rrvd_info.randr_info_12->modes || !mode)
> +EAPI E_Randr_Screen_Info e_randr_screen_info;
> +static Eina_List *_event_handlers = NULL;
>
> -static Eina_Bool _e_randr_init(void);
> -static void _e_randr_shutdown(void);
> -static Eina_Bool _e_randr_screen_info_refresh(void);
> -static void _e_randr_event_listeners_add(void);
> -static void _e_randr_event_listeners_remove(void);
> -static Eina_Bool _e_randr_event_cb(void *data, int type, void *e);
> -static Eina_Bool _e_event_config_loaded_cb(void *data, int type, void *e);
> -static Eina_Bool _e_randr_x_poll_cb(void *data __UNUSED__);
> -static E_Randr_Screen_Info *_e_randr_screen_info_new(void);
> -static void _e_randr_screen_info_free(E_Randr_Screen_Info *screen_info);
> -static E_Randr_Screen_Info_11 *_e_randr_screen_info_11_new(void);
> -static Eina_Bool _e_randr_screen_info_11_set(void);
> -static void _e_randr_screen_info_11_free(E_Randr_Screen_Info_11 *screen_info_11);
> -static E_Randr_Screen_Info_12 *_e_randr_screen_info_12_new(void);
> -static Eina_Bool _e_randr_screen_info_12_set(E_Randr_Screen_Info_12 *screen_info_12);
> -static void _e_randr_screen_info_12_free(E_Randr_Screen_Info_12 *screen_info_12);
> -static E_Randr_Output_Info *_e_randr_output_info_new(int nrequested);
> -static void _e_randr_output_info_free(E_Randr_Output_Info *output_info);
> -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);
> -void _e_randr_restore_12_policies(E_Randr_Screen_Info_12 *si_12);
> -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);
> -static Ecore_X_Randr_Mode_Info *_e_randr_mode_info_get(Ecore_X_Randr_Mode mode);
> -static E_Randr_Crtc_Info *_e_randr_crtc_info_get(Ecore_X_Randr_Crtc crtc);
> -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 Ecore_X_Randr_Output *_e_randr_outputs_to_array(Eina_List *outputs_info);
> -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);
> -static Eina_Bool _e_randr_crtc_move_policy(E_Randr_Crtc_Info *new_crtc);
> -//static int _crtcs_size_sort_cb(const void *d1, const void *d2);
> -static int _outputs_size_sort_cb(const void *d1, const void *d2);
> -static int _modes_size_sort_cb(const void *d1, const void *d2);
> -static Eina_List *_e_randr_outputs_common_modes_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode);
> -static Ecore_X_Randr_Mode_Info *_e_randr_outputs_common_mode_max_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode);
> -static Ecore_X_Randr_Mode_Info *_e_randr_mode_geo_identical_find(Eina_List *modes, Ecore_X_Randr_Mode_Info *mode);
> -static Eina_Bool _e_randr_crtc_mode_intersects_crtcs(E_Randr_Crtc_Info *crtc_info, Ecore_X_Randr_Mode_Info *mode);
> -static Eina_Bool _e_randr_crtc_outputs_mode_max_set(E_Randr_Crtc_Info *crtc_info);
> -static Eina_Bool _e_randr_crtcs_clone_crtc_removed(E_Randr_Crtc_Info *former_clone);
> -static void _e_randr_screen_primary_output_assign(E_Randr_Output_Info *removed);
> -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);
> -
> -EAPI E_Randr_Screen_Info * e_randr_screen_info = NULL;
> -static Eina_List *_e_randr_event_handlers = NULL;
> -static Ecore_Poller *poller = NULL;
> -
> EINTERN Eina_Bool
> e_randr_init(void)
> {
> - return _e_randr_init();
> + return _init();
> }
>
> EINTERN int
> e_randr_shutdown(void)
> {
> - _e_randr_shutdown();
> + _shutdown();
> return 1;
> }
>
> -EAPI Eina_Bool
> +EAPI void
> e_randr_screen_info_refresh(void)
> {
> - return _e_randr_screen_info_refresh();
> + _screen_info_refresh();
> }
>
> static Eina_Bool
> -_e_randr_init(void)
> +_init(void)
> {
> - EINA_SAFETY_ON_FALSE_RETURN_VAL(e_randr_screen_info_refresh(), EINA_FALSE);
> - _e_randr_event_listeners_add();
> - return EINA_TRUE;
> -}
> + e_randr_screen_info_refresh();
> + _event_listeners_add();
>
> -static void
> -_e_randr_shutdown(void)
> -{
> - _e_randr_screen_info_free(e_randr_screen_info);
> -}
> + _try_restore_configuration();
>
> -static Eina_Bool
> -_e_randr_screen_info_refresh(void)
> -{
> - int n;
> - Ecore_X_Window *roots;
> - Ecore_X_Window root;
> -
> - if (e_randr_screen_info)
> - _e_randr_screen_info_free(e_randr_screen_info);
> -
> - if (!(roots = ecore_x_window_root_list(&n))) return EINA_FALSE;
> - /* first (and only) root window */
> - root = roots[0];
> - free(roots);
> -
> - if (!ecore_x_randr_query())
> - goto e_randr_screen_info_refresh_fail;
> - if (!(e_randr_screen_info = _e_randr_screen_info_new()))
> - goto e_randr_screen_info_refresh_fail_free_screen;
> -
> - e_randr_screen_info->randr_version = ecore_x_randr_version_get();
> - e_randr_screen_info->root = root;
> -
> - if (e_randr_screen_info->randr_version == ECORE_X_RANDR_1_1)
> + if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - if (!(e_randr_screen_info->rrvd_info.randr_info_11 = _e_randr_screen_info_11_new()))
> - goto e_randr_screen_info_refresh_fail_free_screen;
> - _e_randr_screen_info_11_set();
> + _12_policies_restore();
> }
> - else if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2)
> - {
> - if (!(e_randr_screen_info->rrvd_info.randr_info_12 = _e_randr_screen_info_12_new()))
> - goto e_randr_screen_info_refresh_fail_free_screen;
> - _e_randr_screen_info_12_set(e_randr_screen_info->rrvd_info.randr_info_12);
> - if (!_e_randr_screen_outputs_init()
> - || !_e_randr_screen_crtcs_init())
> - goto e_randr_screen_info_refresh_fail_free_screen;
> - _e_randr_screen_primary_output_assign(NULL);
> - //also restore stored policies
> - _e_randr_restore_12_policies(e_randr_screen_info->rrvd_info.randr_info_12);
> - }
> - else
> - goto e_randr_screen_info_refresh_fail_free_screen;
>
> return EINA_TRUE;
> -
> -e_randr_screen_info_refresh_fail_free_screen:
> - if (e_randr_screen_info)
> - _e_randr_screen_info_free(e_randr_screen_info);
> -e_randr_screen_info_refresh_fail:
> - return EINA_FALSE;
> }
>
> -/**
> - * @param nrequeste
> - * @return Instance of E_Randr_Screen_Info or if memory couldn't be
> - * allocated NULL.
> - */
> -static E_Randr_Screen_Info *
> -_e_randr_screen_info_new(void)
> -{
> - E_Randr_Screen_Info *ret = NULL;
> - E_Randr_Screen_Info default_info =
> - {
> - .root = Ecore_X_Randr_Unset,
> - .randr_version = Ecore_X_Randr_None,
> - .rrvd_info.randr_info_11 = NULL
> - };
> -
> - if (!(ret = malloc(sizeof(E_Randr_Screen_Info)))) return NULL;
> -
> - memcpy(ret, &default_info, sizeof(default_info));
> -
> - return ret;
> -}
> -
> -/**
> - * @param screen_info the screen info to free.
> - */
> static void
> -_e_randr_screen_info_free(E_Randr_Screen_Info *screen_info)
> +_shutdown(void)
> {
> - if ((!screen_info) || !(screen_info->rrvd_info.randr_info_11)) return;
> - switch (e_randr_screen_info->randr_version)
> + if (e_randr_screen_info.randr_version == ECORE_X_RANDR_1_1)
> {
> - case ECORE_X_RANDR_1_1:
> - _e_randr_screen_info_11_free(screen_info->rrvd_info.randr_info_11);
> - break;
> -
> - case ECORE_X_RANDR_1_2:
> - case ECORE_X_RANDR_1_3:
> - _e_randr_screen_info_12_free(screen_info->rrvd_info.randr_info_12);
> - break;
> + _11_screen_info_free(e_randr_screen_info.rrvd_info.randr_info_11);
> + e_randr_screen_info.rrvd_info.randr_info_11 = NULL;
> }
> - free(screen_info);
> - screen_info = NULL;
> -}
> -
> -/**
> - * @return array of E_Randr_Screen_Info_11 elements, or in case not all could
> - * be created or parameter 'nrequested'==0, NULL
> - */
> -static E_Randr_Screen_Info_11 *
> -_e_randr_screen_info_11_new(void)
> -{
> - E_Randr_Screen_Info_11 *ret = NULL;
> - static const E_Randr_Screen_Info_11 default_info =
> - {
> - .sizes = NULL,
> - .csize_index = Ecore_X_Randr_Unset,
> - .corientation = Ecore_X_Randr_Unset,
> - .orientations = Ecore_X_Randr_Unset,
> - .rates = NULL,
> - .current_rate = Ecore_X_Randr_Unset
> - };
> -
> - if (!(ret = malloc(sizeof(E_Randr_Screen_Info_11)))) return NULL;
> -
> - ret = memcpy(ret, &default_info, sizeof(default_info));
> -
> - return ret;
> -}
> -
> -/**
> - * @param screen_info the screen info to be freed.
> - */
> -static void
> -_e_randr_screen_info_11_free(E_Randr_Screen_Info_11 *screen_info)
> -{
> - if (!screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_1))
> - return;
> -
> - if (screen_info->sizes)
> + else if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - free(eina_list_nth(screen_info->sizes, 0));
> - eina_list_free(screen_info->sizes);
> - screen_info->sizes = NULL;
> + _12_screen_info_free(e_randr_screen_info.rrvd_info.randr_info_12);
> + e_randr_screen_info.rrvd_info.randr_info_12 = NULL;
> }
> - if (screen_info->rates)
> - {
> - /* this may be leaking, but at least it will be valid */
> - eina_list_free(eina_list_nth(screen_info->rates, 0));
> - eina_list_free(screen_info->rates);
> - screen_info->rates = NULL;
> - }
> - free(screen_info);
> - screen_info = NULL;
> + _event_listeners_remove();
> }
>
> -/**
> - * @return array of E_Randr_Screen_Info_12 elements, or in case not all could
> - * be created or parameter 'nrequested'==0, NULL
> - */
> -static E_Randr_Screen_Info_12 *
> -_e_randr_screen_info_12_new(void)
> -{
> - E_Randr_Screen_Info_12 *ret = NULL;
> - static const E_Randr_Screen_Info_12 default_info =
> - {
> - .min_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .max_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .current_size = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .crtcs = NULL,
> - .outputs = NULL,
> - .primary_output = NULL,
> - .alignment = ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE
> - };
>
> - if (!(ret = malloc(sizeof(E_Randr_Screen_Info_12)))) return NULL;
> - ret = memcpy(ret, &default_info, sizeof(default_info));
> -
> - return ret;
> -}
> -
> -static Eina_Bool
> -_e_randr_screen_info_12_set(E_Randr_Screen_Info_12 *screen_info)
> -{
> - E_RANDR_NO_12_RET(EINA_FALSE);
> -
> - ecore_x_randr_screen_size_range_get(e_randr_screen_info->root,
> - &screen_info->min_size.width,
> - &screen_info->min_size.height,
> - &screen_info->max_size.width,
> - &screen_info->max_size.height);
> - ecore_x_randr_screen_current_size_get(e_randr_screen_info->root,
> - &screen_info->current_size.width,
> - &screen_info->current_size.height,
> - NULL, NULL);
> -
> - return EINA_TRUE;
> -}
> -
> -static Eina_Bool
> -_e_randr_screen_info_11_set(void)
> -{
> - E_RANDR_NO_11_RET(EINA_FALSE);
> -
> - E_Randr_Screen_Info_11 *screen_info_11 = e_randr_screen_info->rrvd_info.randr_info_11;
> - Ecore_X_Randr_Screen_Size_MM *sizes = NULL;
> - Ecore_X_Randr_Refresh_Rate *rates = NULL;
> - Eina_List *rates_list;
> - int i, j, nsizes, nrates;
> -
> - if (!(sizes = ecore_x_randr_screen_primary_output_sizes_get(e_randr_screen_info->root, &nsizes)))
> - return EINA_FALSE;
> - for (i = 0; i < nsizes; i++)
> - if (!(screen_info_11->sizes = eina_list_append(screen_info_11->sizes, &sizes[i])))
> - goto _e_randr_screen_info_11_fill_fail_sizes;
> - ecore_x_randr_screen_primary_output_current_size_get(e_randr_screen_info->root, NULL, NULL, NULL, NULL, &(screen_info_11->csize_index));
> - screen_info_11->corientation = ecore_x_randr_screen_primary_output_orientation_get(e_randr_screen_info->root);
> - screen_info_11->orientations = ecore_x_randr_screen_primary_output_orientations_get(e_randr_screen_info->root);
> - for (i = 0; i < nsizes; i++)
> - {
> - rates_list = NULL;
> - if (!(rates = ecore_x_randr_screen_primary_output_refresh_rates_get(e_randr_screen_info->root, i, &nrates)))
> - return EINA_FALSE;
> - for (j = 0; j < nrates; j++)
> - if (!(rates_list = eina_list_append(rates_list, &rates[j])))
> - goto _e_randr_screen_info_11_fill_fail_rates_list;
> - if (!(screen_info_11->rates = eina_list_append(screen_info_11->rates, rates_list)))
> - goto _e_randr_screen_info_11_fill_fail_rates;
> - }
> - screen_info_11->current_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(e_randr_screen_info->root);
> -
> - return EINA_TRUE;
> -
> -_e_randr_screen_info_11_fill_fail_rates_list:
> - eina_list_free(rates_list);
> -_e_randr_screen_info_11_fill_fail_rates:
> - free(rates);
> -_e_randr_screen_info_11_fill_fail_sizes:
> - free(sizes);
> - free(screen_info_11);
> - return EINA_FALSE;
> -}
> -
> /**
> - * @param screen_info the screen info to be freed.
> + * @return EINA_TRUE if info could be refreshed, else EINA_FALSE
> */
> static void
> -_e_randr_screen_info_12_free(E_Randr_Screen_Info_12 *screen_info)
> +_screen_info_refresh(void)
> {
> - Ecore_X_Randr_Mode_Info *mode_info;
> - E_Randr_Crtc_Info *crtc_info;
> - E_Randr_Output_Info *output_info;
> + Ecore_X_Window *roots;
> + Ecore_X_Window root;
> + int n;
>
> - if (!screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2)) return;
> + EINA_SAFETY_ON_FALSE_RETURN(ecore_x_randr_query());
>
> - if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->crtcs)
> - {
> - EINA_LIST_FREE (screen_info->crtcs, crtc_info)
> - _e_randr_crtc_info_free(crtc_info);
> - free(eina_list_nth(screen_info->crtcs, 0));
> - }
> + if (!(roots = ecore_x_window_root_list(&n))) return;
> + /* first (and only) root window */
> + root = roots[0];
> + free(roots);
>
> - if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->outputs)
> - {
> - EINA_LIST_FREE (screen_info->outputs, output_info)
> - _e_randr_output_info_free(output_info);
> - free(eina_list_nth(screen_info->outputs, 0));
> - }
> + e_randr_screen_info.randr_version = ecore_x_randr_version_get();
> + e_randr_screen_info.root = root;
> + e_randr_screen_info.rrvd_info.randr_info_11 = NULL;
>
> - if (e_randr_screen_info->randr_version >= ECORE_X_RANDR_1_2 && screen_info->modes)
> + // Value set/retrieval helper functions
> + if (e_randr_screen_info.randr_version == ECORE_X_RANDR_1_1)
> {
> - EINA_LIST_FREE (screen_info->modes, mode_info)
> - ecore_x_randr_mode_info_free(mode_info);
> + _11_screen_info_refresh();
> }
> -
> - _e_randr_event_listeners_remove();
> -
> - free (screen_info);
> - screen_info = NULL;
> -}
> -
> -/**
> - * @brief allocates structs with and fills them with default values. The
> - * returned pointer is allocated as one chunk of data since it won't change.
> - * @param nrequested number of E_Randr_Crtc_Info to be created
> - * @return array of E_Randr_Crtc_Info elements, or in case not all could
> - * be created or parameter 'nrequested'==0, NULL
> - */
> -static E_Randr_Crtc_Info *
> -_e_randr_crtc_info_new(int nrequested)
> -{
> - E_Randr_Crtc_Info *ret = NULL;
> - static E_Randr_Crtc_Info default_info =
> - {
> - .xid = Ecore_X_Randr_Unset,
> - .geometry = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .panning = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .tracking = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .border = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .current_orientation = ECORE_X_RANDR_ORIENTATION_ROT_0,
> - .orientations = Ecore_X_Randr_Unset,
> - .gamma_ramps = NULL,
> - .gamma_ramp_size = Ecore_X_Randr_Unset,
> - .outputs = NULL,
> - .possible_outputs = NULL
> - };
> -
> - if (!(ret = malloc(sizeof(E_Randr_Crtc_Info) * nrequested))) return NULL;
> -
> - while (nrequested > 0)
> + else if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - memcpy(&ret[--nrequested], &default_info, sizeof(default_info));
> + _12_screen_info_refresh();
> }
> -
> - return ret;
> }
>
> -/**
> - * @param crtc_info the crtc info to be freed.
> - */
> -static void
> -_e_randr_crtc_info_free(E_Randr_Crtc_Info *crtc_info)
> -{
> - if (!crtc_info) return;
> -
> - if (crtc_info->gamma_ramps) free(crtc_info->gamma_ramps);
> - if (crtc_info->outputs)
> - {
> - eina_list_free(crtc_info->outputs);
> - crtc_info->outputs = NULL;
> - }
> - if (crtc_info->possible_outputs)
> - {
> - eina_list_free(crtc_info->possible_outputs);
> - crtc_info->possible_outputs = NULL;
> - }
> -}
> -
> -/**
> - * @brief allocates structs with and fills them with default values. The
> - * returned pointer is allocated as one chunk of data since it won't change.
> - * @param nrequested number of E_Randr_Output_Info to be created
> - * @return E_Randr_Output_Info element, or it could not be
> - * created, NULL
> - */
> -static E_Randr_Output_Info *
> -_e_randr_output_info_new(int nrequested)
> -{
> - E_Randr_Output_Info *ret = NULL;
> - static E_Randr_Output_Info default_info =
> - {
> - .xid = Ecore_X_Randr_Unset,
> - .name = NULL,
> - .crtc = NULL,
> - .possible_crtcs = NULL,
> - .preferred_modes = NULL,
> - .max_backlight = Ecore_X_Randr_Unset,
> - .backlight_level = 0.0,
> - .edid = NULL,
> - .edid_length = 0,
> - .size_mm = {Ecore_X_Randr_Unset, Ecore_X_Randr_Unset},
> - .wired_clones = NULL,
> - .signalformats = Ecore_X_Randr_Unset,
> - .signalformat = Ecore_X_Randr_Unset,
> - .connector_number = Ecore_X_Randr_Unset,
> - .connector_type = Ecore_X_Randr_Unset,
> - .connection_status = ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED,
> - .subpixel_order = Ecore_X_Randr_Unset,
> - .compatible_outputs = NULL,
> - .policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE
> - };
> -
> - if (!(ret = malloc(sizeof(E_Randr_Output_Info) * nrequested))) return NULL;
> -
> - while (nrequested > 0)
> - {
> - memcpy(&ret[--nrequested], &default_info, sizeof(default_info));
> - }
> -
> - return ret;
> -}
> -
> -/*
> - * removes all traces of an output within the data.
> - * @param output_info the output info to be freed.
> - */
> -static void
> -_e_randr_output_info_free(E_Randr_Output_Info *output_info)
> -{
> - Eina_List *iter;
> - E_Randr_Crtc_Info *crtc_info;
> -
> - if (!output_info) return;
> - if (output_info->name)
> - {
> - free(output_info->name);
> - output_info->name = NULL;
> - }
> - _e_randr_output_hw_info_free(output_info);
> -
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - crtc_info->outputs = eina_list_remove(crtc_info->outputs, output_info);
> - }
> -}
> -
> -static void
> -_e_randr_output_info_set(E_Randr_Output_Info *output_info)
> -{
> - if (E_RANDR_NO_12 || !output_info) return;
> -
> - output_info->name = ecore_x_randr_output_name_get(e_randr_screen_info->root, output_info->xid, &output_info->name_length);
> - output_info->connection_status = ecore_x_randr_output_connection_status_get(e_randr_screen_info->root, output_info->xid);
> -}
> -
> -/*
> - * fills a given crtc_info using its xid with
> - * - geometry data (x,y,w,h)
> - * - used outputs structs
> - * - possible outputs structs
> - * - mode
> - * - connection status
> - * - orientation
> - */
> -static void
> -_e_randr_crtc_info_set(E_Randr_Crtc_Info *crtc_info)
> -{
> - Ecore_X_Randr_Mode mode = 0;
> - fprintf(stderr, "E_RANDR: Filling CRTC %d (%p)\n", crtc_info->xid, crtc_info);
> - if (E_RANDR_NO_12 || !crtc_info) return;
> -
> - //get references to used and possible E_Randr_Output_Info structs
> - _e_randr_crtc_outputs_refs_update(crtc_info);
> -
> - ecore_x_randr_crtc_geometry_get(e_randr_screen_info->root, crtc_info->xid, &crtc_info->geometry.x, &crtc_info->geometry.y, &crtc_info->geometry.w, &crtc_info->geometry.h);
> - mode = ecore_x_randr_crtc_mode_get(e_randr_screen_info->root, crtc_info->xid);
> - crtc_info->current_mode = _e_randr_mode_info_get(mode);
> - fprintf(stderr, "E_RANDR:\t CRTC %x apparently is in mode %x, trying to find it in the list of modes..\n", crtc_info->xid, mode);
> - if (crtc_info->current_mode)
> - fprintf(stderr, "E_RANDR:\t\t found CRTC %d in mode %d\n", crtc_info->xid, crtc_info->current_mode->xid);
> - crtc_info->current_orientation = ecore_x_randr_crtc_orientation_get(e_randr_screen_info->root, crtc_info->xid);
> - if (crtc_info->outputs_common_modes)
> - {
> - eina_list_free(crtc_info->outputs_common_modes);
> - crtc_info->outputs_common_modes = NULL;
> - }
> - crtc_info->outputs_common_modes = _e_randr_outputs_common_modes_get(crtc_info->outputs, NULL);
> -}
> -
> -/*
> - * looks up modes supported by an output and adds them - if they are not already
> - * known by - to the screen's information struct ant the output_info itself
> - */
> -static Eina_Bool
> -_e_randr_output_modes_add(E_Randr_Output_Info *output_info)
> -{
> - Ecore_X_Randr_Mode *modes;
> - Ecore_X_Randr_Mode_Info *mode_info;
> - int nmodes, npreferred;
> - Eina_List *iter;
> - Eina_Bool added_yet = EINA_FALSE;
> -
> - if (E_RANDR_NO_12 || !(modes = ecore_x_randr_output_modes_get(e_randr_screen_info->root, output_info->xid, &nmodes, &npreferred))) return EINA_FALSE;
> -
> - //In case the monitor does not have any preferred mode at all
> - if (nmodes > 0 && npreferred == 0) npreferred = 1;
> -
> - while (--nmodes >= 0)
> - {
> - added_yet = EINA_FALSE;
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->modes, iter, mode_info)
> - {
> - if (mode_info && mode_info->xid == modes[nmodes])
> - {
> - added_yet = EINA_TRUE;
> - break;
> - }
> - }
> - if (!added_yet)
> - {
> - mode_info = ecore_x_randr_mode_info_get(e_randr_screen_info->root, modes[nmodes]);
> - e_randr_screen_info->rrvd_info.randr_info_12->modes = eina_list_prepend(e_randr_screen_info->rrvd_info.randr_info_12->modes, mode_info);
> - }
> - output_info->modes = eina_list_prepend(output_info->modes, mode_info);
> - if (nmodes < npreferred) output_info->preferred_modes = eina_list_prepend(output_info->preferred_modes, mode_info);
> - }
> -
> - free(modes);
> - return EINA_TRUE;
> -}
> -
> -static Eina_Bool
> -_e_randr_screen_crtcs_init(void)
> -{
> - Ecore_X_Randr_Crtc *crtcs = NULL;
> - E_Randr_Crtc_Info *crtcs_info = NULL, *crtc = NULL;
> - int i, ncrtcs;
> -
> - if (E_RANDR_NO_12 || !(crtcs = ecore_x_randr_crtcs_get(e_randr_screen_info->root, &ncrtcs))) return EINA_FALSE;
> -
> - if (!(crtcs_info = _e_randr_crtc_info_new(ncrtcs))) goto ecore_x_randr_screen_crtcs_init_fail_free_crtcs;
> - for (i = 0; i < ncrtcs; i++)
> - {
> - fprintf (stderr, "E_RANDR: filling %d/%d (%d)\n", (i + 1), ncrtcs, crtcs[i]);
> - crtcs_info[i].xid = crtcs[i];
> - _e_randr_crtc_info_set(&crtcs_info[i]);
> - if (!(e_randr_screen_info->rrvd_info.randr_info_12->crtcs = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, &crtcs_info[i]))) break;
> - }
> - if (i == ncrtcs)
> - {
> - //successfully initialized crtcs!
> - free (crtcs);
> - return EINA_TRUE;
> - }
> - EINA_LIST_FREE (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, crtc)
> - _e_randr_crtc_info_free(crtc);
> - if (e_randr_screen_info->rrvd_info.randr_info_12->crtcs)
> - {
> - free(eina_list_nth(e_randr_screen_info->rrvd_info.randr_info_12->crtcs, 0));
> - }
> -
> -ecore_x_randr_screen_crtcs_init_fail_free_crtcs:
> - free(crtcs);
> - return EINA_FALSE;
> -}
> -
> -static Eina_Bool
> -_e_randr_screen_outputs_init(void)
> -{
> - Ecore_X_Randr_Output *outputs;
> - E_Randr_Output_Info *outputs_info = NULL, *output_info = NULL;
> - int noutputs = 0;
> - if (E_RANDR_NO_12 || !(outputs = ecore_x_randr_outputs_get(e_randr_screen_info->root, &noutputs))) return EINA_FALSE;
> -
> - if (!(outputs_info = _e_randr_output_info_new(noutputs))) goto _e_randr_screen_outputs_init_fail_free_outputs;
> - while (--noutputs >= 0)
> - {
> - outputs_info[noutputs].xid = outputs[noutputs];
> - _e_randr_output_info_set(&outputs_info[noutputs]);
> - if (outputs_info[noutputs].connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
> - _e_randr_output_info_hw_info_set(&outputs_info[noutputs]);
> -
> - if (!(e_randr_screen_info->rrvd_info.randr_info_12->outputs = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->outputs, &outputs_info[noutputs]))) goto _e_randr_screen_outputs_init_fail_free_outputs_list;
> - }
> -
> - free(outputs);
> - return EINA_TRUE;
> -
> -_e_randr_screen_outputs_init_fail_free_outputs_list:
> - if (e_randr_screen_info->rrvd_info.randr_info_12->outputs)
> - {
> - EINA_LIST_FREE (e_randr_screen_info->rrvd_info.randr_info_12->outputs, output_info)
> - free(output_info);
> - }
> -_e_randr_screen_outputs_init_fail_free_outputs:
> - free(outputs);
> - return EINA_FALSE;
> -}
> -
> -static Ecore_X_Randr_Mode_Info *
> -_e_randr_mode_info_get(Ecore_X_Randr_Mode mode)
> -{
> - Eina_List *iter;
> - Ecore_X_Randr_Mode_Info *mode_info;
> -
> - E_RANDR_NO_MODE_RET(mode, NULL);
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->modes, iter, mode_info)
> - {
> - if (mode_info && mode_info->xid == mode) return mode_info;
> - }
> - return NULL;
> -}
> -
> -static E_Randr_Output_Info *
> -_e_randr_output_info_get(Ecore_X_Randr_Output output)
> -{
> - Eina_List *iter;
> - E_Randr_Output_Info *output_info;
> -
> - E_RANDR_NO_OUTPUTS_RET(NULL);
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info)
> - {
> - if (output_info && output_info->xid == output) return output_info;
> - }
> - return NULL;
> -}
> -
> -static E_Randr_Crtc_Info *
> -_e_randr_crtc_info_get(Ecore_X_Randr_Crtc crtc)
> -{
> - Eina_List *iter;
> - E_Randr_Crtc_Info *crtc_info;
> -
> - E_RANDR_NO_CRTCS_RET(NULL);
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if (crtc_info && crtc_info->xid == crtc) return crtc_info;
> - }
> - return NULL;
> -}
> -
> -static Eina_Bool
> -_e_randr_event_cb(void *data __UNUSED__, int type, void *ev)
> -{
> - E_Randr_Crtc_Info *crtc_info;
> - Ecore_X_Randr_Mode_Info *mode_info;
> - Eina_Bool enabled = EINA_FALSE;
> -
> - if (!e_randr_screen_info) return ECORE_CALLBACK_RENEW;
> -
> - if (type == ECORE_X_EVENT_RANDR_CRTC_CHANGE)
> - {
> - Ecore_X_Event_Randr_Crtc_Change *event = (Ecore_X_Event_Randr_Crtc_Change *)ev;
> - /* available information:
> - struct _Ecore_X_Event_Randr_Crtc_Change
> - {
> - Ecore_X_Window win;
> - Ecore_X_Randr_Crtc crtc;
> - Ecore_X_Randr_Mode mode;
> - Ecore_X_Randr_Orientation orientation;
> - int x;
> - int y;
> - int width;
> - int height;
> - };
> - */
> - crtc_info = _e_randr_crtc_info_get(event->crtc);
> - if (!crtc_info) return ECORE_CALLBACK_RENEW;
> -
> - // Update CRTC's information (Output(s), (Common) Mode(s), etc.)
> - _e_randr_crtc_info_set(crtc_info);
> -
> - // Get mode info of set mode
> - mode_info = _e_randr_mode_info_get(event->mode);
> -
> - fprintf(stderr, "E_RANDR: CRTC %x was set to mode %x.\n", event->crtc, event->mode);
> -
> - if (event->mode != Ecore_X_Randr_None)
> - {
> - //switched (on)
> - if(!crtc_info->outputs_common_modes)
> - fprintf(stderr, "E_RANDR: Though this monitor was switched on, no outputs are known to be connected to CRTC %x. Therefore no common modes available.\n", crtc_info->xid);
> - if ((crtc_info->current_mode != mode_info))
> - {
> - crtc_info->current_mode = mode_info;
> - _e_randr_notify_crtc_mode_change(crtc_info);
> - }
> - else
> - crtc_info->current_mode = _e_randr_mode_info_get(event->mode);
> - crtc_info->current_orientation = event->orientation;
> - crtc_info->geometry.x = event->geo.x;
> - crtc_info->geometry.y = event->geo.y;
> - crtc_info->geometry.w = event->geo.w;
> - crtc_info->geometry.h = event->geo.h;
> - //update screensize if necessary
> - e_randr_screen_info->rrvd_info.randr_info_12->current_size.width = MAX((event->geo.x + event->geo.w), e_randr_screen_info->rrvd_info.randr_info_12->current_size.width);
> - e_randr_screen_info->rrvd_info.randr_info_12->current_size.height = MAX((event->geo.y + event->geo.h), e_randr_screen_info->rrvd_info.randr_info_12->current_size.height);
> - }
> - else
> - {
> - //set the max mode common amongst outputs
> - _e_randr_crtcs_clone_crtc_removed(crtc_info);
> -
> - //disabled
> - crtc_info->current_orientation = event->orientation;
> - crtc_info->geometry.x = 0;
> - crtc_info->geometry.y = 0;
> - crtc_info->geometry.w = 0;
> - crtc_info->geometry.h = 0;
> - crtc_info->current_mode = NULL;
> - if (crtc_info->outputs)
> - {
> - eina_list_free(crtc_info->outputs);
> - crtc_info->outputs = NULL;
> - }
> -
> - //update screensize of necessary
> - ecore_x_randr_screen_reset(e_randr_screen_info->root);
> - ecore_x_randr_screen_current_size_get(e_randr_screen_info->root, &e_randr_screen_info->rrvd_info.randr_info_12->current_size.width, &e_randr_screen_info->rrvd_info.randr_info_12->current_size.height, NULL, NULL);
> - }
> - }
> - else if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE)
> - {
> - Ecore_X_Event_Randr_Output_Change *event = ev;
> - E_Randr_Output_Info *output_info = NULL;
> - /* available information:
> - struct _Ecore_X_Event_Randr_Output_Change
> - {
> - Ecore_X_Window win;
> - Ecore_X_Randr_Output output;
> - Ecore_X_Randr_Crtc crtc;
> - Ecore_X_Randr_Mode mode;
> - Ecore_X_Randr_Orientation orientation;
> - Ecore_X_Randr_Connection_Status connection;
> - Ecore_X_Render_Subpixel_Order subpixel_order;
> - };
> - */
> - fprintf(stderr, "E_RANDR: Output connected!: \n"
> - "E_RANDR: relative to win: %x\n"
> - "E_RANDR: output (xid): %x\n"
> - "E_RANDR: used by crtc (xid): %x\n"
> - "E_RANDR: mode: %x\n"
> - "E_RANDR: orientation: %d\n"
> - "E_RANDR: connection state: %d (connected = %d, disconnected = %d, unknown = %d)\n"
> - "E_RANDR: subpixel_order: %d\n",
> - event->win, event->output, event->crtc, event->mode, event->orientation, event->connection, ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED, ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN, event->subpixel_order);
> -
> - output_info = _e_randr_output_info_get(event->output);
> - if (!output_info) return ECORE_CALLBACK_RENEW;
> -
> - if ((output_info->crtc = _e_randr_crtc_info_get(event->crtc)))
> - {
> - if (!eina_list_data_find(output_info->crtc->outputs, output_info))
> - output_info->crtc->outputs = eina_list_append(output_info->crtc->outputs, output_info);
> - //update the list of common modes for the crtc's connected outputs
> - if (output_info->crtc->outputs_common_modes)
> - {
> - eina_list_free(output_info->crtc->outputs_common_modes);
> - output_info->crtc->outputs_common_modes = NULL;
> - }
> - output_info->crtc->outputs_common_modes = _e_randr_outputs_common_modes_get(output_info->crtc->outputs, NULL);
> - }
> -
> - output_info->connection_status = event->connection;
> - output_info->subpixel_order = event->subpixel_order;
> -
> - if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
> - {
> - if (event->crtc)
> - output_info->crtc = _e_randr_crtc_info_get(event->crtc);
> -
> - if (output_info && !output_info->crtc && (event->crtc == Ecore_X_Randr_None) && (event->mode == Ecore_X_Randr_None))
> - {
> - //Monitor was attached!
> - _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 (output_info->policy != ECORE_X_RANDR_OUTPUT_POLICY_NONE)
> - enabled = _e_randr_try_enable_output(output_info, EINA_FALSE); //maybe give a success message?
> - fprintf(stderr, "E_RANDR: Output %d %s.", output_info->xid, (enabled ? "was enabled sucessfully" : "could not be enabled"));
> - }
> - _e_randr_notify_output_change(output_info);
> - }
> - else if (event->connection == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED)
> - {
> - if (output_info->crtc)
> - {
> - //remove output from CRTC
> - output_info->crtc->outputs = eina_list_remove(output_info->crtc->outputs, output_info);
> - if (eina_list_count(output_info->crtc->outputs) == 0)
> - output_info->crtc->outputs = NULL;
> -
> - if (output_info->crtc->current_mode)
> - {
> - //in case this output was enabled on some CRTC
> - if (eina_list_count(output_info->crtc->outputs) == 0)
> - {
> - //in case it was the only output running on this CRTC, disable
> - //it.
> - ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, output_info->crtc->xid, NULL, Ecore_X_Randr_None, Ecore_X_Randr_None);
> - //crop the screen of course.
> - ecore_x_randr_screen_reset(e_randr_screen_info->root);
> - }
> - else
> - _e_randr_crtc_outputs_mode_max_set(output_info->crtc);
> - }
> -
> - //reset assigned CRTC
> - output_info->crtc = NULL;
> - if (output_info == e_randr_screen_info->rrvd_info.randr_info_12->primary_output)
> - _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);
> - }
> - }
> - else if (type == ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY)
> - {
> - //Ecore_X_Event_Randr_Output_Property_Notify *event = (Ecore_X_Event_Randr_Output_Property_Notify*) ev;
> - /* available information:
> - struct _Ecore_X_Event_Randr_Output_Property_Notify
> - {
> - Ecore_X_Window win;
> - Ecore_X_Randr_Output output;
> - Ecore_X_Atom property;
> - Ecore_X_Time time;
> - Ecore_X_Randr_Property_Change state;
> - };
> - */
> - }
> - e_randr_try_restore_configuration(e_randr_screen_info);
> - return ECORE_CALLBACK_RENEW;
> -}
> -
> -static Eina_Bool
> -_e_randr_x_poll_cb(void *data __UNUSED__)
> -{
> - EINA_SAFETY_ON_NULL_RETURN_VAL(e_randr_screen_info, ECORE_CALLBACK_CANCEL);
> -
> - ecore_x_randr_screen_primary_output_orientations_get(e_randr_screen_info->root);
> -
> - return ECORE_CALLBACK_RENEW;
> -}
> -
> static Eina_Bool
> _e_event_config_loaded_cb(void *data __UNUSED__, int type, void *ev __UNUSED__)
> {
> if (type != E_EVENT_CONFIG_LOADED) return EINA_TRUE;
>
> - e_randr_try_restore_configuration(e_randr_screen_info);
> + _try_restore_configuration();
>
> return EINA_FALSE;
> }
>
> -static void
> -_e_randr_event_listeners_add(void)
> + static void
> +_event_listeners_add(void)
> {
> - if (E_RANDR_NO_12) return;
> - ecore_x_randr_events_select(e_randr_screen_info->root, EINA_TRUE);
> - _e_randr_event_handlers = eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_CRTC_CHANGE, _e_randr_event_cb, NULL));
> - _e_randr_event_handlers = eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_OUTPUT_CHANGE, _e_randr_event_cb, NULL));
> - _e_randr_event_handlers = eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(ECORE_X_EVENT_RANDR_OUTPUT_PROPERTY_NOTIFY, _e_randr_event_cb, NULL));
> - _e_randr_event_handlers = eina_list_append(_e_randr_event_handlers, ecore_event_handler_add(E_EVENT_CONFIG_LOADED, _e_event_config_loaded_cb, NULL));
> - // WORKAROUND problem of X not sending events
> - poller = ecore_poller_add(ECORE_POLLER_CORE, POLLINTERVAL, _e_randr_x_poll_cb, NULL);
> -}
> + _event_handlers = eina_list_append(_event_handlers, ecore_event_handler_add(E_EVENT_CONFIG_LOADED, _e_event_config_loaded_cb, NULL));
>
> -static void
> -_e_randr_event_listeners_remove(void)
> -{
> - Ecore_Event_Handler *_event_handler = NULL;
> - EINA_LIST_FREE (_e_randr_event_handlers, _event_handler)
> - ecore_event_handler_del(_event_handler);
> - ecore_poller_del(poller);
> - poller = NULL;
> -}
> -
> -static void
> -_e_randr_notify_crtc_mode_change(E_Randr_Crtc_Info *crtc_info)
> -{
> - // E_Notification *n;
> - // char buff[200];
> - //
> - if (crtc_info->current_mode)
> + if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - // snprintf(buff, 200, "New resolution is %dx%d. Click here for further information.", crtc_info->current_mode->width, crtc_info->current_mode->height);
> - // n = e_notification_full_new("RandRR", crtc_info->xid, NULL, "Resolution changed", buff, -1);
> - // //n = e_notification_full_new("RandRR", id, icon, function, body, timeout);
> - // e_notification_send(n, NULL, NULL);
> - // e_notification_unref(n);
> + _12_event_listeners_add();
> }
> }
>
> -static void
> -_e_randr_notify_output_change(E_Randr_Output_Info *output_info)
> + static void
> +_try_restore_configuration(void)
> {
> - // E_Notification *n;
> - // char buff[100];
> - if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
> + if (e_randr_screen_info.randr_version == ECORE_X_RANDR_1_1)
> {
> - // snprintf(buff, 100, "Output %s connected", output_info->name);
> - // n = e_notification_full_new("RandRR", output_info->xid, NULL, buff, "Click here for further information.", -1);
> + _11_try_restore_configuration();
> }
> - else
> + else if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - // snprintf(buff, 100, "Output %s disconnected", output_info->name);
> - // n = e_notification_full_new("RandRR", output_info->xid, NULL, buff, "Click here to adjust screen setup.", -1);
> + _12_try_restore_configuration();
> }
> -
> - // //n = e_notification_full_new("RandRR", id, icon, function, body, timeout);
> - // e_notification_send(n, NULL, NULL);
> - // e_notification_unref(n);
> }
>
> -/*
> - * this retrieves a CRTC depending on a policy.
> - * Note that this is enlightenment specific! Enlightenment doesn't 'allow' zones
> - * to overlap. Thus we always use the output with the most extreme position
> - * instead of trying to fill gaps like tetris. Though this could be done by
> - * simply implementing another policy.
> - *
> - * Simply put: get the
> - * -right
> - * -left
> - * -top
> - * -bottom
> - * most CRTC and return it.
> - */
> -static const E_Randr_Crtc_Info *
> -_e_randr_policy_crtc_get(E_Randr_Crtc_Info *but, E_Randr_Crtc_Info *hint __UNUSED__, Ecore_X_Randr_Output_Policy policy)
> -{
> - Eina_List *iter, *possible_crtcs = NULL;
> - E_Randr_Crtc_Info *crtc_info, *ret = NULL;
> -
> - E_RANDR_NO_CRTCS_RET(NULL);
> -
> - //get any crtc that besides 'but' to start with
> - possible_crtcs = eina_list_clone(e_randr_screen_info->rrvd_info.randr_info_12->crtcs);
> - possible_crtcs = eina_list_remove(possible_crtcs, but);
> -
> - if ((eina_list_count(possible_crtcs) == 0) && (policy != ECORE_X_RANDR_OUTPUT_POLICY_CLONE))
> - {
> - eina_list_free(possible_crtcs);
> - return NULL;
> - }
> -
> - // get an initial value for ret
> - ret = (E_Randr_Crtc_Info*)eina_list_data_get(eina_list_last(possible_crtcs));
> -
> - switch (policy)
> - {
> - case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if (crtc_info->geometry.y < ret->geometry.y)
> - ret = crtc_info;
> - }
> - break;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if ((crtc_info->geometry.x + crtc_info->geometry.w) >
> - (ret->geometry.x + ret->geometry.w))
> - ret = crtc_info;
> - }
> - break;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if ((crtc_info->geometry.y + crtc_info->geometry.h) >
> - (ret->geometry.y + ret->geometry.h))
> - ret = crtc_info;
> - }
> - break;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if (crtc_info->geometry.x < ret->geometry.x)
> - ret = crtc_info;
> - }
> - break;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
> - ret = (e_randr_screen_info->rrvd_info.randr_info_12->primary_output) ? e_randr_screen_info->rrvd_info.randr_info_12->primary_output->crtc : NULL;
> - break;
> -
> - default:
> - break;
> - }
> -
> - eina_list_free(possible_crtcs);
> - return ret;
> -}
> -
> -// Setup store functions
> -Eina_Bool
> -_e_randr_copy_mode_info(Ecore_X_Randr_Mode_Info *dest, Ecore_X_Randr_Mode_Info *src)
> -{
> - if (!dest || !src) return EINA_FALSE;
> -
> - 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;
> -
> -_e_randr_copy_mode_info_fail_free_name:
> - free(dest->name);
> - return EINA_FALSE;
> -}
> -
> -void
> -_e_randr_free_serialized_mode_info(Ecore_X_Randr_Mode_Info *mode_info)
> -{
> - if (mode_info->name) free(mode_info->name);
> -}
> -
> -Eina_List *
> -_e_randr_create_outputs_policies_list(Eina_List *outputs)
> -{
> - Eina_List *iter, *list = NULL;
> - E_Randr_Output_Info *oi;
> - E_Randr_Serialized_Output_Policy *sop;
> -
> - 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;
> - }
> -
> - 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;
> -}
> -
> -void
> -_e_randr_free_serialized_output_policy(E_Randr_Serialized_Output_Policy *sop)
> -{
> - if (!sop) return;
> -
> - free(sop->name);
> - free(sop);
> -}
> -
> -Eina_List *
> -_e_randr_update_serialized_outputs_policies(E_Randr_Screen_Info_12 *si_12, Eina_List *sops)
> -{
> - /*
> - * Do not free this mem, since it might be in e_config's teritory
> - *
> - E_Randr_Serialized_Output_Policy *sop;
> -
> - EINA_LIST_FREE (sops, sop)
> - {
> - _e_randr_free_serialized_output_policy(sop);
> - }
> - */
> -
> - eina_list_free(sops);
> -
> - 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;
> -
> - 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);
> - return NULL;
> -}
> -
> -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);
> - }
> - free(ss);
> - return NULL;
> -}
> -
> -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;
> -
> - 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);
> - setups_12 = eina_list_remove(setups_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 __UNUSED__)
> -{
> - return E_NEW(E_Randr_Serialized_Setup, 1);
> -}
> -
> -EAPI void
> -e_randr_store_configuration(E_Randr_Screen_Info *screen_info, E_Randr_Configuration_Store_Modifier modifier)
> -{
> - if (E_RANDR_NO_11) return;
> -
> - if (!e_config->randr_serialized_setup)
> - e_config->randr_serialized_setup = _e_randr_create_serialized_setup(screen_info);
> -
> - fprintf(stderr, "E_RANDR: Configuration shall be stored using the following modifier: %d.\n", modifier);
> -
> - if (screen_info->randr_version == ECORE_X_RANDR_1_1)
> - {
> - if (e_config->randr_serialized_setup->serialized_setup_11)
> - 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
> - e_config->randr_serialized_setup->serialized_setup_11 = _e_randr_create_serialized_setup_11(screen_info->rrvd_info.randr_info_11);
> - }
> - else if (screen_info->randr_version >= ECORE_X_RANDR_1_2)
> - {
> - /*
> - if (modifier & (E_RANDR_CONFIGURATION_STORE_RESOLUTIONS | E_RANDR_CONFIGURATION_STORE_ARRANGEMENT | E_RANDR_CONFIGURATION_STORE_ORIENTATIONS))
> - {
> - if (e_config->randr_serialized_setup->serialized_setups_12)
> - 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);
> - else
> - e_config->randr_serialized_setup->serialized_setups_12 = eina_list_append(e_config->randr_serialized_setup->serialized_setups_12, _e_randr_create_serialized_setup_12(screen_info->rrvd_info.randr_info_12));
> - }
> - */
> -
> - if (modifier & E_RANDR_CONFIGURATION_STORE_POLICIES)
> - {
> - //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)
> -{
> - 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))
> - {
> - return ecore_x_randr_screen_primary_output_size_set(e_randr_screen_info->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_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)
> - {
> - EINA_LIST_FOREACH (ci->possible_outputs, p_output_iter, oi)
> - {
> - if (oi->name)
> - {
> - if (!strncmp(s_output_name, oi->name, oi->name_length))
> - return ci;
> - }
> - }
> - }
> - }
> - 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)
> - {
> - fprintf(stderr, "E_RANDR: Looking for serialized output %d(hash)\n", so->edid_hash.hash);
> - EINA_LIST_FOREACH (ois, r_output_iter, oi)
> - {
> - fprintf(stderr, "E_RANDR: \tComparing to output %d(hash)\n", oi->edid_hash.hash);
> - 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;
> -}
> -
> -void
> -_e_randr_restore_12_policies(E_Randr_Screen_Info_12 *si_12)
> -{
> - E_Randr_Output_Info *output;
> - E_Randr_Serialized_Output_Policy *sop;
> - Eina_List *iter, *iter2;
> -
> - EINA_SAFETY_ON_NULL_RETURN(si_12);
> - EINA_SAFETY_ON_NULL_RETURN(e_config->randr_serialized_setup);
> - EINA_SAFETY_ON_NULL_RETURN(e_config->randr_serialized_setup->serialized_outputs_policies);
> -
> - // Restore policies
> - EINA_LIST_FOREACH(si_12->outputs, iter, output)
> - {
> - EINA_LIST_FOREACH(e_config->randr_serialized_setup->serialized_outputs_policies, iter2, sop)
> - {
> - if (output->name)
> - {
> - if (strncmp(sop->name, output->name, sop->name_length) == 0)
> - {
> - output->policy = sop->policy;
> - }
> - }
> - }
> - }
> -}
> -
> -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;
> - */
> - Eina_Bool ret = EINA_TRUE;
> -
> - //Restore policies
> - _e_randr_restore_12_policies(si_12);
> -
> - /*
> - * step by step. disable entire setup matching for now
> - if (!(ss_12 = _e_randr_find_matching_serialized_setup(e_config->randr_serialized_setup->serialized_setups_12, si_12))) return EINA_FALSE;
> -
> - 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);
> - if (!(mi = _e_randr_find_matching_mode_info(si_12->modes, &sc->mode_info)))
> - {
> - // The serialized mode is no longer available
> - eina_list_free(outputs_list);
> - free(outputs_array);
> - continue;
> - }
> - ret &= ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, ci->xid, outputs_array, eina_list_count(outputs_list), mi->xid);
> - ret &= ecore_x_randr_crtc_pos_set(e_randr_screen_info->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;
> - E_Randr_Output_Info *output_info;
> - Eina_List *output_iter;
> - int i = 0;
> -
> - 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! */
> - ret[i++] = output_info ? output_info->xid : Ecore_X_Randr_None;
> - return ret;
> -}
> -
> -/*
> - * Try to enable this output on an unoccupied CRTC. 'Force' in this context
> - * means, that if there are only occupied CRTCs, we disable another output to
> - * enable this one. If not forced we will - if we don't find an unoccupied CRTC
> - * - try to share the output of a CRTC with other outputs already using it
> - * (clone).
> - */
> - static Eina_Bool
> -_e_randr_try_enable_output(E_Randr_Output_Info *output_info, Eina_Bool force)
> -{
> - if (!output_info) return EINA_FALSE;
> - else if (output_info->crtc && output_info->crtc->current_mode)
> - return EINA_TRUE;
> -
> - Eina_List *iter, *outputs_list = NULL;
> - E_Randr_Crtc_Info *crtc_info, *usable_crtc = NULL;
> - E_Randr_Output_Info *primary_output;
> - Ecore_X_Randr_Output *outputs;
> - Ecore_X_Randr_Mode_Info *mode_info;
> - Eina_Bool ret = EINA_FALSE;
> -
> - /*
> - * Try to find a usable crtc for this output. Either unused or forced.
> - */
> - EINA_LIST_FOREACH (output_info->possible_crtcs, iter, crtc_info)
> - {
> - if (crtc_info && (!crtc_info->current_mode || force))
> - {
> - usable_crtc = crtc_info;
> - break;
> - }
> - }
> -
> - /*
> - * apparently we don't have a CRTC to make use of the device
> - */
> - if (!usable_crtc) return EINA_FALSE;
> -
> - fprintf(stderr, "E_RANDR: Try to enable output %x using policy %d.\n", output_info->xid, output_info->policy);
> -
> - //get the CRTC we will refer to, dependend on policy
> - switch (output_info->policy)
> - {
> - case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
> - return EINA_TRUE;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
> - /*
> - * Order of approaches to enable a clone (of the primary output):
> - *
> - * 0. Get Primary output from Server
> - * 1. Try to add new Output to primary output's CRTC, using the mode used
> - * by the primary output
> - * 2. Try to enable clone in the same
> - * 2a. exact mode or a
> - * 2b. geometrically identical mode
> - * 3. Find a most high resolution mode in common to enable on primary output's CRTC and the new
> - * output's CRTC
> - * 4. fail.
> - */
> - if ((primary_output = e_randr_screen_info->rrvd_info.randr_info_12->primary_output))
> - {
> - if (primary_output->crtc && primary_output->crtc->current_mode && eina_list_data_find(output_info->modes, primary_output->crtc->current_mode))
> - {
> - /*
> - * mode currently used by primary output's CRTC is also supported by the new output
> - */
> - if (_e_randr_outputs_are_clones(output_info, primary_output->crtc->outputs))
> - {
> - /*
> - * 1. Try to add new Output to primary output's CRTC, using the mode used
> - * by the primary output
> - * TODO: check with compatibility list in RandRR >= 1.3
> - * if available
> - *
> - * The new output is also usable by the primary output's
> - * CRTC. Try to enable this output together with the already
> - * enabled outputs on the CRTC in already used mode.
> - */
> - outputs_list = eina_list_clone(primary_output->crtc->outputs);
> - outputs_list = eina_list_append(outputs_list, output_info);
> - outputs = _e_randr_outputs_to_array(outputs_list);
> - ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, primary_output->crtc->xid, outputs, eina_list_count(outputs_list), primary_output->crtc->current_mode->xid);
> - free(outputs);
> - eina_list_free(outputs_list);
> - return ret;
> - }
> - else
> - {
> - /*
> - * 2. Try to enable clone in the same
> - */
> -
> - /*
> - * 2a. exact mode.
> - */
> - ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, primary_output->crtc->current_mode->xid);
> - return ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
> - }
> - }
> - else
> - {
> - /*
> - * 2b. geometrically identical mode
> - */
> - if (primary_output->crtc && (mode_info = _e_randr_mode_geo_identical_find(output_info->modes, primary_output->crtc->current_mode)))
> - {
> - ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid);
> - return ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
> - }
> - /*
> - * 3. Find the highest resolution mode common to enable on primary output's CRTC and the new one.
> - */
> - if (((outputs_list = eina_list_append(outputs_list, primary_output)) && (outputs_list = eina_list_append(outputs_list, output_info))))
> - {
> - if (primary_output->crtc)
> - {
> - if ((mode_info = _e_randr_outputs_common_mode_max_get(outputs_list, primary_output->crtc->current_mode)))
> - {
> - fprintf(stderr, "Will try to set mode: %dx%d for primary and clone.\n", mode_info->width, mode_info->height);
> - ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, primary_output->crtc->xid, ((Ecore_X_Randr_Output *)Ecore_X_Randr_Unset), Ecore_X_Randr_Unset, mode_info->xid);
> - ret = (ret && ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid));
> - ret = (ret && ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, usable_crtc->xid, primary_output->crtc->xid, ECORE_X_RANDR_OUTPUT_POLICY_CLONE, e_randr_screen_info->rrvd_info.randr_info_12->alignment));
> - }
> - }
> - eina_list_free(outputs_list);
> - }
> - }
> - }
> - else
> - fprintf(stderr, "Couldn't get primary output!\n");
> - /*
> - * 4. FAIL
> - */
> - break;
> -
> - default:
> - if (usable_crtc)
> - {
> - //enable and position according to used policies
> - if (!(mode_info = ((Ecore_X_Randr_Mode_Info *)eina_list_nth(output_info->preferred_modes, 0))))
> - {
> - fprintf(stderr, "E_RANDR: Could not enable output(%x), as it has no preferred (and there for none at all) modes.!\n", output_info->xid);
> - ret = EINA_FALSE;
> - break;
> - }
> - if ((ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, usable_crtc->xid, &output_info->xid, 1, mode_info->xid)))
> - {
> - usable_crtc->geometry.w = mode_info->width;
> - usable_crtc->geometry.h = mode_info->height;
> - usable_crtc->geometry.x = 0;
> - usable_crtc->geometry.y = 0;
> - usable_crtc->outputs = eina_list_append(usable_crtc->outputs, output_info);
> -
> - ret &= _e_randr_crtc_move_policy(usable_crtc);
> - }
> - }
> - }
> - ecore_x_randr_screen_reset(e_randr_screen_info->root);
> - return ret;
> -}
> -
> -/*
> - * updates all crtcs information regarding a new output
> - */
> +// "Free" helper functions
> static void
> -_e_randr_crtcs_possible_output_update(E_Randr_Output_Info *output_info)
> +_event_listeners_remove(void)
> {
> - Eina_List *iter;
> - E_Randr_Crtc_Info *crtc_info;
> - Ecore_X_Randr_Output *outputs = NULL;
> - int noutputs = 0;
> + Ecore_Event_Handler *_event_handler = NULL;
> + EINA_LIST_FREE (_event_handlers, _event_handler)
> + ecore_event_handler_del(_event_handler);
>
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> + if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
> {
> - if (!eina_list_data_find(crtc_info->possible_outputs, output_info))
> - {
> - if ((outputs = ecore_x_randr_crtc_possible_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs)))
> - {
> - while (--noutputs >= 0)
> - {
> - if (outputs[noutputs] == output_info->xid)
> - {
> - crtc_info->possible_outputs = eina_list_append(crtc_info->possible_outputs, output_info);
> - break;
> - }
> - }
> - free(outputs);
> - }
> - }
> + _12_event_listeners_remove();
> }
> }
> -
> -/*
> - * setup a crtc's current (possible) outputs references
> - */
> -static void
> -_e_randr_crtc_outputs_refs_update(E_Randr_Crtc_Info *crtc_info)
> -{
> - Ecore_X_Randr_Output *outputs;
> - E_Randr_Output_Info *output_info;
> - int i, noutputs;
> -
> - EINA_SAFETY_ON_NULL_RETURN(e_randr_screen_info->rrvd_info.randr_info_12->outputs);
> -
> - //get references to output_info structs which are related to this CRTC
> - if ((outputs = ecore_x_randr_crtc_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs)))
> - {
> - eina_list_free(crtc_info->outputs);
> - crtc_info->outputs = NULL;
> - for (i = 0; i < noutputs; i++)
> - {
> - if (!(output_info = _e_randr_output_info_get(outputs[i])))
> - {
> - output_info = _e_randr_output_info_new(1);
> - output_info->xid = outputs[i];
> - _e_randr_output_info_set(output_info);
> - e_randr_screen_info->rrvd_info.randr_info_12->outputs = eina_list_append(e_randr_screen_info->rrvd_info.randr_info_12->outputs, output_info);
> - }
> - crtc_info->outputs = eina_list_append(crtc_info->outputs, output_info);
> - output_info->crtc = crtc_info;
> - }
> - free(outputs);
> - }
> - //get references to possible output_info structs which are related to this CRTC
> - if ((outputs = ecore_x_randr_crtc_possible_outputs_get(e_randr_screen_info->root, crtc_info->xid, &noutputs)))
> - {
> - eina_list_free(crtc_info->possible_outputs);
> - crtc_info->possible_outputs = NULL;
> - for (i = 0; i < noutputs; i++)
> - {
> - output_info = _e_randr_output_info_get(outputs[i]);
> - crtc_info->possible_outputs = eina_list_append(crtc_info->possible_outputs, output_info);
> - }
> - free(outputs);
> - }
> -}
> -
> -/*
> - * reconfigure screen setup according to policy. This is only required if all
> - * CRTCs' positions might be affected by the another screens' movement. This includes 'virtual' moves,
> - * which means that e.g. when a crtc should be placed at a position < 0, all
> - * other crtcs are accordingly moved instead, so the result is the same.
> - */
> -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, last_output->policy))) return EINA_TRUE;
> -
> - //following is policy dependend.
> - switch (last_output->policy)
> - {
> - case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
> - dy = (crtc_rel->geometry.y - new_crtc->geometry.h);
> - if (dy < 0)
> - {
> - //virtual move (move other CRTCs as nessesary)
> - dy = -dy;
> - ret = ecore_x_randr_move_all_crtcs_but(e_randr_screen_info->root,
> - &new_crtc->xid,
> - 1,
> - dx,
> - dy);
> - }
> - break;
> -
> - case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
> - dx = (crtc_rel->geometry.x - new_crtc->geometry.w);
> - if (dx < 0)
> - {
> - //virtual move (move other CRTCs as nessesary)
> - dx = -dx;
> - ret = ecore_x_randr_move_all_crtcs_but(e_randr_screen_info->root,
> - &new_crtc->xid,
> - 1,
> - dx,
> - dy);
> - }
> - break;
> -
> - default:
> - break;
> - }
> - 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;
> -}
> -
> -/*
> - * returns the highest resolution mode common ammongst the given outputs,
> - * optionally limited by max_size_mode. If none is found, NULL is returned.
> - */
> -static Ecore_X_Randr_Mode_Info *
> -_e_randr_outputs_common_mode_max_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode)
> -{
> - Eina_List *all_modes = NULL, *iter, *output_iter, *right;
> - E_Randr_Output_Info *output_info;
> - Ecore_X_Randr_Mode_Info *mode_info;
> - int outputs_mode_found;
> -
> - //create a list of all available modes
> - EINA_LIST_FOREACH (outputs, iter, output_info)
> - {
> - right = eina_list_clone(output_info->modes);
> - all_modes = eina_list_merge(all_modes, right);
> - }
> -
> - if (max_size_mode)
> - {
> - //remove all modes that are larger than max_size_mode
> - EINA_LIST_FOREACH (all_modes, iter, mode_info)
> - {
> - if (_modes_size_sort_cb((void *)max_size_mode, (void *)mode_info) < 0)
> - all_modes = eina_list_remove(all_modes, mode_info);
> - }
> - }
> -
> - //sort modes by their sizes
> - all_modes = eina_list_sort(all_modes, eina_list_count(all_modes), _modes_size_sort_cb);
> - EINA_LIST_REVERSE_FOREACH (all_modes, iter, mode_info)
> - {
> - outputs_mode_found = 0;
> - EINA_LIST_FOREACH (outputs, output_iter, output_info)
> - {
> - if (eina_list_data_find(output_info->modes, mode_info))
> - outputs_mode_found++;
> - }
> - if (outputs_mode_found == (int)eina_list_count(outputs))
> - break;
> - mode_info = NULL;
> - }
> - return mode_info;
> -}
> -
> -/*
> - static int
> - _crtcs_size_sort_cb(const void *d1, const void *d2)
> - {
> - E_Randr_Crtc_Info *crtc1 = ((E_Randr_Crtc_Info*)d1), *crtc2 = ((E_Randr_Crtc_Info*)d2);
> -
> - return ((crtc1->geometry.w * crtc1->geometry.h) - (crtc2->geometry.w * crtc2->geometry.h));
> - }
> - */
> -
> -static int
> -_outputs_size_sort_cb(const void *d1, const void *d2)
> -{
> - E_Randr_Output_Info *output1 = ((E_Randr_Output_Info *)d1), *output2 = ((E_Randr_Output_Info *)d2);
> -
> - return (output1 && output1->crtc && output1->crtc->current_mode && output2 && output2->crtc && output2->crtc->current_mode) ? ((output1->crtc->current_mode->width * output1->crtc->current_mode->height) - (output2->crtc->current_mode->width * output2->crtc->current_mode->height)) : 0;
> -}
> -
> -static int
> -_modes_size_sort_cb(const void *d1, const void *d2)
> -{
> - Ecore_X_Randr_Mode_Info *mode1 = ((Ecore_X_Randr_Mode_Info *)d1), *mode2 = ((Ecore_X_Randr_Mode_Info *)d2);
> -
> - return (mode1->width * mode1->height) - (mode2->width * mode2->height);
> -}
> -
> -/*
> - * returns a mode within a given list of modes that is gemetrically identical.
> - * If none is found, NULL is returned.
> - */
> -static Ecore_X_Randr_Mode_Info *
> -_e_randr_mode_geo_identical_find(Eina_List *modes, Ecore_X_Randr_Mode_Info *mode)
> -{
> - Eina_List *iter;
> - Ecore_X_Randr_Mode_Info *mode_info;
> -
> - EINA_LIST_FOREACH (modes, iter, mode_info)
> - {
> - if ((mode_info->width == mode->width) && (mode_info->height == mode->height))
> - return mode_info;
> - }
> - return NULL;
> -}
> -
> -/*
> - * reconfigures a CRTC enabling the highest resolution amongst its outputs,
> - * without touching any other CRTC currently activated
> - */
> -static Eina_Bool
> -_e_randr_crtc_outputs_mode_max_set(E_Randr_Crtc_Info *crtc_info)
> -{
> - Ecore_X_Randr_Mode_Info *mode_info;
> - Eina_List *iter;
> - Eina_Bool ret = EINA_TRUE;
> - Ecore_X_Randr_Output *outputs;
> -
> - if (!crtc_info || !crtc_info->outputs || !crtc_info->outputs_common_modes) return EINA_FALSE;
> -
> - EINA_LIST_REVERSE_FOREACH (crtc_info->outputs_common_modes, iter, mode_info)
> - {
> - if (!_e_randr_crtc_mode_intersects_crtcs(crtc_info, mode_info))
> - break;
> - }
> - if (!mode_info)
> - {
> - //eina_list_free(crtc_info->outputs_common_modes);
> - return EINA_FALSE;
> - }
> - if ((outputs = _e_randr_outputs_to_array(crtc_info->outputs)))
> - {
> - ret = ecore_x_randr_crtc_mode_set(e_randr_screen_info->root, crtc_info->xid, outputs, eina_list_count(crtc_info->outputs), mode_info->xid);
> - free(outputs);
> - }
> - //eina_list_free(crtc_info->outputs_common_modes);
> - //crtc_info->outputs_common_modes = NULL;
> -
> - ecore_x_randr_screen_reset(e_randr_screen_info->root);
> -
> - return ret;
> -}
> -
> -/*
> - * returns EINA_TRUE if given CRTC would intersect with other CRTCs if set to
> - * given mode
> - */
> -static Eina_Bool
> -_e_randr_crtc_mode_intersects_crtcs(E_Randr_Crtc_Info *crtc_info, Ecore_X_Randr_Mode_Info *mode)
> -{
> - Eina_List *iter;
> - E_Randr_Crtc_Info *tmp;
> -
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, tmp)
> - {
> - if ((tmp == crtc_info) ||
> - ((tmp->geometry.w <= 0) || (tmp->geometry.h <= 0)))
> - continue;
> - if (E_INTERSECTS(crtc_info->geometry.x, crtc_info->geometry.y,
> - mode->width, mode->height, tmp->geometry.x,
> - tmp->geometry.y, tmp->geometry.w, tmp->geometry.h)
> - && ((crtc_info->geometry.x != tmp->geometry.x) &&
> - (crtc_info->geometry.y != tmp->geometry.y)))
> - return EINA_TRUE;
> - }
> - return EINA_FALSE;
> -}
> -
> -/*
> - * returns a list of modes common ammongst the given outputs,
> - * optionally limited by max_size_mode. If none are found, NULL is returned.
> - */
> -static Eina_List *
> -_e_randr_outputs_common_modes_get(Eina_List *outputs, Ecore_X_Randr_Mode_Info *max_size_mode)
> -{
> - Eina_List *common_modes = NULL, *iter, *output_iter, *right;
> - E_Randr_Output_Info *output_info;
> - Ecore_X_Randr_Mode_Info *mode_info;
> - int outputs_mode_found;
> -
> - if (!outputs) return NULL;
> -
> - //create a list of all available modes
> - EINA_LIST_FOREACH (outputs, iter, output_info)
> - {
> - right = eina_list_clone(output_info->modes);
> - common_modes = eina_list_merge(common_modes, right);
> - }
> -
> - if (max_size_mode)
> - {
> - //remove all modes that are larger than max_size_mode
> - EINA_LIST_FOREACH (common_modes, iter, mode_info)
> - {
> - if (_modes_size_sort_cb((void *)max_size_mode, (void *)mode_info) < 0)
> - common_modes = eina_list_remove(common_modes, mode_info);
> - }
> - }
> -
> - //sort modes desc. by their sizes
> - for (iter = eina_list_last(common_modes); iter; )
> - {
> - mode_info = iter->data;
> - iter = iter->prev;
> - outputs_mode_found = 0;
> - EINA_LIST_FOREACH (outputs, output_iter, output_info)
> - {
> - if (eina_list_data_find(output_info->modes, mode_info))
> - outputs_mode_found++;
> - }
> - if (outputs_mode_found != (int)eina_list_count(outputs))
> - common_modes = eina_list_remove(common_modes, mode_info);
> - }
> - return common_modes;
> -}
> -
> -/*
> - * reconfigure all CRTCs that had a given CRTC as a clone
> - */
> -static Eina_Bool
> -_e_randr_crtcs_clone_crtc_removed(E_Randr_Crtc_Info *former_clone)
> -{
> - Eina_List *iter;
> - E_Randr_Crtc_Info *crtc_info;
> -
> - if (!former_clone) return EINA_FALSE;
> -
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - if ((crtc_info == former_clone) || ((crtc_info->geometry.w <= 0) || (crtc_info->geometry.h <= 0))) continue;
> - if ((former_clone->geometry.x == crtc_info->geometry.x) && (former_clone->geometry.y == crtc_info->geometry.y) && (former_clone->geometry.w == crtc_info->geometry.w) && (former_clone->geometry.h == crtc_info->geometry.h))
> - {
> - if (!_e_randr_crtc_outputs_mode_max_set(crtc_info)) return EINA_FALSE;
> - }
> - }
> -
> - return EINA_TRUE;
> -}
> -
> -static void
> -_e_randr_screen_primary_output_assign(E_Randr_Output_Info *removed)
> -{
> - Eina_List *iter;
> - E_Randr_Output_Info *primary_output = NULL, *output_info;
> -
> - E_RANDR_NO_OUTPUTS_RET();
> -
> - if (e_randr_screen_info->rrvd_info.randr_info_12->primary_output && (removed != e_randr_screen_info->rrvd_info.randr_info_12->primary_output)) return;
> - if (!(primary_output = _e_randr_output_info_get(ecore_x_randr_primary_output_get(e_randr_screen_info->root))))
> - {
> - primary_output = eina_list_data_get(eina_list_last(e_randr_screen_info->rrvd_info.randr_info_12->outputs));
> -
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info)
> - {
> - if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED || !output_info->crtc || !output_info->crtc->current_mode) continue;
> - if ((!primary_output->crtc || !primary_output->crtc->current_mode) || _outputs_size_sort_cb(output_info, primary_output) > 0) primary_output = output_info;
> - }
> - if (!primary_output->crtc || !primary_output->crtc->current_mode) primary_output = NULL;
> - }
> - e_randr_screen_info->rrvd_info.randr_info_12->primary_output = primary_output;
> -}
> -
> -static void
> -_e_randr_output_info_hw_info_set(E_Randr_Output_Info *output_info)
> -{
> - Ecore_X_Randr_Output *outputs;
> - Ecore_X_Randr_Crtc *crtcs;
> - E_Randr_Output_Info *output;
> - E_Randr_Crtc_Info *crtc;
> - int i, num;
> -
> - _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((char *)output_info->edid, output_info->edid_length);
> -
> - //get the outputs we can use on the same CRTC alongside this one.
> - if (output_info->clones)
> - {
> - eina_list_free(output_info->clones);
> - output_info->clones = NULL;
> - }
> - if ((outputs = ecore_x_randr_output_clones_get(e_randr_screen_info->root, output_info->xid, &num)))
> - {
> - for (i = 0; i < num; i++)
> - {
> - if ((output = _e_randr_output_info_get(outputs[i])))
> - output_info->clones = eina_list_append(output_info->clones, output);
> - }
> - free(outputs);
> - }
> -
> - //get the CRTCs which are usable with this output.
> - if (output_info->possible_crtcs)
> - {
> - eina_list_free(output_info->possible_crtcs);
> - output_info->possible_crtcs = NULL;
> - }
> - if ((crtcs = ecore_x_randr_output_possible_crtcs_get(e_randr_screen_info->root, output_info->xid, &num)))
> - {
> - for (i = 0; i < num; i++)
> - {
> - fprintf(stderr, "E_RANDR: possible CRTC: %d\n", crtcs[i]);
> - if ((crtc = _e_randr_crtc_info_get(crtcs[i])))
> - {
> - fprintf(stderr, "E_RANDR: \tfound the suiting struct at %p\n", crtc);
> - output_info->possible_crtcs = eina_list_append(output_info->possible_crtcs, crtc);
> - }
> - }
> - free(crtcs);
> - }
> - else
> - {
> - fprintf(stderr, "E_RANDR: Output %x does not have a single possible CRTC.\n", output_info->xid);
> - }
> -}
> -
> -/*
> - * free the hardware specifig parts of the information
> - * removes all traces of an output within the data.
> - * @param output_info the output info to be freed.
> - */
> -static void
> -_e_randr_output_hw_info_free(E_Randr_Output_Info *output_info)
> -{
> - E_Randr_Crtc_Info *crtc_info;
> - Eina_List *iter;
> - if (!output_info) return;
> -
> - if (output_info->modes)
> - {
> - eina_list_free(output_info->modes);
> - output_info->modes = NULL;
> - }
> - if (output_info->preferred_modes)
> - {
> - eina_list_free(output_info->preferred_modes);
> - output_info->preferred_modes = NULL;
> - }
> - if (output_info->edid)
> - {
> - free(output_info->edid);
> - output_info->edid = NULL;
> - }
> - if (output_info->wired_clones)
> - {
> - eina_list_free(output_info->wired_clones);
> - output_info->wired_clones = NULL;
> - }
> - if (output_info->compatible_outputs)
> - {
> - eina_list_free(output_info->compatible_outputs);
> - output_info->compatible_outputs = NULL;
> - }
> - if (output_info->possible_crtcs)
> - {
> - eina_list_free(output_info->possible_crtcs);
> - output_info->possible_crtcs = NULL;
> - }
> - if (output_info->clones)
> - {
> - eina_list_free(output_info->clones);
> - output_info->clones = NULL;
> - }
> -
> - EINA_LIST_FOREACH (e_randr_screen_info->rrvd_info.randr_info_12->crtcs, iter, crtc_info)
> - {
> - crtc_info->possible_outputs = eina_list_remove(crtc_info->possible_outputs, output_info);
> - }
> -}
> -
> -/*
> - * checks whether a given output is a common clone of the given list's outputs
> - */
> -static Eina_Bool
> -_e_randr_outputs_are_clones(E_Randr_Output_Info *output_info, Eina_List *outputs)
> -{
> - E_Randr_Output_Info *output;
> - Eina_List *iter;
> -
> - if (!outputs || !output_info) return EINA_FALSE;
> -
> - EINA_LIST_FOREACH (output_info->clones, iter, output)
> - {
> - if (!eina_list_data_find(output_info->clones, output))
> - return EINA_FALSE;
> - }
> - return EINA_TRUE;
> -}
> -
>
> Modified: trunk/e/src/bin/e_randr.h
> ===================================================================
> --- trunk/e/src/bin/e_randr.h 2012-02-18 15:56:00 UTC (rev 68113)
> +++ trunk/e/src/bin/e_randr.h 2012-02-18 16:49:07 UTC (rev 68114)
> @@ -2,6 +2,7 @@
>
> typedef struct _E_Randr_Crtc_Info E_Randr_Crtc_Info;
> typedef struct _E_Randr_Edid_Hash E_Randr_Edid_Hash;
> +typedef struct _E_Randr_Monitor_Info E_Randr_Monitor_Info;
> 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;
> @@ -27,8 +28,7 @@
> | E_RANDR_CONFIGURATION_STORE_ORIENTATIONS)
> } E_Randr_Configuration_Store_Modifier;
>
> -EAPI void e_randr_store_configuration(E_Randr_Screen_Info *screen_info, E_Randr_Configuration_Store_Modifier modifier);
> -EAPI Eina_Bool e_randr_try_restore_configuration(E_Randr_Screen_Info *screen_info);
> +EAPI void e_randr_store_configuration(E_Randr_Configuration_Store_Modifier modifier);
>
> #else
> #ifndef E_RANDR_H
> @@ -56,6 +56,18 @@
> int hash;
> };
>
> +struct _E_Randr_Monitor_Info
> +{
> + Eina_List *modes;
> + Eina_List *preferred_modes;
> + 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;
> +};
> +
> struct _E_Randr_Output_Info
> {
> Ecore_X_ID xid;
> @@ -69,21 +81,13 @@
> Ecore_X_Randr_Connector_Type connector_type;
> Ecore_X_Randr_Connection_Status connection_status;
> Ecore_X_Randr_Output_Policy policy;
> + Eina_List *possible_crtcs;
> + Eina_List *compatibility_list;
> + Ecore_X_Render_Subpixel_Order subpixel_order;
> /*
> * Attached Monitor specific:
> */
> - Eina_List *modes;
> - Eina_List *preferred_modes;
> - Eina_List *clones;
> - Eina_List *possible_crtcs;
> - 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;
> - Eina_List *compatible_outputs;
> + E_Randr_Monitor_Info *monitor;
> };
>
> struct _E_Randr_Screen_Info_11
> @@ -129,41 +133,35 @@
> struct _E_Randr_Serialized_Output_Policy
> {
> char *name;
> - int name_length;
> Ecore_X_Randr_Output_Policy policy;
> };
>
> struct _E_Randr_Serialized_Output
> {
> char *name;
> - int name_length;
> - E_Randr_Edid_Hash edid_hash;
> double backlight_level;
> };
>
> struct _E_Randr_Serialized_Crtc
> {
> + int index;
> //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;
> + Eina_List *outputs;
> 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;
> + //the serialized mode_info
> + Ecore_X_Randr_Mode_Info mode_info;
> };
>
> struct _E_Randr_Serialized_Setup_12
> {
> double timestamp;
> //List of E_Randr_Serialized_Crtc objects
> - Eina_List *serialized_crtcs;
> + Eina_List *crtcs;
> /*
> - * List of E_Randr_Edid_Hash elements of monitors,
> - * that were enabled, when the setup was stored
> + * List of E_Randr_Edid_Hash elements of all connected monitors
> */
> - Eina_List *serialized_edid_hashes;
> + Eina_List *edid_hashes;
> };
>
> struct _E_Randr_Serialized_Setup_11
> @@ -179,14 +177,18 @@
> //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;
> + Eina_List *outputs_policies;
> };
>
> EINTERN Eina_Bool e_randr_init(void);
> -EAPI Eina_Bool e_randr_screen_info_refresh(void);
> +EAPI void e_randr_screen_info_refresh(void);
> EINTERN int e_randr_shutdown(void);
> +EINTERN void e_randr_serialized_setup_free(E_Randr_Serialized_Setup *ss);
> +EINTERN void e_randr_11_serialized_setup_free(E_Randr_Serialized_Setup_11 *ss_11);
> +EINTERN void e_randr_12_serialized_setup_free(E_Randr_Serialized_Setup_12 *ss_12);
> +EINTERN void e_randr_12_serialized_output_policy_free(E_Randr_Serialized_Output_Policy *policy);
>
> -EAPI extern E_Randr_Screen_Info *e_randr_screen_info;
> +EAPI extern E_Randr_Screen_Info e_randr_screen_info;
>
> #endif
> #endif
>
>
> ------------------------------------------------------------------------------
> Virtualization & Cloud Management Using Capacity Planning
> Cloud computing makes use of virtualization - but cloud computing
> also focuses on allowing computing to be delivered as a service.
> http://www.accelacomm.com/jaw/sfnl/114/51521223/
> _______________________________________________
> enlightenment-svn mailing list
> enlightenment-svn@...
> https://lists.sourceforge.net/lists/listinfo/enlightenment-svn
--
Leif
|