Improved RANDR support.

This commit is contained in:
David Reveman 2008-06-02 22:54:14 -04:00
parent ccaf6779fe
commit 162a060f4c
4 changed files with 191 additions and 47 deletions

View file

@ -685,30 +685,60 @@ int dmxConfigureDesktop(DMXDesktopAttributesPtr attribs)
attribs->height <= 0 || attribs->height >= 32767)
return DMX_BAD_VALUE;
/* If the desktop is shrinking, adjust the "root" windows on each
/* If the desktop is changing size, adjust the "root" windows on each
* "screen" window to only show the visible desktop. Also, handle
* the special case where the desktop shrinks such that the it no
* longer overlaps an portion of a "screen" window. */
if (attribs->width < dmxGlobalWidth || attribs->height < dmxGlobalHeight) {
if (attribs->width != dmxGlobalWidth || attribs->height != dmxGlobalHeight) {
int i;
for (i = 0; i < dmxNumScreens; i++) {
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->rootXOrigin
+ dmxScreen->rootWidth > attribs->width ||
dmxScreen->rootYOrigin
+ dmxScreen->rootHeight > attribs->height) {
int w, h;
if ((w = attribs->width - dmxScreen->rootXOrigin) < 0) w = 0;
if ((h = attribs->height - dmxScreen->rootYOrigin) < 0) h = 0;
int w, h;
w = attribs->width;
h = attribs->height;
#ifdef RANDR
if (dmxScreen->beRandr)
{
if (w > dmxScreen->beWidth) w = dmxScreen->beWidth;
if (h > dmxScreen->beHeight) h = dmxScreen->beHeight;
}
else
#endif
{
if (w > dmxScreen->scrnWidth) w = dmxScreen->scrnWidth;
if (h > dmxScreen->scrnHeight) h = dmxScreen->scrnHeight;
}
dmxConfigureScreenWindow (i,
dmxScreen->scrnX,
dmxScreen->scrnY,
w,
h);
if ((w = attribs->width - dmxScreen->rootXOrigin) < 0) w = 0;
if ((h = attribs->height - dmxScreen->rootYOrigin) < 0) h = 0;
#ifdef RANDR
if (dmxScreen->beRandr)
{
if (w > dmxScreen->beWidth) w = dmxScreen->beWidth;
if (h > dmxScreen->beHeight) h = dmxScreen->beHeight;
}
else
#endif
{
if (w > dmxScreen->rootWidth) w = dmxScreen->rootWidth;
if (h > dmxScreen->rootHeight) h = dmxScreen->rootHeight;
dmxConfigureRootWindow(i,
dmxScreen->rootX,
dmxScreen->rootY,
w, h);
}
dmxConfigureRootWindow (i,
dmxScreen->rootX,
dmxScreen->rootY,
w, h);
}
}
@ -1420,22 +1450,53 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
{
#ifdef RANDR
int ignore;
XLIB_PROLOGUE (dmxScreen);
dmxScreen->beRandr = XRRQueryExtension (dmxScreen->beDisplay,
&dmxScreen->beRandrEventBase,
&ignore);
XLIB_EPILOGUE (dmxScreen);
int major, minor, status = 0;
#endif
attr->screenWindowWidth = dmxScreen->beWidth;
attr->screenWindowHeight = dmxScreen->beHeight;
#ifdef RANDR
XLIB_PROLOGUE (dmxScreen);
status = XRRQueryVersion (dmxScreen->beDisplay, &major, &minor);
XLIB_EPILOGUE (dmxScreen);
if (status)
{
if (major > 1 || (major == 1 && minor >= 2))
{
int ignore;
XLIB_PROLOGUE (dmxScreen);
dmxScreen->beRandr =
XRRQueryExtension (dmxScreen->beDisplay,
&dmxScreen->beRandrEventBase,
&ignore);
XLIB_EPILOGUE (dmxScreen);
if (attr->screenWindowWidth > dmxGlobalWidth)
attr->screenWindowWidth = dmxGlobalWidth;
if (attr->screenWindowHeight > dmxGlobalHeight)
attr->screenWindowHeight = dmxGlobalHeight;
dmxLog (dmxInfo, "RandR 1.2 is present\n");
}
else
{
dmxLog (dmxInfo, "RandR 1.2 is not present\n");
}
}
else
{
dmxLog (dmxInfo, "RandR extension missing\n");
}
#endif
attr->screenWindowWidth = dmxScreen->beWidth;
attr->screenWindowHeight = dmxScreen->beHeight;
attr->screenWindowXoffset = 0;
attr->screenWindowYoffset = 0;
attr->rootWindowWidth = dmxScreen->beWidth;
attr->rootWindowHeight = dmxScreen->beHeight;
attr->rootWindowWidth = attr->screenWindowWidth;
attr->rootWindowHeight = attr->screenWindowHeight;
attr->rootWindowXoffset = 0;
attr->rootWindowYoffset = 0;

View file

@ -54,6 +54,7 @@
#include "dmxprop.h"
#include "dmxdpms.h"
#include "dmxlog.h"
#include "dmxcb.h"
#ifdef RENDER
#include "dmxpict.h"
@ -262,9 +263,11 @@ dmxRRUpdateCrtc (ScreenPtr pScreen,
mode = dmxRRGetMode (r, c->mode);
for (i = 0; i < c->noutput; i++)
{
outputs[i] = dmxRRGetOutput (pScreen, dmxScreen, c->outputs[i]);
if (!outputs[i])
return FALSE;
}
XLIB_PROLOGUE (dmxScreen);
gamma = XRRGetCrtcGamma (dmxScreen->beDisplay, xcrtc);
@ -636,7 +639,7 @@ dmxRRGetInfo (ScreenPtr pScreen,
return (dmxScreen->beRandrPending = FALSE);
}
}
else if (dmxScreen->beDisplay)
else if (dmxScreen->beDisplay && j == 0)
{
RRModePtr mode;
xRRModeInfo modeInfo;
@ -644,11 +647,11 @@ dmxRRGetInfo (ScreenPtr pScreen,
sprintf (name,
"%dx%d",
dmxScreen->scrnWidth, dmxScreen->scrnHeight);
dmxScreen->beWidth, dmxScreen->beHeight);
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = dmxScreen->scrnWidth;
modeInfo.height = dmxScreen->scrnHeight;
modeInfo.width = dmxScreen->beWidth;
modeInfo.height = dmxScreen->beHeight;
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
@ -693,7 +696,7 @@ dmxRRGetInfo (ScreenPtr pScreen,
RRCrtcNotify (crtc, NULL, 0, 0, RR_Rotate_0, 0, NULL);
}
}
else if (dmxScreen->beDisplay)
else if (dmxScreen->beDisplay && j == 0)
{
RRModePtr mode;
xRRModeInfo modeInfo;
@ -701,11 +704,11 @@ dmxRRGetInfo (ScreenPtr pScreen,
sprintf (name,
"%dx%d",
dmxScreen->scrnWidth, dmxScreen->scrnHeight);
dmxScreen->beWidth, dmxScreen->beHeight);
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = dmxScreen->scrnWidth;
modeInfo.height = dmxScreen->scrnHeight;
modeInfo.width = dmxScreen->beWidth;
modeInfo.height = dmxScreen->beHeight;
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
@ -1150,21 +1153,91 @@ dmxRRCheckScreen (ScreenPtr pScreen)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (dmxScreen->beDisplay && dmxScreen->beRandr)
if (dmxScreen->beDisplay)
{
XEvent event;
XEvent X;
for (;;)
{
Bool status = FALSE;
XLIB_PROLOGUE (dmxScreen);
status = XCheckTypedEvent (dmxScreen->beDisplay, ConfigureNotify, &X);
XLIB_EPILOGUE (dmxScreen);
if (!status)
break;
XRRUpdateConfiguration (&X);
dmxScreen->beWidth =
DisplayWidth (dmxScreen->beDisplay,
DefaultScreen (dmxScreen->beDisplay));
dmxScreen->beHeight =
DisplayHeight (dmxScreen->beDisplay,
DefaultScreen (dmxScreen->beDisplay));
if (dmxScreen->beRandr)
{
DMXScreenAttributesRec attr;
CARD32 scrnNum = dmxScreen->index;
memset (&attr, 0, sizeof (attr));
attr.screenWindowWidth = dmxGlobalWidth;
attr.screenWindowHeight = dmxGlobalHeight;
if (attr.screenWindowWidth > dmxScreen->beWidth)
attr.screenWindowWidth = dmxScreen->beWidth;
if (attr.screenWindowHeight > dmxScreen->beHeight)
attr.screenWindowHeight = dmxScreen->beHeight;
attr.rootWindowWidth = attr.screenWindowWidth;
attr.rootWindowHeight = attr.screenWindowHeight;
dmxConfigureScreenWindows (1, &scrnNum, &attr, NULL);
}
XLIB_PROLOGUE (dmxScreen);
while (XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase +
RRScreenChangeNotify,
&event))
RRTellChanged (screenInfo.screens[0]);
while (XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase + RRNotify,
&event))
RRTellChanged (screenInfo.screens[0]);
XLIB_EPILOGUE (dmxScreen);
}
if (dmxScreen->beRandr)
{
for (;;)
{
Bool status = FALSE;
XLIB_PROLOGUE (dmxScreen);
status = XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase +
RRScreenChangeNotify,
&X);
XLIB_EPILOGUE (dmxScreen);
if (!status)
break;
XRRUpdateConfiguration (&X);
RRTellChanged (screenInfo.screens[0]);
}
for (;;)
{
Bool status = FALSE;
XLIB_PROLOGUE (dmxScreen);
status = XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase + RRNotify,
&X);
XLIB_EPILOGUE (dmxScreen);
if (!status)
break;
XRRUpdateConfiguration (&X);
RRTellChanged (screenInfo.screens[0]);
}
}
}
}
@ -1348,6 +1421,10 @@ void dmxBEScreenInit(int idx, ScreenPtr pScreen)
}
#ifdef RANDR
XSelectInput (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay),
StructureNotifyMask);
if (dmxScreen->beRandr)
XRRSelectInput (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay),

