335 lines
9.6 KiB
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 */
|
|
}
|
|
|