mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2026-05-04 21:08:13 +02:00
Implement support for multiple screens in xglx module.
This commit is contained in:
parent
6c69efe661
commit
9a3fe13433
2 changed files with 179 additions and 32 deletions
|
|
@ -1014,7 +1014,7 @@ dnl Xglx DDX
|
|||
|
||||
AC_MSG_CHECKING([whether to build Xglx DDX])
|
||||
if test "x$XGLX" != xno; then
|
||||
PKG_CHECK_MODULES([XGLXMODULES], [glitz-glx >= $XGL_REQUIRED_GLITZ_VERSION xrender >= 0.5 xrandr >= 0.5 xkbfile], [XGLX=yes], [XGLX=no])
|
||||
PKG_CHECK_MODULES([XGLXMODULES], [glitz-glx >= $XGL_REQUIRED_GLITZ_VERSION xrender >= 0.5 xrandr >= 0.5 xkbfile xinerama], [XGLX=yes], [XGLX=no])
|
||||
AC_SUBST(XGLXMODULES_CFLAGS)
|
||||
AC_SUBST(XGLXMODULES_LIBS)
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "xglx.h"
|
||||
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#include <X11/extensions/dpms.h>
|
||||
#include <X11/cursorfont.h>
|
||||
|
|
@ -132,17 +133,24 @@ static char *xDisplayName = 0;
|
|||
static Display *xdisplay = 0;
|
||||
static int xscreen;
|
||||
static CARD32 lastEventTime = 0;
|
||||
static ScreenPtr currentScreen = 0;
|
||||
static Bool softCursor = FALSE;
|
||||
static Bool fullscreen = TRUE;
|
||||
static Bool xDpms = FALSE;
|
||||
static int displayOffset = 0;
|
||||
static int numScreen = 1;
|
||||
static int primaryScreen = 0;
|
||||
|
||||
static Bool randrExtension = FALSE;
|
||||
static int randrEvent, randrError;
|
||||
|
||||
static glitz_drawable_format_t *xglxScreenFormat = 0;
|
||||
|
||||
static RegionRec screenRegion;
|
||||
static BoxPtr screenRect = NULL;
|
||||
static int nScreenRect = 0;
|
||||
|
||||
static Window currentEventWindow = None;
|
||||
|
||||
static Bool
|
||||
xglxAllocatePrivates (ScreenPtr pScreen)
|
||||
{
|
||||
|
|
@ -192,7 +200,7 @@ xglxRandRGetInfo (ScreenPtr pScreen,
|
|||
sizes = XRRConfigSizes (xconfig, &nSizes);
|
||||
currentRate = XRRConfigCurrentRate (xconfig);
|
||||
|
||||
if (pScreenPriv->fullscreen)
|
||||
if (pScreenPriv->fullscreen && nScreenRect == 0)
|
||||
{
|
||||
Rotation rotation;
|
||||
|
||||
|
|
@ -281,7 +289,7 @@ xglxRandRSetConfig (ScreenPtr pScreen,
|
|||
|
||||
for (i = 0; i < nSizes; i++)
|
||||
{
|
||||
if (pScreenPriv->fullscreen)
|
||||
if (pScreenPriv->fullscreen && nScreenRect == 0)
|
||||
{
|
||||
if (sizes[i].width == pSize->width &&
|
||||
sizes[i].height == pSize->height &&
|
||||
|
|
@ -423,9 +431,8 @@ xglxWindowExposures (WindowPtr pWin,
|
|||
static void
|
||||
xglxEnqueueEvents (void)
|
||||
{
|
||||
ScreenPtr pScreen = currentScreen;
|
||||
XEvent X;
|
||||
xEvent x;
|
||||
XEvent X;
|
||||
xEvent x;
|
||||
|
||||
while (XCheckIfEvent (xdisplay, &X, xglxNotExposurePredicate, NULL))
|
||||
{
|
||||
|
|
@ -464,11 +471,26 @@ xglxEnqueueEvents (void)
|
|||
mieqEnqueue (&x);
|
||||
break;
|
||||
case EnterNotify:
|
||||
if (X.xcrossing.detail != NotifyInferior)
|
||||
if (!nScreenRect && X.xcrossing.detail != NotifyInferior)
|
||||
{
|
||||
ScreenPtr pScreen = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
{
|
||||
XGLX_SCREEN_PRIV (screenInfo.screens[i]);
|
||||
|
||||
if (pScreenPriv->win == X.xcrossing.window)
|
||||
{
|
||||
pScreen = screenInfo.screens[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (pScreen)
|
||||
{
|
||||
NewCurrentScreen (pScreen, X.xcrossing.x, X.xcrossing.y);
|
||||
|
||||
x.u.u.type = MotionNotify;
|
||||
x.u.u.detail = 0;
|
||||
x.u.keyButtonPointer.rootX = X.xcrossing.x;
|
||||
|
|
@ -656,7 +678,25 @@ xglxSetCursorPosition (ScreenPtr pScreen,
|
|||
{
|
||||
XGLX_SCREEN_PRIV (pScreen);
|
||||
|
||||
XWarpPointer (xdisplay, pScreenPriv->win, pScreenPriv->win,
|
||||
if (currentEventWindow != pScreenPriv->win)
|
||||
{
|
||||
currentEventWindow = pScreenPriv->win;
|
||||
|
||||
if (nScreenRect)
|
||||
XGrabPointer (xdisplay,
|
||||
currentEventWindow,
|
||||
TRUE,
|
||||
ButtonPressMask |
|
||||
ButtonReleaseMask |
|
||||
PointerMotionMask,
|
||||
GrabModeAsync,
|
||||
GrabModeAsync,
|
||||
currentEventWindow,
|
||||
None,
|
||||
CurrentTime);
|
||||
}
|
||||
|
||||
XWarpPointer (xdisplay, currentEventWindow, pScreenPriv->win,
|
||||
0, 0, 0, 0, x, y);
|
||||
|
||||
if (generateEvent)
|
||||
|
|
@ -732,14 +772,13 @@ xglxScreenInit (int index,
|
|||
XEvent xevent;
|
||||
glitz_drawable_format_t *format;
|
||||
glitz_drawable_t *drawable;
|
||||
int x = 0, y = 0;
|
||||
|
||||
format = xglxScreenFormat;
|
||||
|
||||
if (!xglxAllocatePrivates (pScreen))
|
||||
return FALSE;
|
||||
|
||||
currentScreen = pScreen;
|
||||
|
||||
pScreenPriv = XGLX_GET_SCREEN_PRIV (pScreen);
|
||||
|
||||
pScreenPriv->root = RootWindow (xdisplay, xscreen);
|
||||
|
|
@ -784,6 +823,24 @@ xglxScreenInit (int index,
|
|||
|
||||
XRRFreeScreenConfigInfo (xconfig);
|
||||
}
|
||||
|
||||
if (nScreenRect)
|
||||
{
|
||||
int w, h;
|
||||
|
||||
x = screenRect[index].x1;
|
||||
y = screenRect[index].y1;
|
||||
w = screenRect[index].x2 - x;
|
||||
h = screenRect[index].y2 - y;
|
||||
|
||||
xglScreenInfo.widthMm = (xglScreenInfo.widthMm * w) /
|
||||
xglScreenInfo.width;
|
||||
xglScreenInfo.width = w;
|
||||
|
||||
xglScreenInfo.heightMm = (xglScreenInfo.heightMm * h) /
|
||||
xglScreenInfo.height;
|
||||
xglScreenInfo.height = h;
|
||||
}
|
||||
}
|
||||
else if (xglScreenInfo.width == 0 || xglScreenInfo.height == 0)
|
||||
{
|
||||
|
|
@ -794,7 +851,7 @@ xglxScreenInit (int index,
|
|||
xswa.colormap = pScreenPriv->colormap;
|
||||
|
||||
pScreenPriv->win =
|
||||
XCreateWindow (xdisplay, pScreenPriv->root, 0, 0,
|
||||
XCreateWindow (xdisplay, pScreenPriv->root, x, y,
|
||||
xglScreenInfo.width, xglScreenInfo.height, 0,
|
||||
vinfo->depth, InputOutput, vinfo->visual,
|
||||
CWColormap, &xswa);
|
||||
|
|
@ -810,10 +867,14 @@ xglxScreenInit (int index,
|
|||
|
||||
if (fullscreen)
|
||||
{
|
||||
normalHints->x = 0;
|
||||
normalHints->y = 0;
|
||||
normalHints->x = x;
|
||||
normalHints->y = y;
|
||||
normalHints->flags |= PPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentEventWindow = pScreenPriv->win;
|
||||
}
|
||||
|
||||
classHint = XAllocClassHint ();
|
||||
classHint->res_name = "xglx";
|
||||
|
|
@ -1000,7 +1061,8 @@ xglxInitOutput (ScreenInfo *pScreenInfo,
|
|||
|
||||
xglxScreenFormat = format;
|
||||
|
||||
AddScreen (xglxScreenInit, argc, argv);
|
||||
for (i = 0; i < numScreen; i++)
|
||||
AddScreen (xglxScreenInit, argc, argv);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -1011,31 +1073,36 @@ xglxBlockHandler (pointer blockData,
|
|||
XEvent X;
|
||||
RegionRec region;
|
||||
BoxRec box;
|
||||
ScreenPtr pScreen;
|
||||
int i;
|
||||
|
||||
XGL_SCREEN_PRIV (currentScreen);
|
||||
|
||||
while (XCheckIfEvent (xdisplay, &X, xglxExposurePredicate, NULL))
|
||||
for (i = 0; i < screenInfo.numScreens; i++)
|
||||
{
|
||||
ScreenPtr pScreen = currentScreen;
|
||||
pScreen = screenInfo.screens[i];
|
||||
|
||||
box.x1 = X.xexpose.x;
|
||||
box.y1 = X.xexpose.y;
|
||||
box.x2 = box.x1 + X.xexpose.width;
|
||||
box.y2 = box.y1 + X.xexpose.height;
|
||||
XGL_SCREEN_PRIV (pScreen);
|
||||
|
||||
REGION_INIT (currentScreen, ®ion, &box, 1);
|
||||
while (XCheckIfEvent (xdisplay, &X, xglxExposurePredicate, NULL))
|
||||
{
|
||||
box.x1 = X.xexpose.x;
|
||||
box.y1 = X.xexpose.y;
|
||||
box.x2 = box.x1 + X.xexpose.width;
|
||||
box.y2 = box.y1 + X.xexpose.height;
|
||||
|
||||
WalkTree (pScreen, xglxWindowExposures, ®ion);
|
||||
REGION_INIT (pScreen, ®ion, &box, 1);
|
||||
|
||||
REGION_UNINIT (pScreen, ®ion);
|
||||
WalkTree (pScreen, xglxWindowExposures, ®ion);
|
||||
|
||||
REGION_UNINIT (pScreen, ®ion);
|
||||
}
|
||||
|
||||
if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
|
||||
FatalError (XGL_SW_FAILURE_STRING);
|
||||
|
||||
glitz_surface_flush (pScreenPriv->surface);
|
||||
glitz_drawable_flush (pScreenPriv->drawable);
|
||||
}
|
||||
|
||||
if (!xglSyncSurface (&pScreenPriv->pScreenPixmap->drawable))
|
||||
FatalError (XGL_SW_FAILURE_STRING);
|
||||
|
||||
glitz_surface_flush (pScreenPriv->surface);
|
||||
glitz_drawable_flush (pScreenPriv->drawable);
|
||||
|
||||
XFlush (xdisplay);
|
||||
}
|
||||
|
||||
|
|
@ -1376,6 +1443,8 @@ xglxUseMsg (void)
|
|||
ErrorF ("-fullscreen run fullscreen\n");
|
||||
ErrorF ("-display string display name of the real server\n");
|
||||
ErrorF ("-softcursor force software cursor\n");
|
||||
ErrorF ("-scrns number of screens to generate\n");
|
||||
ErrorF ("-primary num xinerama screen to use as first screen\n");
|
||||
|
||||
if (!xDisplayName)
|
||||
xglxUseXorgMsg ();
|
||||
|
|
@ -1456,6 +1525,32 @@ xglxProcessArgument (int argc,
|
|||
softCursor = TRUE;
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp (argv[i], "-scrns"))
|
||||
{
|
||||
if ((i + 1) < argc)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = atoi (argv[i + 1]);
|
||||
if (n > 1 && n <= MAXSCREENS)
|
||||
numScreen = n;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
else if (!strcmp (argv[i], "-primary"))
|
||||
{
|
||||
if ((i + 1) < argc)
|
||||
{
|
||||
primaryScreen = atoi (argv[i + 1]);
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 2;
|
||||
}
|
||||
else if (!xDisplayName)
|
||||
{
|
||||
return xglxProcessXorgArgument (argc, argv, i);
|
||||
|
|
@ -1479,6 +1574,8 @@ xglxGiveUp (void)
|
|||
void
|
||||
xglxOsVendorInit (void)
|
||||
{
|
||||
miRegionInit (&screenRegion, NULL, 0);
|
||||
|
||||
if (!xdisplay)
|
||||
{
|
||||
char *name = xDisplayName;
|
||||
|
|
@ -1520,6 +1617,56 @@ xglxOsVendorInit (void)
|
|||
XSetScreenSaver (xdisplay, 0, interval,
|
||||
preferBlanking, allowExposures);
|
||||
XResetScreenSaver (xdisplay);
|
||||
|
||||
if (XineramaIsActive (xdisplay))
|
||||
{
|
||||
XineramaScreenInfo *info;
|
||||
int nInfo = 0;
|
||||
RegionRec region;
|
||||
BoxRec box;
|
||||
BoxPtr rect;
|
||||
int i;
|
||||
|
||||
info = XineramaQueryScreens (xdisplay, &nInfo);
|
||||
|
||||
for (i = 0; i < nInfo; i++)
|
||||
{
|
||||
box.x1 = info[i].x_org;
|
||||
box.y1 = info[i].y_org;
|
||||
box.x2 = box.x1 + info[i].width;
|
||||
box.y2 = box.y1 + info[i].height;
|
||||
|
||||
if (miRectIn (&screenRegion, &box) == rgnOUT)
|
||||
{
|
||||
rect = Xrealloc (screenRect,
|
||||
sizeof (BoxRec) * (nScreenRect + 1));
|
||||
if (!rect)
|
||||
continue;
|
||||
|
||||
if (nScreenRect &&
|
||||
info[i].screen_number == primaryScreen)
|
||||
{
|
||||
memmove (rect + 1, rect,
|
||||
sizeof (BoxRec) * nScreenRect);
|
||||
*rect = box;
|
||||
}
|
||||
else
|
||||
{
|
||||
rect[nScreenRect] = box;
|
||||
screenRect = rect;
|
||||
}
|
||||
|
||||
nScreenRect++;
|
||||
|
||||
miRegionInit (®ion, &box, 1);
|
||||
miUnion (&screenRegion, &screenRegion, ®ion);
|
||||
miRegionUninit (®ion);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (nScreenRect > 1 && nScreenRect <= MAXSCREENS)
|
||||
numScreen = nScreenRect;
|
||||
}
|
||||
|
||||
if (!glitz_glx_find_window_format (xdisplay, xscreen, 0, NULL, 0))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue