enlightenment/src/bin/e_randr.c

161 lines
3.8 KiB
C

/*
* vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
*/
#include "e.h"
#include "e_randr_private.h"
#define ECORE_X_RANDR_1_1 ((1 << 16) | 1)
#define ECORE_X_RANDR_1_2 ((1 << 16) | 2)
#define ECORE_X_RANDR_1_3 ((1 << 16) | 3)
#define Ecore_X_Randr_None 0
#define Ecore_X_Randr_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.
* - Depend on the sequence in which the XIDs are returned provided by the X
* server. This means that relative indexes are used for setup store/restore.
*
*/
static Eina_Bool _init(void);
static void _shutdown(void);
static Eina_Bool _screen_info_refresh(void);
static Eina_Bool _e_event_config_loaded_cb(void *data, int type, void *e);
static void _event_listeners_add(void);
static void _event_listeners_remove(void);
EAPI E_Randr_Screen_Info e_randr_screen_info;
static Eina_List *_event_handlers = NULL;
EINTERN Eina_Bool
e_randr_init(void)
{
return _init();
}
EINTERN int
e_randr_shutdown(void)
{
_shutdown();
return 1;
}
EAPI Eina_Bool
e_randr_screen_info_refresh(void)
{
return _screen_info_refresh();
}
static Eina_Bool
_init(void)
{
if (!e_randr_screen_info_refresh())
return EINA_FALSE;
_event_listeners_add();
if (e_config->randr_serialized_setup)
{
e_randr_try_restore_configuration();
if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
{
if (e_config->randr_serialized_setup->outputs_policies)
_12_policies_restore();
}
}
return EINA_TRUE;
}
static void
_shutdown(void)
{
if (e_randr_screen_info.randr_version == ECORE_X_RANDR_1_1)
{
_11_screen_info_free(e_randr_screen_info.rrvd_info.randr_info_11);
e_randr_screen_info.rrvd_info.randr_info_11 = NULL;
}
else if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
{
_12_screen_info_free(e_randr_screen_info.rrvd_info.randr_info_12);
e_randr_screen_info.rrvd_info.randr_info_12 = NULL;
}
_event_listeners_remove();
}
/**
* @return EINA_TRUE if info could be refreshed, else EINA_FALSE
*/
static Eina_Bool
_screen_info_refresh(void)
{
Ecore_X_Window *roots;
Ecore_X_Window root;
int n;
EINA_SAFETY_ON_FALSE_RETURN_VAL(ecore_x_randr_query(), EINA_FALSE);
if (!(roots = ecore_x_window_root_list(&n))) return EINA_FALSE;
/* first (and only) root window */
root = roots[0];
free(roots);
e_randr_screen_info.randr_version = ecore_x_randr_version_get();
e_randr_screen_info.root = root;
e_randr_screen_info.rrvd_info.randr_info_11 = NULL;
// Value set/retrieval helper functions
if (e_randr_screen_info.randr_version == ECORE_X_RANDR_1_1)
{
return _11_screen_info_refresh();
}
else if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
{
return _12_screen_info_refresh();
}
return EINA_FALSE;
}
static Eina_Bool
_e_event_config_loaded_cb(void *data __UNUSED__, int type, void *ev __UNUSED__)
{
if (type != E_EVENT_CONFIG_LOADED) return EINA_TRUE;
_try_restore_configuration();
return EINA_FALSE;
}
static void
_event_listeners_add(void)
{
_event_handlers = eina_list_append(_event_handlers, ecore_event_handler_add(E_EVENT_CONFIG_LOADED, _e_event_config_loaded_cb, NULL));
if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
{
_12_event_listeners_add();
}
}
// "Free" helper functions
static void
_event_listeners_remove(void)
{
Ecore_Event_Handler *_event_handler = NULL;
EINA_LIST_FREE (_event_handlers, _event_handler)
ecore_event_handler_del(_event_handler);
if (e_randr_screen_info.randr_version >= ECORE_X_RANDR_1_2)
{
_12_event_listeners_remove();
}
}