way for it to be worked on by people for release.
SVN revision: 64801
AC_E_OPTIONAL_MODULE([shot], true)
AC_E_OPTIONAL_MODULE([backlight], true)
AC_E_OPTIONAL_MODULE([tasks], true)
+AC_E_OPTIONAL_MODULE([conf_randr], true)
SUSPEND=""
HIBERNATE=""
src/modules/conf_interaction/module.desktop
src/modules/msgbus/Makefile
src/modules/msgbus/module.desktop
+src/modules/conf_randr/Makefile
+src/modules/conf_randr/module.desktop
src/modules/gadman/Makefile
src/modules/gadman/module.desktop
src/modules/mixer/Makefile
#define DEF_MENUCLICK 0.25
#endif
-typedef enum _Eet_Union
-{
- EET_SCREEN_INFO_11 = (int)((1 << 16) | 1),
- EET_SCREEN_INFO_12 = (int)((1 << 16) | 2),
- EET_SCREEN_INFO_13 = (int)((1 << 16) | 3),
- EET_UNKNOWN
-} Eet_Union;
-
-struct {
- Eet_Union u;
- const char *name;
-} eet_mapping[] = {
- { EET_SCREEN_INFO_11, "E_Config_Screen_11" },
- { EET_SCREEN_INFO_12, "E_Config_Screen_12" },
- { EET_SCREEN_INFO_12, "E_Config_Screen_13" },
- { EET_UNKNOWN, NULL }
-};
+#define RANDR_SERIALIZED_SETUP_11 ((int)((1 << 16) | 1))
+#define RANDR_SERIALIZED_SETUP_12 ((int)((1 << 16) | 2))
+#define RANDR_SERIALIZED_SETUP_13 ((int)((1 << 16) | 3))
EAPI E_Config *e_config = NULL;
static Eina_Bool _e_config_cb_timer(void *data);
static int _e_config_eet_close_handle(Eet_File *ef, char *file);
static void _e_config_acpi_bindings_add(void);
-static const char * _eet_union_type_get(const void *data, Eina_Bool *unknow);
-static Eina_Bool _eet_union_type_set(const char *type, void *data, Eina_Bool unknow);
/* local subsystem globals */
static int _e_config_save_block = 0;
static E_Config_DD *_e_config_mime_icon_edd = NULL;
static E_Config_DD *_e_config_syscon_action_edd = NULL;
static E_Config_DD *_e_config_env_var_edd = NULL;
-static E_Config_DD *_e_config_screen_size_edd = NULL;
-static E_Config_DD *_e_config_screen_size_mm_edd = NULL;
-static E_Config_DD *_e_config_eina_rectangle_edd = NULL;
-static E_Config_DD *_e_config_screen_info_edd = NULL;
-static E_Config_DD *_e_config_screen_restore_info_11_edd = NULL;
-static E_Config_DD *_e_config_screen_restore_info_12_edd = NULL;
-static E_Config_DD *_e_config_screen_output_edid_hash_edd = NULL;
-static E_Config_DD *_e_config_screen_output_restore_info_edd = NULL;
-static E_Config_DD *_e_config_screen_crtc_restore_info_edd = NULL;
+static E_Config_DD *_e_config_randr_size_edd = NULL;
+static E_Config_DD *_e_config_randr_size_mm_edd = NULL;
+static E_Config_DD *_e_config_randr_edid_hash_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_11_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_setup_12_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_output_policy_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_output_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_mode_info_edd = NULL;
+static E_Config_DD *_e_config_randr_serialized_crtc_edd = NULL;
EAPI int E_EVENT_CONFIG_ICON_THEME = 0;
E_CONFIG_VAL(D, T, val, STR);
E_CONFIG_VAL(D, T, unset, UCHAR);
- _e_config_screen_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size);
+ _e_config_randr_size_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size", Ecore_X_Randr_Screen_Size);
#undef T
#undef D
#define T Ecore_X_Randr_Screen_Size
-#define D _e_config_screen_size_edd
+#define D _e_config_randr_size_edd
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
- _e_config_screen_size_mm_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size_MM", Ecore_X_Randr_Screen_Size_MM);
+ _e_config_randr_size_mm_edd = E_CONFIG_DD_NEW("Ecore_X_Randr_Screen_Size_MM", Ecore_X_Randr_Screen_Size_MM);
#undef T
#undef D
#define T Ecore_X_Randr_Screen_Size_MM
-#define D _e_config_screen_size_mm_edd
+#define D _e_config_randr_size_mm_edd
E_CONFIG_VAL(D, T, width, INT);
E_CONFIG_VAL(D, T, height, INT);
E_CONFIG_VAL(D, T, width_mm, INT);
E_CONFIG_VAL(D, T, height_mm, INT);
- _e_config_screen_restore_info_11_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11", E_Randr_Screen_Restore_Info_11);
+ _e_config_randr_edid_hash_edd = E_CONFIG_DD_NEW("E_Randr_Edid_Hash", E_Randr_Edid_Hash);
+#undef T
+#undef D
+#define T E_Randr_Edid_Hash
+#define D _e_config_randr_edid_hash_edd
+ E_CONFIG_VAL(D, T, hash, INT);
+
+ _e_config_randr_serialized_setup_11_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup_11", E_Randr_Serialized_Setup_11);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info_11
-#define D _e_config_screen_restore_info_11_edd
- E_CONFIG_SUB(D, T, size, _e_config_screen_size_edd);
+#define T E_Randr_Serialized_Setup_11
+#define D _e_config_randr_serialized_setup_11_edd
+ E_CONFIG_SUB(D, T, size, _e_config_randr_size_edd);
E_CONFIG_VAL(D, T, orientation, INT);
E_CONFIG_VAL(D, T, refresh_rate, SHORT);
- _e_config_eina_rectangle_edd = E_CONFIG_DD_NEW("Eina_Rectangle", Eina_Rectangle);
+ _e_config_randr_serialized_output_policy_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Output_Policy", E_Randr_Serialized_Output_Policy);
#undef T
#undef D
-#define T Eina_Rectangle
-#define D _e_config_eina_rectangle_edd
- E_CONFIG_VAL(D, T, x, INT);
- E_CONFIG_VAL(D, T, y, INT);
- E_CONFIG_VAL(D, T, w, INT);
- E_CONFIG_VAL(D, T, h, INT);
+#define T E_Randr_Serialized_Output_Policy
+#define D _e_config_randr_serialized_output_policy_edd
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, name_length, INT);
+ E_CONFIG_VAL(D, T, policy, INT);
- _e_config_screen_output_edid_hash_edd = E_CONFIG_DD_NEW("E_Randr_Output_Edid_Hash", E_Randr_Output_Edid_Hash);
+ _e_config_randr_serialized_output_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Output", E_Randr_Serialized_Output);
#undef T
#undef D
-#define T E_Randr_Output_Edid_Hash
-#define D _e_config_screen_output_edid_hash_edd
- E_CONFIG_VAL(D, T, hash, INT);
+#define T E_Randr_Serialized_Output
+#define D _e_config_randr_serialized_output_edd
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, name_length, INT);
+ E_CONFIG_SUB(D, T, edid_hash, _e_config_randr_edid_hash_edd);
+ E_CONFIG_VAL(D, T, backlight_level, DOUBLE);
- // FIXME: need to totally re-do this randr config stuff - remove the
- // union stuff. do this differently to not use unions really. not
- // intended for how it is used here really.
- _e_config_screen_output_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Output_Restore_Info", E_Randr_Output_Restore_Info);
+ _e_config_randr_serialized_mode_info_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Mode_Info", Ecore_X_Randr_Mode_Info);
#undef T
#undef D
-#define T E_Randr_Output_Restore_Info
-#define D _e_config_screen_output_restore_info_edd
- E_CONFIG_SUB(D, T, edid_hash, _e_config_screen_output_edid_hash_edd);
- E_CONFIG_VAL(D, T, backlight_level, DOUBLE);
+#define T Ecore_X_Randr_Mode_Info
+#define D _e_config_randr_serialized_mode_info_edd
+ E_CONFIG_VAL(D, T, width, INT);
+ E_CONFIG_VAL(D, T, height, INT);
+ E_CONFIG_VAL(D, T, dotClock, LL);
+ E_CONFIG_VAL(D, T, hSyncStart, INT);
+ E_CONFIG_VAL(D, T, hSyncEnd, INT);
+ E_CONFIG_VAL(D, T, hTotal, INT);
+ E_CONFIG_VAL(D, T, hSkew, INT);
+ E_CONFIG_VAL(D, T, vSyncStart, INT);
+ E_CONFIG_VAL(D, T, vSyncEnd, INT);
+ E_CONFIG_VAL(D, T, vTotal, INT);
+ E_CONFIG_VAL(D, T, name, STR);
+ E_CONFIG_VAL(D, T, nameLength, INT);
+ E_CONFIG_VAL(D, T, modeFlags, LL);
- _e_config_screen_crtc_restore_info_edd = E_CONFIG_DD_NEW("E_Randr_Crtc_Restore_Info", E_Randr_Crtc_Restore_Info);
+ _e_config_randr_serialized_crtc_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Crtc", E_Randr_Serialized_Crtc);
#undef T
#undef D
-#define T E_Randr_Crtc_Restore_Info
-#define D _e_config_screen_crtc_restore_info_edd
- E_CONFIG_SUB(D, T, geometry, _e_config_eina_rectangle_edd);
- E_CONFIG_LIST(D, T, outputs, _e_config_screen_output_restore_info_edd);
+#define T E_Randr_Serialized_Crtc
+#define D _e_config_randr_serialized_crtc_edd
+ E_CONFIG_LIST(D, T, serialized_outputs, _e_config_randr_serialized_output_edd);
+ E_CONFIG_SUB(D, T, mode_info, _e_config_randr_serialized_mode_info_edd);
+ E_CONFIG_VAL(D, T, pos.x, INT);
+ E_CONFIG_VAL(D, T, pos.y, INT);
+ EET_DATA_DESCRIPTOR_ADD_LIST_STRING(D, T, "Crtc_Possible_Outputs_Names", possible_outputs_names);
E_CONFIG_VAL(D, T, orientation, INT);
- _e_config_screen_restore_info_12_edd = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12", E_Randr_Screen_Restore_Info_12);
+ _e_config_randr_serialized_setup_12_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup_12", E_Randr_Serialized_Setup_12);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info_12
-#define D _e_config_screen_restore_info_12_edd
- E_CONFIG_LIST(D, T, crtcs, _e_config_screen_crtc_restore_info_edd);
- E_CONFIG_LIST(D, T, outputs_edid_hashes, _e_config_screen_output_edid_hash_edd);
- E_CONFIG_VAL(D, T, noutputs, INT);
- E_CONFIG_VAL(D, T, output_policy, INT);
- E_CONFIG_VAL(D, T, alignment, INT);
+#define T E_Randr_Serialized_Setup_12
+#define D _e_config_randr_serialized_setup_12_edd
+ E_CONFIG_VAL(D, T, timestamp, DOUBLE);
+ E_CONFIG_LIST(D, T, serialized_crtcs, _e_config_randr_serialized_crtc_edd);
+ E_CONFIG_LIST(D, T, serialized_edid_hashes, _e_config_randr_edid_hash_edd);
+ _e_config_randr_serialized_setup_edd = E_CONFIG_DD_NEW("E_Randr_Serialized_Setup", E_Randr_Serialized_Setup);
#undef T
#undef D
-#define T E_Randr_Screen_Restore_Info
-#define D _e_config_screen_info_edd
- Eet_Data_Descriptor_Class eddc;
- Eet_Data_Descriptor *unified, *edd_11_info, *edd_12_info;
- EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, T);
- D = eet_data_descriptor_stream_new(&eddc);
- eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
- eddc.func.type_get = _eet_union_type_get;
- eddc.func.type_set = _eet_union_type_set;
- //virtual types to work around EET's inability to differentiate when it
- //comes to pointers (a->b) vs. values (a.b) in union mappings
- edd_11_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_11_Struct", E_Randr_Screen_Restore_Info_11);
- E_CONFIG_SUB(edd_11_info, E_Randr_Screen_Restore_Info_Union, restore_info_11, _e_config_screen_restore_info_11_edd);
- edd_12_info = E_CONFIG_DD_NEW("E_Randr_Screen_Restore_Info_12_Struct", E_Randr_Screen_Restore_Info_12);
- E_CONFIG_LIST(edd_12_info, E_Randr_Screen_Restore_Info_Union, restore_info_12, _e_config_screen_restore_info_12_edd);
- unified = eet_data_descriptor_stream_new(&eddc);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_11", edd_11_info);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_12", edd_12_info);
- EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "E_Config_Screen_13", edd_12_info);
-// DISABLE! crashie crashie long time
-// EET_DATA_DESCRIPTOR_ADD_UNION(D, T, "E_Randr_Screen_Restore_Info_Union", rrvd_restore_info, randr_version, unified);
- E_CONFIG_VAL(D, T, randr_version, INT);
+#define T E_Randr_Serialized_Setup
+#define D _e_config_randr_serialized_setup_edd
+ E_CONFIG_SUB(D, T, serialized_setup_11, _e_config_randr_serialized_setup_11_edd);
+ E_CONFIG_LIST(D, T, serialized_setups_12, _e_config_randr_serialized_setup_12_edd);
+ E_CONFIG_LIST(D, T, serialized_outputs_policies, _e_config_randr_serialized_output_policy_edd);
_e_config_edd = E_CONFIG_DD_NEW("E_Config", E_Config);
#undef T
E_CONFIG_VAL(D, T, desklock_ask_presentation, UCHAR);
E_CONFIG_VAL(D, T, desklock_ask_presentation_timeout, DOUBLE);
- E_CONFIG_LIST(D, T, screen_info, _e_config_screen_info_edd);
+ //randr specifics
+ E_CONFIG_SUB(D, T, randr_serialized_setup, _e_config_randr_serialized_setup_edd);
E_CONFIG_VAL(D, T, screensaver_enable, INT);
E_CONFIG_VAL(D, T, screensaver_timeout, INT);
E_CONFIG_DD_FREE(_e_config_mime_icon_edd);
E_CONFIG_DD_FREE(_e_config_syscon_action_edd);
E_CONFIG_DD_FREE(_e_config_env_var_edd);
- E_CONFIG_DD_FREE(_e_config_screen_info_edd);
+ E_CONFIG_DD_FREE(_e_config_randr_serialized_setup_edd);
return 1;
}
E_Color_Class *cc;
E_Path_Dir *epd;
E_Remember *rem;
- E_Randr_Screen_Restore_Info *screen_info;
- E_Randr_Crtc_Restore_Info *crtc_info;
- E_Randr_Output_Info *output_info;
- E_Randr_Screen_Restore_Info_12 *restore_info_12;
+ E_Randr_Serialized_Setup *serialized_setup;
+ E_Randr_Serialized_Setup_12 *serialized_setup_12;
+ E_Randr_Serialized_Crtc *serialized_crtc;
+ E_Randr_Serialized_Output_Policy *serialized_output_policy;
+ E_Randr_Serialized_Output *serialized_output;
+ E_Randr_Edid_Hash *edid_hash;
+ char *output_name;
E_Config_Env_Var *evr;
if (sca->icon) eina_stringshare_del(sca->icon);
E_FREE(sca);
}
- if (ecf->screen_info)
+ if(ecf->randr_serialized_setup)
{
- EINA_LIST_FREE(ecf->screen_info, screen_info)
- {
- switch (screen_info->randr_version)
- {
- case EET_SCREEN_INFO_11:
- free(screen_info->rrvd_restore_info.restore_info_11);
- break;
- case EET_SCREEN_INFO_12:
- case EET_SCREEN_INFO_13:
- EINA_LIST_FREE(screen_info->rrvd_restore_info.restore_info_12, restore_info_12)
- {
- EINA_LIST_FREE(restore_info_12->crtcs, crtc_info)
- {
- EINA_LIST_FREE(crtc_info->outputs, output_info)
- {
- free(output_info->name);
- free(output_info->edid);
- free (output_info);
- }
- free (crtc_info);
- }
- free(restore_info_12);
- }
- eina_list_free(screen_info->rrvd_restore_info.restore_info_12);
- break;
- }
- free(screen_info);
- }
+ if(ecf->randr_serialized_setup->serialized_setup_11)
+ free(serialized_setup->serialized_setup_11);
+ else if(ecf->randr_serialized_setup->serialized_setups_12)
+ {
+ EINA_LIST_FREE(ecf->randr_serialized_setup->serialized_setups_12, serialized_setup_12)
+ {
+ EINA_LIST_FREE(serialized_setup_12->serialized_crtcs, serialized_crtc)
+ {
+ if (!serialized_crtc) continue;
+ EINA_LIST_FREE(serialized_crtc->serialized_outputs, serialized_output)
+ {
+ if (serialized_output)
+ {
+ if (serialized_output->name) free(serialized_output);
+ free(serialized_output);
+ }
+ }
+ EINA_LIST_FREE(serialized_crtc->possible_outputs_names, output_name)
+ {
+ if (output_name) free(output_name);
+ }
+ if (serialized_crtc->mode_info.name)
+ free(serialized_crtc->mode_info.name);
+ free(serialized_crtc);
+ }
+ EINA_LIST_FREE(serialized_setup_12->serialized_edid_hashes, edid_hash)
+ {
+ if (edid_hash) free(edid_hash);
+ }
+ free(serialized_setup_12);
+ }
+ }
+ EINA_LIST_FREE(ecf->randr_serialized_setup->serialized_outputs_policies, serialized_output_policy)
+ {
+ if (!serialized_output) continue;
+ if (serialized_output_policy->name)
+ free(serialized_output_policy->name);
+ free(serialized_output_policy);
+ }
+ free(ecf->randr_serialized_setup);
}
+
EINA_LIST_FREE(ecf->env_vars, evr)
{
if (evr->var) eina_stringshare_del(evr->var);
E_FREE(ecf);
}
-static Eina_Bool
+ static Eina_Bool
_e_config_cb_timer(void *data)
{
e_util_dialog_show(_("Settings Upgraded"), "%s", (char *)data);
return 0;
}
-static int
+ static int
_e_config_eet_close_handle(Eet_File *ef, char *file)
{
Eet_Error err;
switch (err)
{
case EET_ERROR_NONE:
- /* all good - no error */
- break;
+ /* all good - no error */
+ break;
case EET_ERROR_BAD_OBJECT:
- erstr = _("The EET file handle is bad.");
- break;
+ erstr = _("The EET file handle is bad.");
+ break;
case EET_ERROR_EMPTY:
- erstr = _("The file data is empty.");
- break;
+ erstr = _("The file data is empty.");
+ break;
case EET_ERROR_NOT_WRITABLE:
- erstr = _("The file is not writable. Perhaps the disk is read-only<br>or you lost permissions to your files.");
+ erstr = _("The file is not writable. Perhaps the disk is read-only<br>or you lost permissions to your files.");
break;
case EET_ERROR_OUT_OF_MEMORY:
erstr = _("Memory ran out while preparing the write.<br>Please free up memory.");
bind->params = eina_stringshare_add("now");
e_config->acpi_bindings = eina_list_append(e_config->acpi_bindings, bind);
}
-
-static const char *
-_eet_union_type_get(const void *data, Eina_Bool *unknow)
-{
- const Eet_Union *u = data;
- int i;
-
- if (unknow) *unknow = EINA_FALSE;
- for (i = 0; eet_mapping[i].name; ++i)
- if (*u == eet_mapping[i].u)
- return eet_mapping[i].name;
-
- if (unknow) *unknow = EINA_TRUE;
- return NULL;
-}
-
-static Eina_Bool
-_eet_union_type_set(const char *type, void *data, Eina_Bool unknow)
-{
- Eet_Union *u = data;
- int i;
-
- if (unknow) return EINA_FALSE;
-
- for (i = 0; eet_mapping[i].name; ++i)
- if (strcmp(eet_mapping[i].name, type) == 0)
- {
- *u = eet_mapping[i].u;
- return EINA_TRUE;
- }
-
- return EINA_FALSE;
-}
/* increment this whenever a new set of config values are added but the users
* config doesn't need to be wiped - simply new values need to be put in
*/
-#define E_CONFIG_FILE_GENERATION 0x0145
+#define E_CONFIG_FILE_GENERATION 0x0146
#define E_CONFIG_FILE_VERSION ((E_CONFIG_FILE_EPOCH << 16) | E_CONFIG_FILE_GENERATION)
#define E_EVAS_ENGINE_DEFAULT 0
int mouse_accel_denominator; // GUI
int mouse_accel_threshold; // GUI
- Eina_List *screen_info; // GUI
+ E_Randr_Serialized_Setup *randr_serialized_setup; // GUI
int border_raise_on_mouse_action; // GUI
int border_raise_on_focus; // GUI
#define Ecore_X_Randr_Unset -1
/*
+ * Save mechanism:
+ * Single monitor:
+ * - Save monitor using the resolution
+ *
+ * Multiple monitors:
+ * - Use the EDID information to make sure we restore the right monitor.
+ *
* TODO:
* -fix output policies above and left
*/
static void _e_randr_crtc_info_free(E_Randr_Crtc_Info *crtc_info);
static Eina_Bool _e_randr_screen_outputs_init(void);
static Eina_Bool _e_randr_screen_crtcs_init(void);
+
+static Eina_Bool _e_randr_try_restore_11(E_Randr_Screen_Info_11 *si_11);
+static Eina_Bool _e_randr_try_restore_12(E_Randr_Screen_Info_12 *si_12);
+EAPI void e_randr_store_configuration(E_Randr_Screen_Info *screen_info);
+EAPI Eina_Bool e_randr_try_restore_configuration(E_Randr_Screen_Info *screen_info);
static Eina_Bool _e_randr_output_modes_add(E_Randr_Output_Info *output_info);
static void _e_randr_notify_crtc_mode_change(E_Randr_Crtc_Info *crtc_info);
static void _e_randr_notify_output_change(E_Randr_Output_Info *output_info);
static void _e_randr_output_info_set(E_Randr_Output_Info *output_info);
static void _e_randr_crtc_info_set(E_Randr_Crtc_Info *crtc_info);
static const E_Randr_Crtc_Info *_e_randr_policy_crtc_get(E_Randr_Crtc_Info* but, E_Randr_Crtc_Info *hint, Ecore_X_Randr_Output_Policy policy);
-//static Eina_Bool _e_randr_outputs_connected(Eina_List *outputs_info);
static Ecore_X_Randr_Output *_e_randr_outputs_to_array(Eina_List *outputs_info);
-//static int _e_randr_config_find_suiting_config_11(E_Randr_Screen_Restore_Info_11** restore_info);
-static E_Randr_Screen_Restore_Info_12 * _e_randr_config_find_suiting_config_12(void);
-//static Eina_Bool _e_randr_config_enable_11(int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation);
-//static Eina_Bool _e_randr_config_enable_12(const E_Randr_Screen_Restore_Info_12 *restore_info);
+static E_Randr_Serialized_Setup_12 * _e_randr_config_find_suiting_config_12(void);
static Eina_Bool _e_randr_try_enable_output(E_Randr_Output_Info *output_info, Eina_Bool force);
static void _e_randr_crtcs_possible_output_update(E_Randr_Output_Info *output_info);
static void _e_randr_crtc_outputs_refs_update(E_Randr_Crtc_Info *crtc_info);
static void _e_randr_output_hw_info_free(E_Randr_Output_Info *output_info);
static Eina_Bool _e_randr_outputs_are_clones(E_Randr_Output_Info *output_info, Eina_List *outputs);
-E_Randr_Screen_Info *e_randr_screen_info = NULL;
+EAPI E_Randr_Screen_Info *e_randr_screen_info = NULL;
static Eina_List *_e_randr_event_handlers = NULL;
EINTERN Eina_Bool
.crtcs = NULL,
.outputs = NULL,
.primary_output = NULL,
- .output_policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE,
.alignment = ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE
};
.connector_type = Ecore_X_Randr_Unset,
.connection_status = ECORE_X_RANDR_CONNECTION_STATUS_DISCONNECTED,
.subpixel_order= Ecore_X_Randr_Unset,
- .compatible_outputs = NULL
+ .compatible_outputs = NULL,
+ .policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE
};
if (!(ret = malloc(sizeof(E_Randr_Output_Info) * nrequested))) return NULL;
else if (type == ECORE_X_EVENT_RANDR_OUTPUT_CHANGE)
{
Ecore_X_Event_Randr_Output_Change *event = ev;
- const E_Randr_Screen_Restore_Info_12 *restore_info;
+ const E_Randr_Serialized_Setup_12 *restore_info;
E_Randr_Output_Info* output_info = NULL;
/* available information:
struct _Ecore_X_Event_Randr_Output_Change
_e_randr_output_info_hw_info_set(output_info);
//make the crtcs aware of their possibly new output
_e_randr_crtcs_possible_output_update(output_info);
+ /*
if ((restore_info = _e_randr_config_find_suiting_config_12()))
//maybe we have a suiting configuration
//_e_randr_config_enable_12(restore_info);
;
else
+ */
enabled = _e_randr_try_enable_output(output_info, EINA_FALSE); //maybe give a success message?
}
_e_randr_notify_output_change(output_info);
_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);
};
*/
}
+ e_randr_try_restore_configuration(e_randr_screen_info);
on_exit:
return ECORE_CALLBACK_RENEW;
}
return ret;
}
-/*
-static Eina_Bool
-_e_randr_outputs_connected(Eina_List *outputs_info)
+// Setup store functions
+ Eina_Bool
+_e_randr_copy_mode_info(Ecore_X_Randr_Mode_Info *dest, Ecore_X_Randr_Mode_Info *src)
{
- Eina_List *iter;
- E_Randr_Output_Info *output_info;
- EINA_LIST_FOREACH(outputs_info, iter, output_info)
- if (output_info->connection_status == ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) return EINA_TRUE;
+ 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;
}
-static Eina_Bool
-_e_randr_config_enable_11(int size_index, Ecore_X_Randr_Refresh_Rate refresh_rate, Ecore_X_Randr_Orientation orientation)
+ 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)
{
- E_Randr_Screen_Info_11 *current_info_11;
+ Eina_List *iter, *list = NULL;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Output_Policy *sop;
+ char *name;
+
+ EINA_LIST_FOREACH(outputs, iter, oi)
+ {
+ if (!oi->name || (oi->name_length <= 0)) continue;
+ if (!(sop = E_NEW(E_Randr_Serialized_Output_Policy, 1))
+ || !(sop->name = malloc(oi->name_length + 1))
+ || !(strncpy(sop->name, oi->name, oi->name_length)))
+ goto _e_randr_create_outputs_policies_list_fail_free_list;
+ sop->name_length = oi->name_length;
+ sop->policy = oi->policy;
+ if (!(list = eina_list_append(list, sop)))
+ goto _e_randr_create_outputs_policies_list_fail_free_list;
+ }
- if (E_RANDR_NO_11 || (size_index < 0) || (refresh_rate < 0) ||
- (orientation < 0)) return EINA_FALSE;
+ 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;
+}
- if (!ecore_x_randr_screen_primary_output_size_set(e_randr_screen_info->root, size_index)
- || !ecore_x_randr_screen_primary_output_orientation_set(e_randr_screen_info->root, orientation)
- || !ecore_x_randr_screen_primary_output_refresh_rate_set(e_randr_screen_info->root, size_index, refresh_rate)) return EINA_FALSE;
+void
+_e_randr_free_serialized_output_policy(E_Randr_Serialized_Output_Policy *sop)
+{
+ if (!sop) return;
+ if (sop->name) free(sop->name);
+ free(sop);
+}
- //TODO: move this to the screen event later.
- current_info_11 = e_randr_screen_info->rrvd_info.randr_info_11;
+ Eina_List
+*_e_randr_update_serialized_outputs_policies(E_Randr_Screen_Info_12 *si_12, Eina_List *sops)
+{
+ E_Randr_Serialized_Output_Policy *sop;
- current_info_11->csize_index = size_index;
- current_info_11->corientation = orientation;
- current_info_11->current_rate = refresh_rate;
+ EINA_LIST_FREE(sops, sop)
+ {
+ _e_randr_free_serialized_output_policy(sop);
+ }
- return EINA_TRUE;
+ return _e_randr_create_outputs_policies_list(si_12->outputs);
}
-static Eina_Bool
-_e_randr_config_enable_12(const E_Randr_Screen_Restore_Info_12 *restore_info __UNUSED__)
-{
- if (E_RANDR_NO_12 || !restore_info) return EINA_FALSE;
- E_Randr_Screen_Info_12 *current_info_12;
- E_Randr_Screen_Restore_Info_12 *restore_info_12 = NULL;
- E_Randr_Crtc_Restore_Info *crtc_restore_info = NULL;
- E_Randr_Crtc_Info *crtc_info;
- E_Randr_Output_Info *output_info;
- Eina_List *crtc_restore_iter;
-
- current_info_12 = (e_randr_screen_info->rrvd_info).randr_info_12;
- EINA_LIST_FOREACH(restore_info_12->crtcs, crtc_restore_iter, crtc_restore_info)
- {
- ;
- }
- current_info_12->alignment = restore_info_12->alignment;
- current_info_12->output_policy = restore_info_12->output_policy;
- return EINA_TRUE;
- return EINA_FALSE;
+ 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;
}
-static int
-_e_randr_config_find_suiting_config_11(E_Randr_Screen_Restore_Info_11 **restore_info)
+ E_Randr_Edid_Hash
+*_e_randr_create_edid_hash(E_Randr_Output_Info *output_info)
{
- E_RANDR_NO_11_RET(Ecore_X_Randr_None);
- Eina_List *cfg_screen_restore_info_iter;
- E_Randr_Screen_Restore_Info *screen_restore_info;
+ E_Randr_Edid_Hash *edid_hash;
- E_Randr_Screen_Restore_Info_11 *restore_info_11;
- Ecore_X_Randr_Screen_Size_MM *sizes;
- Ecore_X_Randr_Refresh_Rate *rates = NULL;
- int i = 0, j = 0, nsizes = 0, nrates = 0;
+ if (!output_info || (output_info->edid_hash.hash == 0) || !(edid_hash = malloc(sizeof(E_Randr_Edid_Hash)))) return NULL;
+
+ edid_hash->hash = output_info->edid_hash.hash;
+
+ return edid_hash;
+}
+
+ E_Randr_Serialized_Output
+*_e_randr_create_serialized_output(E_Randr_Output_Info *output_info)
+{
+ E_Randr_Serialized_Output *so;
+ char *name;
+
+ if (!output_info || !output_info->name || (output_info->name_length <= 0) || !(so = malloc(sizeof(E_Randr_Serialized_Output)))) return NULL;
+
+ if (!(name = malloc(output_info->name_length))
+ || !strncpy(so->name, output_info->name, output_info->name_length))
+ goto _e_randr_create_serialized_outputs_fail_free_so;
+ so->name_length = output_info->name_length;
+ so->edid_hash.hash = output_info->edid_hash.hash;
+ so->backlight_level = output_info->backlight_level;
+
+ return so;
+
+_e_randr_create_serialized_outputs_fail_free_so:
+ free(so);
+ return NULL;
+}
+
+ void
+_e_randr_free_serialized_output(E_Randr_Serialized_Output *so)
+{
+ if (so->name) free(so->name);
+ free(so);
+}
+
+ E_Randr_Serialized_Crtc
+*_e_randr_create_serialized_crtc(E_Randr_Crtc_Info *crtc_info)
+{
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Serialized_Output *so;
+ E_Randr_Output_Info *output_info;
+ Eina_List *iter;
+ char *output_name;
+ size_t len;
+
+ if (!(sc = E_NEW(E_Randr_Serialized_Crtc, 1))) return NULL;
+ if(!_e_randr_copy_mode_info(&sc->mode_info, crtc_info->current_mode)) goto _e_randr_create_serialized_crtc_free_sc;
+ if(!(sc->possible_outputs_names = _e_randr_create_possible_outputs_names_list(crtc_info->possible_outputs))) goto _e_randr_create_serialized_crtc_free_mode_sc;
+ //Create list of serialized outputs
+ EINA_LIST_FOREACH(crtc_info->outputs, iter, output_info)
+ {
+ if(!(so = _e_randr_create_serialized_output(output_info))
+ || !(sc->serialized_outputs = eina_list_append(sc->serialized_outputs, so))) goto _e_randr_create_serialized_crtc_free_outputs_list_sc;
+ }
+ sc->pos.x = crtc_info->geometry.x;
+ sc->pos.y = crtc_info->geometry.y;
+ sc->orientation = crtc_info->current_orientation;
+
+ return sc;
+
+_e_randr_create_serialized_crtc_free_outputs_list_sc:
+ EINA_LIST_FREE(sc->possible_outputs_names, output_name)
+ {
+ if (output_name) free(output_name);
+ }
+ EINA_LIST_FREE(sc->serialized_outputs, so)
+ {
+ if (so) _e_randr_free_serialized_output(so);
+ }
+_e_randr_create_serialized_crtc_free_mode_sc:
+ _e_randr_free_serialized_mode_info(&sc->mode_info);
+_e_randr_create_serialized_crtc_free_sc:
+ E_FREE(sc);
+
+ return NULL;
+}
+
+ void
+_e_randr_free_serialized_crtc(E_Randr_Serialized_Crtc *sc)
+{
+ E_Randr_Serialized_Output *so;
+ char *name;
+
+ EINA_LIST_FREE(sc->serialized_outputs, so)
+ _e_randr_free_serialized_output(so);
+ _e_randr_free_serialized_mode_info(&sc->mode_info);
+ EINA_LIST_FREE(sc->possible_outputs_names, name)
+ free(name);
+ free(sc);
+}
+
+ E_Randr_Serialized_Setup_11
+*_e_randr_create_serialized_setup_11(E_Randr_Screen_Info_11 *screen_info_11)
+{
+ E_Randr_Serialized_Setup_11 *ss;
+ Ecore_X_Randr_Screen_Size_MM* size;
+
+ if (!(ss = malloc(sizeof(*ss)))) return NULL;
+ if(!(size = (Ecore_X_Randr_Screen_Size_MM*)eina_list_data_get(eina_list_nth(screen_info_11->sizes, screen_info_11->csize_index)))) goto _e_randr_create_serialized_setup_11_failed_free_ss;
+ ss->size.width = size->width;
+ ss->size.height = size->height;
+ ss->refresh_rate = screen_info_11->current_rate;
+ ss->orientation = screen_info_11->corientation;
+
+ return ss;
+
+_e_randr_create_serialized_setup_11_failed_free_ss:
+ free(ss);
+}
+
+ E_Randr_Serialized_Setup_11
+*_e_randr_update_serialized_setup_11(E_Randr_Serialized_Setup_11 *ss_11, E_Randr_Screen_Info_11 *si_11)
+{
+ Ecore_X_Randr_Screen_Size_MM* size;
+
+ if (ss_11)
+ {
+ if(!(size = (Ecore_X_Randr_Screen_Size_MM*)eina_list_data_get(eina_list_nth(si_11->sizes, si_11->csize_index)))) return NULL;
+ if (!memcpy(&ss_11->size, size, sizeof(Ecore_X_Randr_Screen_Size_MM)))
+ goto _e_randr_update_serialized_setup_11_failed_free_ss;
+ ss_11->refresh_rate = si_11->current_rate;
+ ss_11->orientation = si_11->corientation;
+ }
+ else
+ ss_11 = _e_randr_create_serialized_setup_11(si_11);
+
+ return ss_11;
+
+_e_randr_update_serialized_setup_11_failed_free_ss:
+ free(ss_11);
+ return NULL;
+}
+
+ E_Randr_Serialized_Setup_12
+*_e_randr_create_serialized_setup_12(E_Randr_Screen_Info_12 *screen_info_12)
+{
+ E_Randr_Serialized_Setup_12 *ss;
+ Eina_List *iter;
+ E_Randr_Crtc_Info *ci;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (!(ss = E_NEW(E_Randr_Serialized_Setup_12, 1))) return NULL;
+
+ ss->timestamp = ecore_time_get();
+
+ //Add CRTCs and their configuration
+ EINA_LIST_FOREACH(screen_info_12->crtcs, iter, ci)
+ {
+ //ignore disabled crtcs for now
+ if (!ci->current_mode) continue;
+
+ if (!(sc = _e_randr_create_serialized_crtc(ci))
+ || !(ss->serialized_crtcs = eina_list_append(ss->serialized_crtcs, sc)))
+ goto _e_randr_create_serialized_setup_12_failed_free_list_ss;
+ }
+
+ /*
+ * Add EDID hashes of connected and enabled
+ * outputs for easier comparison during
+ * setup restoration
+ */
+ EINA_LIST_FOREACH(screen_info_12->outputs, iter, oi)
+ {
+ if ((oi->connection_status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED) || !oi->crtc || !oi->crtc->current_mode)
+ continue;
+ if (!(edid_hash = _e_randr_create_edid_hash(oi)) || !(ss->serialized_edid_hashes = eina_list_append(ss->serialized_edid_hashes, edid_hash)))
+ goto _e_randr_create_serialized_setup_12_failed_free_output_list_crtc_list_ss;
+ }
- EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info)
+ 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)
{
- // 'screen_restore_info' should _never_ be NULL, since this functions shouldn't be called due to randr init failing.
- if (!screen_restore_info) continue;
- if (screen_restore_info->randr_version != ECORE_X_RANDR_1_1) continue;
- restore_info_11 = screen_restore_info->rrvd_restore_info.restore_info_11;
- if((sizes = ecore_x_randr_screen_primary_output_sizes_get(e_randr_screen_info->root, &nsizes)))
+ _e_randr_free_serialized_crtc(sc);
+ }
+_e_randr_create_serialized_setup_12_failed_free_ss:
+ free(ss);
+}
+
+E_Randr_Serialized_Setup_12
+*_e_randr_find_matching_serialized_setup(Eina_List *setups_12, E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ Eina_List *setups_iter, *r_iter, *s_iter;
+ Eina_Bool found = EINA_FALSE;
+ E_Randr_Edid_Hash *edid_hash;
+ E_Randr_Output_Info *oi;
+
+ if (!setups_12 || !si_12) return NULL;
+
+ EINA_LIST_FOREACH(setups_12, setups_iter, ss_12)
+ {
+ EINA_LIST_FOREACH(si_12->outputs, r_iter, oi)
{
- for (i = 0; i < nsizes; i++)
+ //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 ((restore_info_11->size.width == sizes[i].width)
- && (restore_info_11->size.height == sizes[i].height))
+ if (oi->edid_hash.hash == edid_hash->hash)
{
- if ((rates = ecore_x_randr_screen_primary_output_refresh_rates_get(e_randr_screen_info->root, i, &nrates)))
- {
- for (j = 0; j < nrates; j++)
- if (rates[j] == restore_info_11->refresh_rate)
- {
- if (restore_info) *restore_info = restore_info_11;
- free(rates);
- free(sizes);
- return i;
- }
- free(rates);
- }
+ found = EINA_TRUE;
+ break;
}
}
- if (sizes) free(sizes);
+ if (!found)
+ break;
}
+ if (found)
+ break;
}
- return Ecore_X_Randr_Unset;
+ if (found)
+ return ss_12;
+
+ return NULL;
}
-*/
-/**
- * @Brief find configuration with the most hardware currently available
- */
-static E_Randr_Screen_Restore_Info_12 *
-_e_randr_config_find_suiting_config_12(void)
+ void
+_e_randr_free_serialized_setup_12(E_Randr_Serialized_Setup_12 *ss_12)
{
- //TODO: write geometry based loading
- /*
- Eina_List *cfg_screen_restore_info_iter;
- E_Randr_Screen_Restore_Info *screen_restore_info;
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Edid_Hash *edid_hash;
- E_Randr_Screen_Info_12 *current_info_12;
- E_Randr_Screen_Restore_Info_12 *restore_info_12, *most_matches = NULL;
- E_Randr_Output_Info *output_info;
- E_Randr_Crtc_Restore_Info *crtc_restore_info;
- Ecore_X_Randr_Output *outputs_xids;
- Ecore_X_Randr_Crtc *crtcs_xids;
- Eina_List *restore_info_12_iter, *output_iter, *restore_crtcs_iter;
+ if (!ss_12) return;
- if (e_randr_screen_info && e_config && e_config->screen_info)
- {
+ 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);
- EINA_LIST_FOREACH(e_config->screen_info, cfg_screen_restore_info_iter, screen_restore_info)
- {
- if (screen_restore_info->randr_version < ECORE_X_RANDR_1_2) continue;
+ free(ss_12);
+}
- //HINT: use eina_list_clone and a sort callback to find proper
- //crtcs and outputs
+ Eina_List
+*_e_randr_update_serialized_setup_12(Eina_List *setups_12, E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ E_Randr_Serialized_Output *so;
+ E_Randr_Output_Info *oi;
+ E_Randr_Edid_Hash *edid_hash;
+
+ if (setups_12)
+ {
+ /*
+ * try to find the setup with the same monitors
+ * connected in order to replace it
+ */
+ if((ss_12 = _e_randr_find_matching_serialized_setup(setups_12, si_12)))
+ _e_randr_free_serialized_setup_12(ss_12);
+ }
+ ss_12 = _e_randr_create_serialized_setup_12(si_12);
+ setups_12 = eina_list_append(setups_12, ss_12);
- //current_info_12 = e_randr_screen_info->rrvd_info.randr_info_12;
- }
+ return setups_12;
+}
- }
- */
+ E_Randr_Serialized_Setup
+*_e_randr_create_serialized_setup(E_Randr_Screen_Info *screen_info)
+{
+ E_Randr_Serialized_Setup *ss;
+ E_Randr_Serialized_Setup_12 *ss_12;
+
+ if (!(ss = E_NEW(E_Randr_Serialized_Setup, 1))) return NULL;
+ if ((screen_info->randr_version == ECORE_X_RANDR_1_1) && !(ss->serialized_setup_11 = _e_randr_create_serialized_setup_11(screen_info->rrvd_info.randr_info_11))) goto _e_randr_create_serialized_setup_failed_free_ss;
+ if ((screen_info->randr_version >= ECORE_X_RANDR_1_2))
+ {
+ if (!(ss_12 = _e_randr_create_serialized_setup_12(screen_info->rrvd_info.randr_info_12))
+ || !(ss->serialized_setups_12 = eina_list_append(ss->serialized_setups_12, ss_12)))
+ goto _e_randr_create_serialized_setup_failed_free_ss;
+ }
+
+ return ss;
+
+_e_randr_create_serialized_setup_failed_free_ss:
+ free(ss);
+}
+
+ EAPI void
+e_randr_store_configuration(E_Randr_Screen_Info *screen_info)
+{
+ if (E_RANDR_NO_11) return;
+
+ if (!e_config->randr_serialized_setup)
+ {
+ e_config->randr_serialized_setup = _e_randr_create_serialized_setup(screen_info);
+ e_config_save_queue();
+ return;
+ }
+
+ if (screen_info->randr_version == ECORE_X_RANDR_1_1)
+ {
+ e_config->randr_serialized_setup->serialized_setup_11 = _e_randr_update_serialized_setup_11(e_config->randr_serialized_setup->serialized_setup_11, screen_info->rrvd_info.randr_info_11);
+ }
+ else if (screen_info->randr_version >= ECORE_X_RANDR_1_2)
+ {
+ e_config->randr_serialized_setup->serialized_setups_12 = _e_randr_update_serialized_setup_12(e_config->randr_serialized_setup->serialized_setups_12, screen_info->rrvd_info.randr_info_12);
+
+ //Also, update output policies
+ e_config->randr_serialized_setup->serialized_outputs_policies = _e_randr_update_serialized_outputs_policies(screen_info->rrvd_info.randr_info_12, e_config->randr_serialized_setup->serialized_outputs_policies);
+ }
+ e_config_save_queue();
+}
+
+//setup restore functions
+ EAPI Eina_Bool
+e_randr_try_restore_configuration(E_Randr_Screen_Info *si)
+{
+ if (!e_config || !e_config->randr_serialized_setup) return EINA_FALSE;
+
+ if (si->randr_version == ECORE_X_RANDR_1_1)
+ return _e_randr_try_restore_11(si->rrvd_info.randr_info_11);
+ else if (si->randr_version >= ECORE_X_RANDR_1_2)
+ return _e_randr_try_restore_12(si->rrvd_info.randr_info_12);
+
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+_e_randr_try_restore_11(E_Randr_Screen_Info_11 *si_11)
+{
+ E_Manager *man;
+ Eina_List *iter;
+ Ecore_X_Randr_Screen_Size_MM *stored_size, *size;
+ int i = 0;
+
+ if (!e_config->randr_serialized_setup->serialized_setup_11) return EINA_FALSE;
+ stored_size = &e_config->randr_serialized_setup->serialized_setup_11->size;
+ EINA_LIST_FOREACH(si_11->sizes, iter, size)
+ {
+ if ((stored_size->width == size->width)
+ && (stored_size->height == size->height)
+ && (stored_size->width_mm == size->width_mm)
+ && (stored_size->height_mm == size->height_mm))
+ {
+ man = e_manager_current_get();
+ return ecore_x_randr_screen_primary_output_size_set(man->root, i);
+ }
+ i++;
+ }
+
+ return EINA_FALSE;
+}
+
+ E_Randr_Crtc_Info
+*_e_randr_find_matching_crtc(Eina_List *crtcs, E_Randr_Serialized_Crtc *sc)
+{
+ Eina_List *iter, *s_name_iter, *p_output_iter;
+ E_Randr_Crtc_Info *ci;
+ E_Randr_Output_Info *oi;
+ char *s_output_name;
+ Eina_Bool name_found;
+
+ EINA_LIST_FOREACH(crtcs, iter, ci)
+ {
+ if (eina_list_count(ci->possible_outputs) != eina_list_count(sc->possible_outputs_names))
+ continue;
+ EINA_LIST_FOREACH(sc->possible_outputs_names, s_name_iter, s_output_name)
+ {
+ name_found = EINA_FALSE;
+ EINA_LIST_FOREACH(ci->possible_outputs, p_output_iter, oi)
+ {
+ if (!strncmp(s_output_name, oi->name, oi->name_length))
+ {
+ name_found = EINA_TRUE;
+ break;
+ }
+ }
+ if (!name_found)
+ break;
+ }
+ if (name_found)
+ break;
+ }
+ if (name_found)
+ return ci;
+ else
+ return NULL;
+}
+
+ Eina_List
+*_e_randr_find_matching_outputs(Eina_List *sois, Eina_List *ois)
+{
+ Eina_List *r_output_iter, *s_output_iter, *list = NULL;
+ E_Randr_Output_Info *oi;
+ E_Randr_Serialized_Output *so;
+
+ EINA_LIST_FOREACH(sois, s_output_iter, so)
+ {
+ EINA_LIST_FOREACH(ois, r_output_iter, oi)
+ {
+ if (so->edid_hash.hash == oi->edid_hash.hash)
+ {
+ list = eina_list_append(list, oi);
+ break;
+ }
+ }
+ }
+ if (list && (eina_list_count(sois) != eina_list_count(list)))
+ {
+ eina_list_free(list);
+ list = NULL;
+ }
+
+ return list;
+}
+
+ Ecore_X_Randr_Mode_Info
+*_e_randr_find_matching_mode_info(Eina_List *modes, Ecore_X_Randr_Mode_Info *mode)
+{
+ Eina_List *iter;
+ Ecore_X_Randr_Mode_Info *mi = NULL;
+
+ EINA_LIST_FOREACH(modes, iter, mi)
+ {
+ if ((mode->width == mi->width)
+ && (mode->height == mi->height)
+ && (mode->dotClock == mi->dotClock)
+ && (mode->hSyncStart == mi->hSyncStart)
+ && (mode->hSyncEnd == mi->hSyncEnd)
+ && (mode->hTotal == mi->hTotal)
+ && (mode->hSkew == mi->hSkew)
+ && (mode->vSyncStart == mi->vSyncStart)
+ && (mode->vSyncEnd == mi->vSyncEnd)
+ && (mode->vTotal == mi->vTotal)
+ && (mode->nameLength == mi->nameLength)
+ && !strncpy(mode->name, mi->name, mode->nameLength)
+ && (mode->modeFlags == mi->modeFlags))
+ return mi;
+ }
return NULL;
}
-static Ecore_X_Randr_Output *
+ Eina_Bool
+_e_randr_try_restore_12(E_Randr_Screen_Info_12 *si_12)
+{
+ E_Randr_Serialized_Setup_12 *ss_12;
+ E_Randr_Serialized_Crtc *sc;
+ E_Randr_Crtc_Info *ci;
+ Ecore_X_Randr_Output *outputs_array;
+ Ecore_X_Randr_Mode_Info *mi;
+ Eina_List *iter, *outputs_list;
+ Eina_Bool ret = EINA_TRUE;
+ E_Manager *man;
+
+ if(!(ss_12 = _e_randr_find_matching_serialized_setup(e_config->randr_serialized_setup->serialized_setups_12, si_12))) return EINA_FALSE;
+
+ man = e_manager_current_get();
+
+ EINA_LIST_FOREACH(ss_12->serialized_crtcs, iter, sc)
+ {
+ ci = _e_randr_find_matching_crtc(si_12->crtcs, sc);
+ outputs_list = _e_randr_find_matching_outputs(si_12->outputs, sc->serialized_outputs);
+ outputs_array = _e_randr_outputs_to_array(outputs_list);
+ mi = _e_randr_find_matching_mode_info(si_12->modes, &sc->mode_info);
+ ret &= ecore_x_randr_crtc_mode_set(man->root, ci->xid, outputs_array, eina_list_count(outputs_list), mi->xid);
+ ret &= ecore_x_randr_crtc_pos_set(man->root, ci->xid, sc->pos.x, sc->pos.y);
+ }
+ return ret;
+}
+
+//Utility functions
+ static Ecore_X_Randr_Output *
_e_randr_outputs_to_array(Eina_List *outputs_info)
{
Ecore_X_Randr_Output *ret = NULL;
if (!outputs_info || !(ret = malloc(sizeof(Ecore_X_Randr_Output) * eina_list_count(outputs_info)))) return NULL;
EINA_LIST_FOREACH(outputs_info, output_iter, output_info)
- /* output_info == NULL should _not_ be possible! */
+ /* output_info == NULL should _not_ be possible! */
ret[i++] = output_info ? output_info->xid : Ecore_X_Randr_None;
return ret;
}
if (!usable_crtc) return EINA_FALSE;
//get the CRTC we will refer to, dependend on policy
- switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy)
+ switch (output_info->policy)
{
case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
return EINA_TRUE;
_e_randr_crtc_move_policy(E_Randr_Crtc_Info *new_crtc)
{
const E_Randr_Crtc_Info *crtc_rel;
+ E_Randr_Output_Info *last_output = NULL;
int dx = Ecore_X_Randr_None, dy = Ecore_X_Randr_None;
Eina_Bool ret = EINA_TRUE;
+ //use the policy of the new crtc's last output
+ last_output = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(new_crtc->outputs));
+ if (!last_output) return EINA_FALSE;
//get the crtc we will place our's relative to. If it's NULL, this is the
//only output attached, work done.
- if(!(crtc_rel = _e_randr_policy_crtc_get(new_crtc, NULL, e_randr_screen_info->rrvd_info.randr_info_12->output_policy))) return EINA_TRUE;
+ if(!(crtc_rel = _e_randr_policy_crtc_get(new_crtc, NULL, last_output->policy))) return EINA_TRUE;
//following is policy dependend.
- switch (e_randr_screen_info->rrvd_info.randr_info_12->output_policy)
+ switch (last_output->policy)
{
case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
dy = (crtc_rel->geometry.y - new_crtc->geometry.h);
default:
break;
}
- ret &= ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, new_crtc->xid, crtc_rel->xid, e_randr_screen_info->rrvd_info.randr_info_12->output_policy, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
+ ret &= ecore_x_randr_crtc_pos_relative_set(e_randr_screen_info->root, new_crtc->xid, crtc_rel->xid, last_output->policy, e_randr_screen_info->rrvd_info.randr_info_12->alignment);
return ret;
}
_e_randr_output_modes_add(output_info);
output_info->edid = ecore_x_randr_output_edid_get(e_randr_screen_info->root, output_info->xid, &output_info->edid_length);
+ if (output_info->edid_length > 0)
+ output_info->edid_hash.hash = eina_hash_superfast(output_info->edid, output_info->edid_length);
//get the outputs we can use on the same CRTC alongside this one.
if ((outputs = ecore_x_randr_output_clones_get(e_randr_screen_info->root, output_info->xid, &num)))
{
}
free(crtcs);
}
+ else
+ {
+ fprintf(stderr, "E_RANDR: Output %x does not have a single possible CRTC.\n", output_info->xid);
+ }
}
/*
#ifdef E_TYPEDEFS
typedef struct _E_Randr_Crtc_Info E_Randr_Crtc_Info;
+typedef struct _E_Randr_Edid_Hash E_Randr_Edid_Hash;
typedef struct _E_Randr_Output_Info E_Randr_Output_Info;
typedef struct _E_Randr_Screen_Info_11 E_Randr_Screen_Info_11;
typedef struct _E_Randr_Screen_Info_12 E_Randr_Screen_Info_12;
typedef union _E_Randr_Screen_RRVD_Info E_Randr_Screen_RRVD_Info;
typedef struct _E_Randr_Screen_Info E_Randr_Screen_Info;
-typedef struct _E_Randr_Output_Edid_Hash E_Randr_Output_Edid_Hash;
-typedef struct _E_Randr_Output_Restore_Info E_Randr_Output_Restore_Info;
-typedef struct _E_Randr_Crtc_Restore_Info E_Randr_Crtc_Restore_Info;
-typedef struct _E_Randr_Screen_Restore_Info_11 E_Randr_Screen_Restore_Info_11;
-typedef struct _E_Randr_Screen_Restore_Info_12 E_Randr_Screen_Restore_Info_12;
-typedef union _E_Randr_Screen_Restore_Info_Union E_Randr_Screen_Restore_Info_Union;
-typedef struct _E_Randr_Screen_Restore_Info E_Randr_Screen_Restore_Info;
+typedef struct _E_Randr_Serialized_Output_Policy E_Randr_Serialized_Output_Policy;
+typedef struct _E_Randr_Serialized_Output E_Randr_Serialized_Output;
+typedef struct _E_Randr_Serialized_Crtc E_Randr_Serialized_Crtc;
+typedef struct _E_Randr_Serialized_Setup_11 E_Randr_Serialized_Setup_11;
+typedef struct _E_Randr_Serialized_Setup_12 E_Randr_Serialized_Setup_12;
+typedef struct _E_Randr_Serialized_Setup E_Randr_Serialized_Setup;
+
+EAPI void e_randr_store_configuration(E_Randr_Screen_Info *screen_info);
#else
#ifndef E_RANDR_H
#define E_RANDR_H
-struct _E_Randr_Crtc_Info
+struct _E_Randr_Crtc_Info
{
Ecore_X_ID xid;
Eina_Rectangle geometry;
Ecore_X_Randr_Mode_Info *current_mode;
};
-struct _E_Randr_Output_Info
+struct _E_Randr_Edid_Hash
+{
+ int hash;
+};
+
+struct _E_Randr_Output_Info
{
Ecore_X_ID xid;
char *name;
int connector_number;
Ecore_X_Randr_Connector_Type connector_type;
Ecore_X_Randr_Connection_Status connection_status;
+ Ecore_X_Randr_Output_Policy policy;
/*
* Attached Monitor specific:
*/
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;
Ecore_X_Randr_Refresh_Rate current_rate;
};
-struct _E_Randr_Screen_Info_12
+struct _E_Randr_Screen_Info_12
{
Ecore_X_Randr_Screen_Size min_size;
Ecore_X_Randr_Screen_Size max_size;
Eina_List *crtcs;
Eina_List *outputs;
E_Randr_Output_Info *primary_output;
- Ecore_X_Randr_Output_Policy output_policy;
Ecore_X_Randr_Relative_Alignment alignment;
};
//RRVD == RandR(R) Version Depended
-union _E_Randr_Screen_RRVD_Info
+union _E_Randr_Screen_RRVD_Info
{
E_Randr_Screen_Info_11 *randr_info_11;
E_Randr_Screen_Info_12 *randr_info_12;
};
-struct _E_Randr_Screen_Info
+struct _E_Randr_Screen_Info
{
Ecore_X_Window root;
int randr_version;
};
//Following stuff is just for configuration purposes
-struct _E_Randr_Output_Edid_Hash {
- int hash;
-};
-struct _E_Randr_Output_Restore_Info
+struct _E_Randr_Serialized_Output_Policy
{
- E_Randr_Output_Edid_Hash edid_hash;
- double backlight_level;
+ char *name;
+ int name_length;
+ Ecore_X_Randr_Output_Policy policy;
};
-struct _E_Randr_Crtc_Restore_Info
+struct _E_Randr_Serialized_Output
{
- Eina_Rectangle geometry;
- Ecore_X_Randr_Orientation orientation;
- //list of the outputs;
- Eina_List *outputs;
+ char *name;
+ int name_length;
+ E_Randr_Edid_Hash edid_hash;
+ double backlight_level;
};
-struct _E_Randr_Screen_Restore_Info_11
+struct _E_Randr_Serialized_Crtc
{
- Ecore_X_Randr_Screen_Size size;
- Ecore_X_Randr_Refresh_Rate refresh_rate;
+ //List of E_Randr_Serialized_Output objects that were used on the same output
+ Eina_List *serialized_outputs;
+ //the serialized mode_info misses its xid value
+ Ecore_X_Randr_Mode_Info mode_info;
+ Evas_Coord_Point pos;
+ //List of all possible outputs' names
+ //e.g. "LVDS", "CRT-0", "VGA"
+ Eina_List *possible_outputs_names;
Ecore_X_Randr_Orientation orientation;
};
-struct _E_Randr_Screen_Restore_Info_12
+struct _E_Randr_Serialized_Setup_12
{
- Eina_List *outputs_edid_hashes;
- int noutputs;
- Eina_List *crtcs;
- Ecore_X_Randr_Output_Policy output_policy;
- Ecore_X_Randr_Relative_Alignment alignment;
+ double timestamp;
+ //List of E_Randr_Serialized_Crtc objects
+ Eina_List *serialized_crtcs;
+ /*
+ * List of E_Randr_Edid_Hash elements of monitors,
+ * that were enabled, when the setup was stored
+ */
+ Eina_List *serialized_edid_hashes;
};
-union _E_Randr_Screen_Restore_Info_Union
+struct _E_Randr_Serialized_Setup_11
{
- E_Randr_Screen_Restore_Info_11 *restore_info_11;
- Eina_List *restore_info_12;
+ Ecore_X_Randr_Screen_Size_MM size;
+ Ecore_X_Randr_Refresh_Rate refresh_rate;
+ Ecore_X_Randr_Orientation orientation;
};
-struct _E_Randr_Screen_Restore_Info
+struct _E_Randr_Serialized_Setup
{
- int randr_version;
- E_Randr_Screen_Restore_Info_Union rrvd_restore_info;
+ E_Randr_Serialized_Setup_11 *serialized_setup_11;
+ //List of E_Randr_Serialized_Setup_12 objects
+ Eina_List *serialized_setups_12;
+ //List of E_Randr_Serialized_Output_Policy objects
+ Eina_List *serialized_outputs_policies;
};
EINTERN Eina_Bool e_randr_init(void);
EINTERN int e_randr_shutdown(void);
-extern E_Randr_Screen_Info *e_randr_screen_info;
+EAPI extern E_Randr_Screen_Info *e_randr_screen_info;
#endif
#endif
SUBDIRS += conf_interaction
endif
+if USE_MODULE_CONF_RANDR
+SUBDIRS += conf_randr
+endif
+
if USE_MODULE_GADMAN
SUBDIRS += gadman
endif
typedef struct _Resolution Resolution;
typedef struct _SureBox SureBox;
-static E_Randr_Screen_Restore_Info_11 *e_screen_config_11 = NULL;
-
struct _Resolution
{
int id;
ecore_x_randr_screen_primary_output_current_size_get(man->root, &c_size.width, &c_size.height, NULL, NULL, NULL);
c_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
- if (e_screen_config_11)
- {
- e_screen_config_11->size.width = c_size.width;
- e_screen_config_11->size.height = c_size.height;
- e_screen_config_11->refresh_rate = c_rate;
- e_config_save_queue();
- }
+ e_randr_store_configuration(e_randr_screen_info);
+
_fill_data(sb->cfdata);
_load_resolutions(sb->cfdata);
/* No need to load rates as the currently selected resolution has not been
_fill_data(E_Config_Dialog_Data *cfdata)
{
E_Manager *man;
- E_Randr_Screen_Restore_Info *restore_info;
Eina_List *iter;
int rots;
ecore_x_randr_screen_primary_output_current_size_get(man->root, &cfdata->orig_size.width, &cfdata->orig_size.height, NULL, NULL, &cfdata->orig_size_index);
cfdata->orig_rate = ecore_x_randr_screen_primary_output_current_refresh_rate_get(man->root);
- EINA_LIST_FOREACH(e_config->screen_info, iter, restore_info)
- {
- if (restore_info->randr_version == RANDR_11)
- {
- e_screen_config_11 = restore_info->rrvd_restore_info.restore_info_11;
- break;
- }
- }
-
- if(!e_screen_config_11)
- {
- if ((restore_info = E_NEW(E_Randr_Screen_Restore_Info, 1)))
- {
- restore_info->randr_version = RANDR_11;
- if ((e_screen_config_11 = E_NEW(E_Randr_Screen_Restore_Info_11, 1)))
- {
- restore_info->rrvd_restore_info.restore_info_11 = e_screen_config_11;
- if (!(e_config->screen_info = eina_list_append(e_config->screen_info, restore_info)))
- {
- free(e_screen_config_11);
- free(restore_info);
- }
- }
- else
- {
- free (restore_info);
- }
- }
- }
-
rots = ecore_x_randr_screen_primary_output_orientations_get(man->root);
if ((rots) && (rots != ECORE_X_RANDR_ORIENTATION_ROT_0))
{
rt = eina_list_nth(res->rates, r);
if (!rt) return 0;
- if (!e_screen_config_11) return EINA_FALSE;
return ((res->size.width != cfdata->orig_size.width) ||
(res->size.height != cfdata->orig_size.height) ||
(cfdata->has_rates && (*rt != cfdata->orig_rate)) ||
(cfdata->orientation | cfdata->flip));
cfdata->orig_orientation = cfdata->orientation;
cfdata->orig_flip = cfdata->flip;
- if (e_screen_config_11)
- e_screen_config_11->orientation = (cfdata->orientation | cfdata->flip);
}
- else
- if (e_screen_config_11)
- e_screen_config_11->orientation = 0;
-
- e_config_save_queue();
return 1;
}
--- /dev/null
+MAINTAINERCLEANFILES = Makefile.in module.desktop
+MODULE = conf_randr
+
+EDJE_CC = @edje_cc@
+EDJE_FLAGS = -v \
+ -id $(top_srcdir)/src/modules/$(MODULE)/images \
+ @EDJE_DEF@
+
+# data files for the module
+filesdir = $(libdir)/enlightenment/modules/$(MODULE)
+files_DATA = \
+ e-module-$(MODULE).edj \
+ module.desktop
+
+EXTRA_DIST = \
+ e-module-$(MODULE).edc \
+ module.desktop.in
+
+# the module .so file
+INCLUDES = -I. \
+ -I$(top_srcdir) \
+ -I$(top_srcdir)/src/modules/$(MODULE) \
+ -I$(top_srcdir)/src/bin \
+ -I$(top_srcdir)/src/lib \
+ -I$(top_srcdir)/src/modules \
+ @e_cflags@
+pkgdir = $(libdir)/enlightenment/modules/$(MODULE)/$(MODULE_ARCH)
+pkg_LTLIBRARIES = module.la
+module_la_SOURCES = e_mod_main.c \
+ e_mod_main.h \
+ e_int_config_randr_orientation.c \
+ e_int_config_randr_resolutions.c \
+ e_int_config_randr_arrangement.c \
+ e_int_config_randr_policies.c \
+ e_int_config_randr.c \
+ e_int_config_randr.h
+
+module_la_LIBADD = @e_libs@ @dlopen_libs@
+module_la_LDFLAGS = -module -avoid-version
+module_la_DEPENDENCIES = $(top_builddir)/config.h
+
+e-module-$(MODULE).edj: Makefile $(EXTRA_DIST)
+ $(EDJE_CC) $(EDJE_FLAGS) \
+ $(top_srcdir)/src/modules/$(MODULE)/e-module-$(MODULE).edc \
+ $(top_builddir)/src/modules/$(MODULE)/e-module-$(MODULE).edj
+
+clean-local:
+ rm -f *.edj
+
+uninstall:
+ rm -rf $(DESTDIR)$(libdir)/enlightenment/modules/$(MODULE)
--- /dev/null
+#define BORDERSIZE 1
+#define SUGGESTION_TIMEOUT 2.5
+
+images {
+ image: "icon.png" COMP;
+ image: "video-display.svg" COMP;
+ image: "display.png" COMP;
+ image: "display-glass-shine.png" COMP;
+}
+
+collections {
+
+ // The icon used in the settings dialog
+ group {
+ name: "icon";
+ parts {
+ part {
+ name: "image";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.normal: "icon.png";
+ }
+ }
+ }
+ }
+
+ /**********************************************/
+ /*********Subdialog - Arrangement**************/
+ /**********************************************/
+
+ //The graphical representation of a single monitor, including its decorations
+ group {
+ name: "e/conf/randr/dialog/subdialog/arrangement/output";
+
+ styles {
+ style {
+ name: "display_name_text";
+ base: "font=Sans:style=Bold font_size=10 text_class=tb_plain align=center valign=center color=#fff style=soft_shadow shadow_color=#0000001f wrap=word";
+ tag: "br" "\n";
+ tag: "hilight" "+ font=Sans:style=Bold text_class=tb_light";
+ }
+ }
+
+
+ parts {
+
+ part {
+ name: "display";
+ type: IMAGE;
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ image.normal: "display.png";
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+
+ part {
+ name: "e.swallow.content";
+ type: SWALLOW; // background of CRTC's zone
+
+ description {
+ state: "default" 0.0;
+ aspect_preference: BOTH;
+ color: 255 255 255 255;
+ rel1 {
+ to: "display";
+ relative: 0.047379 0.049303;
+ }
+ rel2 {
+ to: "display";
+ //relative: 0.97 0.657804;
+ relative: 0.975 0.66;
+ }
+ }
+
+ description {
+ state: "disabled" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 128;
+ }
+ }
+
+ part {
+ name: "output_selected_frame_clip";
+ type: RECT;
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_top";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 0 2;
+ fixed: 0 1;
+ align: 0.5 0.0;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ relative: 1.0 0.0;
+ offset: 0 BORDERSIZE;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_right";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 1 0;
+ fixed: 1 0;
+ align: 1.0 0.5;
+
+ rel1 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_top";
+ relative: 1.0 1.0;
+ offset: (-BORDERSIZE-1) 0;
+ }
+ rel2 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_bottom";
+ relative: 1.0 0.0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_bottom";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 0 2;
+ fixed: 0 1;
+ align: 0.5 1.0;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ relative: 0.0 1.0;
+ offset: 0 (-BORDERSIZE-1);
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ relative: 1.0 1.0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frame_border_left";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 128 128 128 255;
+ min: 1 0;
+ fixed: 1 0;
+ align: 0.0 0.5;
+
+ rel1 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_top";
+ relative: 0.0 1.0;
+ }
+ rel2 {
+ to_x: "output_selected_frame_clip";
+ to_y: "output_selected_frame_border_bottom";
+ relative: 0.0 0.0;
+ offset: BORDERSIZE 0;
+ }
+ }
+ }
+
+ part {
+ name: "output_selected_frm_inside";
+ type: RECT;
+ clip_to: "output_selected_frame_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 120;
+
+ rel1 {
+ to: "output_selected_frame_clip";
+ offset: BORDERSIZE BORDERSIZE;
+ }
+ rel2 {
+ to: "output_selected_frame_clip";
+ offset: -BORDERSIZE -BORDERSIZE;
+ }
+ }
+ }
+
+ part {
+ name: "output_txt_bg";
+ type: RECT;
+ //clip_to: "output_txt_clip";
+ mouse_events: 0;
+
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 128;
+ align: 0.5 0.5;
+
+ rel1 {
+ to: "output_txt";
+ relative: 0.0 0.0;
+ offset: -5 -5;
+ }
+ rel2 {
+ to: "output_txt";
+ relative: 1.0 1.0;
+ offset: 5 5;
+ }
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 255;
+ }
+ }
+
+ part {
+ name: "output_txt";
+ type: TEXTBLOCK;
+ //clip_to: "output_txt_clip";
+ mouse_events: 0;
+
+ description {
+ align: 0.5 0.5;
+ state: "default" 0.0;
+ color: 0 0 0 255;
+ // define part coordinates:
+ //rel1.to: "output_txt_clip";
+ //rel2.to: "output_txt_clip";
+ rel1.to: "e.swallow.content";
+ rel2.to: "e.swallow.content";
+
+ text {
+ style: "display_name_text";
+ text: "output name";
+ min: 1.0 1.0;
+ max: 1.0 1.0;
+ }
+ }
+ description {
+ state: "selected" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+
+ part {
+ name: "selected_toggle_on";
+ type: RECT;
+ mouse_events: 1;
+
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 1;
+
+ rel1 {
+ to: "e.swallow.content";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "e.swallow.content";
+ relative: 1.0 1.0;
+ }
+ }
+
+ description {
+ state: "disable" 0.0;
+ inherit: "default" 0.0;
+ visible: 0;
+ }
+ }
+
+ part {
+ name: "selected_toggle_off";
+ type: RECT;
+ mouse_events: 1;
+
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ visible: 0;
+
+ rel1 {
+ to: "selected_toggle_on";
+ relative: 0.0 0.0;
+ }
+ rel2 {
+ to: "selected_toggle_on";
+ relative: 1.0 1.0;
+ }
+ }
+
+ description {
+ state: "disable" 0.0;
+ inherit: "default" 0.0;
+ visible: 1;
+ }
+ }
+
+ part {
+ name: "display-glass-shine";
+ type: IMAGE;
+
+ description {
+ state: "default" 0.0;
+ image.normal: "display-glass-shine.png";
+ }
+ }
+
+ programs {
+ program {
+ name: "highlight";
+ signal: "mouse,down,1";
+ source: "selected_toggle_on";
+
+ action: STATE_SET "selected" 0.0;
+ transition: LINEAR 0.1;
+ //target: "e.swallow.content";
+ //target: "output_selected_clip";
+ target: "output_txt";
+ target: "output_txt_bg";
+ target: "output_selected_frame_clip";
+ }
+
+ program {
+ name: "normal";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_off";
+
+ action: STATE_SET "default" 0.0;
+ transition: LINEAR 0.1;
+ //target: "e.swallow.content";
+ //target: "output_selected_clip";
+ target: "output_txt";
+ target: "output_txt_bg";
+ target: "output_selected_frame_clip";
+ }
+
+ program {
+ name: "selected_toggle_off_on";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_on";
+ action: STATE_SET "disable" 1.0;
+ target: "selected_toggle_on";
+ target: "selected_toggle_off";
+ }
+
+ program {
+ name: "selected_toggle_on_off";
+ signal: "mouse,clicked,1";
+ source: "selected_toggle_off";
+ action: STATE_SET "default" 1.0;
+ target: "selected_toggle_on";
+ target: "selected_toggle_off";
+ }
+
+ program {
+ name: "emit_highlight";
+ signal: "select";
+ source: "e";
+ after: "highlight";
+ }
+
+ program {
+ name: "emit_normal";
+ signal: "deselect";
+ source: "e";
+ after: "normal";
+ }
+
+ program {
+ name: "disable";
+ signal: "disabled";
+ source: "e";
+ action: STATE_SET "disabled" 0.0;
+ target: "e.swallow.content";
+ }
+
+ program {
+ name: "enable";
+ signal: "enabled";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "e.swallow.content";
+ }
+
+ program {
+ name: "init";
+ after: "normal";
+ }
+ }
+ }
+ }
+
+ //This group describes the look of the suggestion entity used, when a monitor
+ //representation is dragged. Its size matches the size of the monitor
+ //dragged.
+ group{
+ name: "e/conf/randr/dialog/subdialog/arrangement/suggestion";
+ data {
+ item: "distance_min" "20";
+ }
+
+ /*
+ script {
+ public fade_out_timer_id = 0;
+
+ public suggestion_fade_out ()
+ {
+ cancel_timer(get_int(fade_out_timer_id));
+ run_program(PROGRAM:"hide");
+ }
+ }
+ */
+
+ parts {
+ part {
+ name: "shape_clip";
+ type: RECT;
+ description {
+ state: "default" 0.0;
+ color: 255 255 255 0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ description {
+ state: "visible" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "shape";
+ type: RECT;
+ mouse_events: 0;
+ clip_to: "shape_clip";
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 100;
+ rel1.to: "shape_clip";
+ rel2.to: "shape_clip";
+ }
+ }
+ }
+ programs {
+ program {
+ name: "show_transition";
+ signal: "show";
+ source: "e";
+ action: STATE_SET "visible" 0.0;
+ target: "shape_clip";
+ transition: LINEAR 0.2;
+ }
+ /*
+ program {
+ name: "set_timeout";
+ signal: "show";
+ source: "e";
+ script {
+ new i = timer(SUGGESTION_TIMEOUT, "suggestion_fade_out", 0);
+ set_int(fade_out_timer_id, i);
+ }
+ }
+ */
+ program {
+ name: "hide";
+ signal: "hide";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "shape_clip";
+ transition: LINEAR 0.2;
+ }
+ }
+ }
+
+ /**********************************************/
+ /************Subdialog - Policies**************/
+ /**********************************************/
+ group{
+ name: "e/conf/randr/dialog/subdialog/policies";
+ parts {
+ part {
+ name: "current_displays_setup/clipper";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.25;
+ rel2.relative: 0.75 0.75;
+ }
+ description {
+ state: "above" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.25 0.5;
+ rel2.relative: 0.75 1.0;
+ }
+ description {
+ state: "right" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.0 0.25;
+ rel2.relative: 0.5 0.75;
+ }
+ description {
+ state: "below" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.25 0.0;
+ rel2.relative: 0.75 0.5;
+ }
+ description {
+ state: "left" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ rel1.relative: 0.5 0.25;
+ rel2.relative: 1.0 0.75;
+ }
+ description {
+ state: "clone" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "none" 0.0;
+ inherit: "default" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "current_displays_setup.swallow.content";
+ type: SWALLOW;
+ clip_to: "current_displays_setup/clipper";
+ description {
+ state: "default" 0.0;
+ rel1.to: "current_displays_setup/clipper";
+ rel2.to: "current_displays_setup/clipper";
+ }
+ }
+ part {
+ name: "new_display/clipper";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.25;
+ rel2.relative: 0.75 0.75;
+ }
+ description {
+ state: "above" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.0;
+ rel2.relative: 0.75 0.5;
+ }
+ description {
+ state: "above_visible" 0.0;
+ inherit: "above" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "right" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.5 0.25;
+ rel2.relative: 1.0 0.75;
+ }
+ description {
+ state: "right_visible" 0.0;
+ inherit: "right" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "below" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.25 0.5;
+ rel2.relative: 0.75 1.0;
+ }
+ description {
+ state: "below_visible" 0.0;
+ inherit: "below" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "left" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ rel1.relative: 0.0 0.25;
+ rel2.relative: 0.5 0.75;
+ }
+ description {
+ state: "left_visible" 0.0;
+ inherit: "left" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "clone" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ description {
+ state: "clone_visible" 0.0;
+ inherit: "clone" 0.0;
+ color: 255 255 255 255;
+ }
+ description {
+ state: "none" 0.0;
+ inherit: "default" 0.0;
+ color: 0 0 0 0;
+ }
+ description {
+ state: "none_visible" 0.0;
+ inherit: "none" 0.0;
+ color: 255 255 255 255;
+ }
+ }
+ part {
+ name: "new_display.swallow.content";
+ type: SWALLOW;
+ clip_to: "new_display/clipper";
+ description {
+ state: "default" 0.0;
+ rel1.to: "new_display/clipper";
+ rel2.to: "new_display/clipper";
+ }
+ }
+ }
+ /*
+ * The signals emitted to the UI are encoded as their corresponding value
+ * in Ecore_X
+ *
+ * Policy = Signal emitted
+ * ECORE_X_RANDR_OUTPUT_POLICY_ABOVE = 1
+ * ECORE_X_RANDR_OUTPUT_POLICY_RIGHT = 2
+ * ECORE_X_RANDR_OUTPUT_POLICY_BELOW = 3
+ * ECORE_X_RANDR_OUTPUT_POLICY_LEFT = 4
+ * ECORE_X_RANDR_OUTPUT_POLICY_CLONE = 5
+ * ECORE_X_RANDR_OUTPUT_POLICY_NONE = 6
+ */
+ programs {
+ program {
+ name: "new_display_hide";
+ signal: "conf,randr,dialog,policies,*";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "new_display/clipper";
+ }
+ program {
+ name: "current_displays_setup_clipper_above";
+ signal: "conf,randr,dialog,policies,1";
+ source: "e";
+ action: STATE_SET "above" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_above_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_above_visible_set";
+ action: STATE_SET "above_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_right";
+ signal: "conf,randr,dialog,policies,2";
+ source: "e";
+ action: STATE_SET "right" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_right_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_right_visible_set";
+ action: STATE_SET "right_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_below";
+ signal: "conf,randr,dialog,policies,3";
+ source: "e";
+ action: STATE_SET "below" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_below_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_below_visible_set";
+ action: STATE_SET "below_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_left";
+ signal: "conf,randr,dialog,policies,4";
+ source: "e";
+ action: STATE_SET "left" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_left_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_left_visible_set";
+ action: STATE_SET "left_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_clone";
+ signal: "conf,randr,dialog,policies,5";
+ source: "e";
+ action: STATE_SET "clone" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ after: "new_display_clone_visible_set";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "new_display_clone_visible_set";
+ action: STATE_SET "clone_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "current_displays_setup_clipper_none";
+ signal: "conf,randr,dialog,policies,6";
+ source: "e";
+ action: STATE_SET "none" 0.0;
+ target: "current_displays_setup/clipper";
+ target: "new_display/clipper";
+ //after: "new_display_none_visible_set";
+ transition: LINEAR 0.5;
+ }
+ /*
+ * following is an analog program for none, but we don't want to show
+ * it anyway.
+ program {
+ name: "new_display_none_visible_set";
+ action: STATE_SET "none_visible" 0.0;
+ target: "new_display/clipper";
+ transition: LINEAR 0.5;
+ }
+ */
+ }
+ }
+
+ // Text objects for rotation and reflection
+ group {
+ name: "e/conf/randr/dialog/subdialog/orientation";
+
+ parts {
+ part {
+ name: "clip";
+ type: RECT;
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 1.0;
+ }
+ }
+ part {
+ name: "display";
+ clip_to: "clip";
+ mouse_events: 0;
+ description {
+ state: "default" 0.0;
+ aspect: 1.0 1.0;
+ aspect_preference: BOTH;
+ image.normal: "video-display.svg";
+ }
+ }
+ part {
+ name: "orientation_text";
+ clip_to: "clip";
+ type: TEXT;
+ mouse_events: 0;
+ scale: 1;
+ description {
+ state: "default" 0.0;
+ rel1.relative: 0.0 0.0;
+ rel2.relative: 1.0 0.8;
+ color: 0 0 0 255;
+ text {
+ //Maybe use some default theme label text style later
+ text: "Orientation";
+ font: "Sans:style=Bold";
+ /* Use the Bold style
+ * of the Sans font from
+ * fontconfig */
+ size: 10;
+ /* size in pixels - 10 */
+ min: 0 1;
+ /* the text will not determine minimum horizontal
+ * size but WILL determine minimal vertical size
+ * (thus 0 1 - horiz then vert flags) */
+ /* align text to top-left of the region
+ * given */
+ text_class: "title_bar";
+ /* text class - so font and size
+ * can be changed by users */
+ }
+ map {
+ on: 1;
+ rotation {
+ x: 0.0;
+ y: 0.0;
+ z: 0.0;
+ }
+ }
+ }
+ description {
+ state: "rotate" 0.90;
+ inherit: "default" 0.0;
+ map.rotation.z: 270.0;
+ }
+ description {
+ state: "rotate" 0.180;
+ inherit: "default" 0.0;
+ map.rotation.z: 180.0;
+ }
+ description {
+ state: "rotate" 0.270;
+ inherit: "default" 0.0;
+ map.rotation.z: 90.0;
+ }
+ description {
+ state: "reflect_horizontal" 0.0;
+ inherit: "default" 0.0;
+ map.rotation.y: 180.0;
+ }
+ description {
+ state: "reflect_vertical" 0.0;
+ inherit: "default" 0.0;
+ map.rotation.x: 180.0;
+ }
+ }
+ }
+ programs {
+ program {
+ name: "rot0";
+ signal: "conf,randr,dialog,orientation,current,1";
+ source: "e";
+ action: STATE_SET "default" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot90";
+ signal: "conf,randr,dialog,orientation,current,2";
+ source: "e";
+ action: STATE_SET "rotate" 0.90;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot180";
+ signal: "conf,randr,dialog,orientation,current,4";
+ source: "e";
+ action: STATE_SET "rotate" 0.180;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "rot270";
+ signal: "conf,randr,dialog,orientation,current,8";
+ source: "e";
+ action: STATE_SET "rotate" 0.270;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "ref_x";
+ signal: "conf,randr,dialog,orientation,current,16";
+ source: "e";
+ action: STATE_SET "reflect_horizontal" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ program {
+ name: "ref_y";
+ signal: "conf,randr,dialog,orientation,current,32";
+ source: "e";
+ action: STATE_SET "reflect_vertical" 0.0;
+ target: "orientation_text";
+ transition: LINEAR 0.5;
+ }
+ }
+
+ }
+
+}
--- /dev/null
+#include "e_int_config_randr.h"
+#include "e_widget_toolbook.h"
+#include "e.h"
+#include "e_randr.h"
+
+/*
+ * BUGS:
+ * - ethumb sometimes returns garbage objects leading to a segv
+ *
+ * TODO:
+ * - write 1.2 per monitor configuration
+ * - write Smart object, so crtcs representations can be properly freed (events,
+ * etc.)
+ *
+ * IMPROVABLE:
+ * See comments starting with 'IMPROVABLE'
+ */
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+
+#ifdef Ecore_X_Randr_None
+#undef Ecore_X_Randr_None
+#define Ecore_X_Randr_None 0
+#else
+#define Ecore_X_Randr_None 0
+#endif
+#ifdef Ecore_X_Randr_Unset
+#undef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#else
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define THEME_FILENAME "/e-module-conf_randr.edj"
+#define TOOLBAR_ICONSIZE 16
+
+static void *create_data (E_Config_Dialog *cfd);
+static void free_cfdata (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static int basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static int basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static Evas_Object *basic_create_widgets (E_Config_Dialog *cfd, Evas *evas, E_Config_Dialog_Data *cfdata);
+static Eina_Bool _deferred_noxrandr_error (void *data);
+static Eina_Bool _deferred_norates_error (void *data);
+
+// Functions for the arrangement subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_arrangement_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_arrangement_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the policies subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_policies_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_policies_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_policies_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the resolutions subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_resolutions_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_resolutions_update_list (Evas *canvas, Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_resolutions_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_resolutions_discard_changes (E_Config_Dialog_Data *cfdata);
+
+// Functions for the orientation subdialog interaction
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_create_data (E_Config_Dialog_Data *cfdata);
+extern Evas_Object *e_config_randr_dialog_subdialog_orientation_basic_create_widgets (Evas *canvas);
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_orientation_update_radio_buttons (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_update_edje (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_keep_changes (E_Config_Dialog_Data *cfdata);
+extern void e_config_randr_dialog_subdialog_orientation_discard_changes (E_Config_Dialog_Data *cfdata);
+
+/* actual module specifics */
+E_Config_Dialog_Data *e_config_runtime_info = NULL;
+extern E_Module *conf_randr_module;
+char _theme_file_path[PATH_MAX];
+
+ E_Config_Randr_Dialog_Output_Dialog_Data *
+_e_config_randr_dialog_output_dialog_data_new(E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ if ((!crtc_info && !output_info) || !(dialog_data = E_NEW(E_Config_Randr_Dialog_Output_Dialog_Data, 1))) return NULL;
+ if (crtc_info)
+ {
+ //already enabled screen
+ dialog_data->crtc = crtc_info;
+ }
+ else if (output_info)
+ {
+ //disabled monitor
+ dialog_data->output = output_info;
+ }
+ return dialog_data;
+
+_e_conf_randr_dialog_create_output_data_failed:
+ free(dialog_data);
+ return NULL;
+}
+
+
+ static void *
+create_data(E_Config_Dialog *cfd)
+{
+ Eina_List *iter;
+ E_Randr_Output_Info *output_info;
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+
+ // Prove we got all things to get going
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2), NULL);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL(!(e_config_runtime_info = E_NEW(E_Config_Dialog_Data, 1)), NULL);
+
+ e_config_runtime_info->cfd = cfd;
+
+ //Compose theme's file path and name
+ snprintf(_theme_file_path, sizeof(_theme_file_path), "%s%s", conf_randr_module->dir, THEME_FILENAME);
+
+ e_config_runtime_info->manager = e_manager_current_get();
+ EINA_LIST_FOREACH(e_randr_screen_info->rrvd_info.randr_info_12->outputs, iter, output_info)
+ {
+ //Create basic data struct for every connected output.
+ //Data would have to be recreated if a monitor is connected while dialog
+ //is open.
+ if (output_info->connection_status != ECORE_X_RANDR_CONNECTION_STATUS_CONNECTED)
+ continue;
+ if ((odd = _e_config_randr_dialog_output_dialog_data_new(output_info->crtc, output_info)))
+ EINA_SAFETY_ON_FALSE_GOTO((e_config_runtime_info->output_dialog_data_list = eina_list_append(e_config_runtime_info->output_dialog_data_list, odd)), _e_conf_randr_create_data_failed_free_data);
+ }
+
+ fprintf(stderr, "CONF_RANDR: Added %d output data structs.\n", eina_list_count(e_config_runtime_info->output_dialog_data_list));
+ //FIXME: Properly (stack-like) free data when creation fails
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_arrangement_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_resolutions_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_policies_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+ EINA_SAFETY_ON_FALSE_GOTO(e_config_randr_dialog_subdialog_orientation_create_data(e_config_runtime_info), _e_conf_randr_create_data_failed_free_data);
+
+ return e_config_runtime_info;
+
+_e_conf_randr_create_data_failed_free_data:
+ free(e_config_runtime_info);
+ return NULL;
+}
+
+ static void
+free_cfdata(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ EINA_SAFETY_ON_TRUE_RETURN(!e_randr_screen_info);
+ e_config_randr_dialog_subdialog_arrangement_free_data(cfd, cfdata);
+
+ if (cfdata) free(cfdata);
+ cfdata = NULL;
+}
+
+ static Eina_Bool
+_e_conf_randr_confirmation_dialog_timer_cb(void *data)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+ char buf[4096];
+
+ if (!cdd) return ECORE_CALLBACK_CANCEL;
+
+ --cdd->countdown;
+
+ if (cdd->countdown > 0)
+ {
+ snprintf(buf, sizeof(buf),
+ _("Does this look OK? Click <hilight>Keep</hilight> if it does, or Restore if not.<br>"
+ "If you do not press a button, the previous settings will be restored in %d seconds."), cdd->countdown);
+ }
+ else
+ {
+ snprintf(buf, sizeof(buf),
+ _("Does this look OK? Click <hilight>Keep</hilight> if it does, or Restore if not.<br>"
+ "If you do not press a button, the previous settings will be restored <highlight>IMMEDIATELY</highlight>."));
+ }
+
+ e_dialog_text_set(cdd->dialog, buf);
+
+ return (cdd->countdown > 0) ? ECORE_CALLBACK_RENEW : ECORE_CALLBACK_CANCEL;
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_delete_cb(E_Win *win)
+{
+ E_Dialog *dia;
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd;
+ E_Config_Dialog *cfd;
+
+ dia = win->data;
+ cd = dia->data;
+ cd->cfdata->gui.confirmation_dialog = NULL;
+ cfd = cd->cfdata->cfd;
+ if (cd->timer) ecore_timer_del(cd->timer);
+ cd->timer = NULL;
+ free(cd);
+ e_object_del(E_OBJECT(dia));
+ e_object_unref(E_OBJECT(cfd));
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_keep_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ e_config_randr_dialog_subdialog_arrangement_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_orientation_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_policies_keep_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_resolutions_keep_changes(cdd->cfdata);
+ _e_conf_randr_confirmation_dialog_delete_cb(dia->win);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_discard_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ e_config_randr_dialog_subdialog_arrangement_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_orientation_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_policies_discard_changes(cdd->cfdata);
+ e_config_randr_dialog_subdialog_resolutions_discard_changes(cdd->cfdata);
+ _e_conf_randr_confirmation_dialog_delete_cb(dia->win);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_store_cb(void *data, E_Dialog *dia)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cdd = (E_Config_Randr_Dialog_Confirmation_Dialog_Data*)data;
+
+ if (!cdd) return;
+
+ _e_conf_randr_confirmation_dialog_keep_cb(data, dia);
+ e_randr_store_configuration(e_randr_screen_info);
+}
+
+ static void
+_e_conf_randr_confirmation_dialog_new(E_Config_Dialog *cfd)
+{
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *cd = E_NEW(E_Config_Randr_Dialog_Confirmation_Dialog_Data, 1);
+
+ if (!cd) return;
+
+ cd->cfd = cfd;
+
+ if((cd->dialog = e_dialog_new(cfd->con, "E", "e_randr_confirmation_dialog")))
+ {
+ e_dialog_title_set(cd->dialog, _("New settings confirmation"));
+ cd->cfdata = cfd->cfdata;
+ cd->timer = ecore_timer_add(1.0, _e_conf_randr_confirmation_dialog_timer_cb, cd);
+ cd->countdown = 15;
+ cd->dialog->data = cd;
+ e_dialog_icon_set(cd->dialog, "preferences-system-screen-resolution", 48);
+ e_win_delete_callback_set(cd->dialog->win, _e_conf_randr_confirmation_dialog_delete_cb);
+ e_dialog_button_add(cd->dialog, _("Keep"), NULL, _e_conf_randr_confirmation_dialog_keep_cb, cd);
+ e_dialog_button_add(cd->dialog, _("Store Permanently"), NULL, _e_conf_randr_confirmation_dialog_store_cb, cd);
+ e_dialog_button_add(cd->dialog, _("Restore"), NULL, _e_conf_randr_confirmation_dialog_discard_cb, cd);
+ e_dialog_button_focus_num(cd->dialog, 1);
+ e_win_centered_set(cd->dialog->win, 1);
+ e_win_borderless_set(cd->dialog->win, 1);
+ e_win_layer_set(cd->dialog->win, 6);
+ e_win_sticky_set(cd->dialog->win, 1);
+ e_dialog_show(cd->dialog);
+ e_object_ref(E_OBJECT(cfd));
+ }
+
+}
+
+ static Evas_Object *
+basic_create_widgets (E_Config_Dialog *cfd, Evas *canvas, E_Config_Dialog_Data *cfdata)
+{
+ Evas_Object *table = NULL, *wl = NULL;
+
+ EINA_SAFETY_ON_TRUE_RETURN_VAL (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2), NULL);
+ EINA_SAFETY_ON_TRUE_RETURN_VAL((!canvas || !cfdata), NULL);
+
+ if(!(cfdata->gui.subdialogs.arrangement.dialog = e_config_randr_dialog_subdialog_arrangement_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_arrangement_fail;
+ if(!(cfdata->gui.subdialogs.policies.dialog = e_config_randr_dialog_subdialog_policies_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_policies_fail;
+ if(!(cfdata->gui.subdialogs.resolutions.dialog = e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_resolutions_fail;
+ if(!(cfdata->gui.subdialogs.orientation.dialog = e_config_randr_dialog_subdialog_orientation_basic_create_widgets(canvas))) goto _e_config_randr_dialog_create_subdialog_orientation_fail;
+
+ EINA_SAFETY_ON_FALSE_GOTO((table = e_widget_table_add(canvas, EINA_FALSE)), _e_config_randr_dialog_create_widgets_fail);
+ EINA_SAFETY_ON_FALSE_GOTO((wl = e_widget_list_add(canvas, EINA_FALSE, EINA_TRUE)), _e_config_randr_dialog_create_widget_list_fail);
+
+ //e_widget_table_object_append(Evas_Object *obj, Evas_Object *sobj, int col, int row, int colspan, int rowspan, int fill_w, int fill_h, int expand_w, int expand_h);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.arrangement.dialog, 1, 1, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ /*
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.policies.dialog, 1, 2, 1, 1, 0, 0, 0, 0);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.orientation.dialog, 2, 2, 1, 1, 0, 0, 0, 0);
+ e_widget_table_object_append(table, cfdata->gui.subdialogs.resolutions.dialog, 3, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ */
+ //e_widget_list_object_append(Evas_Object *obj, Evas_Object *sobj, int fill, int expand, double align);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.policies.dialog, 0, 0, 0.0);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.orientation.dialog, 0, 0, 0.0);
+ e_widget_list_object_append(wl, cfdata->gui.subdialogs.resolutions.dialog, EVAS_HINT_FILL, EVAS_HINT_EXPAND, 1.0);
+ e_widget_table_object_append(table, wl, 1, 2, 1, 1, EVAS_HINT_FILL, EVAS_HINT_FILL, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
+ cfdata->gui.widget_list = wl;
+
+ cfdata->gui.dialog = table;
+
+ e_dialog_resizable_set(cfd->dia, EINA_TRUE);
+
+ return cfdata->gui.dialog;
+
+_e_config_randr_dialog_create_widget_list_fail:
+ evas_object_del(table);
+_e_config_randr_dialog_create_widgets_fail:
+ evas_object_del(cfdata->gui.subdialogs.orientation.dialog);
+_e_config_randr_dialog_create_subdialog_orientation_fail:
+ evas_object_del(cfdata->gui.subdialogs.resolutions.dialog);
+_e_config_randr_dialog_create_subdialog_resolutions_fail:
+ evas_object_del(cfdata->gui.subdialogs.policies.dialog);
+_e_config_randr_dialog_create_subdialog_policies_fail:
+ evas_object_del(cfdata->gui.subdialogs.arrangement.dialog);
+_e_config_randr_dialog_create_subdialog_arrangement_fail:
+ return NULL;
+}
+
+static int
+ basic_apply_data
+(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_Bool ret = EINA_TRUE;
+
+ fprintf(stderr, "CONF_RANDR: New configuration is beeing applied.\n");
+ //this is a special case, where the function is called, before the
+ //configuration data is created.
+ if (!cfdata) return EINA_FALSE;
+
+ //the order matters except for policies!
+ if (e_config_randr_dialog_subdialog_policies_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_policies_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_resolutions_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_resolutions_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_arrangement_basic_check_changed(cfd, cfdata))
+ {
+ ret &= e_config_randr_dialog_subdialog_arrangement_basic_apply_data(cfd, cfdata);
+ if (!ret) return EINA_FALSE;
+ }
+
+ if (e_config_randr_dialog_subdialog_orientation_basic_check_changed(cfd, cfdata))
+ ret &= e_config_randr_dialog_subdialog_orientation_basic_apply_data(cfd, cfdata);
+
+ _e_conf_randr_confirmation_dialog_new(cfd);
+
+ return ret;
+}
+
+E_Config_Dialog *
+e_int_config_randr(E_Container *con, const char *params __UNUSED__){
+ E_Config_Dialog *cfd;
+ E_Config_Dialog_View *v;
+
+ if (!e_randr_screen_info || (e_randr_screen_info->randr_version < ECORE_X_RANDR_1_2))
+ {
+ ecore_timer_add(0.5, _deferred_noxrandr_error, NULL);
+ fprintf(stderr, "CONF_RANDR: XRandR version >= 1.2 necessary to work.\n");
+ return NULL;
+ }
+
+ //Dialog already opened?
+ if (e_config_dialog_find("E", "screen/screen_setup")) return NULL;
+
+ v = E_NEW(E_Config_Dialog_View, 1);
+ v->create_cfdata = create_data;
+ v->free_cfdata = free_cfdata;
+ v->basic.apply_cfdata = basic_apply_data;
+ v->basic.create_widgets = basic_create_widgets;
+ v->basic.check_changed = basic_check_changed;
+ //v->override_auto_apply = 0;
+
+ cfd = e_config_dialog_new(con, _("Screen Setup"),
+ "E", "screen/screen_setup",
+ "preferences-system-screen-setup", 0, v, NULL);
+ return cfd;
+}
+
+ static Eina_Bool
+_deferred_noxrandr_error(void *data __UNUSED__)
+{
+ e_util_dialog_show(_("Missing Features"),
+ _("Your X Display Server is missing support for<br>"
+ "the <hilight>XRandR</hilight> (X Resize and Rotate) extension version 1.2 or above.<br>"
+ "You cannot change screen resolutions without<br>"
+ "the support of this extension. It could also be<br>"
+ "that at the time <hilight>ecore</hilight> was built, there<br>"
+ "was no XRandR support detected."));
+ return ECORE_CALLBACK_CANCEL;
+}
+
+ static int
+basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ if (!cfdata) return EINA_FALSE;
+ else
+ return (e_config_randr_dialog_subdialog_arrangement_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_policies_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_orientation_basic_check_changed(cfd, cfdata)
+ || e_config_randr_dialog_subdialog_resolutions_basic_check_changed(cfd, cfdata));
+}
+
--- /dev/null
+#ifdef E_TYPEDEFS
+#else
+#ifndef E_INT_CONFIG_RANDR_H
+#define E_INT_CONFIG_RANDR_H
+
+#include "e.h"
+
+typedef struct _E_Config_Randr_Dialog_Output_Dialog_Data E_Config_Randr_Dialog_Output_Dialog_Data;
+typedef struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data E_Config_Randr_Dialog_Confirmation_Dialog_Data;
+
+struct _E_Config_Dialog_Data
+{
+ E_Config_Dialog *cfd;
+
+ //list of E_Config_Randr_Dialog_Output_Dialog_Data
+ Eina_List *output_dialog_data_list;
+ E_Manager *manager;
+ struct {
+ Evas_Object *dialog, *widget_list, *selected_eo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *selected_output_dd;
+ E_Config_Randr_Dialog_Confirmation_Dialog_Data *confirmation_dialog;
+ struct {
+ struct {
+ Evas_Object *dialog, *swallowing_edje, *smart_parent, *suggestion, *clipper;
+ Evas_Coord_Point previous_pos, relative_zero;
+ int suggestion_dist_min;
+ } arrangement;
+ struct {
+ Evas_Object *dialog;
+ //Evas_Object *swallowing_edje;
+ Evas_Object *radio_above, *radio_right, *radio_below, *radio_left, *radio_clone, *radio_none;
+ int radio_val;
+ //Evas_Object *current_displays_setup, *current_displays_setup_background, *new_display, *new_display_background;
+ } policies;
+ struct {
+ Evas_Object *dialog;
+ } resolutions;
+ struct {
+ Evas_Object *dialog;
+ //Evas_Object *swallowing_edje;
+ Evas_Object *radio_normal, *radio_rot90, *radio_rot180, *radio_rot270, *radio_reflect_horizontal, *radio_reflect_vertical;
+ int radio_val;
+ } orientation;
+ } subdialogs;
+ } gui;
+ Ecore_X_Randr_Screen_Size screen_size;
+
+};
+
+struct _E_Config_Randr_Dialog_Output_Dialog_Data
+{
+ E_Randr_Crtc_Info *crtc;
+ E_Randr_Output_Info *output;
+ Evas_Coord_Point previous_pos, new_pos;
+ Ecore_X_Randr_Mode_Info *previous_mode, *new_mode, *preferred_mode;
+ Ecore_X_Randr_Orientation previous_orientation, new_orientation;
+ Ecore_X_Randr_Output_Policy previous_policy, new_policy;
+ Evas_Object *bg;
+};
+
+struct _E_Config_Randr_Dialog_Confirmation_Dialog_Data
+{
+ E_Config_Dialog *cfd;
+ E_Config_Dialog_Data *cfdata;
+ E_Dialog *dialog;
+ Ecore_Timer *timer;
+ int countdown;
+};
+
+E_Config_Dialog *e_int_config_randr(E_Container *con, const char *params __UNUSED__);
+
+#endif
+#endif
--- /dev/null
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+#include "Ecore_X.h"
+
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define DOUBLECLICK_TIMEOUT 0.2
+#define CRTC_THUMB_SIZE_W 300
+#define CRTC_THUMB_SIZE_H 300
+
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_create_data (E_Config_Dialog_Data *e_config_runtime_info);
+Evas_Object *e_config_randr_dialog_subdialog_arrangement_basic_create_widgets (Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_check_changed (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_arrangement_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_arrangement_free_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+static inline Eina_List *_e_config_randr_dialog_subdialog_arrangement_neighbors_get (Evas_Object *obj);
+static void _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive (Evas_Object *obj);
+
+static inline E_Config_Randr_Dialog_Output_Dialog_Data *_e_config_randr_dialog_subdialog_arrangement_output_dialog_data_new (E_Randr_Crtc_Info *crtc_info, E_Randr_Output_Info *output_info);
+static inline void _e_config_randr_dialog_subdialog_arrangement_suggestion_add (Evas *evas);
+static inline void _e_config_randr_dialog_subdialog_arrangement_make_suggestion (Evas_Object *obj);
+static void _e_config_randr_dialog_subdialog_arrangement_smart_class_resize (Evas_Object *obj, Evas_Coord w, Evas_Coord h);
+static Evas_Object *_e_config_randr_dialog_subdialog_arrangement_output_add (Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+static void _e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info);
+
+// Function for the resolutions subdialog interaction
+extern void e_config_randr_dialog_subdialog_resolutions_update_list (Evas_Object *crtc);
+// Function for the orientation subdialog interaction
+extern void e_config_randr_dialog_subdialog_orientation_update_radio_buttons (Evas_Object *crtc);
+extern void e_config_randr_dialog_subdialog_orientation_update_edje (Evas_Object *crtc);
+// Functions for the orientation subdialog interaction
+extern void e_config_randr_dialog_subdialog_policies_update_radio_buttons (Evas_Object *crtc);
+
+Evas_Smart_Class screen_setup_smart_class = EVAS_SMART_CLASS_INIT_NAME_VERSION("EvasObjectSmartScreenSetup");
+Evas_Smart *screen_setup_smart;
+
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_dialog_data_fill(E_Config_Randr_Dialog_Output_Dialog_Data *odd)
+{
+ if (!odd) return;
+
+ if (odd->crtc)
+ {
+ //already enabled screen
+ odd->previous_pos.x = odd->crtc->geometry.x;
+ odd->previous_pos.y = odd->crtc->geometry.y;
+ odd->previous_mode = odd->crtc->current_mode;
+ }
+ else if (odd->output)
+ {
+ //disabled monitor
+ //try to get a mode from the preferred list, else use default list
+ if(!(odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->preferred_modes))))
+ odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->modes));
+ odd->previous_pos.x = Ecore_X_Randr_Unset;
+ odd->previous_pos.y = Ecore_X_Randr_Unset;
+ }
+
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_create_data(E_Config_Dialog_Data *data)
+{
+ Eina_List *iter;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ EINA_LIST_FOREACH(data->output_dialog_data_list, iter, dialog_data)
+ {
+ _e_config_randr_dialog_subdialog_arrangement_output_dialog_data_fill(dialog_data);
+ }
+
+ return EINA_TRUE;
+}
+
+//IMPROVABLE: Clean up properly if instances can't be created
+ Evas_Object *
+e_config_randr_dialog_subdialog_arrangement_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog, *crtc;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Eina_List *iter;
+
+ if (!canvas || !e_config_runtime_info || !e_config_runtime_info->output_dialog_data_list) return NULL;
+
+ //initialize smart object
+ evas_object_smart_clipped_smart_set(&screen_setup_smart_class);
+ screen_setup_smart_class.resize = _e_config_randr_dialog_subdialog_arrangement_smart_class_resize;
+ screen_setup_smart = evas_smart_class_new(&screen_setup_smart_class);
+
+ subdialog = evas_object_smart_add(canvas, screen_setup_smart);
+ e_config_runtime_info->gui.subdialogs.arrangement.clipper = evas_object_smart_clipped_clipper_get(subdialog);
+ fprintf(stderr, "CONF_RANDR: Arrangement subdialog added (%p).\n", subdialog);
+
+
+ //only use information we can restore.
+ EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, output_dialog_data)
+ {
+ if ((!output_dialog_data->crtc && !output_dialog_data->output))
+ continue;
+ crtc = _e_config_randr_dialog_subdialog_arrangement_output_add(canvas, output_dialog_data);
+
+ if (!crtc) continue;
+ evas_object_show(crtc);
+
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_DOWN, _e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb, NULL);
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_MOVE, _e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb, NULL);
+ evas_object_event_callback_add (crtc, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb, NULL);
+
+
+ evas_object_smart_member_add(crtc, subdialog);
+ fprintf(stderr, "CONF_RANDR: CRTC representation (%p) added to arrangement subdialog (%p).\n", crtc, subdialog);
+ }
+
+ e_config_runtime_info->gui.subdialogs.arrangement.smart_parent = subdialog;
+
+ return subdialog;
+}
+
+ static Evas_Object *
+_e_config_randr_dialog_subdialog_arrangement_output_add(Evas *canvas, E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data)
+{
+ E_Randr_Output_Info *output_info;
+ Evas_Object *output, *bg;
+ const char* output_name = NULL;
+
+ if (!canvas || !output_dialog_data || !e_config_runtime_info) return NULL;
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((output = edje_object_add(canvas)), NULL);
+
+ //set instance data for output
+ evas_object_data_set(output, "output_info", output_dialog_data);
+
+ //set theme for monitor representation
+ EINA_SAFETY_ON_FALSE_GOTO(edje_object_file_set(output, _theme_file_path, "e/conf/randr/dialog/subdialog/arrangement/output"), _e_config_randr_dialog_subdialog_arrangement_output_add_edje_set_fail);
+ //indicate monitor state
+ if (!output_dialog_data->crtc || (output_dialog_data->crtc && !output_dialog_data->previous_mode))
+ edje_object_signal_emit(output, "disabled", "e");
+ else
+ edje_object_signal_emit(output, "enabled", "e");
+ //for now use deskpreview widget as background of output, maybe change this to
+ //live image from comp module
+ output_dialog_data->bg = e_widget_deskpreview_add(canvas, 1, 1);
+ edje_object_part_swallow(output, "e.swallow.content", output_dialog_data->bg);
+
+ //Try to get the name of the monitor connected to the output's last output via edid
+ //else use the output's name
+ if (output_dialog_data->crtc)
+ output_info = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(output_dialog_data->crtc->outputs));
+ else
+ output_info = output_dialog_data->output;
+ if (output_info)
+ {
+ if (ecore_x_randr_edid_has_valid_header(output_info->edid, output_info->edid_length))
+ output_name = ecore_x_randr_edid_display_name_get(output_info->edid, output_info->edid_length);
+ else if (output_info->name)
+ output_name = output_info->name;
+ }
+ if (output_name)
+ edje_object_part_text_set(output, "output_txt", output_name);
+
+ //set output orientation
+ e_config_randr_dialog_subdialog_orientation_update_edje(output);
+ return output;
+
+_e_config_randr_dialog_subdialog_arrangement_output_add_edje_set_fail:
+ evas_object_del(output);
+ return NULL;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_smart_class_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
+{
+ Evas_Object *output;
+ Evas_Coord real_sum_w = 0 , real_sum_h = 0;
+ Eina_Rectangle parent_geo, new_geo;
+ Evas_Coord_Point offset = {.x = 0, .y = 0};
+ Evas_Coord offset_x_max = 0;
+ float scaling_factor = 0.1;
+ Eina_List *lst, *itr;
+ const E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ evas_object_geometry_get(obj, &parent_geo.x, &parent_geo.y, &parent_geo.w, &parent_geo.h);
+ fprintf(stderr, "CONF_RANDR: Arrangement dialog shall be resized to %d x %d\n", w, h);
+ fprintf(stderr, "CONF_RANDR: Arrangement dialog Smart object geo: %d x %d, %d x %d\n", parent_geo.x, parent_geo.y, parent_geo.w, parent_geo.h);
+ if ((w < 1) || (h < 1)) return;
+
+ lst = evas_object_smart_members_get(obj);
+ //Calc average aspect ratio from all available monitors
+ EINA_LIST_FOREACH(lst, itr, output)
+ {
+ if ((output == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(output_dialog_data = evas_object_data_get(output, "output_info")) || (!output_dialog_data->previous_mode && !output_dialog_data->preferred_mode)) continue;
+ if (output_dialog_data->previous_mode)
+ {
+ real_sum_w += output_dialog_data->previous_mode->width;
+ real_sum_h += output_dialog_data->previous_mode->height;
+ }
+ else
+ {
+ real_sum_w += output_dialog_data->preferred_mode->width;
+ real_sum_h += output_dialog_data->preferred_mode->height;
+ }
+ }
+
+ scaling_factor = (((float)parent_geo.w / (float)real_sum_w) < ((float)parent_geo.h / (float)real_sum_h)) ? ((float)parent_geo.w / (float)real_sum_w) : ((float)parent_geo.h / (float)real_sum_h);
+ scaling_factor *= e_scale;
+
+ EINA_LIST_FOREACH(lst, itr, output)
+ {
+ //Skip elements that are either the clipped smart object or falsely added
+ //to the list of outputs (which should not happen)
+ if ((output == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(output_dialog_data = evas_object_data_get(output, "output_info"))) continue;
+ if (output_dialog_data->previous_mode)
+ {
+ new_geo.w = (int)((float)output_dialog_data->previous_mode->width * scaling_factor);
+ new_geo.h = (int)((float)output_dialog_data->previous_mode->height * scaling_factor);
+ }
+ else if (output_dialog_data->preferred_mode)
+ {
+ new_geo.w = (int)((float)output_dialog_data->preferred_mode->width * scaling_factor);
+ new_geo.h = (int)((float)output_dialog_data->preferred_mode->height * scaling_factor);
+ }
+ else
+ {
+ fprintf(stderr, "CONF_RANDR: Can't resize thumb, as neither mode nor preferred mode are avavailable for %x\n", (output_dialog_data->crtc ? output_dialog_data->crtc->xid : output_dialog_data->output->xid));
+ continue;
+ }
+ if ((new_geo.w <= 0) || (new_geo.h <= 0))
+ {
+ //this is an effect, occuring during dialog closing.
+ //If we don't return here, e_thumb will segfault!
+ return;
+ }
+ if ((output_dialog_data->previous_pos.x == Ecore_X_Randr_Unset) || (output_dialog_data->previous_pos.y == Ecore_X_Randr_Unset))
+ {
+ //this is a non enabled monitor
+ new_geo.x = parent_geo.x + parent_geo.w - new_geo.w - offset.x;
+ new_geo.y = parent_geo.y + offset.y;
+ offset.y = new_geo.y + new_geo.h;
+ if (offset_x_max < new_geo.w)
+ {
+ //adopt new max value for x
+ offset_x_max = new_geo.w;
+ }
+ if ((offset.y + new_geo.h) > (parent_geo.y + parent_geo.h))
+ {
+ //reset offset.y and adjust offset.x
+ offset.y = 0;
+ offset.x += offset_x_max;
+ }
+ }
+ else
+ {
+ new_geo.x = ((int)((float)output_dialog_data->previous_pos.x * scaling_factor)) + parent_geo.x;
+ new_geo.y = ((int)((float)output_dialog_data->previous_pos.y * scaling_factor)) + parent_geo.y;
+ }
+ //resize edje element
+ evas_object_resize(output, new_geo.w, new_geo.h);
+ //also resize bg
+ e_thumb_icon_size_set(output_dialog_data->bg, new_geo.w, new_geo.h); //need to clarify the usage of e_thumb. Usable without e_thumb_icon_file_set??!!
+ evas_object_move(output, new_geo.x, new_geo.y);
+ fprintf(stderr, "CONF_RANDR: output representation %p was resized to %d x %d\n", output, new_geo.w, new_geo.h);
+ fprintf(stderr, "CONF_RANDR: output representation %p was moved to %d x %d\n", output, new_geo.x, new_geo.y);
+ }
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_down_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*)event_info;
+ Evas_Object *element = NULL;
+ Eina_List *iter;
+ Eina_Bool crtc_selected = EINA_FALSE;
+
+ EINA_LIST_FOREACH(evas_object_smart_members_get(evas_object_smart_parent_get(obj)), iter, element)
+ {
+ if (e_config_runtime_info->gui.subdialogs.arrangement.clipper == obj) continue;
+ if (element != obj)
+ edje_object_signal_emit(element, "deselect", "e");
+ else
+ {
+ edje_object_signal_emit(element, "select", "e");
+ //update data for other dialogs
+ e_config_runtime_info->gui.selected_eo = obj;
+
+ //update resolutions list
+ e_config_randr_dialog_subdialog_resolutions_update_list(obj);
+
+ //update orientation radio buttons
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(obj);
+
+ //update policy radio buttons
+ e_config_randr_dialog_subdialog_policies_update_radio_buttons(obj);
+
+ crtc_selected = EINA_TRUE;
+ }
+ }
+ if (!crtc_selected)
+ {
+ //update data for other dialogs
+ e_config_runtime_info->gui.selected_eo = NULL;
+
+ //update resolutions list
+ e_config_randr_dialog_subdialog_resolutions_update_list(NULL);
+
+ //update orientation radio buttons
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(NULL);
+
+ //update policy radio buttons
+ e_config_randr_dialog_subdialog_policies_update_radio_buttons(NULL);
+ }
+
+ evas_object_geometry_get(obj, &e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.x, &e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.y, NULL, NULL);
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_move_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Event_Mouse_Move *ev = event_info;
+ Eina_Rectangle geo, parent;
+ Evas_Coord_Point delta, new;
+
+ if (ev->buttons == 1)
+ {
+ evas_object_geometry_get (obj, &geo.x, &geo.y, &geo.w, &geo.h);
+ evas_object_geometry_get (evas_object_smart_parent_get(obj), &parent.x, &parent.y, &parent.w, &parent.h);
+ delta.x = ev->cur.canvas.x - ev->prev.canvas.x;
+ delta.y = ev->cur.canvas.y - ev->prev.canvas.y;
+
+ new.x = geo.x + delta.x;
+ new.y = geo.y + delta.y;
+ //respect container borders
+ if (new.x < parent.x + 1)
+ new.x = parent.x + 1;
+ else if (new.x > parent.x + parent.w - geo.w)
+ new.x = parent.x + parent.w - geo.w;
+ if (new.y < parent.y + 1)
+ new.y = parent.y + 1;
+ else if (new.y > parent.y + parent.h - geo.h)
+ new.y = parent.y + parent.h - geo.h;
+ //only take action if position changed
+ if ((geo.x != new.x) || (geo.y != new.y))
+ {
+ evas_object_move(obj, new.x, new.y);
+ _e_config_randr_dialog_subdialog_arrangement_make_suggestion(obj);
+ }
+ }
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_output_mouse_up_cb (void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ Evas_Coord_Point coords;
+
+ if (evas_object_visible_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion))
+ {
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "hide", "e");
+ evas_object_geometry_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, &coords.x, &coords.y, NULL, NULL);
+ evas_object_move(obj, coords.x, coords.y);
+ }
+ else
+ {
+ evas_object_move(obj, e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.x, e_config_runtime_info->gui.subdialogs.arrangement.previous_pos.y);
+ }
+
+}
+
+void
+_e_config_randr_dialog_subdialog_arrangement_suggestion_add(Evas *evas)
+{
+ const char *theme_data_item = NULL;
+
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion = edje_object_add(evas);
+ edje_object_file_set(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, _theme_file_path, "e/conf/randr/dialog/subdialog/arrangement/suggestion");
+ if ((theme_data_item = edje_object_data_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "distance_min")))
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min = MIN(MAX(atoi(theme_data_item), 0), 100);
+ else
+ e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min = 20;
+}
+
+ void
+_e_config_randr_dialog_subdialog_arrangement_make_suggestion (Evas_Object *obj)
+{
+ Eina_List *li, *crtcs = evas_object_smart_members_get(evas_object_smart_parent_get(obj));
+ Evas_Object *crtc = NULL;
+ Eina_Rectangle p_geo, geo, crtc_geo, s_geo;
+ int dxa = 10000, dya = 10000, tmp, min_dist;
+
+ if (!obj) return;
+
+ if (!e_config_runtime_info->gui.subdialogs.arrangement.suggestion)
+ {
+ _e_config_randr_dialog_subdialog_arrangement_suggestion_add(evas_object_evas_get(obj));
+ evas_object_show(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ }
+
+ min_dist = e_config_runtime_info->gui.subdialogs.arrangement.suggestion_dist_min;
+
+ evas_object_geometry_get(evas_object_smart_parent_get(obj), &p_geo.x, &p_geo.y, &p_geo.w, &p_geo.h);
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+
+ s_geo.x = geo.x;
+ s_geo.y = geo.y;
+ s_geo.w = geo.w;
+ s_geo.h = geo.h;
+
+ //compare possible positions
+ //aritifical (relative) 0x0 element
+ tmp = s_geo.x;
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = p_geo.x;
+ dxa = tmp;
+ }
+ tmp = s_geo.y;
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = p_geo.y;
+ dya = tmp;
+ }
+ //iterate crtc list
+ EINA_LIST_FOREACH(crtcs, li, crtc)
+ {
+ if ((crtc == obj) || (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper)) continue;
+ evas_object_geometry_get(crtc, &crtc_geo.x, &crtc_geo.y, &crtc_geo.w, &crtc_geo.h);
+ //X-Axis
+ tmp = abs(s_geo.x - crtc_geo.x);
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = crtc_geo.x;
+ dxa = abs(s_geo.x - crtc_geo.x);
+ }
+
+ tmp = abs(s_geo.x - (crtc_geo.x + crtc_geo.w));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x + crtc_geo.w);
+ dxa = tmp;
+ }
+
+ tmp = abs((s_geo.x + s_geo.w) - (crtc_geo.x - 1));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x - s_geo.w);
+ dxa = tmp;
+ }
+
+ tmp = abs((s_geo.x + s_geo.w) - (crtc_geo.x + crtc_geo.w));
+ if ((tmp < dxa) && (tmp < min_dist))
+ {
+ s_geo.x = (crtc_geo.x + crtc_geo.w - s_geo.w);
+ dxa = tmp;
+ }
+
+ //Y-Axis
+ tmp = abs(s_geo.y - crtc_geo.y);
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = crtc_geo.y;
+ dya = abs(s_geo.y - crtc_geo.y);
+ }
+
+ tmp = abs(s_geo.y - (crtc_geo.y + crtc_geo.h));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y + crtc_geo.h);
+ dya = tmp;
+ }
+
+ tmp = abs((s_geo.y + s_geo.h) - (crtc_geo.y - 1));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y - s_geo.h);
+ dya = tmp;
+ }
+
+ tmp = abs((s_geo.y + s_geo.h) - (crtc_geo.y + crtc_geo.h));
+ if ((tmp < dya) && (tmp < min_dist))
+ {
+ s_geo.y = (crtc_geo.y + crtc_geo.h - s_geo.h);
+ dya = tmp;
+ }
+
+ }
+
+
+ if ((s_geo.x != geo.x) && (s_geo.y != geo.y))
+ {
+ if (s_geo.x < p_geo.x) s_geo.x = p_geo.x;
+ if ((s_geo.x + s_geo.w) > (p_geo.x + p_geo.w)) s_geo.x = ((p_geo.x + p_geo.w) - s_geo.w);
+ if (s_geo.y < p_geo.y) s_geo.y = p_geo.y;
+ if ((s_geo.y + s_geo.h) > (p_geo.y + p_geo.h)) s_geo.y = ((p_geo.y + p_geo.h) - s_geo.h);
+
+ if (!evas_object_visible_get(e_config_runtime_info->gui.subdialogs.arrangement.suggestion))
+ {
+ evas_object_show(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "show", "e");
+ }
+
+ evas_object_resize(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, s_geo.w, s_geo.h);
+ evas_object_move(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, s_geo.x, s_geo.y);
+ }
+ else
+ {
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.arrangement.suggestion, "hide", "e");
+ evas_object_hide(e_config_runtime_info->gui.subdialogs.arrangement.suggestion);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_free_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data;
+
+ EINA_SAFETY_ON_NULL_RETURN(cfdata);
+
+ EINA_LIST_FREE(cfdata->output_dialog_data_list, dialog_data)
+ {
+ if (dialog_data)
+ {
+ if (dialog_data->bg)
+ {
+ evas_object_del(dialog_data->bg);
+ dialog_data->bg = NULL;
+ }
+ free(dialog_data);
+ dialog_data = NULL;
+ }
+ }
+}
+
+ static Eina_List
+*_e_config_randr_dialog_subdialog_arrangement_neighbors_get(Evas_Object *obj)
+{
+ Evas_Object *smart_parent, *crtc;
+ Eina_List *crtcs, *iter, *neighbors = NULL;
+ Eina_Rectangle geo, neighbor_geo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data, *neighbor_info;
+
+ smart_parent = evas_object_smart_parent_get(obj);
+ crtcs = evas_object_smart_members_get(smart_parent);
+
+ EINA_SAFETY_ON_FALSE_RETURN_VAL((dialog_data = evas_object_data_get(obj, "output_info")), NULL);
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if ((crtc == obj)
+ || (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper)) continue;
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+ if(!(neighbor_info = evas_object_data_get(crtc, "output_info"))) continue;
+
+ if (((geo.x + geo.w) == neighbor_geo.x)
+ || (geo.x == (neighbor_geo.x + neighbor_geo.w))
+ || (geo.x == neighbor_geo.x)
+ || ((geo.x + geo.w) == (neighbor_geo.x + neighbor_geo.w))
+ || ((geo.y + geo.h) == neighbor_geo.y)
+ || (geo.y == (neighbor_geo.y + neighbor_geo.h))
+ || (geo.y == neighbor_geo.y)
+ || ((geo.y + geo.h) == (neighbor_geo.y + neighbor_geo.h)))
+ {
+ neighbors = eina_list_append(neighbors, crtc);
+ }
+ }
+
+ return neighbors;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(Evas_Object *obj)
+{
+ Eina_List *neighbors, *iter;
+ Evas_Object *smart_parent, *crtc;
+ E_Config_Randr_Dialog_Output_Dialog_Data *dialog_data, *neighbor_info;
+ Eina_Rectangle geo, neighbor_geo, smart_geo;
+
+ // Each object is seen as a tree. All its edges are compared to their
+ // neighbors and wandered recusively.
+ EINA_SAFETY_ON_NULL_RETURN(obj);
+
+ smart_parent = e_config_runtime_info->gui.subdialogs.arrangement.smart_parent;
+ evas_object_geometry_get(smart_parent, &smart_geo.x, &smart_geo.y, &smart_geo.w, &smart_geo.h);
+ //fprintf(stderr, "CONF_RANDR: Smart Parent is at %dx%d\n", smart_geo.x, smart_geo.y);
+ neighbors = _e_config_randr_dialog_subdialog_arrangement_neighbors_get(obj);
+
+ EINA_SAFETY_ON_FALSE_RETURN((dialog_data = evas_object_data_get(obj, "output_info")));
+ evas_object_geometry_get(obj, &geo.x, &geo.y, &geo.w, &geo.h);
+
+ //fprintf(stderr, "CONF_RANDR: Traversed element (%p) is at %dx%d\n", obj, geo.x, geo.y);
+ if (geo.x == e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.x) dialog_data->new_pos.x = 0;
+ if (geo.y == e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.y) dialog_data->new_pos.y = 0;
+
+ if ((dialog_data->new_pos.x != 0) || (dialog_data->new_pos.y != 0))
+ {
+ // Find neighbor object we can calculate our own coordinates from
+ EINA_LIST_FOREACH(neighbors, iter, crtc)
+ {
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+ if (!(neighbor_info = evas_object_data_get(crtc, "output_info"))) continue;
+
+ evas_object_geometry_get(crtc, &neighbor_geo.x, &neighbor_geo.y, &neighbor_geo.w, &neighbor_geo.h);
+
+ if ((dialog_data->new_pos.x == Ecore_X_Randr_Unset) && (neighbor_info->new_pos.x != Ecore_X_Randr_Unset))
+ {
+ if ((geo.x + geo.w) == neighbor_geo.x)
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x - dialog_data->previous_mode->width;
+ }
+
+ if (geo.x == (neighbor_geo.x + neighbor_geo.w))
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x + neighbor_info->previous_mode->width;
+ }
+
+ if (geo.x == neighbor_geo.x)
+ {
+ dialog_data->new_pos.x = neighbor_info->new_pos.x;
+ }
+
+ if ((geo.x + geo.w) == (neighbor_geo.x + neighbor_geo.w))
+ {
+ dialog_data->new_pos.x = (neighbor_info->new_pos.x + neighbor_info->previous_mode->width) - dialog_data->previous_mode->width;
+ }
+ }
+
+ if ((dialog_data->new_pos.y == Ecore_X_Randr_Unset) && (neighbor_info->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ if ((geo.y + geo.h) == neighbor_geo.y)
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y - dialog_data->previous_mode->height;
+ }
+
+ if (geo.y == (neighbor_geo.y + neighbor_geo.h))
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y + neighbor_info->previous_mode->height;
+ }
+
+ if (geo.y == neighbor_geo.y)
+ {
+ dialog_data->new_pos.y = neighbor_info->new_pos.y;
+ }
+
+ if ((geo.y + geo.h) == (neighbor_geo.y + neighbor_geo.h))
+ {
+ dialog_data->new_pos.y = (neighbor_info->new_pos.y + neighbor_info->previous_mode->height) - dialog_data->previous_mode->height;
+ }
+ }
+ if ((dialog_data->new_pos.x != Ecore_X_Randr_Unset)
+ && (dialog_data->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ //fprintf(stderr, "CONF_RANDR: Determined position for %p: %dx%d\n", obj, dialog_data->new_pos.x, dialog_data->new_pos.y);
+ break;
+ }
+ }
+ }
+ if ((dialog_data->new_pos.x != Ecore_X_Randr_Unset) || (dialog_data->new_pos.y != Ecore_X_Randr_Unset))
+ {
+ //Only wander all neighbors recursively, if they can use the current
+ //element as reference for their position
+ EINA_LIST_FOREACH(neighbors, iter, crtc)
+ {
+ neighbor_info = evas_object_data_get(crtc, "output_info");
+ if ((neighbor_info->new_pos.x == Ecore_X_Randr_Unset)
+ || (neighbor_info->new_pos.y == Ecore_X_Randr_Unset))
+ {
+ //fprintf(stderr, "CONF_RANDR: Now going to travel %p.\n", crtc);
+ _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(crtc);
+ }
+ }
+ }
+ eina_list_free(neighbors);
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_List *crtcs, *iter;
+ Evas_Object *smart_parent, *crtc, *top_left = NULL;
+ Eina_Rectangle geo, smart_geo;
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Evas_Coord_Point relz = { .x = 10000, .y = 10000};
+ Eina_Bool arrangement_failed = EINA_FALSE;
+
+ smart_parent = e_config_runtime_info->gui.subdialogs.arrangement.smart_parent;
+ evas_object_geometry_get(smart_parent, &smart_geo.x, &smart_geo.y, &smart_geo.w, &smart_geo.h);
+ crtcs = evas_object_smart_members_get(smart_parent);
+
+ //Create virtual borders around the displayed representations by finding
+ //relative x and y as virtual 0x0
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if (crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper) continue;
+ //Already reset values for upcoming calculation
+ if (!(odd = evas_object_data_get(crtc, "output_info"))) continue;
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+ odd = NULL;
+
+ //See whether this element is closer to 0x0 than any before
+ evas_object_geometry_get(crtc, &geo.x, &geo.y, &geo.w, &geo.h);
+ if (geo.x < relz.x)
+ {
+ relz.x = geo.x;
+ top_left = crtc;
+ }
+ if (geo.y < relz.y)
+ {
+ relz.y = geo.y;
+ top_left = crtc;
+ }
+ }
+ e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.x = relz.x;
+ e_config_runtime_info->gui.subdialogs.arrangement.relative_zero.y = relz.y;
+ if (top_left) _e_config_randr_dialog_subdialog_arrangement_determine_positions_recursive(top_left);
+
+ EINA_LIST_FOREACH(crtcs, iter, crtc)
+ {
+ if ((crtc == e_config_runtime_info->gui.subdialogs.arrangement.clipper) || !(odd = evas_object_data_get(crtc, "output_info")) || !odd->crtc
+ || ((odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))) continue;
+ if ((odd->previous_pos.x != odd->new_pos.x) || (odd->previous_pos.y != odd->new_pos.y))
+ {
+ fprintf(stderr, "CONF_RANDR: CRTC %x is moved to %dx%d\n", odd->crtc->xid, odd->new_pos.x, odd->new_pos.y);
+ if (!ecore_x_randr_crtc_pos_set(cfd->con->manager->root, odd->crtc->xid, odd->new_pos.x, odd->new_pos.y))
+ {
+ arrangement_failed = EINA_TRUE;
+ break;
+ }
+ }
+ }
+ if (arrangement_failed)
+ return EINA_FALSE;
+ else
+ {
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ return EINA_TRUE;
+ }
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_arrangement_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Eina_List *iter;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, output_dialog_data)
+ {
+ if ((output_dialog_data->previous_pos.x != output_dialog_data->new_pos.x)
+ || (output_dialog_data->previous_pos.y != output_dialog_data->new_pos.y)
+ ) return EINA_TRUE;
+ }
+ return EINA_FALSE;
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || ((odd->new_pos.x == Ecore_X_Randr_Unset) || (odd->new_pos.y == Ecore_X_Randr_Unset))) continue;
+ odd->previous_pos.x = odd->new_pos.x;
+ odd->previous_pos.y = odd->new_pos.y;
+ odd->new_pos.x = Ecore_X_Randr_Unset;
+ odd->new_pos.y = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_arrangement_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || ((odd->previous_pos.x == Ecore_X_Randr_Unset) || (odd->previous_pos.y == Ecore_X_Randr_Unset))) continue;
+ if (ecore_x_randr_crtc_pos_set(cfdata->manager->root, odd->crtc->xid, odd->previous_pos.x, odd->previous_pos.y))
+ {
+ odd->new_pos.x = odd->previous_pos.x;
+ odd->new_pos.y = odd->previous_pos.y;
+ odd->previous_pos.x = Ecore_X_Randr_Unset;
+ odd->previous_pos.y = Ecore_X_Randr_Unset;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
--- /dev/null
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#define RANDR_DIALOG_ORIENTATION_ALL (ECORE_X_RANDR_ORIENTATION_ROT_0 | ECORE_X_RANDR_ORIENTATION_ROT_90 | ECORE_X_RANDR_ORIENTATION_ROT_180 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_ROT_270 | ECORE_X_RANDR_ORIENTATION_FLIP_X | ECORE_X_RANDR_ORIENTATION_FLIP_Y)
+
+Eina_Bool e_config_randr_dialog_subdialog_orientation_create_data (E_Config_Dialog_Data *cfdata);
+Evas_Object *e_config_randr_dialog_subdialog_orientation_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_orientation_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_orientation_update_radio_buttons(Evas_Object *crtc);
+void e_config_randr_dialog_subdialog_orientation_update_edje(Evas_Object *crtc);
+
+static void _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+/*
+static void
+_e_config_randr_dialog_subdialog_orientation_radio_add_callbacks(void)
+{
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add (e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb, NULL);
+}
+*/
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_create_data(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Crtc_Info *ci;
+ Eina_List *iter;
+
+ if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!ci || !ci->current_mode) continue;
+ odd->new_orientation = Ecore_X_Randr_Unset;
+ odd->previous_orientation = ci->current_orientation;
+ }
+
+ return EINA_TRUE;
+}
+
+Evas_Object *
+e_config_randr_dialog_subdialog_orientation_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+ E_Radio_Group *rg;
+ //char signal[29];
+
+ if (!canvas || !e_config_runtime_info) return NULL;
+ if (e_config_runtime_info->gui.subdialogs.orientation.dialog) return e_config_runtime_info->gui.subdialogs.orientation.dialog;
+
+ if (!(subdialog = e_widget_framelist_add(canvas, _("Display Orientation"), EINA_FALSE))) return NULL;
+
+ // Add radio buttons
+ if(!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.subdialogs.orientation.radio_val))) goto _e_config_randr_dialog_subdialog_orientation_radio_add_fail;
+
+ //IMPROVABLE: use enum to determine objects via 'switch'-statement
+ e_config_runtime_info->gui.subdialogs.orientation.radio_normal = e_widget_radio_add(canvas, _("Normal"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_normal);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot90 = e_widget_radio_add(canvas, _("Rotated, 90°"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot90);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot180 = e_widget_radio_add(canvas, _("Rotated, 180°"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot180);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_rot270 = e_widget_radio_add(canvas, _("Rotated, 270°"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_rot270);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal = e_widget_radio_add(canvas, _("Flipped, horizontally"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal);
+
+ e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical = e_widget_radio_add(canvas, _("Flipped, vertically"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical);
+
+ //_e_config_randr_dialog_subdialog_orientation_radio_add_callbacks();
+
+ /*
+ // Add orientation demonstration edje
+ if (!(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje = edje_object_add(canvas)))
+ goto _e_config_randr_dialog_subdialog_orientation_edje_add_fail;
+ if (!edje_object_file_set(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/subdialog/orientation"))
+ goto _e_config_randr_dialog_subdialog_orientation_edje_set_fail;
+
+ e_widget_table_object_align_append(subdialog, e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
+ */
+
+ //disable widgets, if no CRTC is selected
+ e_config_randr_dialog_subdialog_orientation_update_radio_buttons(e_config_runtime_info->gui.selected_eo);
+
+ //evas_object_show(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje);
+
+ return subdialog;
+
+ /*
+_e_config_randr_dialog_subdialog_orientation_edje_set_fail:
+ evas_object_del(ol);
+ evas_object_del(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje);
+_e_config_randr_dialog_subdialog_orientation_edje_add_fail:
+ fprintf(stderr, "CONF_RANDR: Couldn't set edj for orientation subdialog!\n");
+ evas_object_del(subdialog);
+ return NULL;
+ */
+_e_config_randr_dialog_subdialog_orientation_radio_add_fail:
+ evas_object_del(subdialog);
+ fprintf(stderr, "CONF_RANDR: Could not add radio group!\n");
+ return NULL;
+}
+
+/*
+ static void
+_e_config_randr_dialog_subdialog_orientation_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ char signal[40];
+ int orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+
+ /*
+ * IMPROVABLE:
+ * "sadly" the evas callbacks are called before radio_val is set to its new
+ * value. If that is ever changed, remove the used code below and just use the
+ * 1-liner below.
+ * snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,%d", e_config_runtime_info->gui.subdialogs.orientation.radio_val);
+ * /
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_normal) orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot90) orientation = ECORE_X_RANDR_ORIENTATION_ROT_90;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot180) orientation = ECORE_X_RANDR_ORIENTATION_ROT_180;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_rot270) orientation = ECORE_X_RANDR_ORIENTATION_ROT_270;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_X;
+ if (obj == e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical) orientation = ECORE_X_RANDR_ORIENTATION_FLIP_Y;
+
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,%d", orientation);
+
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.orientation.swallowing_edje, signal, "e");
+
+ fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to orientation: %s\n", signal);
+}
+*/
+
+ void
+e_config_randr_dialog_subdialog_orientation_update_radio_buttons(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Orientation supported_oris, ori;
+ char signal[40];
+
+ //disable widgets, if no crtc is selected
+ if (!crtc)
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+ return;
+ }
+
+ if (!(output_dialog_data = evas_object_data_get(crtc, "output_info"))) return;
+
+ if (output_dialog_data->crtc)
+ {
+ //enabled monitor
+ supported_oris = output_dialog_data->crtc->orientations;
+ ori = output_dialog_data->crtc->current_orientation;
+ }
+ else
+ {
+ //disabled monitor
+ //assume all orientations are supported
+ supported_oris = RANDR_DIALOG_ORIENTATION_ALL;
+ ori = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ }
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_0)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_90)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_180)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_ROT_270)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_X)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+
+ if (supported_oris & ECORE_X_RANDR_ORIENTATION_FLIP_Y)
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_FALSE);
+ else
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+
+ //toggle the switch of the currently used orientation
+ switch (ori)
+ {
+ case ECORE_X_RANDR_ORIENTATION_ROT_90:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot90, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_ROT_180:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot180, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_ROT_270:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_rot270, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_FLIP_X:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_horizontal, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_ORIENTATION_FLIP_Y:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_reflect_vertical, EINA_TRUE);
+ break;
+ default: //== ECORE_X_RANDR_ORIENTATION_ROT_0:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.orientation.radio_normal, EINA_TRUE);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_update_edje(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Orientation supported_oris, ori;
+ char signal[40];
+
+ if (!e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(crtc, "output_info"))) return;
+
+ if (output_dialog_data->crtc)
+ {
+ //enabled monitor
+ supported_oris = output_dialog_data->crtc->orientations;
+ ori = output_dialog_data->crtc->current_orientation;
+ }
+ else
+ {
+ //disabled monitor
+ //assume all orientations are supported
+ supported_oris = RANDR_DIALOG_ORIENTATION_ALL;
+ ori = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ }
+ //Send signal to the edje, to represent the supported and current set orientation
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,supported,%d", supported_oris);
+ edje_object_signal_emit(crtc, signal, "e");
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,orientation,current,%d", ori);
+ edje_object_signal_emit(crtc, signal, "e");
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Orientation orientation;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.subdialogs.orientation.dialog || !e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info")) || !output_dialog_data->crtc) return EINA_FALSE;
+
+ orientation = e_config_runtime_info->gui.subdialogs.orientation.radio_val;
+
+ fprintf(stderr, "CONF_RANDR: Change orientation of crtc %x to %d.\n", output_dialog_data->crtc->xid, orientation);
+
+ if (ecore_x_randr_crtc_orientation_set(cfd->con->manager->root, output_dialog_data->crtc->xid, orientation))
+ {
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ output_dialog_data->previous_orientation = output_dialog_data->new_orientation;
+ output_dialog_data->new_orientation = orientation;
+ return EINA_TRUE;
+ }
+ else
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_orientation_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Orientation orientation = ECORE_X_RANDR_ORIENTATION_ROT_0;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.subdialogs.orientation.dialog || !e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info"))) return EINA_FALSE;
+
+ return (output_dialog_data->previous_orientation != e_config_runtime_info->gui.subdialogs.orientation.radio_val);
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd || (odd->previous_orientation == Ecore_X_Randr_Unset)) continue;
+ odd->previous_orientation = odd->new_orientation;
+ odd->new_orientation = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_orientation_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || (odd->previous_orientation == Ecore_X_Randr_Unset)) continue;
+ if (ecore_x_randr_crtc_orientation_set(cfdata->manager->root, odd->crtc->xid, odd->previous_orientation))
+ {
+ odd->new_orientation = odd->previous_orientation;
+ odd->previous_orientation = Ecore_X_Randr_Unset;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
--- /dev/null
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+
+#ifndef ECORE_X_RANDR_1_2
+#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
+#endif
+#ifndef ECORE_X_RANDR_1_3
+#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
+#endif
+
+#ifndef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#endif
+
+Evas_Object *e_config_randr_dialog_subdialog_policies_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_policies_basic_apply_data(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_policies_update_radio_buttons(Evas_Object *crtc);
+
+static void _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
+extern E_Config_Dialog_Data *e_config_runtime_info;
+extern char _theme_file_path[];
+
+/*
+static void
+_e_config_randr_dialog_subdialog_policies_radio_add_callbacks(void)
+{
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_none, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_left, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_below, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_above, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+ evas_object_event_callback_add(e_config_runtime_info->gui.subdialogs.policies.radio_right, EVAS_CALLBACK_MOUSE_UP, _e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb, NULL);
+}
+*/
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_create_data(E_Config_Dialog_Data *e_config_runtime_info)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Output_Info *oi;
+ Eina_List *iter;
+
+ if (!e_config_runtime_info || !e_config_runtime_info->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(e_config_runtime_info->output_dialog_data_list, iter, odd)
+ {
+ if (odd->crtc)
+ oi = eina_list_data_get(eina_list_last(odd->crtc->outputs));
+ else if (odd->output)
+ oi = odd->output;
+ if (!oi) continue;
+ odd->previous_policy = oi->policy;
+ odd->new_policy = Ecore_X_Randr_Unset;
+ }
+
+ return EINA_TRUE;
+}
+
+Evas_Object *
+e_config_randr_dialog_subdialog_policies_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+ E_Radio_Group *rg;
+ //char signal[29];
+
+ if (!canvas || !e_config_runtime_info) return NULL;
+
+ if (e_config_runtime_info->gui.subdialogs.policies.dialog) return e_config_runtime_info->gui.subdialogs.policies.dialog;
+
+ if(!(subdialog = e_widget_framelist_add(canvas, _("Screen attachement policy"), EINA_FALSE))) return NULL;
+
+ // Add radio buttons
+ if (!(rg = e_widget_radio_group_new(&e_config_runtime_info->gui.subdialogs.policies.radio_val))) goto _e_config_randr_dialog_subdialog_policies_radio_add_fail;
+
+ //IMPROVABLE: use enum to determine objects via 'switch'-statement
+ e_config_runtime_info->gui.subdialogs.policies.radio_above = e_widget_radio_add(canvas, _("Above"), ECORE_X_RANDR_OUTPUT_POLICY_ABOVE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_above);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_right = e_widget_radio_add(canvas, _("Right"), ECORE_X_RANDR_OUTPUT_POLICY_RIGHT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_right);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_below = e_widget_radio_add(canvas, _("Below"), ECORE_X_RANDR_OUTPUT_POLICY_BELOW, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_below);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_left = e_widget_radio_add(canvas, _("Left"), ECORE_X_RANDR_OUTPUT_POLICY_LEFT, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_left);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_clone = e_widget_radio_add(canvas, _("Clone display content"), ECORE_X_RANDR_OUTPUT_POLICY_CLONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_clone);
+
+ e_config_runtime_info->gui.subdialogs.policies.radio_none = e_widget_radio_add(canvas, _("No reaction"), ECORE_X_RANDR_OUTPUT_POLICY_NONE, rg);
+ e_widget_framelist_object_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.radio_none);
+
+ //_e_config_randr_dialog_subdialog_policies_radio_add_callbacks();
+
+ /*
+ // Add policies demonstration edje
+ if (!(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje = edje_object_add(canvas)))
+ {
+ goto _e_config_randr_dialog_subdialog_policies_edje_add_fail;
+
+ }
+ if (!edje_object_file_set(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, _theme_file_path, "e/conf/randr/dialog/subdialog/policies"))
+ {
+ goto _e_config_randr_dialog_subdialog_policies_edje_set_fail;
+ }
+
+ e_widget_table_object_align_append(subdialog, e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, 1, 0, 1, 1, 1, 1, 1, 1, 1.0, 1.0);
+ */
+
+ /*
+ evas_object_show(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje);
+
+ //emit signal to edje so a demonstration can be shown
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_randr_screen_info->rrvd_info.randr_info_12->output_policy);
+ edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, signal, "e");
+ fprintf(stderr, "CONF_RANDR: Initial signal emitted to policy dialog: %s\n", signal);
+
+ //Use theme's background as screen representation
+ e_config_runtime_info->gui.subdialogs.policies.new_display = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.new_display, "base/theme/widgets", "e/widgets/frame");
+ e_config_runtime_info->gui.subdialogs.policies.new_display_background = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.new_display_background, "base/theme/background", "e/desktop/background");
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.new_display, "e.swallow.content", e_config_runtime_info->gui.subdialogs.policies.new_display_background);
+ edje_object_part_text_set(e_config_runtime_info->gui.subdialogs.policies.new_display, "e.text.label", _("New display"));
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, "new_display.swallow.content", e_config_runtime_info->gui.subdialogs.policies.new_display);
+ //add theme's frame
+ //for now use the theme's background for the new display as well
+ e_config_runtime_info->gui.subdialogs.policies.current_displays_setup = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "base/theme/widgets", "e/widgets/frame");
+ e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background = edje_object_add(canvas);
+ e_theme_edje_object_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background, "base/theme/background", "e/desktop/background");
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "e.swallow.content", e_config_runtime_info->gui.subdialogs.policies.current_displays_setup_background);
+ edje_object_part_text_set(e_config_runtime_info->gui.subdialogs.policies.current_displays_setup, "e.text.label", _("Used display"));
+ edje_object_part_swallow(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, "current_displays_setup.swallow.content", e_config_runtime_info->gui.subdialogs.policies.current_displays_setup);
+ */
+
+ evas_object_show(subdialog);
+
+ return subdialog;
+
+ /*
+_e_config_randr_dialog_subdialog_policies_edje_set_fail:
+ evas_object_del(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje);
+_e_config_randr_dialog_subdialog_policies_edje_add_fail:
+ fprintf(stderr, "CONF_RANDR: Couldn't set edj for policies subdialog!\n");
+ evas_object_del(subdialog);
+ return NULL;
+ */
+_e_config_randr_dialog_subdialog_policies_radio_add_fail:
+ evas_object_del(subdialog);
+ return NULL;
+}
+
+ static void
+_e_config_randr_dialog_subdialog_policies_policy_mouse_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
+{
+ char signal[29];
+ int policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
+
+ /*
+ * IMPROVABLE:
+ * "sadly" the evas callbacks are called before radio_val is set to its new
+ * value. If that is ever changed, remove the used code below and just use the
+ * 1-liner below.
+ * snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", e_config_runtime_info->gui.subdialogs.policies.radio_val);
+ */
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_above) policy = ECORE_X_RANDR_OUTPUT_POLICY_ABOVE;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_right) policy = ECORE_X_RANDR_OUTPUT_POLICY_RIGHT;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_below) policy = ECORE_X_RANDR_OUTPUT_POLICY_BELOW;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_left) policy = ECORE_X_RANDR_OUTPUT_POLICY_LEFT;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_clone) policy = ECORE_X_RANDR_OUTPUT_POLICY_CLONE;
+ if (obj == e_config_runtime_info->gui.subdialogs.policies.radio_none) policy = ECORE_X_RANDR_OUTPUT_POLICY_NONE;
+
+ snprintf(signal, sizeof(signal), "conf,randr,dialog,policies,%d", policy);
+
+ //edje_object_signal_emit(e_config_runtime_info->gui.subdialogs.policies.swallowing_edje, signal, "e");
+
+ fprintf(stderr, "CONF_RANDR: mouse button released. Emitted signal to policy: %s\n", signal);
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ E_Randr_Output_Info *output_info;
+
+ if (!e_randr_screen_info || !e_config_runtime_info->gui.selected_output_dd) return EINA_FALSE;
+
+ //policy update
+ e_config_runtime_info->gui.selected_output_dd->previous_policy = e_config_runtime_info->gui.selected_output_dd->new_policy;
+ e_config_runtime_info->gui.selected_output_dd->new_policy = e_config_runtime_info->gui.subdialogs.policies.radio_val;
+ fprintf(stderr, "CONF_RANDR: 'New display attached'-policy set to %d\n", e_config_runtime_info->gui.selected_output_dd->new_policy);
+
+ return EINA_TRUE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_policies_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ if (!e_randr_screen_info || !cfdata || !cfdata->gui.selected_output_dd) return EINA_FALSE;
+
+ return (cfdata->gui.selected_output_dd->previous_policy != cfdata->gui.subdialogs.policies.radio_val);
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_update_radio_buttons(Evas_Object *crtc)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ E_Randr_Output_Info *output;
+ Ecore_X_Randr_Output_Policy policy;
+ char signal[40];
+
+ //disable widgets, if no crtc is selected
+ if (!crtc || !(output_dialog_data = evas_object_data_get(crtc, "output_info")))
+ {
+ //Evas_Object *radio_above, *radio_right, *radio_below, *radio_left, *radio_clone, *radio_none;
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_TRUE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_TRUE);
+ return;
+ }
+ else
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_FALSE);
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_FALSE);
+ }
+
+ if (output_dialog_data->crtc && output_dialog_data->crtc->outputs)
+ {
+ output = (E_Randr_Output_Info*)eina_list_data_get(eina_list_last(output_dialog_data->crtc->outputs));
+ }
+ else if (output_dialog_data->output)
+ {
+ output = output_dialog_data->output;
+ }
+
+ if (!output) return;
+ policy = output->policy;
+ e_config_runtime_info->gui.selected_output_dd = output_dialog_data;
+ //toggle the switch of the currently used policies
+ switch (policy)
+ {
+ case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_right, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_below, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_left, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_clone, EINA_TRUE);
+ break;
+ case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_none, EINA_TRUE);
+ break;
+ default: //== ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
+ e_widget_radio_toggle_set(e_config_runtime_info->gui.subdialogs.policies.radio_above, EINA_TRUE);
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd || (odd->previous_policy == Ecore_X_Randr_Unset)) continue;
+ odd->previous_policy = odd->new_policy;
+ odd->new_policy = Ecore_X_Randr_Unset;
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_policies_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (!odd->crtc || (odd->previous_policy == Ecore_X_Randr_Unset)) continue;
+ odd->new_policy = odd->previous_policy;
+ odd->previous_policy = Ecore_X_Randr_Unset;
+ }
+}
--- /dev/null
+#include "e_int_config_randr.h"
+#include "e_randr.h"
+#include "e_widget_ilist.h"
+
+#ifdef Ecore_X_Randr_Unset
+#undef Ecore_X_Randr_Unset
+#define Ecore_X_Randr_Unset -1
+#else
+#define Ecore_X_Randr_Unset -1
+#endif
+
+#ifdef Ecore_X_Randr_None
+#undef Ecore_X_Randr_None
+#endif
+#define Ecore_X_Randr_None 0
+
+#define ICON_WIDTH 10
+#define ICON_HEIGHT 10
+#define RESOLUTION_TXT_MAX_LENGTH 50
+
+Evas_Object *e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas);
+Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+Eina_Bool e_config_randr_dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_resolutions_update_list(Evas_Object *crtc);
+void e_config_randr_dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata);
+void e_config_randr_dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata);
+
+extern E_Config_Dialog_Data *e_config_runtime_info;
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_create_data(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ E_Randr_Crtc_Info *ci;
+ Ecore_X_Randr_Mode_Info *mi;
+ Eina_List *iter;
+
+ if (!cfdata || !cfdata->output_dialog_data_list) return EINA_FALSE;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (odd->previous_mode || odd->preferred_mode)
+ {
+ //this means, that mode info is already filled
+ //(by the display arrangement code)
+ break;
+ }
+ if (odd->crtc)
+ {
+ if(!(mi = odd->crtc->current_mode))
+ mi = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->crtc->outputs_common_modes));
+ odd->previous_mode = mi;
+ }
+ else if (odd->output)
+ {
+ odd->preferred_mode = (Ecore_X_Randr_Mode_Info*)eina_list_data_get(eina_list_last(odd->output->preferred_modes));
+ }
+ }
+
+ return EINA_TRUE;
+}
+
+ Evas_Object *
+e_config_randr_dialog_subdialog_resolutions_basic_create_widgets(Evas *canvas)
+{
+ Evas_Object *subdialog;
+
+ if (!canvas || !e_config_runtime_info || e_config_runtime_info->gui.subdialogs.resolutions.dialog || !(subdialog = e_widget_ilist_add(canvas, ICON_WIDTH * e_scale, ICON_HEIGHT * e_scale, NULL))) return NULL;
+
+ e_widget_ilist_multi_select_set(subdialog, EINA_FALSE);
+ e_widget_disabled_set(subdialog, EINA_TRUE);
+
+ evas_object_show(subdialog);
+
+ return subdialog;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_basic_apply_data (E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ //Apply new mode
+ Ecore_X_Randr_Mode_Info* selected_mode;
+ Ecore_X_ID selected_mode_xid;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Output *output = NULL;
+ E_Randr_Crtc_Info *crtc_info = NULL, *crtc_iter;
+ Eina_List *iter;
+ int noutputs = Ecore_X_Randr_Unset;
+
+ if (!e_config_runtime_info->gui.selected_eo || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info")))
+ {
+ fprintf(stderr, "CONF_RADNR: no crtc was selected or no output info could be retrieved for the selected crtc element (%p).\n", e_config_runtime_info->gui.selected_eo);
+ return EINA_FALSE;
+ }
+
+ if (output_dialog_data->crtc)
+ {
+ //CRTC is already asssigned, easy one!
+ crtc_info = output_dialog_data->crtc;
+ }
+ else if (output_dialog_data->output)
+ {
+ //CRTC not assigned yet. Let's try to find a non occupied one.
+ fprintf(stderr, "CONF_RANDR: Trying to find a CRTC for output %x, %d crtcs are possible.\n", output_dialog_data->output->xid, eina_list_count(output_dialog_data->output->possible_crtcs));
+ output = &output_dialog_data->output->xid;
+ noutputs = 1;
+ EINA_LIST_FOREACH(output_dialog_data->output->possible_crtcs, iter, crtc_iter)
+ {
+ if (!crtc_iter->outputs)
+ {
+ //CRTC is not occupied yet
+ crtc_info = crtc_iter;
+ break;
+ }
+ }
+ }
+ if (!crtc_info)
+ {
+ fprintf(stderr, "CONF_RANDR: Changing mode failed, no unoccupied CRTC found!\n");
+ return EINA_FALSE;
+ }
+ //get selected mode
+ if ((selected_mode = (Ecore_X_Randr_Mode_Info*)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)))
+ {
+ selected_mode_xid = selected_mode->xid;
+ }
+ else
+ {
+ selected_mode_xid = Ecore_X_Randr_None;
+ }
+
+ fprintf(stderr, "CONF_RANDR: Change mode of crtc %x to %x.\n", crtc_info->xid, selected_mode_xid);
+
+ if (ecore_x_randr_crtc_mode_set(cfd->con->manager->root, crtc_info->xid, output, noutputs, selected_mode_xid))
+ {
+ //remove unused space
+ ecore_x_randr_screen_reset(cfd->con->manager->root);
+ //update information
+ if (!output_dialog_data->crtc)
+ output_dialog_data->crtc = crtc_info;
+ output_dialog_data->new_mode = selected_mode;
+ return EINA_TRUE;
+ }
+
+ return EINA_FALSE;
+}
+
+ Eina_Bool
+e_config_randr_dialog_subdialog_resolutions_basic_check_changed(E_Config_Dialog *cfd, E_Config_Dialog_Data *cfdata)
+{
+ Ecore_X_Randr_Mode_Info* selected_mode;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+
+ if (!e_config_runtime_info->gui.selected_eo || !(selected_mode = (Ecore_X_Randr_Mode_Info*)e_widget_ilist_selected_data_get(e_config_runtime_info->gui.subdialogs.resolutions.dialog)) || !(output_dialog_data = evas_object_data_get(e_config_runtime_info->gui.selected_eo, "output_info"))) return EINA_FALSE;
+
+ return (selected_mode != output_dialog_data->previous_mode);
+}
+
+ void
+e_config_randr_dialog_subdialog_resolutions_update_list(Evas_Object *crtc)
+{
+ Eina_List *iter, *modelist = NULL;
+ E_Config_Randr_Dialog_Output_Dialog_Data *output_dialog_data;
+ Ecore_X_Randr_Mode_Info *mode_info, *current_mode;
+ char resolution_text[RESOLUTION_TXT_MAX_LENGTH];
+ float rate;
+ int str_ret, i = 0;
+
+ e_widget_ilist_freeze(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ e_widget_ilist_clear(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ if (!crtc)
+ {
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_TRUE);
+ return;
+ }
+ if (!(output_dialog_data = evas_object_data_get(crtc, "output_info")))
+ return;
+
+ //select correct mode list
+ if (output_dialog_data->crtc)
+ {
+ current_mode = output_dialog_data->crtc->current_mode;
+ modelist = output_dialog_data->crtc->outputs_common_modes;
+ }
+ else if (output_dialog_data->output)
+ {
+ current_mode = NULL;
+ if (output_dialog_data->output->modes)
+ modelist = output_dialog_data->output->modes;
+ else
+ modelist = output_dialog_data->output->modes;
+ }
+ EINA_LIST_FOREACH(modelist, iter, mode_info)
+ {
+ //calculate refresh rate
+ if (!mode_info) continue;
+ if (mode_info->hTotal && mode_info->vTotal)
+ rate = ((float) mode_info->dotClock /
+ ((float) mode_info->hTotal * (float) mode_info->vTotal));
+ else
+ rate = 0.0;
+
+ str_ret = snprintf(resolution_text, RESOLUTION_TXT_MAX_LENGTH, "%dx%d@%.1fHz", mode_info->width, mode_info->height, rate);
+ if (str_ret < 0 || str_ret > (RESOLUTION_TXT_MAX_LENGTH - 1))
+ {
+ fprintf(stderr, "CONF_RANDR: Resolution text could not be created.");
+ continue;
+ }
+ e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, resolution_text, NULL, mode_info, NULL);
+
+ //select currently enabled mode
+ if (mode_info == current_mode)
+ e_widget_ilist_selected_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, i);
+ i++;
+ }
+
+ //append 'disabled' mode
+ e_widget_ilist_append(e_config_runtime_info->gui.subdialogs.resolutions.dialog, NULL, _("Disabled"), NULL, NULL, NULL);
+
+ //reenable widget
+ e_widget_disabled_set(e_config_runtime_info->gui.subdialogs.resolutions.dialog, EINA_FALSE);
+ e_widget_ilist_go(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+ e_widget_ilist_thaw(e_config_runtime_info->gui.subdialogs.resolutions.dialog);
+}
+
+
+void
+e_config_randr_dialog_subdialog_resolutions_keep_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ if (odd && odd->new_mode && (odd->new_mode != odd->previous_mode))
+ {
+ odd->previous_mode = odd->new_mode;
+ odd->new_mode = NULL;
+ }
+ }
+}
+
+ void
+e_config_randr_dialog_subdialog_resolutions_discard_changes(E_Config_Dialog_Data *cfdata)
+{
+ E_Config_Randr_Dialog_Output_Dialog_Data *odd;
+ Eina_List *iter;
+
+ if (!cfdata) return;
+
+ EINA_LIST_FOREACH(cfdata->output_dialog_data_list, iter, odd)
+ {
+ //for now, there is no way to redisable an output during discartion
+ if (!odd->crtc || !odd->previous_mode) continue;
+ //use currently used outputs (noutputs == Ecore_X_Randr_Unset)
+ if (ecore_x_randr_crtc_mode_set(cfdata->manager->root, odd->crtc->xid, NULL, Ecore_X_Randr_Unset, odd->previous_mode->xid))
+ {
+ odd->new_mode = odd->previous_mode;
+ odd->previous_mode = NULL;
+ ecore_x_randr_screen_reset(cfdata->manager->root);
+ }
+ }
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+#include "e.h"
+#include "e_mod_main.h"
+
+/* actual module specifics */
+E_Module *conf_randr_module = NULL;
+
+/* module setup */
+EAPI E_Module_Api e_modapi =
+{
+ E_MODULE_API_VERSION,
+ "Settings - Screen Setup"
+};
+
+EAPI void *
+e_modapi_init(E_Module *m)
+{
+ e_configure_registry_category_add("screen", 30, _("Screen"), NULL, "preferences-desktop-display");
+ e_configure_registry_item_add("screen/randr", 20, _("Screen Setup"), NULL, "preferences-system-screen-resolution", e_int_config_randr);
+ conf_randr_module = m;
+ e_module_delayed_set(m, 1);
+ return m;
+}
+
+EAPI int
+e_modapi_shutdown(E_Module *m)
+{
+ E_Config_Dialog *cfd;
+ while ((cfd = e_config_dialog_get("E", "screen/randr"))) e_object_del(E_OBJECT(cfd));
+ e_configure_registry_item_del("screen/randr");
+ e_configure_registry_category_del("screen");
+ conf_randr_module = NULL;
+ return 1;
+}
+
+EAPI int
+e_modapi_save(E_Module *m)
+{
+ return 1;
+}
--- /dev/null
+/*
+ * vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
+ */
+#ifndef E_MOD_MAIN_H
+#define E_MOD_MAIN_H
+
+#define E_TYPEDEFS 1
+#include "e_int_config_randr.h"
+
+#undef E_TYPEDEFS
+#include "e_int_config_randr.h"
+
+EAPI extern E_Module_Api e_modapi;
+
+EAPI void *e_modapi_init (E_Module *m);
+EAPI int e_modapi_shutdown (E_Module *m);
+EAPI int e_modapi_save (E_Module *m);
+
+#endif
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.0"
+ width="96"
+ height="96"
+ id="svg2408">
+ <defs
+ id="defs2410">
+ <linearGradient
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396"
+ id="ButtonShadow"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="scale(1.0058652,0.994169)">
+ <stop
+ id="stop3750"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3752"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3737">
+ <stop
+ id="stop3739"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3741"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3700">
+ <stop
+ id="stop3702"
+ style="stop-color:#2276c5;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3704"
+ style="stop-color:#68baf4;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <filter
+ color-interpolation-filters="sRGB"
+ id="filter3174">
+ <feGaussianBlur
+ id="feGaussianBlur3176"
+ stdDeviation="1.71" />
+ </filter>
+ <filter
+ x="-0.192"
+ y="-0.192"
+ width="1.3839999"
+ height="1.3839999"
+ color-interpolation-filters="sRGB"
+ id="filter3794">
+ <feGaussianBlur
+ id="feGaussianBlur3796"
+ stdDeviation="5.28" />
+ </filter>
+ <linearGradient
+ x1="48"
+ y1="20.220806"
+ x2="48"
+ y2="138.66119"
+ id="linearGradient3613"
+ xlink:href="#linearGradient3737"
+ gradientUnits="userSpaceOnUse" />
+ <radialGradient
+ cx="48"
+ cy="72.097908"
+ r="42"
+ fx="48"
+ fy="72.097908"
+ id="radialGradient3619"
+ xlink:href="#linearGradient3737"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.1573129,0,0,0.99590774,-7.55102,0.1971319)" />
+ <clipPath
+ id="clipPath3613">
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="6"
+ y="6"
+ id="rect3615"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </clipPath>
+ <linearGradient
+ x1="48"
+ y1="90"
+ x2="48"
+ y2="5.9877172"
+ id="linearGradient3617"
+ xlink:href="#linearGradient3700"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-100,0)" />
+ <linearGradient
+ x1="45.447727"
+ y1="92.539597"
+ x2="45.447727"
+ y2="7.0165396"
+ id="ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0058652,0,0,0.994169,100,0)">
+ <stop
+ id="stop3750-8"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3752-5"
+ style="stop-color:#000000;stop-opacity:0.58823532"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3780"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3772"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3725"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,98.857143,-98.071429)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3721"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(100,-97)" />
+ <linearGradient
+ x1="32.251034"
+ y1="6.1317081"
+ x2="32.251034"
+ y2="90.238609"
+ id="linearGradient3026"
+ xlink:href="#ButtonShadow-0"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1.0238095,0,0,1.0119048,-1.1428571,-98.071429)" />
+ <linearGradient
+ x1="43.30954"
+ y1="91.125015"
+ x2="43.30954"
+ y2="82.822479"
+ id="linearGradient3831"
+ xlink:href="#linearGradient3734"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3734">
+ <stop
+ id="stop3736"
+ style="stop-color:#bfbfbf;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3738"
+ style="stop-color:#9a9a9a;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="48"
+ y1="86.071426"
+ x2="48"
+ y2="72.303963"
+ id="linearGradient3769"
+ xlink:href="#linearGradient3771"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)" />
+ <linearGradient
+ id="linearGradient3771">
+ <stop
+ id="stop3773"
+ style="stop-color:#ababab;stop-opacity:0"
+ offset="0" />
+ <stop
+ id="stop3779"
+ style="stop-color:#e6e6e6;stop-opacity:1"
+ offset="0.15620089" />
+ <stop
+ id="stop3777"
+ style="stop-color:#aaaaaa;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="37"
+ y1="72.089287"
+ x2="37"
+ y2="84"
+ id="linearGradient3797"
+ xlink:href="#linearGradient3803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)" />
+ <linearGradient
+ id="linearGradient3803">
+ <stop
+ id="stop3805"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3807"
+ style="stop-color:#000000;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="60"
+ y1="70"
+ x2="60"
+ y2="84.028442"
+ id="linearGradient3809"
+ xlink:href="#linearGradient3803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(0,1)" />
+ <linearGradient
+ x1="44.69643"
+ y1="66.995277"
+ x2="44.69643"
+ y2="78.306824"
+ id="linearGradient3813"
+ xlink:href="#linearGradient3803"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(1,0,0,0.4210526,-1.3176576e-7,44.789471)" />
+ <linearGradient
+ id="linearGradient3737-5">
+ <stop
+ id="stop3739-6"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3741-9"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <radialGradient
+ cx="48"
+ cy="4.3132138"
+ r="35.9375"
+ fx="48"
+ fy="4.3132138"
+ id="radialGradient3465"
+ xlink:href="#linearGradient3175-4"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(-2.7021356e-8,1.6165908,-1.3333334,-2.2260868e-8,53.750954,-65.764352)" />
+ <linearGradient
+ id="linearGradient3700-8">
+ <stop
+ id="stop3702-5"
+ style="stop-color:#000000;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3704-6"
+ style="stop-color:#1f1f1f;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="48"
+ y1="72"
+ x2="48"
+ y2="5.9877172"
+ id="linearGradient3205"
+ xlink:href="#linearGradient3700-8"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ id="linearGradient3175-4">
+ <stop
+ id="stop3177-5"
+ style="stop-color:#55a6eb;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3179-1"
+ style="stop-color:#1754c4;stop-opacity:1"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3737-1">
+ <stop
+ id="stop3739-4"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3741-91"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="142.47113"
+ y1="16.125"
+ x2="142.47113"
+ y2="58"
+ id="linearGradient4126"
+ xlink:href="#linearGradient3687"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(-78,-2)" />
+ <linearGradient
+ id="linearGradient3687">
+ <stop
+ id="stop3689"
+ style="stop-color:#ffffff;stop-opacity:1"
+ offset="0" />
+ <stop
+ id="stop3691"
+ style="stop-color:#ffffff;stop-opacity:0"
+ offset="1" />
+ </linearGradient>
+ <linearGradient
+ x1="65.15625"
+ y1="16.125"
+ x2="65.15625"
+ y2="66"
+ id="linearGradient3129"
+ xlink:href="#linearGradient3737-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2,-2)" />
+ <linearGradient
+ x1="36.357143"
+ y1="6"
+ x2="36.357143"
+ y2="63.893143"
+ id="linearGradient3922"
+ xlink:href="#linearGradient3737-5"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="68.517296"
+ y1="9.0625"
+ x2="68.517296"
+ y2="90"
+ id="linearGradient3926"
+ xlink:href="#linearGradient3737-1"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="translate(2,-2)" />
+ <linearGradient
+ x1="49"
+ y1="91"
+ x2="49"
+ y2="7"
+ id="linearGradient3963"
+ xlink:href="#ButtonShadow"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="48"
+ y1="92"
+ x2="48"
+ y2="7"
+ id="linearGradient3971"
+ xlink:href="#ButtonShadow"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="48"
+ y1="92"
+ x2="48"
+ y2="7"
+ id="linearGradient3979"
+ xlink:href="#ButtonShadow"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="48"
+ y1="92"
+ x2="48"
+ y2="7"
+ id="linearGradient3993"
+ xlink:href="#ButtonShadow"
+ gradientUnits="userSpaceOnUse" />
+ <linearGradient
+ x1="48"
+ y1="92"
+ x2="48"
+ y2="7"
+ id="linearGradient4001"
+ xlink:href="#ButtonShadow"
+ gradientUnits="userSpaceOnUse" />
+ </defs>
+ <metadata
+ id="metadata2413">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ id="layer2"
+ style="display:none">
+ <rect
+ width="86"
+ height="85"
+ rx="6"
+ ry="6"
+ x="5"
+ y="7"
+ id="rect3745"
+ style="opacity:0.9;fill:url(#ButtonShadow);fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3174)" />
+ </g>
+ <g
+ id="layer3"
+ style="display:inline">
+ <path
+ d="M 12,4.09375 C 5.9613395,3.9244333 1.3717854,9.755257 2.09375,15.53125 c 7.11e-5,0.04167 -6.96e-5,0.08333 0,0.125 0.03021,18.08647 -0.077057,36.153677 0.03125,54.25 a 0.90025051,0.90025051 0 0 0 0,0.0625 c 0.4184133,5.802734 6.1884567,9.609601 11.65625,8.9375 0.04186,-0.0051 0.08318,0.0057 0.125,0 l 19.1875,0 0,4.1875 c -2.499546,0.03714 -5.174711,-0.290519 -7.90625,0.28125 a 0.90025051,0.90025051 0 0 0 -0.21875,0.0625 C 22.809074,84.567345 20.410796,85.596019 18.25,86.96875 A 0.90025051,0.90025051 0 0 0 18.1875,87 c -0.642036,0.482767 -1.048788,1.079165 -1.125,1.6875 -0.04143,0.330682 0.105307,0.526001 0.1875,0.78125 A 0.90025051,0.90025051 0 0 0 17.125,89.875 c -0.03273,0.857171 -0.01746,1.889931 0.375,2.875 0.392456,0.985069 1.342746,1.904932 2.71875,2.0625 a 0.90025051,0.90025051 0 0 0 0.09375,0 c 15.617822,0.185808 31.239339,0.04099 46.84375,0.09375 a 0.90025051,0.90025051 0 0 0 0.03125,0 c 2.951065,-0.149941 6.201956,0.373788 9.4375,-0.375 A 0.90025051,0.90025051 0 0 0 76.78125,94.5 c 1.277831,-0.54082 1.849418,-1.735213 2,-2.78125 0.150582,-1.046037 0.04646,-2.060675 0.0625,-2.75 A 0.90025051,0.90025051 0 0 0 78.8125,88.6875 C 78.421122,87.295119 77.292427,86.511625 76.25,86 75.207573,85.488375 74.168052,85.128844 73.5,84.65625 a 0.90025051,0.90025051 0 0 0 -0.03125,0 c -1.786839,-1.169019 -3.880761,-1.826018 -6.09375,-1.5625 -0.04278,0.0051 -0.08212,-0.0058 -0.125,0 l -4.34375,0 0,-4.1875 c 7.327061,-0.01883 14.648932,0.07177 22,-0.03125 a 0.90025051,0.90025051 0 0 0 0.0625,0 c 5.802735,-0.418412 9.609601,-6.188457 8.9375,-11.65625 -0.0051,-0.04186 0.0057,-0.08318 0,-0.125 -0.0302,-18.002081 0.07705,-35.988023 -0.03125,-54 a 0.90025051,0.90025051 0 0 0 0,-0.0625 C 93.456586,7.2285158 87.686543,3.4216484 82.21875,4.09375 l -0.125,0 -70.0625,0 -0.03125,0 z m 7.4375,85 c 0.435403,-0.195218 0.474305,-0.03846 0.53125,0 0.02847,0.01923 0.05666,0.04612 0.125,0.15625 0.06834,0.110128 0.184555,0.436566 0.03125,0.75 -0.113421,0.23189 -0.242297,0.241514 -0.34375,0.28125 L 19.84375,89.5 19,89.78125 c 0.01573,0.04847 -0.02566,0.02862 0,-0.125 0.02566,-0.153618 0.219799,-0.464891 0.4375,-0.5625 z"
+ id="path3999"
+ style="opacity:0.07999998;fill:url(#linearGradient4001);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="M 12,5 C 6.509126,4.8269979 2.2704592,10.243848 3,15.518889 3.030925,33.651707 2.9380651,51.787661 3.0465784,69.918512 3.4266036,75.188863 8.7599468,78.679673 13.772038,78 20.514692,78 27.257346,78 34,78 c 0,2 0,4 0,6 -2.863018,0.167374 -5.817648,-0.337638 -8.625,0.25 -2.206186,1.154177 -4.584739,2.152741 -6.65625,3.46875 -2.039077,1.533245 0.827765,2.89849 -0.6875,2.1875 -0.06209,1.626137 0.110499,3.763753 2.295391,4.013948 15.605111,0.185657 31.228083,0.02701 46.840087,0.0798 3.081171,-0.156552 6.258842,0.354584 9.263992,-0.340885 1.951471,-0.825926 1.469923,-3.13775 1.50678,-4.721613 C 77.342616,86.821119 74.624444,86.581766 72.959094,85.403661 71.275352,84.302092 69.404655,83.727453 67.384212,84 65.589475,84 63.794737,84 62,84 c 0,-2 0,-4 0,-6 7.639142,-0.02982 15.281326,0.06045 22.918512,-0.04658 C 90.188864,77.573396 93.679673,72.240053 93,67.227962 92.969076,49.179528 93.061933,31.127957 92.953422,13.081488 92.573396,7.8111365 87.240053,4.3203269 82.227962,5 58.818642,5 35.409321,5 12,5 z m 64.65625,82.375 c 0.443788,0.116083 -0.07015,0.135709 0,0 z M 18.625,88.84375 c 0.490815,-0.09404 -0.281499,0.190111 0,0 z M 19.84375,89.5 c 0.339223,1.045339 -1.365589,-0.106181 0,0 z M 18,89.6875 c 0.0091,0.262209 0.07874,-0.0391 0,0 z m 1.09375,0.1875 c 0.133214,0.140583 -0.104769,0.06649 0,0 z"
+ inkscape:connector-curvature="0"
+ id="path3985"
+ style="opacity:0.1;fill:url(#linearGradient3993);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="M 12,5.9375 C 7.5479319,5.9375 3.9375,9.5479319 3.9375,14 l 0,55 c 0,4.452068 3.6104319,8.0625 8.0625,8.0625 l 22.9375,0 0,5.9375 0,1.9375 -8.03125,0 c -0.02106,-0.0015 -0.03968,9.23e-4 -0.0625,0 -0.09128,-0.0037 -0.165774,-0.0062 -0.25,0 a 1.0697271,1.0697271 0 0 0 -0.03125,0 c -0.113912,0.0099 -0.232434,0.0088 -0.34375,0.03125 -0.238155,0.04974 -0.298203,0.09966 -0.15625,0.0625 -0.1094,0.02878 -0.205232,0.04934 -0.3125,0.09375 0.148955,-0.06011 0.125526,-0.07948 -0.15625,0.0625 l -5.75,2.90625 A 1.0697271,1.0697271 0 0 0 19.75,88.15625 c 0.0024,-0.0046 -0.04344,0.01897 -0.21875,0.15625 -0.0299,0.02463 -0.06441,0.03471 -0.09375,0.0625 -0.03066,0.02509 -0.02774,-0.0025 -0.0625,0.03125 -0.258639,0.247527 -0.47898,0.680341 -0.4375,1.15625 a 1.0697271,1.0697271 0 0 0 0,0.03125 c -0.02667,-0.246617 -0.0055,-0.08862 0.03125,0.125 0.0098,0.04408 -0.0094,-0.0046 0,0.03125 0.05332,0.203063 0.05614,0.172383 0.0625,0.15625 0.0011,-0.0028 0.0014,0.0395 0,0.03125 l 0,1.5625 a 1.0697271,1.0697271 0 0 0 0.125,0.53125 c 0.411388,0.743167 1.181042,1.034371 1.9375,1.03125 l 53.8125,0 c 0.756392,0.0031 1.526105,-0.288062 1.9375,-1.03125 A 1.0697271,1.0697271 0 0 0 76.96875,91.5 l 0,-1.59375 c 0.01533,-0.03903 0.05034,-0.05182 0.0625,-0.09375 a 1.0697271,1.0697271 0 0 0 0,-0.09375 c 0.07191,-0.325369 0.03141,-0.420878 0.03125,-0.28125 a 1.0697271,1.0697271 0 0 0 0,-0.15625 c -0.0021,-0.01308 -0.02882,-0.01835 -0.03125,-0.03125 -0.0013,-0.01516 0.0052,-0.03647 0,-0.0625 -0.0022,-0.0093 0.0023,-0.02206 0,-0.03125 -0.0035,-0.02534 -0.01855,-0.04986 -0.03125,-0.09375 -0.0068,-0.02076 -0.02358,-0.04243 -0.03125,-0.0625 -0.01417,-0.0371 -0.01465,-0.09047 -0.03125,-0.125 a 1.0697271,1.0697271 0 0 0 0,-0.03125 c -0.02551,-0.05386 -0.06382,-0.07754 -0.09375,-0.125 a 1.0697271,1.0697271 0 0 0 -0.125,-0.1875 A 1.0697271,1.0697271 0 0 0 76.65625,88.5 c -0.0049,-0.0057 0.0049,-0.02564 0,-0.03125 A 1.0697271,1.0697271 0 0 0 76.625,88.40625 c -7.2e-5,-6.9e-5 -0.04396,-0.0183 -0.0625,-0.03125 l 0,0.03125 c -0.0051,-0.0051 -0.02617,0.0049 -0.03125,0 0,0 0.03125,-0.03125 0.03125,-0.03125 8.1e-5,7.2e-5 -0.04274,-0.01847 -0.0625,-0.03125 -0.01202,-0.0078 -0.01515,-0.02083 -0.03125,-0.03125 A 1.0697271,1.0697271 0 0 0 76.4375,88.28125 c -0.02526,-0.01761 -0.04975,-0.02237 -0.0625,-0.03125 -0.0096,-0.0062 -0.02352,0.005 -0.03125,0 4.97e-4,1.54e-4 9.97e-4,-0.03028 0,-0.03125 -0.01,-0.0097 -0.02786,-0.05973 -0.15625,-0.125 a 1.0697271,1.0697271 0 0 0 -0.0625,0 L 75.90625,88 l 0,-0.03125 -5.46875,-2.78125 a 1.0697271,1.0697271 0 0 0 -0.125,-0.03125 c -0.02218,-0.0083 -0.04017,-0.02366 -0.0625,-0.03125 -0.0272,-0.0108 -0.06444,-0.02057 -0.09375,-0.03125 -0.03819,-0.01391 -0.0817,-0.0179 -0.125,-0.03125 -0.03323,-0.01024 -0.05661,-0.02155 -0.09375,-0.03125 -0.0224,-0.0073 -0.03993,-0.02455 -0.0625,-0.03125 a 1.0697271,1.0697271 0 0 0 -0.09375,-0.03125 c -0.233345,-0.0473 -0.441538,-0.03364 -0.625,-0.03125 l -8.09375,0 0,-1.9375 0,-5.9375 22.9375,0 c 4.452068,0 8.0625,-3.610432 8.0625,-8.0625 l 0,-55 C 92.0625,9.5479319 88.452068,5.9375 84,5.9375 l -72,0 z M 75.8125,88.125 c 0.07929,0.0014 0.250997,2e-4 0.25,0 -2.9e-5,-6e-6 -0.0011,0.03088 0,0.03125 -0.04111,-0.0046 -0.193357,-0.03459 -0.25,-0.03125 z"
+ id="path3977"
+ style="opacity:0.2;fill:url(#linearGradient3979);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="M 12,7 C 8.122,7 5,10.122 5,14 l 0,55 c 0,3.878 3.122,7 7,7 l 24,0 0,7 0,3 -9.15625,0 c -0.06979,-0.0051 -0.117707,-0.0051 -0.1875,0 -0.07481,0.0065 -0.148253,0.01703 -0.21875,0.03125 -0.03256,0.0068 -0.06235,0.02303 -0.09375,0.03125 -0.06653,0.0175 -0.129479,0.03848 -0.1875,0.0625 -0.02929,0.01182 -0.06785,0.0182 -0.09375,0.03125 l -5.75,2.90625 c -0.04788,0.02898 -0.08984,0.06045 -0.125,0.09375 -0.0177,0.01386 -0.0476,0.01678 -0.0625,0.03125 -0.08984,0.08598 -0.133465,0.184129 -0.125,0.28125 0.0011,0.01017 -0.0023,0.02107 0,0.03125 0.0045,0.02024 0.02225,0.04235 0.03125,0.0625 0.008,0.02112 0.01843,0.042 0.03125,0.0625 0.0083,0.01224 0.02121,0.01916 0.03125,0.03125 l 0,1.84375 c 0.170718,0.3084 0.558565,0.501821 1,0.5 l 53.8125,0 c 0.441438,0.0018 0.829283,-0.191598 1,-0.5 l 0,-1.84375 C 75.952613,89.6069 75.984325,89.554047 76,89.5 c 0.0045,-0.02036 -2.3e-5,-0.04222 0,-0.0625 -0.005,-0.03163 -0.01551,-0.06303 -0.03125,-0.09375 -0.0027,-0.0076 0.0034,-0.02375 0,-0.03125 -0.01521,-0.03211 -0.03616,-0.06353 -0.0625,-0.09375 -0.0037,-0.0043 -0.02736,0.0042 -0.03125,0 5.85e-4,-0.01041 5.85e-4,-0.02084 0,-0.03125 -0.0056,-0.0054 -0.02527,0.0053 -0.03125,0 -0.01818,-0.02147 -0.03907,-0.04236 -0.0625,-0.0625 -0.03158,-0.02183 -0.05486,-0.04273 -0.09375,-0.0625 L 75.40625,88.9375 69.9375,86.15625 C 69.90734,86.14503 69.87604,86.13459 69.84375,86.125 69.78704,86.10249 69.719972,86.07915 69.65625,86.0625 69.62609,86.05128 69.59479,86.04084 69.5625,86.03125 69.429572,86.004306 69.300914,85.998112 69.15625,86 L 60,86 l 0,-3 0,-7 24,0 c 3.878,0 7,-3.122 7,-7 L 91,14 C 91,10.122 87.878,7 84,7 L 12,7 z"
+ inkscape:connector-curvature="0"
+ id="path3951"
+ style="opacity:0.3;fill:url(#linearGradient3971);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="m 12,-95.03125 c -5.5110903,0 -10.03125,4.52016 -10.03125,10.03125 l 0,71 c 0,5.5110902 4.5201598,10.03125 10.03125,10.03125 l 72,0 c 5.51109,0 10.03125,-4.5201597 10.03125,-10.03125 l 0,-71 c 0,-5.51109 -4.52016,-10.03125 -10.03125,-10.03125 l -72,0 z"
+ transform="matrix(1,0,0,-1,100,0)"
+ id="path3786"
+ style="opacity:0.07999998;fill:url(#linearGradient3026);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="m 12,-94.03125 c -4.971633,0 -9.03125,4.059617 -9.03125,9.03125 l 0,71 c 0,4.9716329 4.0596171,9.03125 9.03125,9.03125 l 72,0 c 4.971633,0 9.03125,-4.059617 9.03125,-9.03125 l 0,-71 c 0,-4.971633 -4.059617,-9.03125 -9.03125,-9.03125 l -72,0 z"
+ transform="matrix(1,0,0,-1,100,0)"
+ id="path3778"
+ style="opacity:0.1;fill:url(#linearGradient3780);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="m 12,-93 c -4.4091333,0 -8,3.590867 -8,8 l 0,71 c 0,4.4091333 3.5908667,8 8,8 l 72,0 c 4.409133,0 8,-3.5908667 8,-8 l 0,-71 c 0,-4.409133 -3.590867,-8 -8,-8 l -72,0 z"
+ transform="matrix(1,0,0,-1,100,0)"
+ id="path3770"
+ style="opacity:0.2;fill:url(#linearGradient3772);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ width="86"
+ height="85"
+ rx="7"
+ ry="7"
+ x="105"
+ y="-92"
+ transform="scale(1,-1)"
+ id="rect3723"
+ style="opacity:0.3;fill:url(#linearGradient3725);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="106"
+ y="-91"
+ transform="scale(1,-1)"
+ id="rect3716"
+ style="opacity:0.45;fill:url(#linearGradient3721);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ <path
+ d="M 12,7 C 8.676,7 6,9.676 6,13 l 0,56 c 0,3.324 2.676,6 6,6 l 24,0 0,7 0,3 -8.15625,0 c -0.06979,-0.0051 -0.117707,-0.0051 -0.1875,0 a 1.0903855,0.55069415 0 0 0 -0.21875,0.03125 c -0.03256,0.0068 -0.06235,0.02303 -0.09375,0.03125 a 1.0903855,0.55069415 0 0 0 -0.1875,0.0625 c -0.02929,0.01182 -0.06785,0.0182 -0.09375,0.03125 l -5.75,2.90625 a 1.0903855,0.55069415 0 0 0 -0.125,0.09375 c -0.0177,0.01386 -0.0476,0.01678 -0.0625,0.03125 A 1.0903855,0.55069415 0 0 0 21,88.46875 c 0.0011,0.01017 -0.0023,0.02107 0,0.03125 0.0045,0.02024 0.02225,0.04235 0.03125,0.0625 a 1.0903855,0.55069415 0 0 0 0.03125,0.0625 c 0.0083,0.01224 0.02121,0.01916 0.03125,0.03125 l 0,1.84375 c 0.170718,0.3084 0.558565,0.501821 1,0.5 l 51.8125,0 c 0.441438,0.0018 0.829283,-0.191598 1,-0.5 l 0,-1.84375 A 1.0903855,0.55069415 0 0 0 75,88.5 c 0.0045,-0.02036 -2.3e-5,-0.04222 0,-0.0625 a 1.0903855,0.55069415 0 0 0 -0.03125,-0.09375 c -0.0027,-0.0076 0.0034,-0.02375 0,-0.03125 a 1.0903855,0.55069415 0 0 0 -0.0625,-0.09375 c -0.0037,-0.0043 -0.02736,0.0042 -0.03125,0 a 1.0903855,0.55069415 0 0 0 0,-0.03125 c -0.0056,-0.0054 -0.02527,0.0053 -0.03125,0 A 1.0903855,0.55069415 0 0 0 74.78125,88.125 C 74.74967,88.10317 74.72639,88.08227 74.6875,88.0625 L 74.40625,87.9375 68.9375,85.15625 A 1.0903855,0.55069415 0 0 0 68.84375,85.125 c -0.05671,-0.02251 -0.123778,-0.04585 -0.1875,-0.0625 A 1.0903855,0.55069415 0 0 0 68.5625,85.03125 C 68.429572,85.004306 68.300914,84.998112 68.15625,85 L 60,85 l 0,-3 0,-7 24,0 c 3.324,0 6,-2.676 6,-6 L 90,13 C 90,9.676 87.324,7 84,7 L 12,7 z"
+ inkscape:connector-curvature="0"
+ id="path3929"
+ style="opacity:0.45;fill:url(#linearGradient3963);fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" />
+ </g>
+ <g
+ id="layer4"
+ style="display:inline">
+ <path
+ d="m 27.65625,83.999995 c -0.215725,0.02037 -0.438368,0.07797 -0.59375,0.15625 l -5.75,2.906246 c -0.31111,0.158167 -0.389467,0.388148 -0.21875,0.593749 l 0,1.843748 c 0.170718,0.3084 0.558565,0.50182 1,0.499999 l 51.8125,0 c 0.441438,0.0018 0.829283,-0.191597 1,-0.499999 l 0,-1.843748 c 0.17072,-0.205604 0.09236,-0.435579 -0.21875,-0.593749 l -5.75,-2.906246 c -0.209745,-0.100724 -0.491922,-0.160026 -0.78125,-0.15625 l -40.3125,0 c -0.06979,-0.0051 -0.117707,-0.0051 -0.1875,0 z"
+ inkscape:connector-curvature="0"
+ id="path3742"
+ style="fill:#414141;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 26.78125,82.875 a 1.1365352,1.1365352 0 0 0 -0.59375,0.3125 l -6,6 A 1.1365352,1.1365352 0 0 0 21,91.125 l 54,0 a 1.1365352,1.1365352 0 0 0 0.8125,-1.9375 l -6,-6 A 1.1365352,1.1365352 0 0 0 69,82.875 l -42,0 a 1.1365352,1.1365352 0 0 0 -0.21875,0 z"
+ transform="matrix(0.9593944,0,0,0.4845377,1.9490699,43.846486)"
+ id="path3732"
+ style="fill:url(#linearGradient3831);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 21.59375,86.937491 -0.28125,0.125 c -0.31111,0.158167 -0.389467,0.388148 -0.21875,0.593749 0.170717,0.205598 0.558565,0.344964 1,0.34375 l 51.8125,0 c 0.441437,0.0012 0.829283,-0.138148 1,-0.34375 0.17072,-0.205604 0.09236,-0.435579 -0.21875,-0.593749 l -0.28125,-0.125 c -0.155282,0.04133 -0.316934,0.063 -0.5,0.0625 l -51.8125,0 c -0.183066,5.03e-4 -0.344719,-0.02117 -0.5,-0.0625 z"
+ inkscape:connector-curvature="0"
+ id="path3758"
+ style="opacity:0.6;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="24"
+ height="19"
+ x="36"
+ y="68"
+ id="rect3727"
+ style="fill:url(#linearGradient3769);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="14"
+ x="36"
+ y="71"
+ id="rect3781"
+ style="opacity:0.5;fill:url(#linearGradient3797);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="14"
+ x="59"
+ y="71"
+ id="rect3799"
+ style="opacity:0.5;fill:url(#linearGradient3809);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="24"
+ height="8"
+ x="36"
+ y="73"
+ id="rect3811"
+ style="opacity:0.8;fill:url(#linearGradient3813);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ id="layer1">
+ <rect
+ width="84"
+ height="68"
+ rx="6"
+ ry="6"
+ x="6"
+ y="6"
+ id="rect2419-9"
+ style="fill:url(#linearGradient3205);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 6,66 0,2 c 0,3.324 2.676,6 6,6 l 72,0 c 3.324,0 6,-2.676 6,-6 l 0,-2 c 0,3.324 -2.676,6 -6,6 L 12,72 C 8.676,72 6,69.324 6,66 z"
+ inkscape:connector-curvature="0"
+ id="rect3884"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,6 C 8.676,6 6,8.676 6,12 l 0,2 0,50.026491 0,2 c 0,0.334721 0.04135,0.6507 0.09375,0.96875 0.0487,0.295596 0.09704,0.596915 0.1875,0.875 0.0099,0.03038 0.02089,0.0636 0.03125,0.09375 0.09886,0.287771 0.23488,0.547452 0.375,0.8125 0.144592,0.273507 0.315616,0.535615 0.5,0.78125 0.184384,0.245635 0.373776,0.473472 0.59375,0.6875 0.439947,0.428056 0.94291,0.814526 1.5,1.09375 0.278545,0.139612 0.573473,0.246947 0.875,0.34375 -0.256202,-0.100222 -0.486711,-0.236272 -0.71875,-0.375 -0.0074,-0.0044 -0.02387,0.0045 -0.03125,0 -0.03193,-0.0193 -0.06229,-0.04251 -0.09375,-0.0625 -0.120395,-0.0767 -0.231023,-0.163513 -0.34375,-0.25 -0.106173,-0.0808 -0.213281,-0.161112 -0.3125,-0.25 -0.17793,-0.161433 -0.34746,-0.345388 -0.5,-0.53125 -0.107579,-0.130255 -0.218394,-0.265285 -0.3125,-0.40625 -0.02509,-0.03838 -0.03845,-0.08587 -0.0625,-0.125 C 7.71649,69.579709 7.651022,69.478224 7.59375,69.370241 7.492742,69.175535 7.388075,68.95454 7.3125,68.745241 7.3045,68.723431 7.28891,68.704691 7.28125,68.682741 7.24942,68.590791 7.24545,68.49591 7.21875,68.401491 7.18842,68.294873 7.14836,68.19846 7.125,68.088991 7.052121,67.747479 7,67.390786 7,67.026491 l 0,-2 L 7,15 7,13 C 7,10.218152 9.218152,8 12,8 l 2,0 68,0 2,0 c 2.781848,0 5,2.218152 5,5 l 0,2 0,50.026491 0,2 c 0,0.364295 -0.05212,0.720988 -0.125,1.0625 -0.04415,0.206893 -0.08838,0.397658 -0.15625,0.59375 -0.0077,0.02195 -0.0233,0.04069 -0.03125,0.0625 -0.06274,0.173739 -0.138383,0.367449 -0.21875,0.53125 -0.04158,0.0828 -0.07904,0.169954 -0.125,0.25 -0.0546,0.09721 -0.126774,0.18835 -0.1875,0.28125 -0.09411,0.140965 -0.204921,0.275995 -0.3125,0.40625 -0.143174,0.17445 -0.303141,0.346998 -0.46875,0.5 -0.01117,0.0102 -0.01998,0.02116 -0.03125,0.03125 -0.138386,0.125556 -0.285091,0.234436 -0.4375,0.34375 -0.102571,0.07315 -0.204318,0.153364 -0.3125,0.21875 -0.0074,0.0045 -0.02384,-0.0044 -0.03125,0 -0.232039,0.138728 -0.462548,0.274778 -0.71875,0.375 0.301527,-0.0968 0.596455,-0.204138 0.875,-0.34375 0.55709,-0.279224 1.060053,-0.665694 1.5,-1.09375 0.219973,-0.214028 0.409366,-0.441865 0.59375,-0.6875 0.184384,-0.245635 0.355408,-0.507743 0.5,-0.78125 0.14012,-0.265048 0.276135,-0.524729 0.375,-0.8125 0.01041,-0.03078 0.02133,-0.06274 0.03125,-0.09375 0.09046,-0.278085 0.1388,-0.579404 0.1875,-0.875 C 89.95865,66.677191 90,66.361212 90,66.026491 l 0,-2 L 90,14 90,12 C 90,8.676 87.324,6 84,6 L 12,6 z"
+ inkscape:connector-curvature="0"
+ id="rect3728-7"
+ style="opacity:0.15;fill:url(#linearGradient3922);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 12.0625,12.0625 0,53.875 71.875,0 0,-53.875 -71.875,0 z"
+ transform="matrix(-1.0017391,0,0,-1.0023202,96.083478,78.090487)"
+ id="path3215"
+ style="fill:url(#radialGradient3465);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 6,67 0,1 c 0,3.324 2.676,6 6,6 l 72,0 c 3.324,0 6,-2.676 6,-6 l 0,-1 c 0,3.324 -2.676,6 -6,6 L 12,73 C 8.676,73 6,70.324 6,67 z"
+ inkscape:connector-curvature="0"
+ id="rect3291"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 12,12 0,54 72,0 0,-54 -72,0 z m 2,2 68,0 0,50 -68,0 0,-50 z"
+ inkscape:connector-curvature="0"
+ id="path4001"
+ style="opacity:0.07999998;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 12.0625,12.0625 0,53.875 71.875,0 0,-53.875 -71.875,0 z"
+ transform="matrix(0.987812,0,0,0.9837399,0.585025,0.6341434)"
+ id="path3374"
+ style="opacity:0.15;fill:none;stroke:#000000;stroke-width:1.01544595;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0" />
+ <rect
+ width="72"
+ height="1"
+ x="12"
+ y="66.064079"
+ id="rect3724"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="84"
+ height="84"
+ rx="6"
+ ry="6"
+ x="-94"
+ y="6"
+ id="rect2419"
+ style="fill:url(#linearGradient3617);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="M 12,74 C 8.676,74 6,71.324 6,68 L 6,66 6,14 6,12 c 0,-0.334721 0.0413,-0.6507 0.0937,-0.96875 0.0487,-0.295596 0.097,-0.596915 0.1875,-0.875 0.01,-0.03038 0.0209,-0.0636 0.0312,-0.09375 C 6.4113,9.774729 6.54728,9.515048 6.6874,9.25 6.83199,8.976493 7.00302,8.714385 7.1874,8.46875 7.37178,8.223115 7.56118,7.995278 7.78115,7.78125 8.2211,7.353194 8.72406,6.966724 9.28115,6.6875 9.55969,6.547888 9.85462,6.440553 10.15615,6.34375 9.89995,6.443972 9.66944,6.580022 9.4374,6.71875 c -0.007,0.0044 -0.0239,-0.0045 -0.0312,0 -0.0319,0.0193 -0.0623,0.04251 -0.0937,0.0625 -0.1204,0.0767 -0.23102,0.163513 -0.34375,0.25 -0.10617,0.0808 -0.21328,0.161112 -0.3125,0.25 C 8.47832,7.442683 8.30879,7.626638 8.15625,7.8125 8.04867,7.942755 7.93786,8.077785 7.84375,8.21875 7.81865,8.25713 7.80535,8.30462 7.78125,8.34375 7.71645,8.446782 7.65102,8.548267 7.59375,8.65625 7.49274,8.850956 7.38807,9.071951 7.3125,9.28125 7.3045,9.30306 7.2889,9.3218 7.2813,9.34375 7.2495,9.4357 7.2455,9.530581 7.2188,9.625 7.1885,9.731618 7.1484,9.828031 7.1251,9.9375 7.05212,10.279012 7,10.635705 7,11 l 0,2 0,52 0,2 c 0,2.781848 2.51184,6.24408 5,5 l 2,0 68,0 2,0 c 2.781848,0 5,-2.218152 5,-5 l 0,-2 0,-52 0,-2 C 89,10.635705 88.94788,10.279012 88.875,9.9375 88.83085,9.730607 88.78662,9.539842 88.71875,9.34375 88.71105,9.3218 88.69545,9.30306 88.6875,9.28125 88.62476,9.107511 88.549117,8.913801 88.46875,8.75 88.42717,8.6672 88.38971,8.580046 88.34375,8.5 88.28915,8.40279 88.216976,8.31165 88.15625,8.21875 88.06214,8.077785 87.951329,7.942755 87.84375,7.8125 87.700576,7.63805 87.540609,7.465502 87.375,7.3125 87.36383,7.3023 87.35502,7.29135 87.34375,7.28125 87.205364,7.155694 87.058659,7.046814 86.90625,6.9375 86.803679,6.86435 86.701932,6.784136 86.59375,6.71875 c -0.0074,-0.0045 -0.02384,0.0044 -0.03125,0 -0.232039,-0.138728 -0.462548,-0.274778 -0.71875,-0.375 0.301527,0.0968 0.596455,0.204138 0.875,0.34375 0.55709,0.279224 1.060053,0.665694 1.5,1.09375 0.219973,0.214028 0.409366,0.441865 0.59375,0.6875 0.184384,0.245635 0.355408,0.507743 0.5,0.78125 0.14012,0.265048 0.276135,0.524729 0.375,0.8125 0.01041,0.03078 0.02133,0.06274 0.03125,0.09375 0.09046,0.278085 0.1388,0.579404 0.1875,0.875 C 89.95865,11.3493 90,11.665279 90,12 l 0,2 0,52 0,2 c 0,3.324 -2.676,6 -6,6 z"
+ inkscape:connector-curvature="0"
+ id="path3615"
+ style="opacity:0.15;fill:url(#radialGradient3619);fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 12,12 0,1 72,0 0,-1 -72,0 z"
+ inkscape:connector-curvature="0"
+ id="path3992"
+ style="opacity:0.3;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <path
+ d="m 49.65625,14.125 17.03125,50.75 1,0 -17.03125,-50.75 z"
+ inkscape:connector-curvature="0"
+ id="path2669"
+ style="opacity:0.5;fill:url(#linearGradient3129);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ d="m 49.65625,14.125 17.03125,50.75 14.3125,0 c 0.538805,0 0.875,-0.336196 0.875,-0.875 l 0,-49 c 0,-0.538805 -0.336194,-0.875 -0.875,-0.875 z"
+ inkscape:connector-curvature="0"
+ id="path3664"
+ style="opacity:0.7;fill:url(#linearGradient4126);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <path
+ d="m 47.375,8 1.03125,2.9375 35.59375,0 c 0.58434,0.0059 1.0566,0.478159 1.0625,1.0625 l 0,55 C 85.0566,67.584341 84.58434,68.056599 84,68.0625 l -14.25,0 1.375,3.875 14.40625,0 c 1.279113,-0.163533 2.314719,-0.91678 2.90625,-1.96875 -0.07832,0.08832 -0.132583,0.197412 -0.21875,0.28125 -0.439947,0.428056 -0.94291,0.814526 -1.5,1.09375 -0.278545,0.139612 -0.573473,0.24695 -0.875,0.34375 0.256202,-0.100222 0.486711,-0.236272 0.71875,-0.375 0.0074,-0.0044 0.02385,0.0045 0.03125,0 0.108182,-0.06539 0.209929,-0.1456 0.3125,-0.21875 0.152409,-0.109314 0.299114,-0.218194 0.4375,-0.34375 0.01127,-0.01009 0.02008,-0.02105 0.03125,-0.03125 0.165609,-0.153002 0.325576,-0.32555 0.46875,-0.5 0.107579,-0.130255 0.21839,-0.265285 0.3125,-0.40625 0.06073,-0.0929 0.1329,-0.18404 0.1875,-0.28125 0.04596,-0.08005 0.08342,-0.1672 0.125,-0.25 0.08037,-0.163801 0.15601,-0.357511 0.21875,-0.53125 0.0079,-0.02181 0.02355,-0.04055 0.03125,-0.0625 0.06787,-0.196092 0.1121,-0.386857 0.15625,-0.59375 0.0236,-0.11059 0.04432,-0.230233 0.0625,-0.34375 l 0,-55.5 C 88.573765,9.8379124 86.52105,8 84,8 L 82,8 47.375,8 z"
+ inkscape:connector-curvature="0"
+ id="path4128"
+ style="opacity:0.25;fill:url(#linearGradient3926);fill-opacity:1;fill-rule:evenodd;stroke:none;display:inline" />
+ <g
+ transform="matrix(1,0,0,1.5,0,-37)"
+ id="g3895">
+ <g
+ transform="translate(0,2)"
+ id="g3302">
+ <rect
+ width="6"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3296"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3298"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="61"
+ y="70"
+ id="rect3300"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ transform="translate(6,2)"
+ id="g3307">
+ <rect
+ width="6"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3309"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3311"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="61"
+ y="70"
+ id="rect3313"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ transform="translate(12,2)"
+ id="g3315">
+ <rect
+ width="6"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3317"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3319"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="61"
+ y="70"
+ id="rect3321"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ <g
+ transform="translate(18,2)"
+ id="g3323">
+ <rect
+ width="6"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3325"
+ style="fill:#b3b3b3;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="56"
+ y="70"
+ id="rect3327"
+ style="opacity:0.4;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ <rect
+ width="1"
+ height="2"
+ x="61"
+ y="70"
+ id="rect3329"
+ style="opacity:0.4;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" />
+ </g>
+ </g>
+ </g>
+ <g
+ id="layer5"
+ style="display:none">
+ <rect
+ width="66"
+ height="66"
+ rx="12"
+ ry="12"
+ x="15"
+ y="15"
+ clip-path="url(#clipPath3613)"
+ id="rect3171"
+ style="opacity:0.1;fill:url(#linearGradient3613);fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;filter:url(#filter3794)" />
+ </g>
+</svg>
--- /dev/null
+[Desktop Entry]
+Type=Link
+Name=Settings - Screen Setup
+Name[cs]=Nastavení - rozlišení obrazovky
+Name[de]=Konfiguration - Bildschirm
+Name[eo]=Agordo - Ekrandistingivo
+Name[es]=Configuración - Resolución de pantalla
+Name[fr]=Configuration - Résolution de l'écran
+Name[hu]=Beállítások - Képernyő felbontása
+Name[it]=Configurazione - Risoluzione schermo
+Name[ja]=
+Name[pt]=
+Name[pt_BR]=
+Name[tr]=Ayarlar - Ekran Çözünürlüğü
+Name[zh_CN]=
+Name[zh_TW]=
+Icon=e-module-conf_randr
+Comment=Used to configure your screen's resolution.
+Comment[cs]=Použit k nastavení rozlišení obrazovky.
+Comment[de]=
+Comment[eo]=Agordi sian ekrandistingivon.
+Comment[es]=Usado para configurar su resolución de pantalla.
+Comment[fr]=Permet de configurer la résolution de l'écran.
+Comment[hu]=Segítségével beállíthatod a képernyőd felbontását.
+Comment[it]=Usato per configurare la risoluzione del vostro schermo.
+Comment[ja]=
+Comment[pt]=
+Comment[pt_BR]=
+Comment[tr]=Ekranınızın çözünürlüğünü yapılandırır.
+Comment[zh_CN]=
+Comment[zh_TW]=
+X-Enlightenment-ModuleType=settings