forked from enlightenment/efl
3739 lines
118 KiB
C
3739 lines
118 KiB
C
/* TODO: List of missing functions
|
|
*
|
|
* ecore_x_randr_crtc_clone_set
|
|
* ecore_x_randr_output_crtc_set
|
|
* ecore_x_randr_edid_version_get
|
|
* ecore_x_randr_edid_info_has_valid_checksum
|
|
* ecore_x_randr_edid_manufacturer_name_get
|
|
* ecore_x_randr_edid_display_ascii_get
|
|
* ecore_x_randr_edid_display_serial_get
|
|
* ecore_x_randr_edid_model_get
|
|
* ecore_x_randr_edid_manufacturer_serial_number_get
|
|
* ecore_x_randr_edid_manufacturer_model_get
|
|
* ecore_x_randr_edid_dpms_available_get
|
|
* ecore_x_randr_edid_dpms_standby_available_get
|
|
* ecore_x_randr_edid_dpms_suspend_available_get
|
|
* ecore_x_randr_edid_dpms_off_available_get
|
|
* ecore_x_randr_edid_display_aspect_ratio_preferred_get
|
|
* ecore_x_randr_edid_display_aspect_ratios_get
|
|
* ecore_x_randr_edid_display_colorscheme_get
|
|
* ecore_x_randr_edid_display_type_digital_get
|
|
* ecore_x_randr_edid_display_interface_type_get
|
|
* ecore_x_randr_screen_backlight_level_set
|
|
* ecore_x_randr_output_subpixel_order_get
|
|
* ecore_x_randr_output_wired_clones_get
|
|
* ecore_x_randr_output_compatibility_list_get
|
|
* ecore_x_randr_output_signal_formats_get
|
|
* ecore_x_randr_output_signal_format_set
|
|
* ecore_x_randr_output_signal_properties_get
|
|
* ecore_x_randr_output_connector_number_get
|
|
* ecore_x_randr_output_connector_type_get
|
|
* ecore_x_randr_crtc_panning_area_get
|
|
* ecore_x_randr_crtc_panning_area_set
|
|
* ecore_x_randr_crtc_tracking_area_get
|
|
* ecore_x_randr_crtc_tracking_area_set
|
|
* ecore_x_randr_crtc_border_area_get
|
|
* ecore_x_randr_crtc_border_area_set
|
|
*/
|
|
|
|
#include "ecore_xcb_private.h"
|
|
# ifdef ECORE_XCB_RANDR
|
|
# include <xcb/randr.h>
|
|
# endif
|
|
|
|
#define Ecore_X_Randr_None 0
|
|
#define Ecore_X_Randr_Unset -1
|
|
|
|
#define RANDR_1_1 ((1 << 16) | 1)
|
|
#define RANDR_1_2 ((1 << 16) | 2)
|
|
#define RANDR_1_3 ((1 << 16) | 3)
|
|
|
|
#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) return ret
|
|
#define RANDR_CHECK_1_2_RET(ret) if (_randr_version < RANDR_1_2) return ret
|
|
#define RANDR_CHECK_1_3_RET(ret) if (_randr_version < RANDR_1_3) return ret
|
|
|
|
#define ECORE_X_RANDR_EDID_VERSION_13 ((1 << 8) | 3)
|
|
#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR 0x12
|
|
#define _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR 0x13
|
|
#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK 0x36
|
|
#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE 3
|
|
#define _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT 5
|
|
#define _ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX 13
|
|
|
|
#define _ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
|
|
for (block = edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK; block <= (edid + _ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK + (3 * 18)); block += 18)
|
|
|
|
#define _ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block) \
|
|
_ECORE_X_RANDR_EDID_FOR_EACH_DESCRIPTOR_BLOCK(edid, block) \
|
|
if ((block[0] == 0) && (block[1] == 0))
|
|
|
|
/* local function prototypes */
|
|
static Eina_Bool _ecore_xcb_randr_output_validate(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output);
|
|
static Eina_Bool _ecore_xcb_randr_crtc_validate(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc);
|
|
static Eina_Bool _ecore_xcb_randr_root_validate(Ecore_X_Window root);
|
|
static int _ecore_xcb_randr_root_to_screen(Ecore_X_Window root);
|
|
static xcb_randr_get_screen_resources_reply_t *_ecore_xcb_randr_12_get_resources(Ecore_X_Window win);
|
|
static xcb_randr_get_screen_resources_current_reply_t *_ecore_xcb_randr_13_get_resources(Ecore_X_Window win);
|
|
static xcb_timestamp_t _ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win);
|
|
static xcb_timestamp_t _ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win);
|
|
|
|
static Ecore_X_Randr_Mode *_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num,
|
|
int *npreferred);
|
|
static Ecore_X_Randr_Mode *_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num,
|
|
int *npreferred);
|
|
static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode);
|
|
static Ecore_X_Randr_Mode_Info *_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode);
|
|
static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root,
|
|
int *num);
|
|
static Ecore_X_Randr_Mode_Info **_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root,
|
|
int *num);
|
|
static void _ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode,
|
|
int *w,
|
|
int *h);
|
|
static void _ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode,
|
|
int *w,
|
|
int *h);
|
|
static Ecore_X_Randr_Output *_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num);
|
|
static Ecore_X_Randr_Output *_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num);
|
|
static Ecore_X_Randr_Crtc *_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num);
|
|
static Ecore_X_Randr_Crtc *_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num);
|
|
static char *_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *len);
|
|
static char *_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *len);
|
|
static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output);
|
|
static Ecore_X_Randr_Connection_Status _ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output);
|
|
static Ecore_X_Randr_Output *_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root,
|
|
int *num);
|
|
static Ecore_X_Randr_Output *_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root,
|
|
int *num);
|
|
static Ecore_X_Randr_Crtc _ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output);
|
|
static Ecore_X_Randr_Crtc _ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output);
|
|
|
|
/* local variables */
|
|
static Eina_Bool _randr_avail = EINA_FALSE;
|
|
static int _randr_version = -1;
|
|
|
|
/* external variables */
|
|
int _ecore_xcb_event_randr = -1;
|
|
|
|
void
|
|
_ecore_xcb_randr_init(void)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_prefetch_extension_data(_ecore_xcb_conn, &xcb_randr_id);
|
|
#endif
|
|
}
|
|
|
|
void
|
|
_ecore_xcb_randr_finalize(void)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
const xcb_query_extension_reply_t *ext_reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
ext_reply = xcb_get_extension_data(_ecore_xcb_conn, &xcb_randr_id);
|
|
if ((ext_reply) && (ext_reply->present))
|
|
{
|
|
xcb_randr_query_version_cookie_t cookie;
|
|
xcb_randr_query_version_reply_t *reply;
|
|
|
|
cookie =
|
|
xcb_randr_query_version_unchecked(_ecore_xcb_conn,
|
|
XCB_RANDR_MAJOR_VERSION,
|
|
XCB_RANDR_MINOR_VERSION);
|
|
reply = xcb_randr_query_version_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
if ((reply->major_version >= XCB_RANDR_MAJOR_VERSION) &&
|
|
(reply->minor_version >= XCB_RANDR_MINOR_VERSION))
|
|
_randr_avail = EINA_TRUE;
|
|
|
|
_randr_version =
|
|
((reply->major_version << 16) | reply->minor_version);
|
|
|
|
free(reply);
|
|
}
|
|
|
|
if (_randr_avail)
|
|
_ecore_xcb_event_randr = ext_reply->first_event;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
static Eina_Bool
|
|
_ecore_xcb_randr_root_validate(Ecore_X_Window root)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Randr_Screen scr = -1;
|
|
# define RANDR_VALIDATE_ROOT(screen, root) \
|
|
((screen == _ecore_xcb_randr_root_to_screen(root)) != -1)
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if ((root) && RANDR_VALIDATE_ROOT(scr, root))
|
|
return EINA_TRUE;
|
|
#endif
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static int
|
|
_ecore_xcb_randr_root_to_screen(Ecore_X_Window root)
|
|
{
|
|
int count = 0, num = 0;
|
|
|
|
CHECK_XCB_CONN;
|
|
|
|
count = xcb_setup_roots_length(xcb_get_setup(_ecore_xcb_conn));
|
|
for (num = 0; num < count; num++)
|
|
if (_ecore_xcb_window_root_of_screen_get(num) == root)
|
|
return num;
|
|
|
|
return -1;
|
|
}
|
|
|
|
/* public functions */
|
|
|
|
/*
|
|
* @brief Query whether RandR is available or not.
|
|
*
|
|
* @return @c EINA_TRUE if extension is available, @c EINA_FALSE otherwise.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_query(void)
|
|
{
|
|
return _randr_avail;
|
|
}
|
|
|
|
/*
|
|
* @return version of the RandRR extension supported by the server or,
|
|
* in case RandRR extension is not available, Ecore_X_Randr_Unset (=-1).
|
|
* bit version information: 31 MAJOR 16 | 15 MINOR 0
|
|
*/
|
|
EAPI int
|
|
ecore_x_randr_version_get(void)
|
|
{
|
|
return _randr_version;
|
|
}
|
|
|
|
/*
|
|
* @param root window which's primary output will be queried
|
|
*/
|
|
EAPI Ecore_X_Randr_Orientation
|
|
ecore_x_randr_screen_primary_output_orientations_get(Ecore_X_Window root)
|
|
{
|
|
int ret = Ecore_X_Randr_None;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
ret = reply->rotations;
|
|
free(reply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @param root window which's primary output will be queried
|
|
* @return the current orientation of the root window's screen primary output
|
|
*/
|
|
EAPI Ecore_X_Randr_Orientation
|
|
ecore_x_randr_screen_primary_output_orientation_get(Ecore_X_Window root)
|
|
{
|
|
int ret = Ecore_X_Randr_None;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
ret = reply->rotation;
|
|
free(reply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief Sets a given screen's primary output's orientation.
|
|
*
|
|
* @param root Window which's screen's primary output will be queried.
|
|
* @param orientation Orientation which should be set for the root window's
|
|
* screen primary output.
|
|
* @return @c EINA_TRUE if the primary output's orientation could be
|
|
* successfully altered.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_screen_primary_output_orientation_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Orientation orientation)
|
|
{
|
|
int ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
xcb_randr_set_screen_config_cookie_t scookie;
|
|
xcb_randr_set_screen_config_reply_t *sreply;
|
|
|
|
scookie =
|
|
xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
|
|
XCB_CURRENT_TIME,
|
|
reply->config_timestamp,
|
|
reply->sizeID, orientation,
|
|
reply->rate);
|
|
sreply =
|
|
xcb_randr_set_screen_config_reply(_ecore_xcb_conn, scookie, NULL);
|
|
if (!sreply)
|
|
ret = EINA_FALSE;
|
|
else
|
|
{
|
|
ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ?
|
|
EINA_TRUE : EINA_FALSE;
|
|
free(sreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief gets a screen's primary output's possible sizes
|
|
* @param root window which's primary output will be queried
|
|
* @param num number of sizes reported as supported by the screen's primary output
|
|
* @return an array of sizes reported as supported by the screen's primary output or - if query failed - NULL
|
|
*/
|
|
EAPI Ecore_X_Randr_Screen_Size_MM *
|
|
ecore_x_randr_screen_primary_output_sizes_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
Ecore_X_Randr_Screen_Size_MM *ret = NULL;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
int len = 0, i = 0;
|
|
xcb_randr_screen_size_t *sizes;
|
|
|
|
len = xcb_randr_get_screen_info_sizes_length(reply);
|
|
sizes = xcb_randr_get_screen_info_sizes(reply);
|
|
if ((!sizes) || (len <= 0))
|
|
{
|
|
free(reply);
|
|
return NULL;
|
|
}
|
|
if (num) *num = len;
|
|
ret = calloc(len, sizeof(Ecore_X_Randr_Screen_Size_MM));
|
|
if (!ret)
|
|
{
|
|
free(reply);
|
|
return NULL;
|
|
}
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
ret[i].width = sizes[i].width;
|
|
ret[i].height = sizes[i].height;
|
|
ret[i].width_mm = sizes[i].mwidth;
|
|
ret[i].height_mm = sizes[i].mheight;
|
|
}
|
|
|
|
free(reply);
|
|
}
|
|
|
|
return ret;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @brief get the current set size of a given screen's primary output
|
|
* @param root window which's primary output will be queried
|
|
* @param w the current size's width
|
|
* @param h the current size's height
|
|
* @param w_mm the current size's width in mm
|
|
* @param h_mm the current size's height in mm
|
|
* @param size_index of current set size to be used with ecore_x_randr_primary_output_size_set()
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_screen_primary_output_current_size_get(Ecore_X_Window root,
|
|
int *w,
|
|
int *h,
|
|
int *w_mm,
|
|
int *h_mm,
|
|
int *size_index)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
int len = 0, idx = 0;
|
|
xcb_randr_screen_size_t *sizes;
|
|
|
|
len = xcb_randr_get_screen_info_sizes_length(reply);
|
|
sizes = xcb_randr_get_screen_info_sizes(reply);
|
|
if ((!sizes) || (len <= 0))
|
|
{
|
|
free(reply);
|
|
return;
|
|
}
|
|
idx = reply->sizeID;
|
|
if ((idx < len) && (idx >= 0))
|
|
{
|
|
if (w) *w = sizes[idx].width;
|
|
if (h) *h = sizes[idx].height;
|
|
if (w_mm) *w_mm = sizes[idx].mwidth;
|
|
if (h_mm) *h_mm = sizes[idx].mheight;
|
|
if (size_index) *size_index = idx;
|
|
}
|
|
|
|
free(reply);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @brief Sets a given screen's primary output size, but disables all other
|
|
* outputs at the same time.
|
|
*
|
|
* @param root Window which's primary output will be queried.
|
|
* @param size_index Within the list of sizes reported as supported by the root
|
|
* window's screen primary output.
|
|
* @return @c EINA_TRUE on success, @c EINA_FALSE on failure due to e.g.
|
|
* invalid times.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_screen_primary_output_size_set(Ecore_X_Window root,
|
|
int size_index)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (!((size_index >= 0) && (_ecore_xcb_randr_root_validate(root))))
|
|
return EINA_FALSE;
|
|
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
int len = 0;
|
|
|
|
len = xcb_randr_get_screen_info_sizes_length(reply);
|
|
if (len <= 0)
|
|
{
|
|
free(reply);
|
|
return EINA_FALSE;
|
|
}
|
|
if ((size_index < len) && (size_index >= 0))
|
|
{
|
|
xcb_randr_set_screen_config_cookie_t scookie;
|
|
xcb_randr_set_screen_config_reply_t *sreply;
|
|
|
|
scookie =
|
|
xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
|
|
XCB_CURRENT_TIME,
|
|
reply->config_timestamp,
|
|
size_index,
|
|
reply->rotation,
|
|
reply->rate);
|
|
sreply =
|
|
xcb_randr_set_screen_config_reply(_ecore_xcb_conn,
|
|
scookie, NULL);
|
|
if (!sreply)
|
|
ret = EINA_FALSE;
|
|
else
|
|
{
|
|
ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ?
|
|
EINA_TRUE : EINA_FALSE;
|
|
free(sreply);
|
|
}
|
|
}
|
|
|
|
free(reply);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @param root window which's primary output will be queried
|
|
* @return currently used refresh rate or - if request failed or RandRR is not available - 0.0
|
|
*/
|
|
EAPI Ecore_X_Randr_Refresh_Rate
|
|
ecore_x_randr_screen_primary_output_current_refresh_rate_get(Ecore_X_Window root)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
Ecore_X_Randr_Refresh_Rate ret = 0.0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (!_ecore_xcb_randr_root_validate(root)) return ret;
|
|
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
ret = reply->rate;
|
|
free(reply);
|
|
}
|
|
|
|
return ret;
|
|
#else
|
|
return 0.0;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @param root window which's primary output will be queried
|
|
* @param size_index referencing the size to query valid refresh rates for
|
|
* @return currently used refresh rate or - if request failed or RandRR is not available - NULL
|
|
*/
|
|
EAPI Ecore_X_Randr_Refresh_Rate *
|
|
ecore_x_randr_screen_primary_output_refresh_rates_get(Ecore_X_Window root,
|
|
int size_index,
|
|
int *num)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
Ecore_X_Randr_Refresh_Rate *ret = NULL;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (!_ecore_xcb_randr_root_validate(root)) return ret;
|
|
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
int len = 0;
|
|
|
|
len = xcb_randr_get_screen_info_rates_length(reply);
|
|
if (num) *num = len;
|
|
|
|
ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * len);
|
|
if (ret)
|
|
{
|
|
xcb_randr_refresh_rates_iterator_t iter;
|
|
int i = 0;
|
|
|
|
iter = xcb_randr_get_screen_info_rates_iterator(reply);
|
|
while (i++ < size_index)
|
|
xcb_randr_refresh_rates_next(&iter);
|
|
|
|
memcpy(ret, xcb_randr_refresh_rates_rates(iter.data),
|
|
sizeof(Ecore_X_Randr_Refresh_Rate) * len);
|
|
}
|
|
free(reply);
|
|
}
|
|
|
|
return ret;
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @brief Sets the current primary output's refresh rate.
|
|
*
|
|
* @param root Window which's primary output will be queried.
|
|
* @param size_index Referencing the size to be set.
|
|
* @param rate The refresh rate to be set.
|
|
* @return @c EINA_TRUE on success, @c EINA_FALSE otherwise.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_screen_primary_output_refresh_rate_set(Ecore_X_Window root,
|
|
int size_index,
|
|
Ecore_X_Randr_Refresh_Rate rate)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_info_cookie_t cookie;
|
|
xcb_randr_get_screen_info_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (_randr_version < RANDR_1_1) return EINA_FALSE;
|
|
|
|
cookie = xcb_randr_get_screen_info_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_info_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
xcb_randr_set_screen_config_cookie_t scookie;
|
|
xcb_randr_set_screen_config_reply_t *sreply;
|
|
|
|
scookie =
|
|
xcb_randr_set_screen_config_unchecked(_ecore_xcb_conn, root,
|
|
XCB_CURRENT_TIME,
|
|
reply->config_timestamp,
|
|
size_index,
|
|
reply->rotation, rate);
|
|
sreply =
|
|
xcb_randr_set_screen_config_reply(_ecore_xcb_conn,
|
|
scookie, NULL);
|
|
if (!sreply)
|
|
ret = EINA_FALSE;
|
|
else
|
|
{
|
|
ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ?
|
|
EINA_TRUE : EINA_FALSE;
|
|
free(sreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief Free detailed mode information. The pointer handed in will be set to
|
|
* @c NULL after freeing the memory.
|
|
*
|
|
* @param mode_info The mode information that should be freed.
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_mode_info_free(Ecore_X_Randr_Mode_Info *mode_info)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
if (!mode_info) return;
|
|
|
|
if (mode_info->name) free(mode_info->name);
|
|
free(mode_info);
|
|
mode_info = NULL;
|
|
}
|
|
|
|
/*
|
|
* @param root window which's screen should be queried
|
|
* @return Ecore_X_Randr_Ouptut_Id or - if query failed or none is set - Ecore_X_Randr_None
|
|
*/
|
|
EAPI Ecore_X_Randr_Output
|
|
ecore_x_randr_primary_output_get(Ecore_X_Window root)
|
|
{
|
|
Ecore_X_Randr_Output ret = Ecore_X_Randr_None;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_output_primary_cookie_t cookie;
|
|
xcb_randr_get_output_primary_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_3_RET(Ecore_X_Randr_None);
|
|
|
|
if (!_ecore_xcb_randr_root_validate(root))
|
|
return Ecore_X_Randr_None;
|
|
|
|
cookie = xcb_randr_get_output_primary_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_output_primary_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
ret = reply->output;
|
|
free(reply);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @param root window which's screen should be queried
|
|
* @param output that should be set as given root window's screen primary output
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_primary_output_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_3_RET();
|
|
|
|
if ((output) && (_ecore_xcb_randr_root_validate(root)))
|
|
xcb_randr_set_output_primary(_ecore_xcb_conn, root, output);
|
|
#endif
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Mode *
|
|
ecore_x_randr_output_modes_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num,
|
|
int *npreferred)
|
|
{
|
|
Ecore_X_Randr_Mode *modes = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
{
|
|
modes =
|
|
_ecore_xcb_randr_13_output_modes_get(root, output, num, npreferred);
|
|
}
|
|
else if (_randr_version == RANDR_1_2)
|
|
{
|
|
modes =
|
|
_ecore_xcb_randr_12_output_modes_get(root, output, num, npreferred);
|
|
}
|
|
#endif
|
|
|
|
return modes;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_output_mode_add(Ecore_X_Randr_Output output, Ecore_X_Randr_Mode mode)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if ((output == Ecore_X_Randr_None) || (mode == Ecore_X_Randr_None))
|
|
return EINA_FALSE;
|
|
|
|
xcb_randr_add_output_mode(_ecore_xcb_conn, output, mode);
|
|
return EINA_TRUE;
|
|
#endif
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/*
|
|
* @brief get detailed information for a given mode id
|
|
* @param root window which's screen's ressources are queried
|
|
* @param mode the XID which identifies the mode of interest
|
|
* @return mode's detailed information
|
|
*/
|
|
EAPI Ecore_X_Randr_Mode_Info *
|
|
ecore_x_randr_mode_info_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode)
|
|
{
|
|
Ecore_X_Randr_Mode_Info *ret = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (!_ecore_xcb_randr_root_validate(root)) return NULL;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
ret = _ecore_xcb_randr_13_mode_info_get(root, mode);
|
|
else if (_randr_version == RANDR_1_2)
|
|
ret = _ecore_xcb_randr_12_mode_info_get(root, mode);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief add a mode to a display
|
|
* @param root window to which's screen's ressources are added
|
|
* @param mode_info
|
|
* @return Ecore_X_Randr_Mode of the added mode. Ecore_X_Randr_None if mode
|
|
* adding failed.
|
|
* @since 1.2.0
|
|
*/
|
|
EAPI Ecore_X_Randr_Mode
|
|
ecore_x_randr_mode_info_add(Ecore_X_Window root, Ecore_X_Randr_Mode_Info *mode_info)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Randr_Mode mode = Ecore_X_Randr_None;
|
|
xcb_randr_create_mode_cookie_t cookie;
|
|
xcb_randr_create_mode_reply_t *reply;
|
|
xcb_randr_mode_info_t info;
|
|
int namelen = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (!mode_info) return Ecore_X_Randr_None;
|
|
if (!_ecore_xcb_randr_root_validate(root)) return Ecore_X_Randr_None;
|
|
|
|
namelen = strlen(mode_info->name);
|
|
|
|
memset(&info, 0, sizeof(info));
|
|
info.width = mode_info->width;
|
|
info.height = mode_info->height;
|
|
info.dot_clock = mode_info->dotClock;
|
|
info.hsync_start = mode_info->hSyncStart;
|
|
info.hsync_end = mode_info->hSyncEnd;
|
|
info.htotal = mode_info->hTotal;
|
|
info.hskew = mode_info->hSkew;
|
|
info.vsync_start = mode_info->vSyncStart;
|
|
info.vsync_end = mode_info->vSyncEnd;
|
|
info.vtotal = mode_info->vTotal;
|
|
info.mode_flags = mode_info->modeFlags;
|
|
info.name_len = namelen;
|
|
|
|
cookie =
|
|
xcb_randr_create_mode_unchecked(_ecore_xcb_conn, root, info,
|
|
namelen, mode_info->name);
|
|
reply = xcb_randr_create_mode_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
mode = mode_info->xid;
|
|
free(reply);
|
|
}
|
|
#endif
|
|
return mode;
|
|
}
|
|
|
|
/*
|
|
* @brief get detailed information for all modes related to a root window's screen
|
|
* @param root window which's screen's ressources are queried
|
|
* @param num number of modes returned
|
|
* @return modes' information
|
|
*/
|
|
EAPI Ecore_X_Randr_Mode_Info **
|
|
ecore_x_randr_modes_info_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Mode_Info **ret = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (num) *num = 0;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (!_ecore_xcb_randr_root_validate(root)) return NULL;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
ret = _ecore_xcb_randr_13_modes_info_get(root, num);
|
|
else if (_randr_version == RANDR_1_2)
|
|
ret = _ecore_xcb_randr_12_modes_info_get(root, num);
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief gets the width and hight of a given mode
|
|
* @param mode the mode which's size is to be looked up
|
|
* @param w width of given mode in px
|
|
* @param h height of given mode in px
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_mode_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
if (mode == Ecore_X_Randr_None) return;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
_ecore_xcb_randr_13_mode_size_get(root, mode, w, h);
|
|
else if (_randr_version == RANDR_1_2)
|
|
_ecore_xcb_randr_12_mode_size_get(root, mode, w, h);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the EDID information of an attached output if available.
|
|
* Note that this information is not to be compared using ordinary string
|
|
* comparison functions, since it includes 0-bytes.
|
|
*
|
|
* @param root Window this information should be queried from.
|
|
* @param output The XID of the output.
|
|
* @param length Length of the byte-array. If @c NULL, request will fail.
|
|
* @return EDID information of the output.
|
|
*/
|
|
EAPI unsigned char *
|
|
ecore_x_randr_output_edid_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
unsigned long *length)
|
|
{
|
|
unsigned char *ret = NULL;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_output_property_cookie_t cookie;
|
|
xcb_randr_get_output_property_reply_t *reply;
|
|
Ecore_X_Atom atom;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if ((!length) || (!_ecore_xcb_randr_output_validate(root, output)))
|
|
return NULL;
|
|
|
|
atom = ecore_x_atom_get("EDID");
|
|
cookie =
|
|
xcb_randr_get_output_property_unchecked(_ecore_xcb_conn, output, atom,
|
|
XCB_GET_PROPERTY_TYPE_ANY,
|
|
0, 100, 0, 0);
|
|
reply =
|
|
xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
if ((reply->type == XCB_ATOM_INTEGER) && (reply->format == 8))
|
|
{
|
|
if (length) *length = reply->num_items;
|
|
if ((ret = malloc(reply->num_items * sizeof(unsigned char))))
|
|
{
|
|
memcpy(ret, xcb_randr_get_output_property_data(reply),
|
|
(reply->num_items * sizeof(unsigned char)));
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Gets the outputs which might be used simultaneously on the same CRTC.
|
|
*
|
|
* @param root Window that this information should be queried for.
|
|
* @param output The output which's clones we concern.
|
|
* @param num Number of possible clones.
|
|
* @return The existing outputs, @c NULL otherwise.
|
|
*/
|
|
EAPI Ecore_X_Randr_Output *
|
|
ecore_x_randr_output_clones_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *outputs = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (output == Ecore_X_Randr_None) return NULL;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
outputs = _ecore_xcb_randr_13_output_clones_get(root, output, num);
|
|
else if (_randr_version == RANDR_1_2)
|
|
outputs = _ecore_xcb_randr_12_output_clones_get(root, output, num);
|
|
#endif
|
|
return outputs;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Crtc *
|
|
ecore_x_randr_output_possible_crtcs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Crtc *crtcs = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (output == Ecore_X_Randr_None) return NULL;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
crtcs = _ecore_xcb_randr_13_output_possible_crtcs_get(root, output, num);
|
|
else if (_randr_version == RANDR_1_2)
|
|
crtcs = _ecore_xcb_randr_12_output_possible_crtcs_get(root, output, num);
|
|
#endif
|
|
return crtcs;
|
|
}
|
|
|
|
/**
|
|
* @brief gets the given output's name as reported by X
|
|
* @param root the window which's screen will be queried
|
|
* @param len length of returned c-string.
|
|
* @return name of the output as reported by X
|
|
*/
|
|
EAPI char *
|
|
ecore_x_randr_output_name_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *len)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (output == Ecore_X_Randr_None) return NULL;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
return _ecore_xcb_randr_13_output_name_get(root, output, len);
|
|
else if (_randr_version == RANDR_1_2)
|
|
return _ecore_xcb_randr_12_output_name_get(root, output, len);
|
|
#endif
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Connection_Status
|
|
ecore_x_randr_output_connection_status_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN);
|
|
|
|
if (output == Ecore_X_Randr_None)
|
|
return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
return _ecore_xcb_randr_13_output_connection_status_get(root, output);
|
|
else if (_randr_version == RANDR_1_2)
|
|
return _ecore_xcb_randr_12_output_connection_status_get(root, output);
|
|
#endif
|
|
|
|
return ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Output *
|
|
ecore_x_randr_outputs_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
return _ecore_xcb_randr_13_outputs_get(root, num);
|
|
else if (_randr_version == RANDR_1_2)
|
|
return _ecore_xcb_randr_12_outputs_get(root, num);
|
|
#endif
|
|
|
|
return NULL;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Crtc
|
|
ecore_x_randr_output_crtc_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
|
|
|
|
if (output == Ecore_X_Randr_None) return Ecore_X_Randr_None;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
return _ecore_xcb_randr_13_output_crtc_get(root, output);
|
|
else if (_randr_version == RANDR_1_2)
|
|
return _ecore_xcb_randr_12_output_crtc_get(root, output);
|
|
#endif
|
|
|
|
return Ecore_X_Randr_None;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_randr_output_size_mm_get(Ecore_X_Window root, Ecore_X_Randr_Output output, int *w_mm, int *h_mm)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
xcb_timestamp_t timestamp = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (w_mm) *w_mm = 0;
|
|
if (h_mm) *h_mm = 0;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
if ((output != Ecore_X_Randr_None) && (_randr_version >= RANDR_1_3))
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
timestamp = reply->config_timestamp;
|
|
free(reply);
|
|
}
|
|
else if ((output != Ecore_X_Randr_None) && (_randr_version == RANDR_1_2))
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
timestamp = reply->config_timestamp;
|
|
free(reply);
|
|
}
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (w_mm) *w_mm = oreply->mm_width;
|
|
if (h_mm) *h_mm = oreply->mm_height;
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Sets the demanded parameters for a given CRTC. Note that the CRTC is
|
|
* auto enabled in it's preferred mode, when it was disabled before.
|
|
*
|
|
* @param root The root window which's default display will be queried.
|
|
* @param crtc The CRTC which's configuration should be altered.
|
|
* @param outputs An array of outputs, that should display this CRTC's content.
|
|
* @param noutputs Number of outputs in the array of outputs. If set to
|
|
* Ecore_X_Randr_Unset, current outputs and number of outputs will be used. If
|
|
* set to Ecore_X_Randr_None, CRTC will be disabled.
|
|
* @param x New x coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current x
|
|
* coordinate will be assumed.
|
|
* @param y New y coordinate. If <0 (e.g. Ecore_X_Randr_Unset) the current y
|
|
* coordinate will be assumed.
|
|
* @param mode The new mode to be set. If Ecore_X_Randr_None is passed, the
|
|
* CRTC will be disabled. If Ecore_X_Randr_Unset is passed, the current mode is
|
|
* assumed.
|
|
* @param orientation The new orientation to be set. If Ecore_X_Randr_Unset is
|
|
* used, the current mode is assumed.
|
|
* @return @c EINA_TRUE if the configuration alteration was successful,
|
|
* @c EINA_FALSE otherwise.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_crtc_settings_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
Ecore_X_Randr_Output *outputs,
|
|
int num,
|
|
int x,
|
|
int y,
|
|
Ecore_X_Randr_Mode mode,
|
|
Ecore_X_Randr_Orientation orientation)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ccookie;
|
|
xcb_randr_get_crtc_info_reply_t *creply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ccookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
creply =
|
|
xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ccookie, NULL);
|
|
if (creply)
|
|
{
|
|
xcb_randr_set_crtc_config_cookie_t scookie;
|
|
xcb_randr_set_crtc_config_reply_t *sreply;
|
|
|
|
if ((mode == Ecore_X_Randr_None) ||
|
|
(num == Ecore_X_Randr_None))
|
|
{
|
|
outputs = NULL;
|
|
num = 0;
|
|
}
|
|
else if (num == (int)Ecore_X_Randr_Unset)
|
|
{
|
|
outputs = xcb_randr_get_crtc_info_outputs(creply);
|
|
num = creply->num_outputs;
|
|
}
|
|
if ((int)mode == Ecore_X_Randr_Unset) mode = creply->mode;
|
|
if (x < 0) x = creply->x;
|
|
if (y < 0) y = creply->y;
|
|
if ((int)orientation == Ecore_X_Randr_Unset)
|
|
orientation = creply->rotation;
|
|
|
|
scookie =
|
|
xcb_randr_set_crtc_config_unchecked(_ecore_xcb_conn,
|
|
crtc, XCB_CURRENT_TIME, stamp,
|
|
x, y, mode, orientation,
|
|
num, outputs);
|
|
sreply =
|
|
xcb_randr_set_crtc_config_reply(_ecore_xcb_conn, scookie, NULL);
|
|
if (sreply)
|
|
{
|
|
ret = (sreply->status == XCB_RANDR_SET_CONFIG_SUCCESS) ?
|
|
EINA_TRUE : EINA_FALSE;
|
|
free(sreply);
|
|
}
|
|
free(creply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a mode for a CRTC and the outputs attached to it.
|
|
*
|
|
* @param root The window's screen to be queried
|
|
* @param crtc The CRTC which shall be set
|
|
* @param outputs Array of outputs which have to be compatible with the mode. If
|
|
* @c NULL CRTC will be disabled.
|
|
* @param num Number of outputs in array to be used. Use
|
|
* Ecore_X_Randr_Unset (or @c -1) to use currently used outputs.
|
|
* @param mode XID of the mode to be set. If set to @c 0 the CRTC will be
|
|
* disabled. If set to @c -1 the call will fail.
|
|
* @return @c EINA_TRUE if mode setting was successful, @c EINA_FALSE
|
|
* otherwise.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_crtc_mode_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
Ecore_X_Randr_Output *outputs,
|
|
int num,
|
|
Ecore_X_Randr_Mode mode)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if ((int)mode == Ecore_X_Randr_Unset) return ret;
|
|
ret =
|
|
ecore_x_randr_crtc_settings_set(root, crtc, outputs, num,
|
|
Ecore_X_Randr_Unset, Ecore_X_Randr_Unset,
|
|
mode, Ecore_X_Randr_Unset);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Get the current set mode of a given CRTC
|
|
* @param root the window's screen to be queried
|
|
* @param crtc the CRTC which's should be queried
|
|
* @return currently set mode or - in case parameters are invalid -
|
|
* Ecore_X_Randr_Unset
|
|
*/
|
|
EAPI Ecore_X_Randr_Mode
|
|
ecore_x_randr_crtc_mode_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc)
|
|
{
|
|
Ecore_X_Randr_Mode ret = Ecore_X_Randr_Unset;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(Ecore_X_Randr_Unset);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->mode;
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Orientation
|
|
ecore_x_randr_crtc_orientation_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc)
|
|
{
|
|
Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->rotation;
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_crtc_orientation_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
Ecore_X_Randr_Orientation orientation)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (orientation != Ecore_X_Randr_None)
|
|
{
|
|
ret =
|
|
ecore_x_randr_crtc_settings_set(root, crtc, NULL,
|
|
Ecore_X_Randr_Unset, Ecore_X_Randr_Unset,
|
|
Ecore_X_Randr_Unset, Ecore_X_Randr_Unset,
|
|
orientation);
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Orientation
|
|
ecore_x_randr_crtc_orientations_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc)
|
|
{
|
|
Ecore_X_Randr_Orientation ret = Ecore_X_Randr_None;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(Ecore_X_Randr_None);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply =
|
|
xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->rotations;
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief get a CRTC's possible outputs.
|
|
* @param root the root window which's screen will be queried
|
|
* @param num number of possible outputs referenced by given CRTC
|
|
*/
|
|
EAPI Ecore_X_Randr_Output *
|
|
ecore_x_randr_crtc_possible_outputs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *ret = NULL;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_possible_outputs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Output) *
|
|
oreply->num_possible_outputs);
|
|
if (ret)
|
|
{
|
|
memcpy(ret, xcb_randr_get_crtc_info_possible(oreply),
|
|
sizeof(Ecore_X_Randr_Output) *
|
|
oreply->num_possible_outputs);
|
|
}
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief get all known CRTCs related to a root window's screen
|
|
* @param root window which's screen's ressources are queried
|
|
* @param num number of CRTCs returned
|
|
* @return CRTC IDs
|
|
*/
|
|
EAPI Ecore_X_Randr_Crtc *
|
|
ecore_x_randr_crtcs_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Crtc *ret = NULL;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_crtcs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs);
|
|
if (ret)
|
|
memcpy(ret, xcb_randr_get_screen_resources_current_crtcs(reply),
|
|
sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs);
|
|
free(reply);
|
|
}
|
|
}
|
|
else if (_randr_version == RANDR_1_2)
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_crtcs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs);
|
|
if (ret)
|
|
memcpy(ret, xcb_randr_get_screen_resources_crtcs(reply),
|
|
sizeof(Ecore_X_Randr_Crtc) * reply->num_crtcs);
|
|
free(reply);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @deprecated bad naming. Use ecore_x_randr_window_crtcs_get instead.
|
|
* @brief Get the CRTCs, which display a certain window.
|
|
*
|
|
* @param window Window the displaying CRTCs shall be found for.
|
|
* @param num The number of CRTCs displaying the window.
|
|
* @return Array of CRTCs that display a certain window. @c NULL if no CRTCs
|
|
* was found that displays the specified window.
|
|
*/
|
|
EAPI Ecore_X_Randr_Crtc *
|
|
ecore_x_randr_current_crtc_get(Ecore_X_Window window,
|
|
int *num)
|
|
{
|
|
return ecore_x_randr_window_crtcs_get(window, num);
|
|
}
|
|
|
|
/*
|
|
* @brief Get the CRTCs, which display a certain window.
|
|
*
|
|
* @param window Window the displaying crtcs shall be found for.
|
|
* @param num The number of crtcs displaying the window.
|
|
* @return Array of crtcs that display a certain window. @c NULL if no crtcs
|
|
* was found that displays the specified window.
|
|
* @since 1.2.0
|
|
*/
|
|
EAPI Ecore_X_Randr_Crtc *
|
|
ecore_x_randr_window_crtcs_get(Ecore_X_Window window,
|
|
int *num)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Window root;
|
|
Eina_Rectangle w_geo, c_geo;
|
|
Ecore_X_Randr_Crtc *crtcs, *ret = NULL;
|
|
Ecore_X_Randr_Mode mode;
|
|
int ncrtcs, i, nret = 0;
|
|
xcb_translate_coordinates_cookie_t cookie;
|
|
xcb_translate_coordinates_reply_t *trans;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
ecore_x_window_geometry_get(window, &w_geo.x, &w_geo.y, &w_geo.w, &w_geo.h);
|
|
|
|
root = ecore_x_window_root_get(window);
|
|
crtcs = ecore_x_randr_crtcs_get(root, &ncrtcs);
|
|
if (!crtcs) return NULL;
|
|
|
|
/* now get window RELATIVE to root window - thats what matters. */
|
|
cookie = xcb_translate_coordinates(_ecore_xcb_conn, window, root, 0, 0);
|
|
trans = xcb_translate_coordinates_reply(_ecore_xcb_conn, cookie, NULL);
|
|
w_geo.x = trans->dst_x;
|
|
w_geo.y = trans->dst_y;
|
|
free(trans);
|
|
|
|
for (i = 0, nret = 0; i < ncrtcs; i++)
|
|
{
|
|
/* if crtc is not enabled, don't bother about it any further */
|
|
mode = ecore_x_randr_crtc_mode_get(root, crtcs[i]);
|
|
if (mode == Ecore_X_Randr_None) continue;
|
|
|
|
ecore_x_randr_crtc_geometry_get(root, crtcs[i], &c_geo.x, &c_geo.y,
|
|
&c_geo.w, &c_geo.h);
|
|
if (eina_rectangles_intersect(&w_geo, &c_geo))
|
|
{
|
|
ret = realloc(ret, (++nret *
|
|
sizeof(Ecore_X_Randr_Output)));
|
|
ret[nret] = crtcs[i];
|
|
}
|
|
}
|
|
free(crtcs);
|
|
|
|
if (num) *num = nret;
|
|
return ret;
|
|
|
|
#endif
|
|
if (num) *num = 0;
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* @brief get a CRTC's outputs.
|
|
* @param root the root window which's screen will be queried
|
|
* @param num number of outputs referenced by given CRTC
|
|
*/
|
|
EAPI Ecore_X_Randr_Output *
|
|
ecore_x_randr_crtc_outputs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *ret = NULL;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(NULL);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return ret;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_outputs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_outputs);
|
|
if (ret)
|
|
memcpy(ret, xcb_randr_get_crtc_info_outputs(oreply),
|
|
sizeof(Ecore_X_Randr_Output) * oreply->num_outputs);
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_randr_crtc_geometry_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int *x,
|
|
int *y,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtc, stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (x) *x = oreply->x;
|
|
if (y) *y = oreply->y;
|
|
if (w) *w = oreply->width;
|
|
if (h) *h = oreply->height;
|
|
free(oreply);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief Sets a CRTC relative to another one.
|
|
*
|
|
* @param crtc1 The CRTC to be positioned.
|
|
* @param crtc2 The CRTC the position should be relative to.
|
|
* @param policy The relation between the crtcs.
|
|
* @param alignment In case CRTCs size differ, aligns CRTC1 accordingly at
|
|
* CRTC2's borders.
|
|
* @return @c EINA_TRUE if crtc could be successfully positioned, @c EINA_FALSE
|
|
* if repositioning failed or if position of new crtc would be out of given
|
|
* screen's min/max bounds.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_crtc_pos_relative_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc1,
|
|
Ecore_X_Randr_Crtc crtc2,
|
|
Ecore_X_Randr_Output_Policy policy,
|
|
Ecore_X_Randr_Relative_Alignment alignment)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Eina_Rectangle r1, r2;
|
|
int w_max = 0, h_max = 0, cw = 0, ch = 0, xn = -1, yn = -1;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if ((ecore_x_randr_crtc_mode_get(root, crtc1) == 0) ||
|
|
(ecore_x_randr_crtc_mode_get(root, crtc2) == 0))
|
|
return EINA_FALSE;
|
|
|
|
if ((!_ecore_xcb_randr_crtc_validate(root, crtc1) ||
|
|
(!(crtc1 != crtc2) && (!_ecore_xcb_randr_crtc_validate(root, crtc2)))))
|
|
return EINA_FALSE;
|
|
|
|
ecore_x_randr_crtc_geometry_get(root, crtc1, &r1.x, &r1.y, &r1.w, &r1.h);
|
|
ecore_x_randr_crtc_geometry_get(root, crtc2, &r2.x, &r2.y, &r2.w, &r2.h);
|
|
ecore_x_randr_screen_size_range_get(root, NULL, NULL, &w_max, &h_max);
|
|
ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
|
|
|
|
switch (policy)
|
|
{
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_RIGHT:
|
|
xn = (r2.x + r2.w);
|
|
if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE)
|
|
yn = -1;
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL)
|
|
yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0)));
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR)
|
|
yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0));
|
|
break;
|
|
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_LEFT:
|
|
xn = (r2.x - r1.w);
|
|
if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE)
|
|
yn = -1;
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL)
|
|
yn = ((int)(((double)r2.h / 2.0) + (double)r2.y - ((double)r1.h / 2.0)));
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR)
|
|
yn = ((int)((double)ch / 2.0) - ((double)r1.h / 2.0));
|
|
break;
|
|
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_BELOW:
|
|
yn = (r2.y + r2.h);
|
|
if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE)
|
|
xn = -1;
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL)
|
|
xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0)));
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR)
|
|
xn = ((int)((double)cw / 2.0));
|
|
break;
|
|
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_ABOVE:
|
|
yn = (r2.y - r1.h);
|
|
if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_NONE)
|
|
xn = -1;
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_REL)
|
|
xn = ((int)((((double)r2.x + (double)r2.w) / 2.0) - ((double)r1.w / 2.0)));
|
|
else if (alignment == ECORE_X_RANDR_RELATIVE_ALIGNMENT_CENTER_SCR)
|
|
xn = ((int)((double)cw / 2.0));
|
|
break;
|
|
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_CLONE:
|
|
return ecore_x_randr_crtc_pos_set(root, crtc1, r2.x, r2.y);
|
|
break;
|
|
|
|
case ECORE_X_RANDR_OUTPUT_POLICY_NONE:
|
|
break;
|
|
}
|
|
|
|
if ((xn == r1.x) && (yn == r1.x)) return EINA_TRUE;
|
|
if (((yn + r1.h) > h_max) || ((xn + r1.w) > w_max))
|
|
return EINA_FALSE;
|
|
|
|
return ecore_x_randr_crtc_pos_set(root, crtc1, xn, yn);
|
|
#endif
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_move_all_crtcs_but(Ecore_X_Window root,
|
|
const Ecore_X_Randr_Crtc *not_moved,
|
|
int num,
|
|
int dx,
|
|
int dy)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Randr_Crtc *crtcs = NULL, *move = NULL;
|
|
int i = 0, j = 0, k = 0, n = 0, total = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if ((num <= 0) || (!not_moved) || (!_ecore_xcb_randr_root_validate(root)))
|
|
return EINA_FALSE;
|
|
|
|
crtcs = ecore_x_randr_crtcs_get(root, &total);
|
|
n = (total - num);
|
|
move = malloc(sizeof(Ecore_X_Randr_Crtc) * n);
|
|
if (move)
|
|
{
|
|
for (i = 0, k = 0; (i < total) && (k < n); i++)
|
|
{
|
|
for (j = 0; j < num; j++)
|
|
if (crtcs[i] == not_moved[j]) break;
|
|
if (j == num)
|
|
move[k++] = crtcs[i];
|
|
}
|
|
ret = ecore_x_randr_move_crtcs(root, move, n, dx, dy);
|
|
free(move);
|
|
free(crtcs);
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_randr_crtc_pos_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int *x,
|
|
int *y)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
ecore_x_randr_crtc_geometry_get(root, crtc, x, y, NULL, NULL);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @brief Sets the position of given CRTC within root window's screen.
|
|
*
|
|
* @param root The window's screen to be queried.
|
|
* @param crtc The CRTC which's position within the mentioned screen is to be
|
|
* altered.
|
|
* @param x Position on the x-axis (0 == left) of the screen. if x < 0 current
|
|
* value will be kept.
|
|
* @param y Position on the y-ayis (0 == top) of the screen. if y < 0, current
|
|
* value will be kept.
|
|
* @return @c EINA_TRUE if position could be successfully be altered.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_crtc_pos_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int x,
|
|
int y)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
int w = 0, h = 0, nw = 0, nh = 0;
|
|
Eina_Rectangle rect;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
ecore_x_randr_crtc_geometry_get(root, crtc,
|
|
&rect.x, &rect.y, &rect.w, &rect.h);
|
|
ecore_x_randr_screen_current_size_get(root, &w, &h, NULL, NULL);
|
|
if (x < 0) x = rect.x;
|
|
if (y < 0) y = rect.y;
|
|
if ((x + rect.w) > w)
|
|
nw = (x + rect.w);
|
|
if ((y + rect.h) > h)
|
|
nh = (y + rect.h);
|
|
|
|
if ((nw != 0) || (nh != 0))
|
|
{
|
|
if (!ecore_x_randr_screen_current_size_set(root, nw, nh, 0, 0))
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
ret = ecore_x_randr_crtc_settings_set(root, crtc, NULL, -1, x, y, -1, -1);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
EAPI void
|
|
ecore_x_randr_crtc_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
ecore_x_randr_crtc_geometry_get(root, crtc, NULL, NULL, w, h);
|
|
#endif
|
|
}
|
|
|
|
EAPI Ecore_X_Randr_Refresh_Rate
|
|
ecore_x_randr_crtc_refresh_rate_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc,
|
|
Ecore_X_Randr_Mode mode)
|
|
{
|
|
Ecore_X_Randr_Refresh_Rate ret = 0.0;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(0.0);
|
|
|
|
if (!_ecore_xcb_randr_crtc_validate(root, crtc)) return 0.0;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
miter =
|
|
xcb_randr_get_screen_resources_current_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
if (minfo->id == mode)
|
|
{
|
|
if ((minfo->htotal) && (minfo->vtotal))
|
|
{
|
|
ret = ((double)minfo->dot_clock /
|
|
((double)minfo->htotal *
|
|
(double)minfo->vtotal));
|
|
}
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
else if (_randr_version == RANDR_1_2)
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
miter = xcb_randr_get_screen_resources_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
if (minfo->id == mode)
|
|
{
|
|
if ((minfo->htotal) && (minfo->vtotal))
|
|
{
|
|
ret = ((double)minfo->dot_clock /
|
|
((double)minfo->htotal *
|
|
(double)minfo->vtotal));
|
|
}
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @brief Move given CRTCs belonging to the given root window's screen dx/dy
|
|
* pixels relative to their current position. The screen size will be
|
|
* automatically adjusted if necessary and possible.
|
|
*
|
|
* @param root Window which's screen's resources are used.
|
|
* @param crtcs List of CRTCs to be moved.
|
|
* @param ncrtc Number of CRTCs in array.
|
|
* @param dx Amount of pixels the CRTCs should be moved in x direction.
|
|
* @param dy Amount of pixels the CRTCs should be moved in y direction.
|
|
* @return @c EINA_TRUE if all crtcs could be moved successfully.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_move_crtcs(Ecore_X_Window root,
|
|
const Ecore_X_Randr_Crtc *crtcs,
|
|
int num,
|
|
int dx,
|
|
int dy)
|
|
{
|
|
Eina_Bool ret = EINA_TRUE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_crtc_info_reply_t *oreply[num];
|
|
int i = 0, cw = 0, ch = 0;
|
|
int mw = 0, mh = 0, nw = 0, nh = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (!_ecore_xcb_randr_root_validate(root)) return EINA_FALSE;
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
ecore_x_randr_screen_size_range_get(root, NULL, NULL, &mw, &mh);
|
|
ecore_x_randr_screen_current_size_get(root, &cw, &ch, NULL, NULL);
|
|
nw = cw;
|
|
nh = ch;
|
|
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i],
|
|
stamp);
|
|
oreply[i] = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply[i])
|
|
{
|
|
if (((oreply[i]->x + dx) < 0) ||
|
|
((oreply[i]->y + dy) < 0) ||
|
|
((oreply[i]->x + oreply[i]->width + dx) > mw) ||
|
|
((oreply[i]->y + oreply[i]->height + dy) > mh))
|
|
{
|
|
continue;
|
|
}
|
|
nw = MAX((int)(oreply[i]->x + oreply[i]->width + dx), nw);
|
|
nh = MAX((int)(oreply[i]->y + oreply[i]->height + dy), nh);
|
|
}
|
|
}
|
|
|
|
if ((nw > cw) || (nh > ch))
|
|
{
|
|
if (!ecore_x_randr_screen_current_size_set(root, nw, nh, -1, -1))
|
|
{
|
|
for (i = 0; i < num; i++)
|
|
if (oreply[i]) free(oreply[i]);
|
|
|
|
return EINA_FALSE;
|
|
}
|
|
}
|
|
|
|
for (i = 0; ((i < num) && (oreply[i])); i++)
|
|
{
|
|
if (!oreply[i]) continue;
|
|
if (!ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
|
|
(oreply[i]->x + dx),
|
|
(oreply[i]->y + dy),
|
|
oreply[i]->mode,
|
|
oreply[i]->rotation))
|
|
{
|
|
ret = EINA_FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < num)
|
|
{
|
|
while (i-- >= 0)
|
|
{
|
|
if (oreply[i])
|
|
ecore_x_randr_crtc_settings_set(root, crtcs[i], NULL, -1,
|
|
(oreply[i]->x - dx),
|
|
(oreply[i]->y - dy),
|
|
oreply[i]->mode,
|
|
oreply[i]->rotation);
|
|
}
|
|
}
|
|
|
|
for (i = 0; i < num; i++)
|
|
if (oreply[i]) free(oreply[i]);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief enable event selection. This enables basic interaction with
|
|
* output/crtc events and requires RRandR >= 1.2.
|
|
* @param win select this window's properties for RandRR events
|
|
* @param on enable/disable selecting
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_events_select(Ecore_X_Window win,
|
|
Eina_Bool on)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
uint16_t mask = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (on)
|
|
{
|
|
mask = XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE;
|
|
if (_randr_version >= ((1 << 16) | 2))
|
|
{
|
|
mask |= (XCB_RANDR_NOTIFY_MASK_CRTC_CHANGE |
|
|
XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE |
|
|
XCB_RANDR_NOTIFY_MASK_OUTPUT_PROPERTY);
|
|
}
|
|
}
|
|
|
|
xcb_randr_select_input(_ecore_xcb_conn, win, mask);
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @brief removes unused screen space. The most upper left CRTC is set to 0x0
|
|
* and all other CRTCs dx,dy respectively.
|
|
* @param root the window's screen which will be reset.
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_screen_reset(Ecore_X_Window root)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_timestamp_t stamp = 0;
|
|
Ecore_X_Randr_Crtc *crtcs = NULL;
|
|
int total = 0, i = 0, w = 0, h = 0;
|
|
int dx = 100000, dy = 100000, num = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (!_ecore_xcb_randr_root_validate(root)) return;
|
|
crtcs = ecore_x_randr_crtcs_get(root, &total);
|
|
|
|
if (_randr_version >= RANDR_1_3)
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
else if (_randr_version == RANDR_1_2)
|
|
stamp = _ecore_xcb_randr_12_get_resource_timestamp(root);
|
|
|
|
/* I hate declaring variables inside code like this, but we need the
|
|
* value of 'total' before we can */
|
|
Ecore_X_Randr_Crtc enabled[total];
|
|
|
|
for (i = 0; i < total; i++)
|
|
{
|
|
xcb_randr_get_crtc_info_cookie_t ocookie;
|
|
xcb_randr_get_crtc_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_crtc_info_unchecked(_ecore_xcb_conn, crtcs[i], stamp);
|
|
oreply = xcb_randr_get_crtc_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (!oreply) continue;
|
|
if ((oreply->mode <= 0) || (oreply->num_outputs == 0))
|
|
{
|
|
free(oreply);
|
|
continue;
|
|
}
|
|
|
|
enabled[num++] = crtcs[i];
|
|
if ((int)(oreply->x + oreply->width) > w)
|
|
w = (oreply->x + oreply->width);
|
|
if ((int)(oreply->y + oreply->height) > h)
|
|
h = (oreply->y + oreply->height);
|
|
|
|
if (oreply->x < dx) dx = oreply->x;
|
|
if (oreply->y < dy) dy = oreply->y;
|
|
|
|
free(oreply);
|
|
}
|
|
free(crtcs);
|
|
|
|
if ((dx > 0) || (dy > 0))
|
|
{
|
|
if (ecore_x_randr_move_crtcs(root, enabled, num, -dx, -dy))
|
|
{
|
|
w -= dx;
|
|
h -= dy;
|
|
}
|
|
}
|
|
|
|
ecore_x_randr_screen_current_size_set(root, w, h, -1, -1);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @param root window which's screen will be queried
|
|
* @param wmin minimum width the screen can be set to
|
|
* @param hmin minimum height the screen can be set to
|
|
* @param wmax maximum width the screen can be set to
|
|
* @param hmax maximum height the screen can be set to
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_screen_size_range_get(Ecore_X_Window root,
|
|
int *minw,
|
|
int *minh,
|
|
int *maxw,
|
|
int *maxh)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
xcb_randr_get_screen_size_range_cookie_t cookie;
|
|
xcb_randr_get_screen_size_range_reply_t *reply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
cookie = xcb_randr_get_screen_size_range_unchecked(_ecore_xcb_conn, root);
|
|
reply = xcb_randr_get_screen_size_range_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (reply)
|
|
{
|
|
if (minw) *minw = reply->min_width;
|
|
if (minh) *minh = reply->min_height;
|
|
if (maxw) *maxw = reply->max_width;
|
|
if (maxh) *maxh = reply->max_height;
|
|
free(reply);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @param w width of screen in px
|
|
* @param h height of screen in px
|
|
*/
|
|
EAPI void
|
|
ecore_x_randr_screen_current_size_get(Ecore_X_Window root,
|
|
int *w,
|
|
int *h,
|
|
int *w_mm,
|
|
int *h_mm)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Randr_Screen scr = 0;
|
|
xcb_screen_t *s;
|
|
# define RANDR_VALIDATE_ROOT(screen, root) \
|
|
((screen == _ecore_xcb_randr_root_to_screen(root)) != -1)
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET();
|
|
|
|
if (!RANDR_VALIDATE_ROOT(scr, root)) return;
|
|
|
|
s = ecore_x_screen_get(scr);
|
|
if (w) *w = s->width_in_pixels;
|
|
if (h) *h = s->height_in_pixels;
|
|
if (w_mm) *w_mm = s->width_in_millimeters;
|
|
if (h_mm) *h_mm = s->height_in_millimeters;
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
* @param root Window which's screen's size should be set. If invalid (e.g.
|
|
* @c NULL) no action is taken.
|
|
* @param w Width in px the screen should be set to. If out of valid
|
|
* boundaries, current value is assumed.
|
|
* @param h Height in px the screen should be set to. If out of valid
|
|
* boundaries, current value is assumed.
|
|
* @param w_mm Width in mm the screen should be set to. If @c 0, current
|
|
* aspect is assumed.
|
|
* @param h_mm Height in mm the screen should be set to. If @c 0, current
|
|
* aspect is assumed.
|
|
* @return @c EINA_TRUE if request was successfully sent or screen is already
|
|
* in requested size, @c EINA_FALSE if parameters are invalid.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_screen_current_size_set(Ecore_X_Window root,
|
|
int w,
|
|
int h,
|
|
int w_mm,
|
|
int h_mm)
|
|
{
|
|
Eina_Bool ret = EINA_TRUE;
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Randr_Screen scr;
|
|
int wc = 0, hc = 0, w_mm_c = 0, h_mm_c = 0;
|
|
int mw = 0, mh = 0, xw = 0, xh = 0;
|
|
# define RANDR_VALIDATE_ROOT(screen, root) \
|
|
((screen == _ecore_xcb_randr_root_to_screen(root)) != -1)
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (!RANDR_VALIDATE_ROOT(scr, root)) return EINA_FALSE;
|
|
ecore_x_randr_screen_current_size_get(root, &wc, &hc, &w_mm_c, &h_mm_c);
|
|
if ((w == wc) && (h == hc) && (w_mm == w_mm_c) && (h_mm == h_mm_c))
|
|
return EINA_TRUE;
|
|
ecore_x_randr_screen_size_range_get(root, &mw, &mh, &xw, &xh);
|
|
if (((w != 1) && ((w < mw) || (w > xw))) ||
|
|
((h != -1) && ((h < mh) || (h > xh)))) return EINA_FALSE;
|
|
|
|
if (w <= 0)
|
|
w = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_pixels;
|
|
if (h <= 0)
|
|
h = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_pixels;
|
|
|
|
/* NB: Hmmmm, xlib version divides w_mm by width ... that seems wrong */
|
|
if (w_mm <= 0)
|
|
w_mm = ((xcb_screen_t *)_ecore_xcb_screen)->width_in_millimeters;
|
|
if (h_mm <= 0)
|
|
h_mm = ((xcb_screen_t *)_ecore_xcb_screen)->height_in_millimeters;
|
|
|
|
xcb_randr_set_screen_size(_ecore_xcb_conn, root, w, h, w_mm, h_mm);
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
/*
|
|
* @deprecated bad naming. Use ecore_x_randr_window_outputs_get instead.
|
|
* @brief Get the outputs, which display a certain window.
|
|
*
|
|
* @param window Window the displaying outputs shall be found for.
|
|
* @param num The number of outputs displaying the window.
|
|
* @return Array of outputs that display a certain window. @c NULL if no
|
|
* outputs was found that displays the specified window.
|
|
*/
|
|
|
|
Ecore_X_Randr_Output *
|
|
ecore_x_randr_current_output_get(Ecore_X_Window window,
|
|
int *num)
|
|
{
|
|
return ecore_x_randr_window_outputs_get(window, num);
|
|
}
|
|
|
|
/*
|
|
* @brief Get the outputs, which display a certain window.
|
|
*
|
|
* @param window Window the displaying outputs shall be found for.
|
|
* @param num The number of outputs displaying the window.
|
|
* @return Array of outputs that display a certain window. @c NULL if no
|
|
* outputs was found that displays the specified window.
|
|
*/
|
|
EAPI Ecore_X_Randr_Output *
|
|
ecore_x_randr_window_outputs_get(Ecore_X_Window window,
|
|
int *num)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Window root;
|
|
Ecore_X_Randr_Crtc *crtcs;
|
|
Ecore_X_Randr_Output *outputs, *ret = NULL;
|
|
int ncrtcs, noutputs, i, nret = 0;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
if (num) *num = 0;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
if (_randr_version < RANDR_1_2) goto _ecore_x_randr_current_output_get_fail;
|
|
|
|
root = ecore_x_window_root_get(window);
|
|
if (!(crtcs = ecore_x_randr_window_crtcs_get(window, &ncrtcs)))
|
|
goto _ecore_x_randr_current_output_get_fail;
|
|
|
|
for (i = 0, nret = 0; i < ncrtcs; i++)
|
|
{
|
|
|
|
outputs = ecore_x_randr_crtc_outputs_get(root, crtcs[i],
|
|
&noutputs);
|
|
if (!outputs)
|
|
goto _ecore_x_randr_current_output_get_fail_free;
|
|
nret += noutputs;
|
|
ret = realloc(ret, (nret * sizeof(Ecore_X_Randr_Output)));
|
|
memcpy(&ret[nret], outputs, (noutputs * sizeof(Ecore_X_Randr_Output)));
|
|
free(outputs);
|
|
}
|
|
free(crtcs);
|
|
|
|
if (num)
|
|
*num = nret;
|
|
|
|
return ret;
|
|
|
|
_ecore_x_randr_current_output_get_fail_free:
|
|
free(outputs);
|
|
free(crtcs);
|
|
free(ret);
|
|
_ecore_x_randr_current_output_get_fail:
|
|
#endif
|
|
if (num) *num = 0;
|
|
return NULL;
|
|
}
|
|
|
|
/*
|
|
* @brief get the backlight level of the given output
|
|
* @param root window which's screen should be queried
|
|
* @param output from which the backlight level should be retrieved
|
|
* @return the backlight level
|
|
*/
|
|
EAPI double
|
|
ecore_x_randr_output_backlight_level_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Atom _backlight;
|
|
xcb_intern_atom_cookie_t acookie;
|
|
xcb_intern_atom_reply_t *areply;
|
|
xcb_randr_get_output_property_cookie_t cookie;
|
|
xcb_randr_get_output_property_reply_t *reply;
|
|
xcb_randr_query_output_property_cookie_t qcookie;
|
|
xcb_randr_query_output_property_reply_t *qreply;
|
|
double dvalue;
|
|
long value, max, min;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(-1);
|
|
|
|
acookie =
|
|
xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
|
|
strlen("Backlight"), "Backlight");
|
|
areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL);
|
|
|
|
if (!areply)
|
|
{
|
|
ERR("Backlight property is not suppported on this server or driver");
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
_backlight = areply->atom;
|
|
free(areply);
|
|
}
|
|
|
|
if (!_ecore_xcb_randr_output_validate(root, output))
|
|
{
|
|
ERR("Invalid output");
|
|
return -1;
|
|
}
|
|
|
|
cookie =
|
|
xcb_randr_get_output_property_unchecked(_ecore_xcb_conn,
|
|
output, _backlight,
|
|
XCB_ATOM_NONE, 0, 4, 0, 0);
|
|
reply =
|
|
xcb_randr_get_output_property_reply(_ecore_xcb_conn, cookie, NULL);
|
|
if (!reply)
|
|
{
|
|
WRN("Backlight not supported on this output");
|
|
return -1;
|
|
}
|
|
|
|
if ((reply->format != 32) || (reply->num_items != 1) ||
|
|
(reply->type != XCB_ATOM_INTEGER))
|
|
{
|
|
free(reply);
|
|
return -1;
|
|
}
|
|
|
|
value = *((long *)xcb_randr_get_output_property_data(reply));
|
|
free (reply);
|
|
|
|
/* I have the current value of the backlight */
|
|
/* Now retrieve the min and max intensities of the output */
|
|
qcookie =
|
|
xcb_randr_query_output_property_unchecked(_ecore_xcb_conn,
|
|
output, _backlight);
|
|
qreply =
|
|
xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL);
|
|
if (qreply)
|
|
{
|
|
dvalue = -1;
|
|
if ((qreply->range) &&
|
|
(xcb_randr_query_output_property_valid_values_length(qreply) == 2))
|
|
{
|
|
int32_t *vals;
|
|
|
|
vals = xcb_randr_query_output_property_valid_values(qreply);
|
|
/* finally convert the current value in the interval [0..1] */
|
|
min = vals[0];
|
|
max = vals[1];
|
|
dvalue = ((double)(value - min)) / ((double)(max - min));
|
|
}
|
|
free(qreply);
|
|
return dvalue;
|
|
}
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* @brief Set the backlight level of a given output.
|
|
*
|
|
* @param root Window which's screen should be queried.
|
|
* @param output That should be set.
|
|
* @param level For which the backlight should be set.
|
|
* @return @c EINA_TRUE in case of success.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_output_backlight_level_set(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
double level)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Atom _backlight;
|
|
xcb_intern_atom_cookie_t acookie;
|
|
xcb_intern_atom_reply_t *areply;
|
|
xcb_randr_query_output_property_cookie_t qcookie;
|
|
xcb_randr_query_output_property_reply_t *qreply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if ((level < 0) || (level > 1))
|
|
{
|
|
ERR("Backlight level should be between 0 and 1");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
if (!_ecore_xcb_randr_output_validate(root, output))
|
|
{
|
|
ERR("Wrong output value");
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
acookie =
|
|
xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
|
|
strlen("Backlight"), "Backlight");
|
|
areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL);
|
|
if (!areply)
|
|
{
|
|
WRN("Backlight property is not suppported on this server or driver");
|
|
return EINA_FALSE;
|
|
}
|
|
else
|
|
{
|
|
_backlight = areply->atom;
|
|
free(areply);
|
|
}
|
|
|
|
qcookie =
|
|
xcb_randr_query_output_property_unchecked(_ecore_xcb_conn,
|
|
output, _backlight);
|
|
qreply =
|
|
xcb_randr_query_output_property_reply(_ecore_xcb_conn, qcookie, NULL);
|
|
if (qreply)
|
|
{
|
|
if ((qreply->range) && (qreply->length == 2))
|
|
{
|
|
int32_t *vals;
|
|
double min, max, tmp;
|
|
long n;
|
|
|
|
vals = xcb_randr_query_output_property_valid_values(qreply);
|
|
min = vals[0];
|
|
max = vals[1];
|
|
tmp = (level * (max - min)) + min;
|
|
n = tmp;
|
|
if (n > max) n = max;
|
|
if (n < min) n = min;
|
|
xcb_randr_change_output_property(_ecore_xcb_conn, output,
|
|
_backlight, XCB_ATOM_INTEGER,
|
|
32, XCB_PROP_MODE_REPLACE,
|
|
1, (unsigned char *)&n);
|
|
ecore_x_flush(); // needed
|
|
}
|
|
|
|
free(qreply);
|
|
return EINA_TRUE;
|
|
}
|
|
#endif
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/*
|
|
* @brief Check if a backlight is available.
|
|
*
|
|
* @return Whether a backlight is available.
|
|
*/
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_output_backlight_available(void)
|
|
{
|
|
#ifdef ECORE_XCB_RANDR
|
|
Ecore_X_Atom _backlight;
|
|
xcb_intern_atom_cookie_t acookie;
|
|
xcb_intern_atom_reply_t *areply;
|
|
#endif
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
acookie =
|
|
xcb_intern_atom_unchecked(_ecore_xcb_conn, 1,
|
|
strlen("Backlight"), "Backlight");
|
|
areply = xcb_intern_atom_reply(_ecore_xcb_conn, acookie, NULL);
|
|
|
|
if (!areply)
|
|
{
|
|
ERR("Backlight property is not suppported on this server or driver");
|
|
return EINA_FALSE;
|
|
}
|
|
else
|
|
{
|
|
_backlight = areply->atom;
|
|
free(areply);
|
|
return EINA_TRUE;
|
|
}
|
|
#endif
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EAPI int
|
|
ecore_x_randr_edid_version_get(unsigned char *edid, unsigned long edid_length)
|
|
{
|
|
if ((edid_length > _ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR) &&
|
|
(ecore_x_randr_edid_has_valid_header(edid, edid_length)))
|
|
return (edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MAJOR] << 8) |
|
|
edid[_ECORE_X_RANDR_EDID_OFFSET_VERSION_MINOR];
|
|
return ECORE_X_RANDR_EDID_UNKNOWN_VALUE;
|
|
}
|
|
|
|
EAPI char *
|
|
ecore_x_randr_edid_display_name_get(unsigned char *edid, unsigned long edid_length)
|
|
{
|
|
unsigned char *block = NULL;
|
|
int version = 0;
|
|
|
|
version = ecore_x_randr_edid_version_get(edid, edid_length);
|
|
if (version < ECORE_X_RANDR_EDID_VERSION_13) return NULL;
|
|
|
|
_ECORE_X_RANDR_EDID_FOR_EACH_NON_PIXEL_DESCRIPTOR_BLOCK(edid, block)
|
|
{
|
|
if (block[_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_TYPE] == 0xfc)
|
|
{
|
|
char *name, *p;
|
|
const char *edid_name;
|
|
|
|
edid_name = (const char *)block +
|
|
_ECORE_X_RANDR_EDID_OFFSET_DESCRIPTOR_BLOCK_CONTENT;
|
|
name =
|
|
malloc(sizeof(char) *
|
|
_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX);
|
|
if (!name) return NULL;
|
|
|
|
strncpy(name, edid_name,
|
|
(_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX - 1));
|
|
name[_ECORE_X_RANDR_EDID_DISPLAY_DESCRIPTOR_BLOCK_CONTENT_LENGTH_MAX] = 0;
|
|
for (p = name; *p; p++)
|
|
if ((*p < ' ') || (*p > '~')) *p = 0;
|
|
|
|
return name;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
ecore_x_randr_edid_has_valid_header(unsigned char *edid, unsigned long edid_length)
|
|
{
|
|
const unsigned char header[] =
|
|
{
|
|
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00
|
|
};
|
|
|
|
if ((!edid) || (edid_length < 8)) return EINA_FALSE;
|
|
if (!memcmp(edid, header, 8)) return EINA_TRUE;
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
/* local functions */
|
|
static Eina_Bool
|
|
_ecore_xcb_randr_output_validate(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if ((output) && (_ecore_xcb_randr_root_validate(root)))
|
|
{
|
|
if (_randr_version >= RANDR_1_3)
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
int len = 0, i = 0;
|
|
xcb_randr_output_t *outputs;
|
|
|
|
len =
|
|
xcb_randr_get_screen_resources_current_outputs_length(reply);
|
|
outputs =
|
|
xcb_randr_get_screen_resources_current_outputs(reply);
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (outputs[i] == output)
|
|
{
|
|
ret = EINA_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
else if (_randr_version == RANDR_1_2)
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
int len = 0, i = 0;
|
|
xcb_randr_output_t *outputs;
|
|
|
|
len = xcb_randr_get_screen_resources_outputs_length(reply);
|
|
outputs = xcb_randr_get_screen_resources_outputs(reply);
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (outputs[i] == output)
|
|
{
|
|
ret = EINA_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* @brief Validates a CRTC for a given root window's screen.
|
|
*
|
|
* @param root The window which's default display will be queried.
|
|
* @param crtc The CRTC to be validated.
|
|
* @return In case it is found @c EINA_TRUE will be returned, else
|
|
* @c EINA_FALSE is returned.
|
|
*/
|
|
static Eina_Bool
|
|
_ecore_xcb_randr_crtc_validate(Ecore_X_Window root,
|
|
Ecore_X_Randr_Crtc crtc)
|
|
{
|
|
Eina_Bool ret = EINA_FALSE;
|
|
|
|
LOGFN(__FILE__, __LINE__, __FUNCTION__);
|
|
CHECK_XCB_CONN;
|
|
|
|
#ifdef ECORE_XCB_RANDR
|
|
RANDR_CHECK_1_2_RET(EINA_FALSE);
|
|
|
|
if (((int)crtc == Ecore_X_Randr_None) || ((int)crtc == Ecore_X_Randr_Unset))
|
|
return ret;
|
|
|
|
if ((crtc) && (_ecore_xcb_randr_root_validate(root)))
|
|
{
|
|
if (_randr_version >= RANDR_1_3)
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
int i = 0;
|
|
xcb_randr_crtc_t *crtcs;
|
|
|
|
crtcs = xcb_randr_get_screen_resources_current_crtcs(reply);
|
|
for (i = 0; i < reply->num_crtcs; i++)
|
|
{
|
|
if (crtcs[i] == crtc)
|
|
{
|
|
ret = EINA_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
else if (_randr_version == RANDR_1_2)
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
int i = 0;
|
|
xcb_randr_crtc_t *crtcs;
|
|
|
|
crtcs = xcb_randr_get_screen_resources_crtcs(reply);
|
|
for (i = 0; i < reply->num_crtcs; i++)
|
|
{
|
|
if (crtcs[i] == crtc)
|
|
{
|
|
ret = EINA_TRUE;
|
|
break;
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode *
|
|
_ecore_xcb_randr_12_output_modes_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num,
|
|
int *npreferred)
|
|
{
|
|
Ecore_X_Randr_Mode *modes = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_modes;
|
|
if (npreferred) *npreferred = oreply->num_preferred;
|
|
|
|
modes = malloc(sizeof(Ecore_X_Randr_Mode) *
|
|
oreply->num_modes);
|
|
if (modes)
|
|
{
|
|
xcb_randr_mode_t *rmodes;
|
|
int len = 0;
|
|
|
|
len = xcb_randr_get_output_info_modes_length(oreply);
|
|
rmodes = xcb_randr_get_output_info_modes(oreply);
|
|
memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len);
|
|
}
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
|
|
return modes;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode *
|
|
_ecore_xcb_randr_13_output_modes_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num,
|
|
int *npreferred)
|
|
{
|
|
Ecore_X_Randr_Mode *modes = NULL;
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
stamp = _ecore_xcb_randr_13_get_resource_timestamp(root);
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output, stamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn, ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_modes;
|
|
if (npreferred) *npreferred = oreply->num_preferred;
|
|
|
|
modes = malloc(sizeof(Ecore_X_Randr_Mode) * oreply->num_modes);
|
|
if (modes)
|
|
{
|
|
xcb_randr_mode_t *rmodes;
|
|
int len = 0;
|
|
|
|
len = xcb_randr_get_output_info_modes_length(oreply);
|
|
rmodes = xcb_randr_get_output_info_modes(oreply);
|
|
memcpy(modes, rmodes, sizeof(Ecore_X_Randr_Mode) * len);
|
|
}
|
|
free(oreply);
|
|
}
|
|
|
|
return modes;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode_Info *
|
|
_ecore_xcb_randr_12_mode_info_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode)
|
|
{
|
|
Ecore_X_Randr_Mode_Info *ret = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
|
|
{
|
|
uint8_t *nbuf;
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
nbuf = xcb_randr_get_screen_resources_names(reply);
|
|
miter = xcb_randr_get_screen_resources_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
nbuf += minfo->name_len;
|
|
|
|
if (minfo->id == mode)
|
|
{
|
|
ret->xid = minfo->id;
|
|
ret->width = minfo->width;
|
|
ret->height = minfo->height;
|
|
ret->dotClock = minfo->dot_clock;
|
|
ret->hSyncStart = minfo->hsync_start;
|
|
ret->hSyncEnd = minfo->hsync_end;
|
|
ret->hTotal = minfo->htotal;
|
|
ret->vSyncStart = minfo->vsync_start;
|
|
ret->vSyncEnd = minfo->vsync_end;
|
|
ret->vTotal = minfo->vtotal;
|
|
ret->modeFlags = minfo->mode_flags;
|
|
|
|
ret->name = NULL;
|
|
ret->nameLength = minfo->name_len;
|
|
if (ret->nameLength > 0)
|
|
{
|
|
ret->name = malloc(ret->nameLength + 1);
|
|
if (ret->name)
|
|
memcpy(ret->name, nbuf, ret->nameLength + 1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
}
|
|
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode_Info *
|
|
_ecore_xcb_randr_13_mode_info_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode)
|
|
{
|
|
Ecore_X_Randr_Mode_Info *ret = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if ((ret = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
|
|
{
|
|
uint8_t *nbuf;
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
nbuf = xcb_randr_get_screen_resources_current_names(reply);
|
|
miter =
|
|
xcb_randr_get_screen_resources_current_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
nbuf += minfo->name_len;
|
|
|
|
if (minfo->id == mode)
|
|
{
|
|
ret->xid = minfo->id;
|
|
ret->width = minfo->width;
|
|
ret->height = minfo->height;
|
|
ret->dotClock = minfo->dot_clock;
|
|
ret->hSyncStart = minfo->hsync_start;
|
|
ret->hSyncEnd = minfo->hsync_end;
|
|
ret->hTotal = minfo->htotal;
|
|
ret->vSyncStart = minfo->vsync_start;
|
|
ret->vSyncEnd = minfo->vsync_end;
|
|
ret->vTotal = minfo->vtotal;
|
|
ret->modeFlags = minfo->mode_flags;
|
|
|
|
ret->name = NULL;
|
|
ret->nameLength = minfo->name_len;
|
|
if (ret->nameLength > 0)
|
|
{
|
|
ret->name = malloc(ret->nameLength + 1);
|
|
if (ret->name)
|
|
memcpy(ret->name, nbuf, ret->nameLength + 1);
|
|
}
|
|
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
}
|
|
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode_Info **
|
|
_ecore_xcb_randr_12_modes_info_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Mode_Info **ret = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_modes;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes);
|
|
if (ret)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
int i = 0;
|
|
uint8_t *nbuf;
|
|
|
|
nbuf = xcb_randr_get_screen_resources_names(reply);
|
|
miter = xcb_randr_get_screen_resources_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
nbuf += minfo->name_len;
|
|
if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
|
|
{
|
|
ret[i]->xid = minfo->id;
|
|
ret[i]->width = minfo->width;
|
|
ret[i]->height = minfo->height;
|
|
ret[i]->dotClock = minfo->dot_clock;
|
|
ret[i]->hSyncStart = minfo->hsync_start;
|
|
ret[i]->hSyncEnd = minfo->hsync_end;
|
|
ret[i]->hTotal = minfo->htotal;
|
|
ret[i]->vSyncStart = minfo->vsync_start;
|
|
ret[i]->vSyncEnd = minfo->vsync_end;
|
|
ret[i]->vTotal = minfo->vtotal;
|
|
ret[i]->modeFlags = minfo->mode_flags;
|
|
|
|
ret[i]->name = NULL;
|
|
ret[i]->nameLength = minfo->name_len;
|
|
if (ret[i]->nameLength > 0)
|
|
{
|
|
ret[i]->name = malloc(ret[i]->nameLength + 1);
|
|
if (ret[i]->name)
|
|
memcpy(ret[i]->name, nbuf,
|
|
ret[i]->nameLength + 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (i > 0)
|
|
free(ret[--i]);
|
|
free(ret);
|
|
ret = NULL;
|
|
break;
|
|
}
|
|
i++;
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Mode_Info **
|
|
_ecore_xcb_randr_13_modes_info_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Mode_Info **ret = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_modes;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Mode_Info *) * reply->num_modes);
|
|
if (ret)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
int i = 0;
|
|
uint8_t *nbuf;
|
|
|
|
nbuf = xcb_randr_get_screen_resources_current_names(reply);
|
|
miter =
|
|
xcb_randr_get_screen_resources_current_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
nbuf += minfo->name_len;
|
|
if ((ret[i] = malloc(sizeof(Ecore_X_Randr_Mode_Info))))
|
|
{
|
|
ret[i]->xid = minfo->id;
|
|
ret[i]->width = minfo->width;
|
|
ret[i]->height = minfo->height;
|
|
ret[i]->dotClock = minfo->dot_clock;
|
|
ret[i]->hSyncStart = minfo->hsync_start;
|
|
ret[i]->hSyncEnd = minfo->hsync_end;
|
|
ret[i]->hTotal = minfo->htotal;
|
|
ret[i]->vSyncStart = minfo->vsync_start;
|
|
ret[i]->vSyncEnd = minfo->vsync_end;
|
|
ret[i]->vTotal = minfo->vtotal;
|
|
ret[i]->modeFlags = minfo->mode_flags;
|
|
|
|
ret[i]->name = NULL;
|
|
ret[i]->nameLength = minfo->name_len;
|
|
if (ret[i]->nameLength > 0)
|
|
{
|
|
ret[i]->name = malloc(ret[i]->nameLength + 1);
|
|
if (ret[i]->name)
|
|
memcpy(ret[i]->name, nbuf,
|
|
ret[i]->nameLength + 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
while (i > 0)
|
|
free(ret[--i]);
|
|
free(ret);
|
|
ret = NULL;
|
|
break;
|
|
}
|
|
i++;
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static void
|
|
_ecore_xcb_randr_12_mode_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
miter = xcb_randr_get_screen_resources_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
if (minfo->id == mode)
|
|
{
|
|
if (w) *w = minfo->width;
|
|
if (h) *h = minfo->height;
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_ecore_xcb_randr_13_mode_size_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Mode mode,
|
|
int *w,
|
|
int *h)
|
|
{
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_mode_info_iterator_t miter;
|
|
|
|
miter = xcb_randr_get_screen_resources_current_modes_iterator(reply);
|
|
while (miter.rem)
|
|
{
|
|
xcb_randr_mode_info_t *minfo;
|
|
|
|
minfo = miter.data;
|
|
if (minfo->id == mode)
|
|
{
|
|
if (w) *w = minfo->width;
|
|
if (h) *h = minfo->height;
|
|
break;
|
|
}
|
|
xcb_randr_mode_info_next(&miter);
|
|
}
|
|
free(reply);
|
|
}
|
|
}
|
|
|
|
static Ecore_X_Randr_Output *
|
|
_ecore_xcb_randr_12_output_clones_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *outputs = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_clones;
|
|
|
|
outputs =
|
|
malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones);
|
|
if (outputs)
|
|
{
|
|
memcpy(outputs, xcb_randr_get_output_info_clones(oreply),
|
|
sizeof(Ecore_X_Randr_Output) * oreply->num_clones);
|
|
}
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return outputs;
|
|
}
|
|
|
|
static Ecore_X_Randr_Output *
|
|
_ecore_xcb_randr_13_output_clones_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *outputs = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_clones;
|
|
|
|
outputs =
|
|
malloc(sizeof(Ecore_X_Randr_Output) * oreply->num_clones);
|
|
if (outputs)
|
|
{
|
|
memcpy(outputs, xcb_randr_get_output_info_clones(oreply),
|
|
sizeof(Ecore_X_Randr_Output) * oreply->num_clones);
|
|
}
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return outputs;
|
|
}
|
|
|
|
static Ecore_X_Randr_Crtc *
|
|
_ecore_xcb_randr_12_output_possible_crtcs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Crtc *crtcs = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_crtcs;
|
|
|
|
crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs);
|
|
if (crtcs)
|
|
{
|
|
memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply),
|
|
sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs);
|
|
}
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return crtcs;
|
|
}
|
|
|
|
static Ecore_X_Randr_Crtc *
|
|
_ecore_xcb_randr_13_output_possible_crtcs_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Crtc *crtcs = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
if (num) *num = oreply->num_crtcs;
|
|
|
|
crtcs = malloc(sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs);
|
|
if (crtcs)
|
|
{
|
|
memcpy(crtcs, xcb_randr_get_output_info_crtcs(oreply),
|
|
sizeof(Ecore_X_Randr_Crtc) * oreply->num_crtcs);
|
|
}
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return crtcs;
|
|
}
|
|
|
|
static char *
|
|
_ecore_xcb_randr_12_output_name_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *len)
|
|
{
|
|
char *ret = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
uint8_t *nbuf;
|
|
|
|
nbuf = xcb_randr_get_output_info_name(oreply);
|
|
nbuf += oreply->name_len;
|
|
|
|
if (len) *len = oreply->name_len;
|
|
if (oreply->name_len > 0)
|
|
{
|
|
ret = malloc(oreply->name_len + 1);
|
|
if (ret)
|
|
memcpy(ret, nbuf, oreply->name_len + 1);
|
|
}
|
|
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static char *
|
|
_ecore_xcb_randr_13_output_name_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output,
|
|
int *len)
|
|
{
|
|
char *ret = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
uint8_t *nbuf;
|
|
|
|
nbuf = xcb_randr_get_output_info_name(oreply);
|
|
nbuf += oreply->name_len;
|
|
|
|
if (len) *len = oreply->name_len;
|
|
if (oreply->name_len > 0)
|
|
{
|
|
ret = malloc(oreply->name_len + 1);
|
|
if (ret)
|
|
memcpy(ret, nbuf, oreply->name_len + 1);
|
|
}
|
|
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Connection_Status
|
|
_ecore_xcb_randr_12_output_connection_status_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->connection;
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Connection_Status
|
|
_ecore_xcb_randr_13_output_connection_status_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
Ecore_X_Randr_Connection_Status ret = ECORE_X_RANDR_CONNECTION_STATUS_UNKNOWN;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->connection;
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Output *
|
|
_ecore_xcb_randr_12_outputs_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *ret = NULL;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_outputs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs);
|
|
if (ret)
|
|
memcpy(ret, xcb_randr_get_screen_resources_outputs(reply),
|
|
sizeof(Ecore_X_Randr_Output) * reply->num_outputs);
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Output *
|
|
_ecore_xcb_randr_13_outputs_get(Ecore_X_Window root,
|
|
int *num)
|
|
{
|
|
Ecore_X_Randr_Output *ret = NULL;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
if (num) *num = reply->num_outputs;
|
|
ret = malloc(sizeof(Ecore_X_Randr_Output) * reply->num_outputs);
|
|
if (ret)
|
|
memcpy(ret, xcb_randr_get_screen_resources_current_outputs(reply),
|
|
sizeof(Ecore_X_Randr_Output) * reply->num_outputs);
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Crtc
|
|
_ecore_xcb_randr_12_output_crtc_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->crtc;
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static Ecore_X_Randr_Crtc
|
|
_ecore_xcb_randr_13_output_crtc_get(Ecore_X_Window root,
|
|
Ecore_X_Randr_Output output)
|
|
{
|
|
Ecore_X_Randr_Crtc ret = Ecore_X_Randr_None;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(root);
|
|
if (reply)
|
|
{
|
|
xcb_randr_get_output_info_cookie_t ocookie;
|
|
xcb_randr_get_output_info_reply_t *oreply;
|
|
|
|
ocookie =
|
|
xcb_randr_get_output_info_unchecked(_ecore_xcb_conn, output,
|
|
reply->config_timestamp);
|
|
oreply = xcb_randr_get_output_info_reply(_ecore_xcb_conn,
|
|
ocookie, NULL);
|
|
if (oreply)
|
|
{
|
|
ret = oreply->crtc;
|
|
free(oreply);
|
|
}
|
|
free(reply);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static xcb_randr_get_screen_resources_reply_t *
|
|
_ecore_xcb_randr_12_get_resources(Ecore_X_Window win)
|
|
{
|
|
xcb_randr_get_screen_resources_cookie_t cookie;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
cookie = xcb_randr_get_screen_resources_unchecked(_ecore_xcb_conn, win);
|
|
reply = xcb_randr_get_screen_resources_reply(_ecore_xcb_conn, cookie, NULL);
|
|
return reply;
|
|
}
|
|
|
|
static xcb_randr_get_screen_resources_current_reply_t *
|
|
_ecore_xcb_randr_13_get_resources(Ecore_X_Window win)
|
|
{
|
|
xcb_randr_get_screen_resources_current_cookie_t cookie;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
cookie =
|
|
xcb_randr_get_screen_resources_current_unchecked(_ecore_xcb_conn, win);
|
|
reply =
|
|
xcb_randr_get_screen_resources_current_reply(_ecore_xcb_conn,
|
|
cookie, NULL);
|
|
return reply;
|
|
}
|
|
|
|
static xcb_timestamp_t
|
|
_ecore_xcb_randr_12_get_resource_timestamp(Ecore_X_Window win)
|
|
{
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_screen_resources_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_12_get_resources(win);
|
|
stamp = reply->config_timestamp;
|
|
free(reply);
|
|
return stamp;
|
|
}
|
|
|
|
static xcb_timestamp_t
|
|
_ecore_xcb_randr_13_get_resource_timestamp(Ecore_X_Window win)
|
|
{
|
|
xcb_timestamp_t stamp = 0;
|
|
xcb_randr_get_screen_resources_current_reply_t *reply;
|
|
|
|
reply = _ecore_xcb_randr_13_get_resources(win);
|
|
stamp = reply->config_timestamp;
|
|
free(reply);
|
|
return stamp;
|
|
}
|
|
|