View file

@ -92,7 +92,7 @@ Window dmxCreateRootWindow(WindowPtr pWindow)
pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel;
attribs.event_mask = ExposureMask | FocusChangeMask;
attribs.event_mask = ExposureMask;
attribs.backing_store = NotUseful;
attribs.colormap = pCmapPriv->cmap;
attribs.border_pixel = 0;
@ -251,7 +251,7 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
}
mask |= CWEventMask;
attribs.event_mask = ExposureMask | FocusChangeMask;
attribs.event_mask = ExposureMask;
/* Incorporate new attributes, if needed */
if (pWinPriv->attribMask) {

View file

@ -163,7 +163,13 @@ static void *dmxBackendTestEvents(DMXScreenInfo *dmxScreen, void *closure)
int result = 0;
XLIB_PROLOGUE (dmxScreen);
result = XCheckNotMaskEvent(dmxScreen->beDisplay, ExposureMask, X);
result = XCheckMaskEvent(dmxScreen->beDisplay,
KeyPressMask | KeyReleaseMask |
ButtonPressMask | ButtonReleaseMask |
EnterWindowMask | LeaveWindowMask |
PointerMotionMask | KeymapStateMask |
FocusChangeMask,
X);
XLIB_EPILOGUE (dmxScreen);
return (result) ? dmxScreen : NULL;
}