summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2008-01-15 19:11:32 -0500
committerDavid Reveman <davidr@novell.com>2008-01-15 19:11:32 -0500
commit3afbef5f93d53a5f4321a741d262c299ad6f45c3 (patch)
treeec1c821af333b760239db7d23bbaaf8f4b3fba6e
parent67157794ae6d7741ade6b14c0ffd3bf0f3989112 (diff)
Add randr 1.2 support to Xgl's GLX backend.
-rw-r--r--hw/xgl/glx/xglx.c924
1 files changed, 759 insertions, 165 deletions
diff --git a/hw/xgl/glx/xglx.c b/hw/xgl/glx/xglx.c
index a568770f9..1ea3c66f9 100644
--- a/hw/xgl/glx/xglx.c
+++ b/hw/xgl/glx/xglx.c
@@ -41,6 +41,7 @@
#include "mipointer.h"
#ifdef RANDR
+#include <X11/Xatom.h>
#include "randrstr.h"
#endif
@@ -147,6 +148,7 @@ static int primaryScreen = 0;
static Bool randrExtension = FALSE;
static int randrEvent, randrError;
+static Bool xRRPending = FALSE;
static glitz_drawable_format_t *xglxScreenFormat = 0;
@@ -181,211 +183,782 @@ xglxAllocatePrivates (ScreenPtr pScreen)
#ifdef RANDR
-#define DEFAULT_REFRESH_RATE 50
+#if RANDR_12_INTERFACE
+static RRModePtr
+xglxRRGetMode (XRRScreenResources *r,
+ RRMode mode)
+{
+ xRRModeInfo modeInfo;
+ int i;
+
+ for (i = 0; i < r->nmode; i++)
+ {
+ if (r->modes[i].id == mode)
+ {
+ memset (&modeInfo, '\0', sizeof (modeInfo));
+
+ modeInfo.width = r->modes[i].width;
+ modeInfo.height = r->modes[i].height;
+ modeInfo.dotClock = r->modes[i].dotClock;
+ modeInfo.hSyncStart = r->modes[i].hSyncStart;
+ modeInfo.hSyncEnd = r->modes[i].hSyncEnd;
+ modeInfo.hTotal = r->modes[i].hTotal;
+ modeInfo.hSkew = r->modes[i].hSkew;
+ modeInfo.vSyncStart = r->modes[i].vSyncStart;
+ modeInfo.vSyncEnd = r->modes[i].vSyncEnd;
+ modeInfo.vTotal = r->modes[i].vTotal;
+ modeInfo.nameLength = strlen (r->modes[i].name);
+ modeInfo.modeFlags = r->modes[i].modeFlags;
+
+ return RRModeGet (&modeInfo, r->modes[i].name);
+ }
+ }
+
+ return NULL;
+}
+
+static RRCrtcPtr
+xglxRRGetCrtc (ScreenPtr pScreen,
+ RRCrtc crtc)
+{
+ int i;
+
+ rrScrPriv (pScreen);
+
+ for (i = 0; i < pScrPriv->numCrtcs; i++)
+ if (pScrPriv->crtcs[i]->devPrivate == (void *) crtc)
+ return pScrPriv->crtcs[i];
+
+ return NULL;
+}
+
+static RROutputPtr
+xglxRRGetOutput (ScreenPtr pScreen,
+ RRMode output)
+{
+ int i;
+
+ rrScrPriv (pScreen);
+
+ for (i = 0; i < pScrPriv->numOutputs; i++)
+ if (pScrPriv->outputs[i]->devPrivate == (void *) output)
+ return pScrPriv->outputs[i];
+
+ return NULL;
+}
static Bool
-xglxRandRGetInfo (ScreenPtr pScreen,
- Rotation *rotations)
+xglxRRUpdateCrtc (ScreenPtr pScreen,
+ XRRScreenResources *r,
+ RRCrtc xcrtc)
{
- RRScreenSizePtr pSize;
+ XRRCrtcInfo *c;
+ RRCrtcPtr crtc;
+ RRModePtr mode = NULL;
+ RROutputPtr *outputs = NULL;
+ XRRCrtcGamma *gamma;
+ int i;
+
+ c = XRRGetCrtcInfo (xdisplay, r, xcrtc);
+ if (!c)
+ return FALSE;
- *rotations = RR_Rotate_0;
+ crtc = xglxRRGetCrtc (pScreen, xcrtc);
+ if (!crtc)
+ return FALSE;
- if (randrExtension)
+ if (c->noutput)
{
- XRRScreenConfiguration *xconfig;
- XRRScreenSize *sizes;
- int nSizes, currentSize = 0;
- short *rates, currentRate;
- int nRates, i, j;
+ outputs = xalloc (sizeof (RROutputPtr) * c->noutput);
+ if (!outputs)
+ return FALSE;
+ }
- XGLX_SCREEN_PRIV (pScreen);
+ if (c->mode)
+ mode = xglxRRGetMode (r, c->mode);
- xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
- sizes = XRRConfigSizes (xconfig, &nSizes);
- currentRate = XRRConfigCurrentRate (xconfig);
+ for (i = 0; i < c->noutput; i++)
+ {
+ outputs[i] = xglxRRGetOutput (pScreen, c->outputs[i]);
+ if (!outputs[i])
+ return FALSE;
+ }
- if (pScreenPriv->fullscreen && nScreenRect == 0)
- {
- Rotation rotation;
+ gamma = XRRGetCrtcGamma (xdisplay, xcrtc);
+ if (!gamma)
+ return FALSE;
- currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
+ RRCrtcGammaSet (crtc, gamma->red, gamma->green, gamma->blue);
- for (i = 0; i < nSizes; i++)
- {
- pSize = RRRegisterSize (pScreen,
- sizes[i].width,
- sizes[i].height,
- sizes[i].mwidth,
- sizes[i].mheight);
+ XRRFreeGamma (gamma);
- rates = XRRConfigRates (xconfig, i, &nRates);
+ RRCrtcNotify (crtc, mode, c->x, c->y, c->rotation, c->noutput, outputs);
- for (j = 0; j < nRates; j++)
- {
- RRRegisterRate (pScreen, pSize, rates[j]);
+ if (outputs)
+ xfree (outputs);
- if (i == currentSize && rates[j] == currentRate)
- RRSetCurrentConfig (pScreen, RR_Rotate_0, currentRate,
- pSize);
- }
- }
- }
- else
- {
- pSize = RRRegisterSize (pScreen,
- pScreen->width,
- pScreen->height,
- pScreen->mmWidth,
- pScreen->mmHeight);
+ XRRFreeCrtcInfo (c);
- for (i = 0; i < nSizes; i++)
- {
- rates = XRRConfigRates (xconfig, i, &nRates);
+ return TRUE;
+}
- for (j = 0; j < nRates; j++)
- {
- RRRegisterRate (pScreen, pSize, rates[j]);
+static Bool
+xglxRRUpdateOutput (ScreenPtr pScreen,
+ XRRScreenResources *r,
+ RROutput xoutput)
+{
+ XRROutputInfo *o;
+ RROutputPtr output, *clones = NULL;
+ RRModePtr *modes = NULL;
+ RRCrtcPtr *crtcs = NULL;
+ int i;
+
+ o = XRRGetOutputInfo (xdisplay, r, xoutput);
+ if (!o)
+ return FALSE;
- if (rates[j] == currentRate)
- RRSetCurrentConfig (pScreen, RR_Rotate_0, currentRate,
- pSize);
- }
- }
- }
+ if (o->nclone)
+ {
+ clones = xalloc (sizeof (RROutputPtr) * o->nclone);
+ if (!clones)
+ return FALSE;
+ }
- XRRFreeScreenConfigInfo (xconfig);
+ if (o->nmode)
+ {
+ modes = xalloc (sizeof (RRModePtr) * o->nmode);
+ if (!modes)
+ return FALSE;
}
- else
+
+ if (o->ncrtc)
+ {
+ crtcs = xalloc (sizeof (RRCrtcPtr) * o->ncrtc);
+ if (!crtcs)
+ return FALSE;
+ }
+
+ output = xglxRRGetOutput (pScreen, xoutput);
+ if (!output)
+ return FALSE;
+
+ for (i = 0; i < o->nclone; i++)
{
- pSize = RRRegisterSize (pScreen,
- pScreen->width,
- pScreen->height,
- pScreen->mmWidth,
- pScreen->mmHeight);
-
- RRRegisterRate (pScreen, pSize, DEFAULT_REFRESH_RATE);
- RRSetCurrentConfig (pScreen, RR_Rotate_0, DEFAULT_REFRESH_RATE, pSize);
+ clones[i] = xglxRRGetOutput (pScreen, o->clones[i]);
+ if (!clones[i])
+ return FALSE;
}
+ if (!RROutputSetClones (output, clones, o->nclone))
+ return FALSE;
+
+ for (i = 0; i < o->nmode; i++)
+ {
+ modes[i] = xglxRRGetMode (r, o->modes[i]);
+ if (!modes[i])
+ return FALSE;
+ }
+
+ if (!RROutputSetModes (output, modes, o->nmode, o->npreferred))
+ return FALSE;
+
+ for (i = 0; i < o->ncrtc; i++)
+ {
+ crtcs[i] = xglxRRGetCrtc (pScreen, o->crtcs[i]);
+ if (!crtcs[i])
+ return FALSE;
+ }
+
+ if (!RROutputSetCrtcs (output, crtcs, o->ncrtc))
+ return FALSE;
+
+ if (!RROutputSetConnection (output, o->connection))
+ return FALSE;
+
+ if (!RROutputSetSubpixelOrder (output, o->subpixel_order))
+ return FALSE;
+
+ if (!RROutputSetPhysicalSize (output, o->mm_width, o->mm_height))
+ return FALSE;
+
+ if (clones)
+ xfree (clones);
+
+ if (modes)
+ xfree (modes);
+
+ if (crtcs)
+ xfree (crtcs);
+
+ XRRFreeOutputInfo (o);
+
return TRUE;
}
static Bool
-xglxRandRSetConfig (ScreenPtr pScreen,
- Rotation rotations,
- int rate,
- RRScreenSizePtr pSize)
+xglxRRUpdateOutputProperty (ScreenPtr pScreen,
+ XRRScreenResources *r,
+ RROutput xoutput,
+ Atom xproperty)
{
- if (randrExtension)
+ RROutputPtr output;
+ XRRPropertyInfo *info;
+ unsigned char *prop;
+ int format, status;
+ unsigned long nElements, bytesAfter;
+ Atom type, atom;
+ char *name;
+ INT32 *values = NULL;
+
+ output = xglxRRGetOutput (pScreen, xoutput);
+ if (!output)
+ return FALSE;
+
+ name = XGetAtomName (xdisplay, xproperty);
+ if (!name)
+ return FALSE;
+
+ atom = MakeAtom (name, strlen (name), TRUE);
+
+ XFree (name);
+
+ status = XRRGetOutputProperty (xdisplay, xoutput, xproperty,
+ 0, 8192, FALSE, FALSE,
+ AnyPropertyType, &type, &format,
+ &nElements, &bytesAfter, &prop);
+
+ if (status != Success)
+ return FALSE;
+
+ info = XRRQueryOutputProperty (xdisplay, xoutput, xproperty);
+ if (!info)
+ return FALSE;
+
+ if (info->num_values)
{
- XRRScreenConfiguration *xconfig;
- XRRScreenSize *sizes;
- int nSizes, currentSize;
- int i, size = -1;
- int status = RRSetConfigFailed;
- Rotation rotation;
+ values = xalloc (info->num_values * sizeof (INT32));
+ if (!values)
+ return FALSE;
- XGLX_SCREEN_PRIV (pScreen);
+ memcpy (values, info->values, info->num_values * sizeof (INT32));
+ }
- xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
- sizes = XRRConfigSizes (xconfig, &nSizes);
- currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
+ if (type == XA_ATOM && format == 32)
+ {
+ int i;
- for (i = 0; i < nSizes; i++)
+ for (i = 0; i < nElements; i++)
{
- if (pScreenPriv->fullscreen && nScreenRect == 0)
- {
- if (sizes[i].width == pSize->width &&
- sizes[i].height == pSize->height &&
- sizes[i].mwidth == pSize->mmWidth &&
- sizes[i].mheight == pSize->mmHeight)
- {
- size = i;
- break;
- }
- }
- else
+ name = XGetAtomName (xdisplay, prop[i]);
+ if (!name)
+ return FALSE;
+
+ prop[i] = MakeAtom (name, strlen (name), TRUE);
+
+ XFree (name);
+ }
+
+ if (!info->range && info->num_values > 0)
+ {
+ for (i = 0; i < info->num_values; i++)
{
- short *rates;
- int nRates, j;
+ name = XGetAtomName (xdisplay, values[i]);
+ if (!name)
+ return FALSE;
- rates = XRRConfigRates (xconfig, i, &nRates);
+ values[i] = MakeAtom (name, strlen (name), TRUE);
- for (j = 0; j < nRates; j++)
- {
- if (rates[j] == rate)
- {
- size = i;
- if (i >= currentSize)
- break;
- }
- }
+ XFree (name);
}
}
+ }
+
+ RRConfigureOutputProperty (output, atom, FALSE,
+ info->range, info->immutable, info->num_values,
+ values);
+
+ RRChangeOutputProperty (output, atom, type, format, PropModeReplace,
+ nElements, prop, FALSE, TRUE);
+
+ if (values)
+ xfree (values);
- if (size >= 0)
- status = XRRSetScreenConfigAndRate (xdisplay,
- xconfig,
- pScreenPriv->root,
- size,
- RR_Rotate_0,
- rate,
- CurrentTime);
+ XFree (info);
+ XFree (prop);
- XRRFreeScreenConfigInfo (xconfig);
+ return TRUE;
+}
+#endif
- if (status == RRSetConfigSuccess)
+static Bool
+xglxRRGetInfo (ScreenPtr pScreen,
+ Rotation *rotations)
+{
+ RRScreenSizePtr pSize;
+
+#if RANDR_12_INTERFACE
+ XGLX_SCREEN_PRIV (pScreen);
+
+ if (pScreenPriv->fullscreen)
+ {
+ XRRScreenResources *r;
+ int i;
+
+ rrScrPriv (pScreen);
+
+ xRRPending = TRUE;
+
+ r = XRRGetScreenResources (xdisplay, pScreenPriv->root);
+ if (!r)
+ return (xRRPending = FALSE);
+
+ for (i = 0; i < r->noutput; i++)
{
- PixmapPtr pPixmap;
+ Atom *props;
+ int nProp, j;
- pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ if (!xglxRRUpdateOutput (pScreen, r, r->outputs[i]))
+ return (xRRPending = FALSE);
- if (pScreenPriv->fullscreen)
+ props = XRRListOutputProperties (xdisplay, r->outputs[i], &nProp);
+ if (nProp)
{
- XGL_PIXMAP_PRIV (pPixmap);
+ for (j = 0; j < nProp; j++)
+ if (!xglxRRUpdateOutputProperty (pScreen, r, r->outputs[i],
+ props[j]))
+ return (xRRPending = FALSE);
+
+ XFree (props);
+ }
+ }
- xglSetRootClip (pScreen, FALSE);
+ for (i = 0; i < r->ncrtc; i++)
+ if (!xglxRRUpdateCrtc (pScreen, r, r->crtcs[i]))
+ return (xRRPending = FALSE);
- XResizeWindow (xdisplay, pScreenPriv->win,
- pSize->width, pSize->height);
+ XRRFreeScreenResources (r);
- glitz_drawable_update_size (pPixmapPriv->drawable,
- pSize->width, pSize->height);
+ *rotations = RR_Rotate_0;
- pScreen->width = pSize->width;
- pScreen->height = pSize->height;
- pScreen->mmWidth = pSize->mmWidth;
- pScreen->mmHeight = pSize->mmHeight;
+ for (i = 0; i < pScrPriv->numCrtcs; i++)
+ *rotations |= pScrPriv->crtcs[i]->rotations;
- (*pScreen->ModifyPixmapHeader) (pPixmap,
- pScreen->width,
- pScreen->height,
- pPixmap->drawable.depth,
- pPixmap->drawable.bitsPerPixel,
- 0, 0);
+ xRRPending = FALSE;
- xglSetRootClip (pScreen, TRUE);
- }
+ return TRUE;
+ }
+#endif
- return TRUE;
+ *rotations = RR_Rotate_0;
+
+ return TRUE;
+}
+
+#if RANDR_12_INTERFACE
+static RRMode
+xglxRRGetXMode (XRRScreenResources *r,
+ RRModePtr mode)
+{
+ xRRModeInfo modeInfo = mode->mode;
+ int i;
+
+ for (i = 0; i < r->nmode; i++)
+ {
+ if (modeInfo.width == r->modes[i].width &&
+ modeInfo.height == r->modes[i].height &&
+ modeInfo.dotClock == r->modes[i].dotClock &&
+ modeInfo.hSyncStart == r->modes[i].hSyncStart &&
+ modeInfo.hSyncEnd == r->modes[i].hSyncEnd &&
+ modeInfo.hTotal == r->modes[i].hTotal &&
+ modeInfo.hSkew == r->modes[i].hSkew &&
+ modeInfo.vSyncStart == r->modes[i].vSyncStart &&
+ modeInfo.vSyncEnd == r->modes[i].vSyncEnd &&
+ modeInfo.vTotal == r->modes[i].vTotal &&
+ modeInfo.nameLength == r->modes[i].nameLength &&
+ modeInfo.modeFlags == r->modes[i].modeFlags)
+ {
+ if (!memcmp (r->modes[i].name, mode->name, modeInfo.nameLength))
+ return r->modes[i].id;
}
}
+ return None;
+}
+
+static Bool
+xglxRRScreenSetSize (ScreenPtr pScreen,
+ CARD16 width,
+ CARD16 height,
+ CARD32 mmWidth,
+ CARD32 mmHeight)
+{
+ PixmapPtr pPixmap;
+
+ XGLX_SCREEN_PRIV (pScreen);
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ if (pPixmap)
+ {
+ XGL_PIXMAP_PRIV (pPixmap);
+
+ if (width != DisplayWidth (xdisplay, xscreen) ||
+ height != DisplayHeight (xdisplay, xscreen) ||
+ mmWidth != DisplayWidthMM (xdisplay, xscreen) ||
+ mmHeight != DisplayHeightMM (xdisplay, xscreen))
+ XRRSetScreenSize (xdisplay, pScreenPriv->root,
+ width, height, mmWidth, mmHeight);
+
+ xglSetRootClip (pScreen, FALSE);
+
+ XResizeWindow (xdisplay, pScreenPriv->win, width, height);
+
+ glitz_drawable_update_size (pPixmapPriv->drawable, width, height);
+
+ pScreen->width = width;
+ pScreen->height = height;
+ pScreen->mmWidth = mmWidth;
+ pScreen->mmHeight = mmHeight;
+
+ (*pScreen->ModifyPixmapHeader) (pPixmap,
+ pScreen->width,
+ pScreen->height,
+ pPixmap->drawable.depth,
+ pPixmap->drawable.bitsPerPixel,
+ 0, 0);
+
+ xglSetRootClip (pScreen, TRUE);
+
+ RRScreenSizeNotify (pScreen);
+
+ return TRUE;
+ }
+
return FALSE;
}
static Bool
+xglxRRCrtcSet (ScreenPtr pScreen,
+ RRCrtcPtr crtc,
+ RRModePtr mode,
+ int x,
+ int y,
+ Rotation rotation,
+ int numOutputs,
+ RROutputPtr *outputs)
+{
+ XRRScreenResources *r;
+ RROutput *o = NULL;
+ RRMode m = None;
+ int i;
+
+ XGLX_SCREEN_PRIV (pScreen);
+
+ if (xRRPending)
+ return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+
+ if (numOutputs)
+ {
+ o = xalloc (sizeof (RROutput *) * numOutputs);
+ if (!o)
+ return FALSE;
+ }
+
+ r = XRRGetScreenResources (xdisplay, pScreenPriv->root);
+ if (!r)
+ return FALSE;
+
+ if (mode)
+ {
+ m = xglxRRGetXMode (r, mode);
+ if (!m)
+ return FALSE;
+ }
+
+ XRRFreeScreenResources (r);
+
+ for (i = 0; i < numOutputs; i++)
+ o[i] = (RROutput) outputs[i]->devPrivate;
+
+ XRRSetCrtcConfig (xdisplay, r,
+ (RRCrtc) crtc->devPrivate,
+ CurrentTime,
+ x, y,
+ m,
+ rotation,
+ o, numOutputs);
+
+ if (o)
+ free (o);
+
+ return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
+}
+
+static Bool
+xglxRRCrtcSetGamma (ScreenPtr pScreen,
+ RRCrtcPtr crtc)
+{
+ XRRCrtcGamma *gamma;
+
+ if (xRRPending)
+ return TRUE;
+
+ gamma = XRRAllocGamma (crtc->gammaSize);
+ if (!gamma)
+ return FALSE;
+
+ memcpy (gamma->red, crtc->gammaRed, gamma->size * sizeof (CARD16));
+ memcpy (gamma->green, crtc->gammaGreen, gamma->size * sizeof (CARD16));
+ memcpy (gamma->blue, crtc->gammaBlue, gamma->size * sizeof (CARD16));
+
+ XRRSetCrtcGamma (xdisplay, (RRCrtc) crtc->devPrivate, gamma);
+
+ XRRFreeGamma (gamma);
+
+ return TRUE;
+}
+
+static Bool
+xglxRROutputSetProperty (ScreenPtr pScreen,
+ RROutputPtr output,
+ Atom property,
+ RRPropertyValuePtr value)
+{
+ RRPropertyPtr p;
+ Atom atom, type;
+ char *data = NULL;
+ long *values = NULL;
+ int i;
+
+ if (xRRPending)
+ return TRUE;
+
+ p = RRQueryOutputProperty (output, property);
+ if (!p)
+ return FALSE;
+
+ if (p->num_valid)
+ {
+ values = xalloc (p->num_valid * sizeof (long));
+ if (!values)
+ return FALSE;
+
+ for (i = 0; i < p->num_valid; i++)
+ values[i] = p->valid_values[i];
+ }
+
+ if (value->size)
+ {
+ int size = value->size * (value->format / 8);
+
+ data = xalloc (size);
+ if (!data)
+ return FALSE;
+
+ memcpy (data, value->data, size);
+ }
+
+ atom = XInternAtom (xdisplay, NameForAtom (property), FALSE);
+ type = XInternAtom (xdisplay, NameForAtom (value->type), FALSE);
+
+ if (type == XA_ATOM && value->format == 32)
+ {
+ int i;
+
+ for (i = 0; i < value->size; i++)
+ data[i] = XInternAtom (xdisplay, NameForAtom (data[i]), FALSE);
+
+ if (!p->range && p->num_valid > 0)
+ for (i = 0; i < p->num_valid; i++)
+ values[i] = XInternAtom (xdisplay, NameForAtom (values[i]),
+ FALSE);
+ }
+
+ XRRConfigureOutputProperty (xdisplay, (RROutput) output->devPrivate, atom,
+ p->is_pending, p->range, p->num_valid, values);
+
+ XRRChangeOutputProperty (xdisplay, (RROutput) output->devPrivate,
+ atom, type, value->format, PropModeReplace,
+ data, value->size);
+
+ if (values)
+ xfree (values);
+
+ if (data)
+ xfree (data);
+
+ return TRUE;
+}
+
+static Bool
+xglxRROutputValidateMode (ScreenPtr pScreen,
+ RROutputPtr output,
+ RRModePtr mode)
+{
+ XRRModeInfo *modeInfo;
+ RRMode m;
+
+ XGLX_SCREEN_PRIV (pScreen);
+
+ if (xRRPending)
+ return TRUE;
+
+ modeInfo = XRRAllocModeInfo (mode->name, mode->mode.nameLength);
+ if (!modeInfo)
+ return FALSE;
+
+ m = XRRCreateMode (xdisplay, pScreenPriv->root, modeInfo);
+ if (!m)
+ return FALSE;
+
+ XRRFreeModeInfo (modeInfo);
+
+ XRRAddOutputMode (xdisplay, (RROutput) output->devPrivate, m);
+
+ return TRUE;
+}
+
+static void
+xglxRRModeDestroy (ScreenPtr pScreen,
+ RRModePtr mode)
+{
+ XRRScreenResources *r;
+
+ XGLX_SCREEN_PRIV (pScreen);
+
+ if (xRRPending)
+ return;
+
+ r = XRRGetScreenResources (xdisplay, pScreenPriv->root);
+ if (r)
+ {
+ RRMode m;
+
+ m = xglxRRGetXMode (r, mode);
+ if (m)
+ XRRDestroyMode (xdisplay, m);
+
+ XRRFreeScreenResources (r);
+ }
+}
+#endif
+
+static Bool
xglxRandRInit (ScreenPtr pScreen)
{
rrScrPrivPtr pScrPriv;
+ XGLX_SCREEN_PRIV (pScreen);
+
if (!RRScreenInit (pScreen))
return FALSE;
pScrPriv = rrGetScrPriv (pScreen);
- pScrPriv->rrGetInfo = xglxRandRGetInfo;
- pScrPriv->rrSetConfig = xglxRandRSetConfig;
+ pScrPriv->rrGetInfo = xglxRRGetInfo;
+
+#if RANDR_12_INTERFACE
+ if (pScreenPriv->fullscreen)
+ {
+ XRRScreenResources *r;
+ int i, minWidth, minHeight, maxWidth, maxHeight;
+
+ pScrPriv->rrScreenSetSize = xglxRRScreenSetSize;
+ pScrPriv->rrCrtcSet = xglxRRCrtcSet;
+ pScrPriv->rrCrtcSetGamma = xglxRRCrtcSetGamma;
+ pScrPriv->rrOutputSetProperty = xglxRROutputSetProperty;
+ pScrPriv->rrOutputValidateMode = xglxRROutputValidateMode;
+ pScrPriv->rrModeDestroy = xglxRRModeDestroy;
+
+ if (!XRRGetScreenSizeRange (xdisplay, pScreenPriv->root,
+ &minWidth, &minHeight,
+ &maxWidth, &maxHeight))
+ return FALSE;
+
+ RRScreenSetSizeRange (pScreen,
+ minWidth, minHeight, maxWidth, maxHeight);
+
+ r = XRRGetScreenResources (xdisplay, pScreenPriv->root);
+ if (!r)
+ return FALSE;
+
+ for (i = 0; i < r->ncrtc; i++)
+ {
+ XRRCrtcInfo *c;
+ RRCrtcPtr crtc;
+
+ crtc = RRCrtcCreate (pScreen, (void *) r->crtcs[i]);
+ if (!crtc)
+ return FALSE;
+
+ c = XRRGetCrtcInfo (xdisplay, r, r->crtcs[i]);
+ if (!c)
+ return FALSE;
+
+ RRCrtcSetRotations (crtc, c->rotations);
+ RRCrtcGammaSetSize (crtc, XRRGetCrtcGammaSize (xdisplay,
+ r->crtcs[i]));
+
+ XRRFreeCrtcInfo (c);
+ }
+
+ for (i = 0; i < r->noutput; i++)
+ {
+ XRROutputInfo *o;
+ RROutputPtr output;
+
+ o = XRRGetOutputInfo (xdisplay, r, r->outputs[i]);
+ if (!o)
+ return FALSE;
+
+ if (!RROutputCreate (pScreen, o->name, strlen (o->name),
+ (void *) r->outputs[i]))
+ return FALSE;
+
+ XRRFreeOutputInfo (o);
+ }
+
+ XRRFreeScreenResources (r);
+ }
+ else
+ {
+ RRModePtr mode;
+ RRCrtcPtr crtc;
+ RROutputPtr output;
+ xRRModeInfo modeInfo;
+ char name[64];
+
+ RRScreenSetSizeRange (pScreen,
+ pScreen->width, pScreen->height,
+ pScreen->width, pScreen->height);
+
+ sprintf (name, "%dx%d", pScreen->width, pScreen->height);
+ memset (&modeInfo, '\0', sizeof (modeInfo));
+ modeInfo.width = pScreen->width;
+ modeInfo.height = pScreen->height;
+ modeInfo.nameLength = strlen (name);
+
+ mode = RRModeGet (&modeInfo, name);
+ if (!mode)
+ return FALSE;
+
+ crtc = RRCrtcCreate (pScreen, NULL);
+ if (!crtc)
+ return FALSE;
+
+ output = RROutputCreate (pScreen, "screen", 6, NULL);
+ if (!output)
+ return FALSE;
+ if (!RROutputSetClones (output, NULL, 0))
+ return FALSE;
+ if (!RROutputSetModes (output, &mode, 1, 0))
+ return FALSE;
+ if (!RROutputSetCrtcs (output, &crtc, 1))
+ return FALSE;
+ if (!RROutputSetConnection (output, RR_Connected))
+ return FALSE;
+
+ RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1, &output);
+ }
+#endif
return TRUE;
}
@@ -510,7 +1083,35 @@ xglxEnqueueEvents (void)
}
break;
default:
+
+#if RANDR_12_INTERFACE
+ XRRUpdateConfiguration (&X);
+
+ switch (X.type - randrEvent) {
+ case RRScreenChangeNotify: {
+ int i;
+
+ if (!randrExtension)
+ break;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+
+ XGLX_SCREEN_PRIV (pScreen);
+
+ if (pScreenPriv->root == X.xany.window)
+ RRScreenSizeSet (pScreen,
+ DisplayWidth (xdisplay, xscreen),
+ DisplayHeight (xdisplay, xscreen),
+ DisplayWidthMM (xdisplay, xscreen),
+ DisplayHeightMM (xdisplay, xscreen));
+ }
+ } break;
+ }
break;
+#endif
+
}
}
}
@@ -954,6 +1555,7 @@ xglxScreenInit (int index,
glitz_drawable_format_t *format;
glitz_drawable_t *drawable;
int x = 0, y = 0;
+ long eventMask;
format = xglxScreenFormat;
@@ -986,25 +1588,6 @@ xglxScreenInit (int index,
xglScreenInfo.widthMm = DisplayWidthMM (xdisplay, xscreen);
xglScreenInfo.heightMm = DisplayHeightMM (xdisplay, xscreen);
- if (randrExtension)
- {
- XRRScreenConfiguration *xconfig;
- Rotation rotation;
- XRRScreenSize *sizes;
- int nSizes, currentSize;
-
- xconfig = XRRGetScreenInfo (xdisplay, pScreenPriv->root);
- currentSize = XRRConfigCurrentConfiguration (xconfig, &rotation);
- sizes = XRRConfigSizes (xconfig, &nSizes);
-
- xglScreenInfo.width = sizes[currentSize].width;
- xglScreenInfo.height = sizes[currentSize].height;
- xglScreenInfo.widthMm = sizes[currentSize].mwidth;
- xglScreenInfo.heightMm = sizes[currentSize].mheight;
-
- XRRFreeScreenConfigInfo (xconfig);
- }
-
if (nScreenRect)
{
int w, h;
@@ -1082,10 +1665,24 @@ xglxScreenInit (int index,
return FALSE;
}
- XSelectInput (xdisplay, pScreenPriv->win,
- ButtonPressMask | ButtonReleaseMask |
- KeyPressMask | KeyReleaseMask | EnterWindowMask |
- PointerMotionMask | ExposureMask);
+ eventMask = ButtonPressMask | ButtonReleaseMask |
+ KeyPressMask | KeyReleaseMask | EnterWindowMask |
+ PointerMotionMask | ExposureMask | StructureNotifyMask;
+
+#ifdef XEVDEV
+ if (useEvdev)
+ eventMask = ExposureMask | StructureNotifyMask;
+#endif
+
+ XSelectInput (xdisplay, pScreenPriv->win, eventMask);
+
+#if RANDR_12_INTERFACE
+ if (fullscreen && randrExtension)
+ {
+ XSelectInput (xdisplay, pScreenPriv->root, StructureNotifyMask);
+ XRRSelectInput (xdisplay, pScreenPriv->root, RRScreenChangeNotifyMask);
+ }
+#endif
XMapWindow (xdisplay, pScreenPriv->win);
@@ -1297,9 +1894,6 @@ xglxWakeupHandler (pointer blockData,
int result,
pointer pReadMask)
{
-#ifdef XEVDEV
- if (!useEvdev)
-#endif
xglxEnqueueEvents ();
}