efl/src/lib/ecore_x/xlib/ecore_x_randr_11.c

335 lines
9.6 KiB
C

/*
* vim:ts=8:sw=3:sts=8:expandtab:cino=>5n-3f0^-2{2
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* ifdef HAVE_CONFIG_H */
#include "ecore_x_private.h"
#include "ecore_x_randr.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define Ecore_X_Randr_None 0
#ifdef ECORE_XRANDR
#define RANDR_1_1 ((1 << 16) | 1)
#define RANDR_VALIDATE_ROOT(screen, \
root) ((screen = \
XRRRootToScreen(_ecore_x_disp, \
root)) != -1)
#define RANDR_CHECK_1_1_RET(ret) if (_randr_version < RANDR_1_1) \
return ret
extern XRRScreenResources *(*_ecore_x_randr_get_screen_resources)(Display *
dpy,
Window
window);
extern int _randr_version;
#endif /* ifdef ECORE_XRANDR */
/*
* @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)
{
#ifdef ECORE_XRANDR
Rotation rot = Ecore_X_Randr_None, crot;
LOGFN(__FILE__, __LINE__, __FUNCTION__);
rot =
XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
root), &crot);
return rot;
#else /* ifdef ECORE_XRANDR */
return Ecore_X_Randr_None;
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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)
{
#ifdef ECORE_XRANDR
Rotation crot = Ecore_X_Randr_None;
XRRRotations(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
root), &crot);
return crot;
#else /* ifdef ECORE_XRANDR */
return Ecore_X_Randr_None;
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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)
{
#ifdef ECORE_XRANDR
XRRScreenConfiguration *xrr_screen_cfg = NULL;
int sizeid;
Rotation crot;
Eina_Bool ret = EINA_FALSE;
if (!(xrr_screen_cfg = XRRGetScreenInfo(_ecore_x_disp, root)))
return EINA_FALSE;
sizeid = XRRConfigCurrentConfiguration(xrr_screen_cfg, &crot);
if (!XRRSetScreenConfig(_ecore_x_disp, xrr_screen_cfg, root, sizeid,
orientation, CurrentTime))
ret = EINA_TRUE;
if (xrr_screen_cfg)
XRRFreeScreenConfigInfo(xrr_screen_cfg);
return ret;
#else /* ifdef ECORE_XRANDR */
return EINA_FALSE;
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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_XRANDR
Ecore_X_Randr_Screen_Size_MM *ret = NULL;
XRRScreenSize *sizes;
int i, n;
/* we don't have to free sizes, because they're hold in a cache inside X*/
sizes =
XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
root), &n);
if ((!sizes) || (n <= 0)) return NULL;
ret = calloc(n, sizeof(Ecore_X_Randr_Screen_Size_MM));
if (!ret)
return NULL;
if (num)
*num = n;
for (i = 0; i < n; 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;
}
return ret;
#else /* ifdef ECORE_XRANDR */
return NULL;
#endif /* ifdef ECORE_XRANDR */
}
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_XRANDR
XRRScreenSize *sizes;
XRRScreenConfiguration *sc = NULL;
int idx;
Rotation orientation;
int n;
if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
{
ERR("Couldn't get screen information for %d", root);
return;
}
idx = XRRConfigCurrentConfiguration(sc, &orientation);
sizes =
XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
root), &n);
if ((idx < n) && (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;
}
XRRFreeScreenConfigInfo(sc);
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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)
{
#ifdef ECORE_XRANDR
XRRScreenConfiguration *sc = NULL;
Eina_Bool ret = EINA_FALSE;
int nsizes = 0;
if (size_index >= 0 && _ecore_x_randr_root_validate(root))
{
XRRSizes(_ecore_x_disp, XRRRootToScreen(_ecore_x_disp,
root), &nsizes);
if (size_index < nsizes)
{
sc = XRRGetScreenInfo(_ecore_x_disp, root);
if (!XRRSetScreenConfig(_ecore_x_disp, sc,
root, size_index,
ECORE_X_RANDR_ORIENTATION_ROT_0, CurrentTime))
{
ret = EINA_TRUE;
}
if (sc)
XRRFreeScreenConfigInfo(sc);
}
}
return ret;
#else /* ifdef ECORE_XRANDR */
return EINA_FALSE;
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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_XRANDR
Ecore_X_Randr_Refresh_Rate ret = 0.0;
XRRScreenConfiguration *sc = NULL;
if (!_ecore_x_randr_root_validate(root) ||
!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
return ret;
ret = XRRConfigCurrentRate(sc);
if (sc)
XRRFreeScreenConfigInfo(sc);
return ret;
#else /* ifdef ECORE_XRANDR */
return 0.0;
#endif /* ifdef ECORE_XRANDR */
}
/*
* @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_XRANDR
Ecore_X_Randr_Refresh_Rate *ret = NULL, *rates = NULL;
Ecore_X_Randr_Screen scr;
int n;
if (num
&& RANDR_VALIDATE_ROOT(scr, root)
&& (rates = XRRRates(_ecore_x_disp, scr, size_index, &n)))
{
if (rates && (ret = malloc(sizeof(Ecore_X_Randr_Refresh_Rate) * n)))
{
memcpy(ret, rates, (sizeof(Ecore_X_Randr_Refresh_Rate) * n));
*num = n;
}
}
return ret;
#else /* ifdef ECORE_XRANDR */
return NULL;
#endif /* ifdef ECORE_XRANDR */
}
//>= 1.1
/*
* @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)
{
#ifdef ECORE_XRANDR
RANDR_CHECK_1_1_RET(EINA_FALSE);
Eina_Bool ret = EINA_FALSE;
XRRScreenConfiguration *sc = NULL;
if (!(sc = XRRGetScreenInfo(_ecore_x_disp, root)))
return ret;
if (!XRRSetScreenConfigAndRate(_ecore_x_disp, sc,
root, size_index,
RR_Rotate_0, rate, CurrentTime))
ret = EINA_TRUE;
XRRFreeScreenConfigInfo(sc);
return ret;
#else /* ifdef ECORE_XRANDR */
return EINA_FALSE;
#endif /* ifdef ECORE_XRANDR */
}