Nomad DMX work.

This commit is contained in:
David Reveman 2008-06-03 18:18:04 -04:00
parent 8dacf32025
commit 2bda1f5610
36 changed files with 3893 additions and 390 deletions

View file

@ -1561,8 +1561,7 @@ AM_CONDITIONAL(INTEGRATED_XPBPROXY, [test "x$INTEGRATED_XPBPROXY" = xyes])
dnl DMX DDX
PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
AC_MSG_CHECKING([whether to build Xdmx DDX])
PKG_CHECK_MODULES([DMXMODULES], [xmuu xext x11 xrender xfixes xfont xi dmxproto xau xcomposite xrandr $XDMCP_MODULES], [have_dmx=yes], [have_dmx=no])
if test "x$DMX" = xauto; then
DMX="$have_dmx"
case $host_os in
@ -1580,7 +1579,7 @@ if test "x$DMX" = xyes; then
fi
DMX_INCLUDES="$XEXT_INC $RENDER_INC $RECORD_INC"
XDMX_CFLAGS="$DMXMODULES_CFLAGS"
XDMX_LIBS="$XEXT_LIB $FB_LIB $CONFIG_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB"
XDMX_LIBS="$XEXT_LIB $FB_LIB $CONFIG_LIB $RENDER_LIB $RECORD_LIB $XI_LIB $XKB_LIB $XKB_STUB_LIB $MIEXT_SHADOW_LIB $MIEXT_DAMAGE_LIB $RANDR_LIB"
XDMX_SYS_LIBS="$DMXMODULES_LIBS"
AC_SUBST([XDMX_CFLAGS])
AC_SUBST([XDMX_LIBS])

View file

@ -72,6 +72,8 @@ Xdmx_SOURCES = dmx.c \
dmxvisual.h \
dmxwindow.c \
dmxwindow.h \
dmxlaunch.c \
dmxlaunch.h \
$(top_srcdir)/mi/miinitext.c \
$(top_srcdir)/fb/fbcmap_mi.c \
$(GLX_SRCS)
@ -84,6 +86,9 @@ Xdmx_SOURCES = dmx.c \
XDMX_LIBS = \
@XDMX_LIBS@ \
$(GLX_LIBS) \
$(top_srcdir)/composite/libcomposite.la \
$(top_srcdir)/xfixes/libxfixes.la \
$(top_srcdir)/damageext/libdamageext.la \
input/libdmxinput.a \
config/libdmxconfig.a \
$(XSERVER_LIBS)

View file

@ -76,7 +76,8 @@ typedef struct DMXConfigCmdStruct {
DMXConfigEntryPtr dmxConfigEntry;
static DMXConfigCmd dmxConfigCmd;
static int dmxDisplaysFromCommandLine;
static int dmxDisplaysFromCommandLine = 0;
static int dmxNumDetached = 0;
/** Make a note that \a display is the name of an X11 display that
* should be initialized as a backend (output) display. Called from
@ -97,6 +98,11 @@ void dmxConfigStoreDisplay(const char *display)
++dmxDisplaysFromCommandLine;
}
void dmxConfigStoreNumDetached(const char *num)
{
dmxNumDetached = strtol (num, NULL, 0);
}
/** Make a note that \a input is the name of an X11 display that should
* be used for input (either a backend or a console input device). */
void dmxConfigStoreInput(const char *input)
@ -361,27 +367,42 @@ static void dmxConfigCopyData(DMXConfigVirtualPtr v)
static void dmxConfigFromCommandLine(void)
{
DMXConfigListPtr pt;
dmxLog(dmxInfo, "Using configuration from command line\n");
for (pt = dmxConfigCmd.displays; pt; pt = pt->next) {
DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0);
if (dmxNumScreens == 1) {
dmxScreen->where = PosAbsolute;
dmxScreen->whereX = 0;
dmxScreen->whereY = 0;
dmxLog(dmxInfo, "Added %s at %d %d\n",
dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY);
} else {
dmxScreen->where = PosRightOf;
dmxScreen->whereRefScreen = dmxNumScreens - 2;
if (dmxScreen->whereRefScreen < 0) dmxScreen->whereRefScreen = 0;
dmxLog(dmxInfo, "Added %s %s %s\n",
dmxScreen->name,
dmxScreen->where == PosBelow ? "below" : "right of",
dmxScreens[dmxScreen->whereRefScreen].name);
}
DMXScreenInfo *dmxScreen = dmxConfigAddDisplay(pt->name,
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0);
if (dmxNumScreens == 1) {
dmxScreen->where = PosAbsolute;
dmxScreen->whereX = 0;
dmxScreen->whereY = 0;
dmxLog(dmxInfo, "Added %s at %d %d\n",
dmxScreen->name, dmxScreen->whereX, dmxScreen->whereY);
} else {
dmxScreen->where = PosRightOf;
dmxScreen->whereRefScreen = dmxNumScreens - 2;
if (dmxScreen->whereRefScreen < 0) dmxScreen->whereRefScreen = 0;
dmxLog(dmxInfo, "Added %s %s %s\n",
dmxScreen->name,
dmxScreen->where == PosBelow ? "below" : "right of",
dmxScreens[dmxScreen->whereRefScreen].name);
}
}
if (dmxNumDetached)
{
dmxLog (dmxInfo, "Adding %d detached displays\n", dmxNumDetached);
while (dmxNumDetached--)
{
DMXScreenInfo *dmxScreen = dmxConfigAddDisplay ("",
0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0);
dmxScreen->where = PosAbsolute;
dmxScreen->whereX = 0;
dmxScreen->whereY = 0;
}
}
}
@ -450,6 +471,11 @@ void dmxConfigConfigure(void)
dmxConfigConfigInputs();
}
int dmxConfigDisplaysFromCommandLine(void)
{
return dmxDisplaysFromCommandLine;
}
/** This function determines the number of displays we WILL have and
* sets MAXSCREENS to that value. This is difficult since the number
* depends on the command line (which is easy to count) or on the config

View file

@ -43,11 +43,13 @@
#define DMX_DEFAULT_XKB_OPTIONS NULL
extern void dmxConfigStoreDisplay(const char *display);
extern void dmxConfigStoreNumDetached(const char *num);
extern void dmxConfigStoreInput(const char *input); /* Core devices */
extern void dmxConfigStoreXInput(const char *input); /* Non-core devices */
extern void dmxConfigStoreFile(const char *file);
extern void dmxConfigStoreConfig(const char *config);
extern void dmxConfigConfigure(void);
extern int dmxConfigDisplaysFromCommandLine(void);
extern void dmxConfigSetMaxScreens(void);
extern void dmxConfigSetXkbRules(const char *rules);

View file

@ -80,9 +80,5 @@
#undef XFreeXDGA
#undef XF86DRI
#undef SCREENSAVER
#undef RANDR
#undef XFIXES
#undef DAMAGE
#undef COMPOSITE
#endif /* DMX_CONFIG_H */

View file

@ -63,10 +63,15 @@
#ifdef PANORAMIX
#include "panoramiX.h"
extern unsigned long XRC_DRAWABLE;
extern unsigned long XRT_WINDOW;
extern int PanoramiXNumScreens;
#endif
#ifdef RANDR
#include "randrstr.h"
#endif
extern void DMXExtensionInit(void);
static unsigned char DMXCode;
@ -481,7 +486,7 @@ static int ProcDMXAddScreen(ClientPtr client)
return BadLength;
memset(&attr, 0, sizeof(attr));
dmxGetScreenAttributes(stuff->physicalScreen, &attr);
/*dmxGetScreenAttributes(stuff->physicalScreen, &attr); */
value_list = (CARD32 *)(stuff + 1);
count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
@ -544,28 +549,32 @@ static int dmxPopulatePanoramiX(ClientPtr client, Window window,
CARD32 *screens, CARD32 *windows,
xRectangle *pos, xRectangle *vis)
{
WindowPtr pWin;
PanoramiXRes *win;
DrawablePtr pDraw;
PanoramiXRes *res;
int i;
int count = 0;
DMXWindowAttributesRec attr;
if (!(win = SecurityLookupIDByType(client, window, XRT_WINDOW,
DixReadAccess)))
return -1; /* BadWindow */
if(!(res = (PanoramiXRes *) SecurityLookupIDByClass(
client, window, XRC_DRAWABLE, DixReadAccess)))
return -1; /* BadDrawable */
FOR_NSCREENS(i) {
if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
DixReadAccess))
return -1; /* BadWindow */
if (dmxGetWindowAttributes(pWin, &attr)) {
screens[count] = attr.screen;
windows[count] = attr.window;
pos[count] = attr.pos;
vis[count] = attr.vis;
++count; /* Only count existing windows */
}
if (Success == dixLookupDrawable (&pDraw, res->info[i].id, client,
M_ANY, DixUnknownAccess))
{
if (dmxGetDrawableAttributes (pDraw, &attr))
{
screens[count] = attr.screen;
windows[count] = attr.window;
pos[count] = attr.pos;
vis[count] = attr.vis;
++count; /* Only count existing windows */
}
}
}
return count;
}
#endif
@ -573,7 +582,7 @@ static int dmxPopulatePanoramiX(ClientPtr client, Window window,
static int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
CARD32 *windows, xRectangle *pos, xRectangle *vis)
{
WindowPtr pWin;
DrawablePtr pDraw;
DMXWindowAttributesRec attr;
#ifdef PANORAMIX
@ -582,14 +591,21 @@ static int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
pos, vis);
#endif
if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
return -1; /* BadWindow */
if (Success != dixLookupDrawable (&pDraw, window, client, 0,
DixReadAccess))
return -1;
if (!dmxGetDrawableAttributes (pDraw, &attr))
return -1;
dmxGetWindowAttributes(pWin, &attr);
*screens = attr.screen;
*windows = attr.window;
*pos = attr.pos;
*vis = attr.vis;
if (!attr.window)
abort ();
return 1;
}
@ -740,6 +756,10 @@ static int ProcDMXChangeDesktopAttributes(ClientPtr client)
#endif
if (status == BadValue) return status;
#ifdef RANDR
RRScreenSizeNotify (screenInfo.screens[0]);
#endif
noxinerama:
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;

View file

@ -71,6 +71,8 @@
#include <GL/glxint.h>
#endif
#include "dmxxlibio.h"
typedef enum {
PosNone = -1,
PosAbsolute = 0,
@ -96,6 +98,8 @@ typedef struct _DMXScreenInfo {
/*---------- Back-end X server information ----------*/
int fd;
Display *beDisplay; /**< Back-end X server's display */
int beWidth; /**< Width of BE display */
int beHeight; /**< Height of BE display */
@ -106,6 +110,7 @@ typedef struct _DMXScreenInfo {
int beNumDepths; /**< Number of depths on BE server */
int *beDepths; /**< Depths from BE server */
int alive;
int beNumPixmapFormats; /**< Number of pixmap formats on BE */
XPixmapFormatValues *bePixmapFormats; /**< Pixmap formats on BE */
@ -120,6 +125,12 @@ typedef struct _DMXScreenInfo {
Pixel beBlackPixel; /**< Default black pixel for BE */
Pixel beWhitePixel; /**< Default white pixel for BE */
#ifdef RANDR
Bool beRandr; /**< Use RANDR support on BE server */
Bool beRandrPending;
int beRandrEventBase;
#endif
/*---------- Screen window information ----------*/
Window scrnWin; /**< "Screen" window on backend display */
@ -216,6 +227,8 @@ typedef struct _DMXScreenInfo {
ChangeBorderWidthProcPtr ChangeBorderWidth;
SetWindowPixmapProcPtr SetWindowPixmap;
GetImageProcPtr GetImage;
GetSpansProcPtr GetSpans;

View file

@ -72,6 +72,11 @@ typedef XID KeySym64;
#define Colormap Colormap64
#define GContext GContext64
#define KeySym KeySym64
#ifdef RANDR
#define RRMode RRMode64
#define RROutput RROutput64
#define RRCrtc RRCrtc64
#endif
#endif
#include <X11/Xlib.h>
@ -91,6 +96,10 @@ typedef XID KeySym64;
#undef PictFormatType
#endif
#ifdef RANDR
#include <X11/extensions/Xrandr.h>
#endif
#ifdef XKB
#include <X11/extensions/XKB.h>
#include <X11/extensions/XKBstr.h>
@ -101,6 +110,7 @@ typedef XID KeySym64;
/* Always include these, since we query them even if we don't export XINPUT. */
#include <X11/extensions/XInput.h> /* For XDevice */
#include <X11/extensions/Xext.h>
#include <X11/extensions/Xcomposite.h>
#undef GC
@ -119,6 +129,11 @@ typedef XID KeySym64;
#undef Colormap
#undef GContext
#undef KeySym
#ifdef RANDR
#undef RRMode
#undef RROutput
#undef RRCrtc
#endif
#endif
/* These are in exglobals.h, but that conflicts with xkbsrv.h */

View file

@ -70,12 +70,15 @@ Bool dmxBECreateColormap(ColormapPtr pColormap)
Visual *visual = dmxLookupVisual(pScreen, pVisual);
if (visual) {
pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
dmxScreen->scrnWin,
visual,
(pVisual->class & DynamicClass ?
AllocAll : AllocNone));
return (pCmapPriv->cmap != 0);
pCmapPriv->cmap = 0;
XLIB_PROLOGUE (dmxScreen);
pCmapPriv->cmap = XCreateColormap(dmxScreen->beDisplay,
dmxScreen->scrnWin,
visual,
(pVisual->class & DynamicClass ?
AllocAll : AllocNone));
XLIB_EPILOGUE (dmxScreen);
return (pCmapPriv->cmap != 0);
}
else {
dmxLog(dmxWarning, "dmxBECreateColormap: No visual found\n");
@ -115,7 +118,9 @@ Bool dmxBEFreeColormap(ColormapPtr pColormap)
dmxColormapPrivPtr pCmapPriv = DMX_GET_COLORMAP_PRIV(pColormap);
if (pCmapPriv->cmap) {
XLIB_PROLOGUE (dmxScreen);
XFreeColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
XLIB_EPILOGUE (dmxScreen);
pCmapPriv->cmap = (Colormap)0;
return TRUE;
}
@ -156,7 +161,9 @@ void dmxInstallColormap(ColormapPtr pColormap)
DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
if (dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
XInstallColormap(dmxScreen->beDisplay, pCmapPriv->cmap);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
@ -182,7 +189,9 @@ void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef)
color[i].flags = pdef[i].flags;
color[i].pad = pdef[i].pad;
}
XLIB_PROLOGUE (dmxScreen);
XStoreColors(dmxScreen->beDisplay, pCmapPriv->cmap, color, ndef);
XLIB_EPILOGUE (dmxScreen);
xfree(color);
} else { /* xalloc failed, so fallback */
XColor c;
@ -193,7 +202,9 @@ void dmxStoreColors(ColormapPtr pColormap, int ndef, xColorItem *pdef)
c.green = pdef[i].green;
c.flags = pdef[i].flags;
c.pad = pdef[i].pad;
XLIB_PROLOGUE (dmxScreen);
XStoreColor(dmxScreen->beDisplay, pCmapPriv->cmap, &c);
XLIB_EPILOGUE (dmxScreen);
}
}
dmxSync(dmxScreen, FALSE);

View file

@ -573,6 +573,14 @@ void dmxInitOverlap(void)
}
}
#ifdef ARGB_CURSOR
static Cursor
dmxCreateARGBCursor (ScreenPtr pScreen,
CursorPtr pCursor);
#endif
/** Create \a pCursor on the back-end associated with \a pScreen. */
void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
{
@ -590,6 +598,17 @@ void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
if (!pCursorPriv)
return;
pCursorPriv->cursor = None;
#ifdef ARGB_CURSOR
if (pCursor->bits->argb)
{
pCursorPriv->cursor = dmxCreateARGBCursor (pScreen, pCursor);
if (pCursorPriv->cursor)
return;
}
#endif
m = GCFunction | GCPlaneMask | GCForeground | GCBackground | GCClipMask;
v.function = GXcopy;
v.plane_mask = AllPlanes;
@ -600,14 +619,18 @@ void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
if (dmxScreen->bePixmapFormats[i].depth == 1) {
/* Create GC in the back-end servers */
XLIB_PROLOGUE (dmxScreen);
gc = XCreateGC(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i],
m, &v);
XLIB_EPILOGUE (dmxScreen);
break;
}
}
if (!gc)
dmxLog(dmxFatal, "dmxRealizeCursor: gc not initialized\n");
XLIB_PROLOGUE (dmxScreen);
src = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
pBits->width, pBits->height, 1);
msk = XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
@ -652,6 +675,8 @@ void dmxBECreateCursor(ScreenPtr pScreen, CursorPtr pCursor)
XFreePixmap(dmxScreen->beDisplay, msk);
XFreeGC(dmxScreen->beDisplay, gc);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -683,8 +708,10 @@ Bool dmxBEFreeCursor(ScreenPtr pScreen, CursorPtr pCursor)
dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
if (pCursorPriv) {
XLIB_PROLOGUE (dmxScreen);
XFreeCursor(dmxScreen->beDisplay, pCursorPriv->cursor);
pCursorPriv->cursor = (Cursor)0;
XLIB_EPILOGUE (dmxScreen);
pCursorPriv->cursor = (Cursor) 0;
return TRUE;
}
@ -719,8 +746,10 @@ static void _dmxMoveCursor(ScreenPtr pScreen, int x, int y)
DMXDBG5("_dmxMoveCursor(%d,%d,%d) -> %d,%d\n",
pScreen->myNum, x, y, newX, newY);
if (dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
XWarpPointer(dmxScreen->beDisplay, None, dmxScreen->scrnWin,
0, 0, 0, 0, newX, newY);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, TRUE);
}
}
@ -735,8 +764,12 @@ static void _dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
dmxCursorPrivPtr pCursorPriv = DMX_GET_CURSOR_PRIV(pCursor, pScreen);
if (pCursorPriv && dmxScreen->curCursor != pCursorPriv->cursor) {
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
pCursorPriv->cursor);
XLIB_EPILOGUE (dmxScreen);
}
dmxScreen->cursor = pCursor;
dmxScreen->curCursor = pCursorPriv->cursor;
dmxScreen->cursorVisible = 1;
@ -744,8 +777,12 @@ static void _dmxSetCursor(ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
_dmxMoveCursor(pScreen, x, y);
} else {
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
dmxScreen->noCursor);
XLIB_EPILOGUE (dmxScreen);
}
dmxScreen->cursor = NULL;
dmxScreen->curCursor = (Cursor)0;
dmxScreen->cursorVisible = 0;
@ -982,3 +1019,62 @@ miPointerSpriteFuncRec dmxPointerSpriteFuncs =
dmxDeviceCursorInitialize,
dmxDeviceCursorCleanup
};
#ifdef ARGB_CURSOR
#include <X11/extensions/Xrender.h>
static Cursor
dmxCreateARGBCursor (ScreenPtr pScreen,
CursorPtr pCursor)
{
Pixmap xpixmap;
XlibGC xgc;
XImage *ximage;
XRenderPictFormat *xformat;
Picture xpicture;
Cursor cursor = None;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
XLIB_PROLOGUE (dmxScreen);
xpixmap = XCreatePixmap (dmxScreen->beDisplay,
dmxScreen->scrnWin,
pCursor->bits->width,
pCursor->bits->height,
32);
xgc = XCreateGC (dmxScreen->beDisplay, xpixmap, 0, NULL);
ximage = XCreateImage (dmxScreen->beDisplay,
DefaultVisual (dmxScreen->beDisplay, 0),
32, ZPixmap, 0,
(char *) pCursor->bits->argb,
pCursor->bits->width,
pCursor->bits->height,
32, pCursor->bits->width * 4);
XPutImage (dmxScreen->beDisplay, xpixmap, xgc, ximage,
0, 0, 0, 0, pCursor->bits->width, pCursor->bits->height);
XFree (ximage);
XFreeGC (dmxScreen->beDisplay, xgc);
xformat = XRenderFindStandardFormat (dmxScreen->beDisplay,
PictStandardARGB32);
xpicture = XRenderCreatePicture (dmxScreen->beDisplay, xpixmap,
xformat, 0, 0);
cursor = XRenderCreateCursor (dmxScreen->beDisplay, xpicture,
pCursor->bits->xhot,
pCursor->bits->yhot);
XRenderFreePicture (dmxScreen->beDisplay, xpicture);
XFreePixmap (dmxScreen->beDisplay, xpixmap);
XLIB_EPILOGUE (dmxScreen);
return cursor;
}
#endif

View file

@ -1,3 +1,4 @@
/* $XFree86$ */
/*
* Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
*

View file

@ -63,6 +63,7 @@ static void _dmxDPMSInit(DMXScreenInfo *dmxScreen)
CARD16 level, standby, suspend, off;
BOOL state;
const char *monitor;
int status = 1;
if (dpmsGeneration != serverGeneration) {
dpmsSupported = TRUE; /* On unless a backend doesn't support it */
@ -74,37 +75,46 @@ static void _dmxDPMSInit(DMXScreenInfo *dmxScreen)
#endif
dmxScreen->dpmsCapable = 0;
dpmsSupported = FALSE;
if (!dmxScreen->beDisplay) {
dmxLogOutput(dmxScreen,
"Cannot determine if DPMS supported (detached screen)\n");
dpmsSupported = FALSE;
return;
}
if (!DPMSQueryExtension(dmxScreen->beDisplay,
&event_base, &error_base)) {
dmxLogOutput(dmxScreen, "DPMS not supported\n");
dpmsSupported = FALSE;
return;
}
if (!DPMSGetVersion(dmxScreen->beDisplay, &major, &minor)) {
dmxLogOutput(dmxScreen, "DPMS not supported\n");
dpmsSupported = FALSE;
return;
}
if (!DPMSCapable(dmxScreen->beDisplay)) {
dmxLogOutput(dmxScreen, "DPMS %d.%d (not DPMS capable)\n",
major, minor);
dpmsSupported = FALSE;
return;
XLIB_PROLOGUE (dmxScreen);
if (!(status = DPMSQueryExtension(dmxScreen->beDisplay,
&event_base, &error_base)))
dmxLogOutput(dmxScreen, "DPMS not supported\n");
if (status)
if (!(status = DPMSGetVersion(dmxScreen->beDisplay, &major, &minor)))
dmxLogOutput(dmxScreen, "DPMS not supported\n");
if (status)
if (!(status = DPMSCapable(dmxScreen->beDisplay)))
dmxLogOutput(dmxScreen, "DPMS %d.%d (not DPMS capable)\n",
major, minor);
if (status)
{
DPMSInfo(dmxScreen->beDisplay, &level, &state);
DPMSGetTimeouts(dmxScreen->beDisplay, &standby, &suspend, &off);
DPMSSetTimeouts(dmxScreen->beDisplay, 0, 0, 0);
DPMSEnable(dmxScreen->beDisplay);
DPMSForceLevel(dmxScreen->beDisplay, DPMSModeOn);
dpmsSupported = TRUE;
}
DPMSInfo(dmxScreen->beDisplay, &level, &state);
DPMSGetTimeouts(dmxScreen->beDisplay, &standby, &suspend, &off);
DPMSSetTimeouts(dmxScreen->beDisplay, 0, 0, 0);
DPMSEnable(dmxScreen->beDisplay);
DPMSForceLevel(dmxScreen->beDisplay, DPMSModeOn);
XLIB_EPILOGUE (dmxScreen);
if (!dpmsSupported)
return;
dmxScreen->dpmsCapable = 1;
dmxScreen->dpmsEnabled = !!state;
dmxScreen->dpmsStandby = standby;
@ -138,11 +148,13 @@ void dmxDPMSInit(DMXScreenInfo *dmxScreen)
return;
/* Turn off screen saver */
XLIB_PROLOGUE (dmxScreen);
XGetScreenSaver(dmxScreen->beDisplay, &dmxScreen->savedTimeout, &interval,
&preferBlanking, &allowExposures);
XSetScreenSaver(dmxScreen->beDisplay, 0, interval,
preferBlanking, allowExposures);
XResetScreenSaver(dmxScreen->beDisplay);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -155,6 +167,7 @@ void dmxDPMSTerm(DMXScreenInfo *dmxScreen)
if (!dmxScreen->beDisplay)
return;
XLIB_PROLOGUE (dmxScreen);
XGetScreenSaver(dmxScreen->beDisplay, &timeout, &interval,
&preferBlanking, &allowExposures);
XSetScreenSaver(dmxScreen->beDisplay, dmxScreen->savedTimeout, interval,
@ -167,6 +180,7 @@ void dmxDPMSTerm(DMXScreenInfo *dmxScreen)
if (dmxScreen->dpmsEnabled) DPMSEnable(dmxScreen->beDisplay);
else DPMSDisable(dmxScreen->beDisplay);
}
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -204,7 +218,9 @@ int DPMSSet(ClientPtr client, int level)
for (i = 0; i < dmxNumScreens; i++) {
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
DPMSForceLevel(dmxScreen->beDisplay, level);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}

View file

@ -54,6 +54,9 @@
#ifdef RENDER
#include "dmxpict.h"
#endif
#ifdef RANDR
#include "randrstr.h"
#endif
#include "dmxinput.h"
#include "dmxsync.h"
#include "dmxscrinit.h"
@ -156,6 +159,76 @@ Bool dmxGetWindowAttributes(WindowPtr pWindow, DMXWindowAttributesPtr attr)
return TRUE;
}
/** This routine provides information to the DMX protocol extension
* about a particular window. */
Bool dmxGetDrawableAttributes(DrawablePtr pDraw, DMXWindowAttributesPtr attr)
{
if ((pDraw->type == UNDRAWABLE_WINDOW) || (pDraw->type == DRAWABLE_WINDOW))
{
WindowPtr pWindow = (WindowPtr) pDraw;
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWindow);
attr->screen = pWindow->drawable.pScreen->myNum;
attr->window = pWinPriv->window;
attr->pos.x = pWindow->drawable.x;
attr->pos.y = pWindow->drawable.y;
attr->pos.width = pWindow->drawable.width;
attr->pos.height = pWindow->drawable.height;
if (!pWinPriv->window || pWinPriv->offscreen) {
attr->vis.x = 0;
attr->vis.y = 0;
attr->vis.height = 0;
attr->vis.width = 0;
return pWinPriv->window ? TRUE : FALSE;
}
/* Compute display-relative coordinates */
attr->vis.x = pWindow->drawable.x;
attr->vis.y = pWindow->drawable.y;
attr->vis.width = pWindow->drawable.width;
attr->vis.height = pWindow->drawable.height;
if (attr->pos.x < 0) {
attr->vis.x -= attr->pos.x;
attr->vis.width = attr->pos.x + attr->pos.width - attr->vis.x;
}
if (attr->pos.x + attr->pos.width > pWindow->drawable.pScreen->width) {
if (attr->pos.x < 0)
attr->vis.width = pWindow->drawable.pScreen->width;
else
attr->vis.width = pWindow->drawable.pScreen->width - attr->pos.x;
}
if (attr->pos.y < 0) {
attr->vis.y -= attr->pos.y;
attr->vis.height = attr->pos.y + attr->pos.height - attr->vis.y;
}
if (attr->pos.y + attr->pos.height > pWindow->drawable.pScreen->height) {
if (attr->pos.y < 0)
attr->vis.height = pWindow->drawable.pScreen->height;
else
attr->vis.height = pWindow->drawable.pScreen->height - attr->pos.y;
}
/* Convert to window-relative coordinates */
attr->vis.x -= attr->pos.x;
attr->vis.y -= attr->pos.y;
}
else
{
PixmapPtr pPixmap = (PixmapPtr) pDraw;
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV (pPixmap);
xRectangle empty = { 0, 0, 0, 0 };
attr->screen = pDraw->pScreen->myNum;
attr->window = pPixPriv->pixmap;
attr->pos = attr->vis = empty;
}
return TRUE;
}
void dmxGetDesktopAttributes(DMXDesktopAttributesPtr attr)
{
attr->width = dmxGlobalWidth;
@ -502,7 +575,12 @@ int dmxConfigureScreenWindows(int nscreens,
/* The "screen" and "root" windows must have valid sizes */
if (attr->screenWindowWidth <= 0 || attr->screenWindowHeight <= 0 ||
attr->rootWindowWidth < 0 || attr->rootWindowHeight < 0)
{
dmxLog(dmxWarning,
"The \"screen\" and \"root\" windows must have valid "
"sizes\n");
return DMX_BAD_VALUE;
}
/* The "screen" window must fit entirely within the BE display */
if (attr->screenWindowXoffset < 0 ||
@ -511,7 +589,12 @@ int dmxConfigureScreenWindows(int nscreens,
+ attr->screenWindowWidth > (unsigned)dmxScreen->beWidth ||
attr->screenWindowYoffset
+ attr->screenWindowHeight > (unsigned)dmxScreen->beHeight)
{
dmxLog(dmxWarning,
"The \"screen\" window must fit entirely within the "
"BE display\n");
return DMX_BAD_VALUE;
}
/* The "root" window must fit entirely within the "screen" window */
if (attr->rootWindowXoffset < 0 ||
@ -520,21 +603,24 @@ int dmxConfigureScreenWindows(int nscreens,
+ attr->rootWindowWidth > attr->screenWindowWidth ||
attr->rootWindowYoffset
+ attr->rootWindowHeight > attr->screenWindowHeight)
{
dmxLog(dmxWarning,
"The \"root\" window must fit entirely within the "
"\"screen\" window\n");
return DMX_BAD_VALUE;
}
/* The "root" window must not expose unaddressable coordinates */
if (attr->rootWindowXorigin < 0 ||
attr->rootWindowYorigin < 0 ||
attr->rootWindowXorigin + attr->rootWindowWidth > 32767 ||
attr->rootWindowYorigin + attr->rootWindowHeight > 32767)
{
dmxLog(dmxWarning,
"The \"root\" window must not expose unaddressable "
"coordinates\n");
return DMX_BAD_VALUE;
/* The "root" window must fit within the global bounding box */
if (attr->rootWindowXorigin
+ attr->rootWindowWidth > (unsigned)dmxGlobalWidth ||
attr->rootWindowYorigin
+ attr->rootWindowHeight > (unsigned)dmxGlobalHeight)
return DMX_BAD_VALUE;
}
/* FIXME: Handle the rest of the illegal value checking */
}
@ -685,6 +771,8 @@ static void dmxBECreateScratchGCs(int scrnNum)
#ifdef PANORAMIX
static Bool FoundPixImage;
extern unsigned long XRT_PICTURE;
/** Search the Xinerama XRT_PIXMAP resources for the pixmap that needs
* to have its image restored. When it is found, see if there is
* another screen with the same image. If so, copy the pixmap image
@ -692,46 +780,128 @@ static Bool FoundPixImage;
static void dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type,
pointer p)
{
PixmapPtr pSrc = NULL;
PixmapPtr pDst = (PixmapPtr) p;
int idx = pDst->drawable.pScreen->myNum;
int i;
if ((type & TypeMask) == (XRT_PIXMAP & TypeMask)) {
PixmapPtr pDst = (PixmapPtr)p;
int idx = pDst->drawable.pScreen->myNum;
PanoramiXRes *pXinPix = (PanoramiXRes *)value;
PixmapPtr pPix;
int i;
pPix = (PixmapPtr)LookupIDByType(pXinPix->info[idx].id, RT_PIXMAP);
if (pPix != pDst) return; /* Not a match.... Next! */
for (i = 0; i < PanoramiXNumScreens; i++) {
PixmapPtr pSrc;
dmxPixPrivPtr pSrcPriv = NULL;
for (i = 0; i < PanoramiXNumScreens; i++)
{
if (i == idx) continue; /* Self replication is bad */
pSrc =
(PixmapPtr)LookupIDByType(pXinPix->info[i].id, RT_PIXMAP);
pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
if (pSrcPriv->pixmap) {
DMXScreenInfo *dmxSrcScreen = &dmxScreens[i];
DMXScreenInfo *dmxDstScreen = &dmxScreens[idx];
dmxPixPrivPtr pDstPriv = DMX_GET_PIXMAP_PRIV(pDst);
XImage *img;
int j;
XlibGC gc = NULL;
break;
}
}
/* This should never happen, but just in case.... */
if (pSrc->drawable.width != pDst->drawable.width ||
pSrc->drawable.height != pDst->drawable.height)
return;
#ifdef RENDER
else if ((type & TypeMask) == (XRT_PICTURE & TypeMask))
{
int idx = pDst->drawable.pScreen->myNum;
PanoramiXRes *pXinPic = (PanoramiXRes *) value;
PicturePtr pPic;
/* Copy from src pixmap to dst pixmap */
img = XGetImage(dmxSrcScreen->beDisplay,
pSrcPriv->pixmap,
0, 0,
pSrc->drawable.width, pSrc->drawable.height,
-1,
ZPixmap);
pPic = (PicturePtr) LookupIDByType (pXinPic->info[idx].id,
PictureType);
/* Not a match.... Next! */
if (!pPic || !pPic->pDrawable) return;
if (pPic->pDrawable->type != DRAWABLE_PIXMAP) return;
if (pPic->pDrawable != (DrawablePtr) pDst) return;
for (i = 0; i < PanoramiXNumScreens; i++)
{
if (i == idx) continue; /* Self replication is bad */
pPic = (PicturePtr) LookupIDByType (pXinPic->info[i].id,
PictureType);
pSrc = (PixmapPtr) pPic->pDrawable;
break;
}
}
#endif
else if ((type & TypeMask) == (XRT_WINDOW & TypeMask))
{
PixmapPtr pDst = (PixmapPtr)p;
int idx = pDst->drawable.pScreen->myNum;
PanoramiXRes *pXinWin = (PanoramiXRes *) value;
Bool border;
WindowPtr pWin;
pWin = (WindowPtr) LookupIDByType (pXinWin->info[idx].id, RT_WINDOW);
if (!pWin) return;
if (!pWin->borderIsPixel && pWin->border.pixmap == pDst)
{
border = TRUE;
}
else if (pWin->backgroundState == BackgroundPixmap &&
pWin->background.pixmap == pDst)
{
border = FALSE;
}
else
{
return;
}
for (i = 0; i < PanoramiXNumScreens; i++)
{
if (i == idx) continue; /* Self replication is bad */
pWin = (WindowPtr) LookupIDByType (pXinWin->info[i].id, RT_WINDOW);
if (border)
pSrc = pWin->border.pixmap;
else
pSrc = pWin->background.pixmap;
break;
}
}
if (pSrc)
{
dmxPixPrivPtr pSrcPriv = DMX_GET_PIXMAP_PRIV (pSrc);
if (pSrcPriv->pixmap)
{
DMXScreenInfo *dmxSrcScreen = &dmxScreens[i];
DMXScreenInfo *dmxDstScreen = &dmxScreens[idx];
dmxPixPrivPtr pDstPriv = DMX_GET_PIXMAP_PRIV(pDst);
XImage *img = NULL;
int j;
XlibGC gc = NULL;
/* This should never happen, but just in case.... */
if (pSrc->drawable.width != pDst->drawable.width ||
pSrc->drawable.height != pDst->drawable.height)
return;
XLIB_PROLOGUE (dmxSrcScreen);
/* Copy from src pixmap to dst pixmap */
img = XGetImage(dmxSrcScreen->beDisplay,
pSrcPriv->pixmap,
0, 0,
pSrc->drawable.width, pSrc->drawable.height,
-1,
ZPixmap);
XLIB_EPILOGUE (dmxSrcScreen);
if (img)
{
for (j = 0; j < dmxDstScreen->beNumPixmapFormats; j++) {
if (dmxDstScreen->bePixmapFormats[j].depth == img->depth) {
unsigned long m;
@ -742,26 +912,31 @@ static void dmxBERestorePixmapImage(pointer value, XID id, RESTYPE type,
v.plane_mask = AllPlanes;
v.clip_mask = None;
XLIB_PROLOGUE (dmxDstScreen);
gc = XCreateGC(dmxDstScreen->beDisplay,
dmxDstScreen->scrnDefDrawables[j],
m, &v);
XLIB_EPILOGUE (dmxDstScreen);
break;
}
}
if (gc) {
XLIB_PROLOGUE (dmxDstScreen);
XPutImage(dmxDstScreen->beDisplay,
pDstPriv->pixmap,
gc, img, 0, 0, 0, 0,
pDst->drawable.width, pDst->drawable.height);
XFreeGC(dmxDstScreen->beDisplay, gc);
XLIB_EPILOGUE (dmxDstScreen);
FoundPixImage = True;
} else {
dmxLog(dmxWarning, "Could not create GC\n");
}
XDestroyImage(img);
return;
} else {
dmxLog(dmxWarning, "Could not create image\n");
}
}
}
@ -810,14 +985,17 @@ static void dmxBERestorePixmap(PixmapPtr pPixmap)
v.plane_mask = AllPlanes;
v.clip_mask = None;
XLIB_PROLOGUE (dmxScreen);
gc = XCreateGC(dmxScreen->beDisplay,
dmxScreen->scrnDefDrawables[i],
m, &v);
XLIB_EPILOGUE (dmxScreen);
break;
}
}
if (gc) {
XLIB_PROLOGUE (dmxScreen);
XPutImage(dmxScreen->beDisplay,
pPixPriv->pixmap,
gc,
@ -825,6 +1003,7 @@ static void dmxBERestorePixmap(PixmapPtr pPixmap)
0, 0, 0, 0,
pPixmap->drawable.width, pPixmap->drawable.height);
XFreeGC(dmxScreen->beDisplay, gc);
XLIB_EPILOGUE (dmxScreen);
} else {
dmxLog(dmxWarning, "Cannot restore pixmap image\n");
}
@ -832,7 +1011,10 @@ static void dmxBERestorePixmap(PixmapPtr pPixmap)
XDestroyImage(pPixPriv->detachedImage);
pPixPriv->detachedImage = NULL;
} else {
dmxLog(dmxWarning, "Cannot restore pixmap image\n");
dmxLog(dmxWarning, "Cannot restore pixmap image: %dx%d - %d\n",
pPixmap->drawable.width,
pPixmap->drawable.height,
pPixmap->drawable.depth);
}
}
#else
@ -888,7 +1070,7 @@ static void dmxBECreateResources(pointer value, XID id, RESTYPE type,
} else if ((type & TypeMask) == (RT_FONT & TypeMask)) {
(void)dmxBELoadFont(pScreen, (FontPtr)value);
} else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) {
dmxBECreateCursor(pScreen, (CursorPtr)value);
AnimForEachCursorElt (pScreen, (CursorPtr) value, dmxBECreateCursor);
} else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) {
ColormapPtr pCmap = value;
if (pCmap->pScreen->myNum == scrnNum)
@ -932,7 +1114,10 @@ static void dmxBECreateWindowTree(int idx)
/* Create root window first */
dmxScreen->rootWin = pWinPriv->window = dmxCreateRootWindow(pRoot);
XLIB_PROLOGUE (dmxScreen);
XMapWindow(dmxScreen->beDisplay, dmxScreen->rootWin);
XLIB_EPILOGUE (dmxScreen);
pWin = pRoot->lastChild;
while (pWin) {
@ -956,8 +1141,7 @@ static void dmxBECreateWindowTree(int idx)
&pWinPriv->visual);
/* Create the window */
if (pWinPriv->mapped && !pWinPriv->offscreen)
dmxCreateAndRealizeWindow(pWin, TRUE);
dmxCreateAndRealizeWindow(pWin, TRUE);
/* Next, create the bottom-most child */
if (pWin->lastChild) {
@ -1009,6 +1193,9 @@ static Bool dmxCompareScreens(DMXScreenInfo *new, DMXScreenInfo *old)
{
int i;
/* hack */
return TRUE;
if (new->beWidth != old->beWidth) return FALSE;
if (new->beHeight != old->beHeight) return FALSE;
if (new->beDepth != old->beDepth) return FALSE;
@ -1153,9 +1340,11 @@ static void dmxBERestoreRenderGlyph(pointer value, XID id, pointer n)
}
/* Now restore the glyph data */
XLIB_PROLOGUE (dmxScreen);
XRenderAddGlyphs(dmxScreen->beDisplay, glyphPriv->glyphSets[scrnNum],
gids,glyphs, glyphSet->hash.tableEntries, images,
len_images);
XLIB_EPILOGUE (dmxScreen);
/* Clean up */
xfree(len_images);
@ -1222,10 +1411,43 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
dmxCheckForWM(dmxScreen);
dmxGetScreenAttribs(dmxScreen);
#ifdef RANDR
dmxScreen->beRandr = FALSE;
#endif
if (attr->screenWindowWidth == 0 || attr->screenWindowHeight == 0)
{
#ifdef RANDR
int ignore;
XLIB_PROLOGUE (dmxScreen);
dmxScreen->beRandr = XRRQueryExtension (dmxScreen->beDisplay,
&dmxScreen->beRandrEventBase,
&ignore);
XLIB_EPILOGUE (dmxScreen);
#endif
attr->screenWindowWidth = dmxScreen->beWidth;
attr->screenWindowHeight = dmxScreen->beHeight;
attr->screenWindowXoffset = 0;
attr->screenWindowYoffset = 0;
attr->rootWindowWidth = dmxScreen->beWidth;
attr->rootWindowHeight = dmxScreen->beHeight;
attr->rootWindowXoffset = 0;
attr->rootWindowYoffset = 0;
attr->rootWindowXorigin = 0;
attr->rootWindowYorigin = 0;
}
if (!dmxGetVisualInfo(dmxScreen)) {
dmxLog(dmxWarning, "dmxGetVisualInfo: No matching visuals found\n");
XFree(dmxScreen->beVisuals);
XLIB_PROLOGUE (dmxScreen);
XCloseDisplay(dmxScreen->beDisplay);
XLIB_EPILOGUE (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
@ -1250,7 +1472,24 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
XLIB_PROLOGUE (dmxScreen);
XCloseDisplay(dmxScreen->beDisplay);
XLIB_EPILOGUE (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
return 1;
}
/* Create the default font */
if (!dmxBELoadFont(pScreen, defaultFont))
{
XFree(dmxScreen->beVisuals);
XFree(dmxScreen->beDepths);
XFree(dmxScreen->bePixmapFormats);
XLIB_PROLOGUE (dmxScreen);
XCloseDisplay(dmxScreen->beDisplay);
XLIB_EPILOGUE (dmxScreen);
/* Restore the old screen */
*dmxScreen = oldDMXScreen;
@ -1270,9 +1509,6 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
/* Create the scratch GCs */
dmxBECreateScratchGCs(idx);
/* Create the default font */
(void)dmxBELoadFont(pScreen, defaultFont);
/* Create all resources that don't depend on windows */
for (i = currentMaxClients; --i >= 0; )
if (clients[i])
@ -1311,10 +1547,15 @@ int dmxAttachScreen(int idx, DMXScreenAttributesPtr attr)
#ifdef PANORAMIX
if (!noPanoramiXExtension)
return dmxConfigureScreenWindows(1, &scrnNum, attr, NULL);
else
if (dmxConfigureScreenWindows(1, &scrnNum, attr, NULL))
return 1;
#endif
return 0; /* Success */
#ifdef RANDR
RRTellChanged (screenInfo.screens[0]);
#endif
return 0; /* Success */
}
/*
@ -1372,6 +1613,7 @@ static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type,
int i;
pPix = (PixmapPtr)LookupIDByType(pXinPix->info[idx].id, RT_PIXMAP);
if (pPix != pDst) return; /* Not a match.... Next! */
for (i = 0; i < PanoramiXNumScreens; i++) {
@ -1382,6 +1624,7 @@ static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type,
pSrc =
(PixmapPtr)LookupIDByType(pXinPix->info[i].id, RT_PIXMAP);
pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc);
if (pSrcPriv->pixmap) {
FoundPixImage = True;
@ -1389,6 +1632,87 @@ static void dmxBEFindPixmapImage(pointer value, XID id, RESTYPE type,
}
}
}
#ifdef RENDER
else if ((type & TypeMask) == (XRT_PICTURE & TypeMask))
{
PixmapPtr pDst = (PixmapPtr) p;
int idx = pDst->drawable.pScreen->myNum;
PanoramiXRes *pXinPic = (PanoramiXRes *) value;
PicturePtr pPic;
int i;
pPic = (PicturePtr) LookupIDByType (pXinPic->info[idx].id,
PictureType);
/* Not a match.... Next! */
if (!pPic || !pPic->pDrawable) return;
if (pPic->pDrawable->type != DRAWABLE_PIXMAP) return;
if (pPic->pDrawable != (DrawablePtr) pDst) return;
for (i = 0; i < PanoramiXNumScreens; i++) {
dmxPixPrivPtr pSrcPriv = NULL;
if (i == idx) continue; /* Self replication is bad */
pPic = (PicturePtr) LookupIDByType (pXinPic->info[i].id,
PictureType);
pSrcPriv = DMX_GET_PIXMAP_PRIV ((PixmapPtr) pPic->pDrawable);
if (pSrcPriv->pixmap)
{
FoundPixImage = True;
return;
}
}
}
#endif
else if ((type & TypeMask) == (XRT_WINDOW & TypeMask))
{
PixmapPtr pDst = (PixmapPtr)p;
int idx = pDst->drawable.pScreen->myNum;
PanoramiXRes *pXinWin = (PanoramiXRes *) value;
Bool border;
WindowPtr pWin;
int i;
pWin = (WindowPtr) LookupIDByType (pXinWin->info[idx].id, RT_WINDOW);
if (!pWin) return;
if (!pWin->borderIsPixel && pWin->border.pixmap == pDst)
{
border = TRUE;
}
else if (pWin->backgroundState == BackgroundPixmap &&
pWin->background.pixmap == pDst)
{
border = FALSE;
}
else
{
return;
}
for (i = 0; i < PanoramiXNumScreens; i++) {
dmxPixPrivPtr pSrcPriv = NULL;
if (i == idx) continue; /* Self replication is bad */
pWin = (WindowPtr) LookupIDByType (pXinWin->info[i].id, RT_WINDOW);
if (border)
pSrcPriv = DMX_GET_PIXMAP_PRIV (pWin->border.pixmap);
else
pSrcPriv = DMX_GET_PIXMAP_PRIV (pWin->background.pixmap);
if (pSrcPriv->pixmap)
{
FoundPixImage = True;
return;
}
}
}
}
#endif
@ -1425,6 +1749,7 @@ static void dmxBESavePixmap(PixmapPtr pPixmap)
ScreenPtr pScreen = pPixmap->drawable.pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
XLIB_PROLOGUE (dmxScreen);
pPixPriv->detachedImage = XGetImage(dmxScreen->beDisplay,
pPixPriv->pixmap,
0, 0,
@ -1432,8 +1757,15 @@ static void dmxBESavePixmap(PixmapPtr pPixmap)
pPixmap->drawable.height,
-1,
ZPixmap);
XLIB_EPILOGUE (dmxScreen);
if (!pPixPriv->detachedImage)
dmxLog(dmxWarning, "Cannot save pixmap image\n");
{
dmxLog(dmxWarning, "Cannot save pixmap image: %p - %dx%d %d\n",
pPixmap, pPixmap->drawable.width,
pPixmap->drawable.height,
pPixmap->drawable.depth);
}
}
}
#else
@ -1475,7 +1807,8 @@ static void dmxBEDestroyResources(pointer value, XID id, RESTYPE type,
} else if ((type & TypeMask) == (RT_FONT & TypeMask)) {
dmxBEFreeFont(pScreen, (FontPtr)value);
} else if ((type & TypeMask) == (RT_CURSOR & TypeMask)) {
dmxBEFreeCursor(pScreen, (CursorPtr)value);
AnimForEachCursorElt (pScreen, (CursorPtr) value,
(void *) dmxBEFreeCursor);
} else if ((type & TypeMask) == (RT_COLORMAP & TypeMask)) {
ColormapPtr pCmap = value;
if (pCmap->pScreen->myNum == scrnNum)
@ -1583,6 +1916,13 @@ int dmxDetachScreen(int idx)
/* Cannot remove a screen that does not exist */
if (idx < 0 || idx >= dmxNumScreens) return 1;
if (idx == 0) {
dmxLog(dmxWarning,
"Attempting to remove screen #%d\n",
idx);
return 1;
}
/* Cannot detach from a screen that is not opened */
if (!dmxScreen->beDisplay) {
dmxLog(dmxWarning,
@ -1596,6 +1936,23 @@ int dmxDetachScreen(int idx)
/* Detach input */
dmxInputDetachAll(dmxScreen);
dmxScreen->scrnWidth = 1;
dmxScreen->scrnHeight = 1;
dmxScreen->scrnX = 0;
dmxScreen->scrnY = 0;
dmxScreen->rootWidth = 0;
dmxScreen->rootHeight = 0;
dmxScreen->rootX = 0;
dmxScreen->rootY = 0;
dmxScreen->rootXOrigin = 0;
dmxScreen->rootYOrigin = 0;
dmxScreen->beWidth = 1;
dmxScreen->beHeight = 1;
dmxScreen->beXDPI = 75;
dmxScreen->beYDPI = 75;
dmxScreen->beDepth = 24;
dmxScreen->beBPP = 32;
/* Save all relevant state (TODO) */
/* Free all non-window resources related to this screen */
@ -1620,5 +1977,9 @@ int dmxDetachScreen(int idx)
/* Adjust the cursor boundaries (paints detached console window) */
dmxAdjustCursorBoundaries();
#ifdef RANDR
RRTellChanged (screenInfo.screens[0]);
#endif
return 0; /* Success */
}

View file

@ -95,6 +95,8 @@ extern Bool dmxGetScreenAttributes(int physical,
DMXScreenAttributesPtr attr);
extern Bool dmxGetWindowAttributes(WindowPtr pWindow,
DMXWindowAttributesPtr attr);
extern Bool dmxGetDrawableAttributes(DrawablePtr pDraw,
DMXWindowAttributesPtr attr);
extern void dmxGetDesktopAttributes(DMXDesktopAttributesPtr attr);
extern int dmxGetInputCount(void);
extern int dmxGetInputAttributes(int deviceId,

View file

@ -103,10 +103,15 @@ static Bool dmxCheckFontPathElement(DMXScreenInfo *dmxScreen, char *fp)
return TRUE;
dmxFontLastError = 0;
#if 0
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
XLIB_PROLOGUE (dmxScreen);
XSetFontPath(dmxScreen->beDisplay, &fp, 1);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
XSetErrorHandler(oldErrorHandler);
#endif
return (dmxFontLastError == 0);
}
@ -121,12 +126,15 @@ static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
if (!dmxScreen->beDisplay)
return result;
#if 0
fp = dmxGetFontPath(&npaths);
if (!fp) return BadAlloc;
dmxFontLastError = 0;
oldErrorHandler = XSetErrorHandler(dmxFontErrorHandler);
XLIB_PROLOGUE (dmxScreen);
XSetFontPath(dmxScreen->beDisplay, fp, npaths);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, TRUE); /* Must complete before removing handler */
XSetErrorHandler(oldErrorHandler);
@ -140,28 +148,35 @@ static int dmxSetFontPath(DMXScreenInfo *dmxScreen)
}
dmxFreeFontPath(fp);
#endif
return result;
}
static int dmxCheckFontPath(DMXScreenInfo *dmxScreen, int *error)
{
char **oldFontPath;
int nOldPaths;
char **oldFontPath = NULL;
int nOldPaths = 0;
int result = Success;
if (!dmxScreen->beDisplay)
return result;
#if 0
/* Save old font path */
XLIB_PROLOGUE (dmxScreen);
oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
XLIB_EPILOGUE (dmxScreen);
result = dmxSetFontPath(dmxScreen);
/* Restore old font path */
XLIB_PROLOGUE (dmxScreen);
XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
XLIB_EPILOGUE (dmxScreen);
XFreeFontPath(oldFontPath);
dmxSync(dmxScreen, FALSE);
#endif
return result;
}
@ -255,7 +270,7 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
char *name;
char **oldFontPath = NULL;
int nOldPaths;
int nOldPaths = 0;
Atom name_atom, value_atom;
int i;
@ -268,8 +283,11 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
return TRUE; /* Already loaded font */
}
#if 0
/* Save old font path */
XLIB_PROLOGUE (dmxScreen);
oldFontPath = XGetFontPath(dmxScreen->beDisplay, &nOldPaths);
XLIB_EPILOGUE (dmxScreen);
/* Set the font path for the font about to be loaded on the back-end */
if (dmxSetFontPath(dmxScreen)) {
@ -402,6 +420,7 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
return FALSE;
}
}
#endif
/* Find requested font on back-end server */
name_atom = MakeAtom("FONT", 4, TRUE);
@ -418,12 +437,17 @@ Bool dmxBELoadFont(ScreenPtr pScreen, FontPtr pFont)
name = (char *)NameForAtom(value_atom);
if (!name) return FALSE;
pFontPriv->font[pScreen->myNum] =
XLoadQueryFont(dmxScreen->beDisplay, name);
pFontPriv->font[pScreen->myNum] = None;
/* Restore old font path */
XLIB_PROLOGUE (dmxScreen);
pFontPriv->font[pScreen->myNum] =
XLoadQueryFont(dmxScreen->beDisplay, name);
XLIB_EPILOGUE (dmxScreen);
/* Restore old font path
XSetFontPath(dmxScreen->beDisplay, oldFontPath, nOldPaths);
XFreeFontPath(oldFontPath);
XFreeFontPath(oldFontPath);*/
dmxSync(dmxScreen, FALSE);
if (!pFontPriv->font[pScreen->myNum]) return FALSE;
@ -472,7 +496,9 @@ Bool dmxBEFreeFont(ScreenPtr pScreen, FontPtr pFont)
dmxFontPrivPtr pFontPriv = FontGetPrivate(pFont, dmxFontPrivateIndex);
if (pFontPriv && pFontPriv->font[pScreen->myNum]) {
XLIB_PROLOGUE (dmxScreen);
XFreeFont(dmxScreen->beDisplay, pFontPriv->font[pScreen->myNum]);
XLIB_EPILOGUE (dmxScreen);
pFontPriv->font[pScreen->myNum] = NULL;
return TRUE;
}

View file

@ -106,9 +106,13 @@ void dmxBECreateGC(ScreenPtr pScreen, GCPtr pGC)
gcvals.graphics_exposures = FALSE;
/* Create GC in the back-end servers */
pGCPriv->gc = None;
XLIB_PROLOGUE (dmxScreen);
pGCPriv->gc = XCreateGC(dmxScreen->beDisplay,
dmxScreen->scrnDefDrawables[i],
mask, &gcvals);
XLIB_EPILOGUE (dmxScreen);
break;
}
}
@ -275,14 +279,20 @@ void dmxChangeGC(GCPtr pGC, unsigned long mask)
if (mask & GCDashList) {
mask &= ~GCDashList;
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XSetDashes(dmxScreen->beDisplay, pGCPriv->gc,
pGC->dashOffset, (char *)pGC->dash,
pGC->numInDashList);
XLIB_EPILOGUE (dmxScreen);
}
}
if (mask & GCArcMode) v.arc_mode = pGC->arcMode;
if (mask && dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
XChangeGC(dmxScreen->beDisplay, pGCPriv->gc, mask, &v);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -303,7 +313,11 @@ void dmxCopyGC(GCPtr pGCSrc, unsigned long changes, GCPtr pGCDst)
/* Copy the GC on the back-end server */
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XCopyGC(dmxScreen->beDisplay, pGCSrcPriv->gc, changes, pGCDstPriv->gc);
XLIB_EPILOGUE (dmxScreen);
}
DMX_GC_FUNC_EPILOGUE(pGCDst);
}
@ -316,7 +330,9 @@ Bool dmxBEFreeGC(GCPtr pGC)
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
if (pGCPriv->gc) {
XLIB_PROLOGUE (dmxScreen);
XFreeGC(dmxScreen->beDisplay, pGCPriv->gc);
XLIB_EPILOGUE (dmxScreen);
pGCPriv->gc = NULL;
return TRUE;
}
@ -358,7 +374,11 @@ void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
switch (pGC->clientClipType) {
case CT_NONE:
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
XLIB_EPILOGUE (dmxScreen);
}
break;
case CT_REGION:
@ -374,9 +394,11 @@ void dmxChangeClip(GCPtr pGC, int type, pointer pvalue, int nrects)
pRects[i].height = pBox[i].y2 - pBox[i].y1;
}
XLIB_PROLOGUE (dmxScreen);
XSetClipRectangles(dmxScreen->beDisplay, pGCPriv->gc,
pGC->clipOrg.x, pGC->clipOrg.y,
pRects, nRects, Unsorted);
XLIB_EPILOGUE (dmxScreen);
xfree(pRects);
}
@ -407,7 +429,11 @@ void dmxDestroyClip(GCPtr pGC)
/* Set the client clip on the back-end server to None */
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XSetClipMask(dmxScreen->beDisplay, pGCPriv->gc, None);
XLIB_EPILOGUE (dmxScreen);
}
DMX_GC_FUNC_EPILOGUE(pGC);
}

View file

@ -98,16 +98,18 @@ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
{
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
dmxGCPrivPtr pGCPriv = DMX_GET_GC_PRIV(pGC);
XImage *img;
XImage *img = NULL;
if (DMX_GCOPS_OFFSCREEN(pDrawable)) return;
XLIB_PROLOGUE (dmxScreen);
img = XCreateImage(dmxScreen->beDisplay,
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
depth, format, leftPad, pBits, w, h,
BitmapPad(dmxScreen->beDisplay),
(format == ZPixmap) ?
PixmapBytePad(w, depth) : BitmapBytePad(w+leftPad));
XLIB_EPILOGUE (dmxScreen);
if (img) {
Drawable draw;
@ -136,6 +138,7 @@ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
nBox = REGION_NUM_RECTS(pSubImages);
pBox = REGION_RECTS(pSubImages);
XLIB_PROLOGUE (dmxScreen);
while (nBox--) {
XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc, img,
pBox->x1 - box.x1,
@ -146,11 +149,14 @@ void dmxPutImage(DrawablePtr pDrawable, GCPtr pGC,
pBox->y2 - pBox->y1);
pBox++;
}
XLIB_EPILOGUE (dmxScreen);
REGION_DESTROY(pGC->pScreen, pClip);
REGION_DESTROY(pGC->pScreen, pSubImages);
} else {
XLIB_PROLOGUE (dmxScreen);
XPutImage(dmxScreen->beDisplay, draw, pGCPriv->gc,
img, 0, 0, x, y, w, h);
XLIB_EPILOGUE (dmxScreen);
}
XFree(img); /* Use XFree instead of XDestroyImage
* because pBits is passed in from the
@ -180,8 +186,10 @@ RegionPtr dmxCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
XLIB_PROLOGUE (dmxScreen);
XCopyArea(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
srcx, srcy, w, h, dstx, dsty);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, w, h,
@ -207,8 +215,10 @@ RegionPtr dmxCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pSrc, srcDraw);
DMX_GCOPS_SET_DRAWABLE(pDst, dstDraw);
XLIB_PROLOGUE (dmxScreen);
XCopyPlane(dmxScreen->beDisplay, srcDraw, dstDraw, pGCPriv->gc,
srcx, srcy, width, height, dstx, dsty, bitPlane);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
return miHandleExposures(pSrc, pDst, pGC, srcx, srcy, width, height,
@ -230,8 +240,10 @@ void dmxPolyPoint(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawPoints(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XPoint *)pptInit, npt, mode);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -250,8 +262,10 @@ void dmxPolylines(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawLines(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XPoint *)pptInit, npt, mode);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -270,8 +284,10 @@ void dmxPolySegment(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawSegments(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XSegment *)pSegs, nseg);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -290,8 +306,10 @@ void dmxPolyRectangle(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XRectangle *)pRects, nrects);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -311,8 +329,10 @@ void dmxPolyArc(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XArc *)parcs, narcs);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -331,8 +351,10 @@ void dmxFillPolygon(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XFillPolygon(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XPoint *)pPts, count, shape, mode);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -351,8 +373,10 @@ void dmxPolyFillRect(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XFillRectangles(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XRectangle *)prectInit, nrectFill);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -371,8 +395,10 @@ void dmxPolyFillArc(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XFillArcs(dmxScreen->beDisplay, draw, pGCPriv->gc,
(XArc *)parcs, narcs);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -400,8 +426,10 @@ int dmxPolyText8(DrawablePtr pDrawable, GCPtr pGC,
if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawString(dmxScreen->beDisplay, draw, pGCPriv->gc,
x, y, chars, count);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -433,8 +461,10 @@ int dmxPolyText16(DrawablePtr pDrawable, GCPtr pGC,
if (n != 0 && !DMX_GCOPS_OFFSCREEN(pDrawable)) {
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
x, y, (XChar2b *)chars, count);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -456,8 +486,10 @@ void dmxImageText8(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawImageString(dmxScreen->beDisplay, draw, pGCPriv->gc,
x, y, chars, count);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -476,8 +508,10 @@ void dmxImageText16(DrawablePtr pDrawable, GCPtr pGC,
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
XLIB_PROLOGUE (dmxScreen);
XDrawImageString16(dmxScreen->beDisplay, draw, pGCPriv->gc,
x, y, (XChar2b *)chars, count);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -553,7 +587,7 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
unsigned int format, unsigned long planeMask, char *pdstLine)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
XImage *img;
XImage *img = NULL;
Drawable draw;
/* Cannot get image from unviewable window */
@ -581,8 +615,10 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
}
}
XLIB_PROLOGUE (dmxScreen);
img = XGetImage(dmxScreen->beDisplay, draw,
sx, sy, w, h, planeMask, format);
XLIB_EPILOGUE (dmxScreen);
if (img) {
int len = img->bytes_per_line * img->height;
memmove(pdstLine, img->data, len);

View file

@ -53,15 +53,18 @@
#include "dmxcb.h"
#include "dmxprop.h"
#include "dmxstat.h"
#include "dmxlaunch.h"
#ifdef RENDER
#include "dmxpict.h"
#endif
#include "dmxextension.h"
#include <X11/Xos.h> /* For gettimeofday */
#include "dixstruct.h"
#include "panoramiXsrv.h"
#include <signal.h> /* For SIGQUIT */
#include <execinfo.h>
#ifdef GLXEXT
#include <GL/glx.h>
@ -81,7 +84,7 @@ extern void GlxSetVisualConfigs(
int dmxNumScreens;
DMXScreenInfo *dmxScreens;
int dmxNumInputs;
int dmxNumInputs = 0;
DMXInputInfo *dmxInputs;
int dmxShadowFB = FALSE;
@ -117,6 +120,34 @@ Bool dmxIgnoreBadFontPaths = FALSE;
Bool dmxAddRemoveScreens = FALSE;
int dmxLaunchIndex = 0;
#ifdef DMXVNC
Bool dmxVnc = TRUE;
#endif
#include <execinfo.h>
static void
dmxSigHandler (int signo)
{
void *array[64];
size_t size, i;
char **strings;
ErrorF ("\nBacktrace:\n");
size = backtrace (array, 64);
strings = backtrace_symbols (array, size);
for (i = 0; i < size; i++)
ErrorF ("%d: %s\n", i, strings[i]);
free (strings);
FatalError ("Caught signal %d. Server aborting\n", signo);
}
/* dmxErrorHandler catches errors that occur when calling one of the
* back-end servers. Some of this code is based on _XPrintDefaultError
* in xc/lib/X11/XlibInt.c */
@ -180,6 +211,30 @@ static int dmxErrorHandler(Display *dpy, XErrorEvent *ev)
ev->serial);
dmxLog(dmxWarning, " Current serial number: %d\n",
dpy->request);
// abort ();
return 0;
}
int _dmx_jumpbuf_set = 0;
int _dmx_io_error = 0;
jmp_buf _dmx_jumpbuf;
static int dmxIOErrorHandler (Display *dpy)
{
_dmx_io_error++;
if (!_dmx_jumpbuf_set)
{
ErrorF ("_dmx_jumpbuf not set\n");
abort ();
}
else
{
longjmp (_dmx_jumpbuf, 1);
}
return 0;
}
@ -192,9 +247,19 @@ static int dmxNOPErrorHandler(Display *dpy, XErrorEvent *ev)
Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
{
dmxScreen->beDisplay = NULL;
if (!dmxScreen->name || !*dmxScreen->name)
return FALSE;
if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->name)))
return FALSE;
/* XSynchronize (dmxScreen->beDisplay, TRUE); */
dmxScreen->alive = 1;
dmxScreen->fd = XConnectionNumber (dmxScreen->beDisplay);
dmxPropertyDisplay(dmxScreen);
return TRUE;
}
@ -202,6 +267,7 @@ Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
void dmxSetErrorHandler(DMXScreenInfo *dmxScreen)
{
XSetErrorHandler(dmxErrorHandler);
XSetIOErrorHandler(dmxIOErrorHandler);
}
static void dmxPrintScreenInfo(DMXScreenInfo *dmxScreen)
@ -325,8 +391,8 @@ void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen)
dmxScreen->rootHeight = dmxScreen->scrnHeight - dmxScreen->rootY;
/* FIXME: Get these from the back-end server */
dmxScreen->beXDPI = 75;
dmxScreen->beYDPI = 75;
dmxScreen->beXDPI = 96;
dmxScreen->beYDPI = 96;
dmxScreen->beDepth = attribs.depth; /* FIXME: verify that this
* works always. In
@ -487,22 +553,54 @@ void dmxCheckForWM(DMXScreenInfo *dmxScreen)
/** Initialize the display and collect relevant information about the
* display properties */
static void dmxDisplayInit(DMXScreenInfo *dmxScreen)
static Bool dmxDisplayInit(DMXScreenInfo *dmxScreen)
{
if (!dmxOpenDisplay(dmxScreen))
dmxLog(dmxFatal,
"dmxOpenDisplay: Unable to open display %s\n",
dmxScreen->name);
{
if (dmxScreen->name)
dmxLog(dmxWarning,
"dmxOpenDisplay: Unable to open display %s\n",
dmxScreen->name);
dmxSetErrorHandler(dmxScreen);
dmxCheckForWM(dmxScreen);
dmxGetScreenAttribs(dmxScreen);
dmxScreen->scrnWidth = 1;
dmxScreen->scrnHeight = 1;
dmxScreen->scrnX = 0;
dmxScreen->scrnY = 0;
dmxScreen->beWidth = 1;
dmxScreen->beHeight = 1;
dmxScreen->beXDPI = 96;
dmxScreen->beYDPI = 96;
dmxScreen->beDepth = 24;
dmxScreen->beBPP = 32;
if (!dmxGetVisualInfo(dmxScreen))
dmxLog(dmxFatal, "dmxGetVisualInfo: No matching visuals found\n");
return FALSE;
}
else
{
dmxSetErrorHandler(dmxScreen);
dmxCheckForWM(dmxScreen);
dmxGetScreenAttribs(dmxScreen);
dmxGetColormaps(dmxScreen);
dmxGetPixmapFormats(dmxScreen);
if (!dmxGetVisualInfo(dmxScreen))
{
dmxLog(dmxWarning,
"dmxGetVisualInfo: No matching visuals found\n");
XLIB_PROLOGUE (dmxScreen);
XCloseDisplay(dmxScreen->beDisplay);
XLIB_EPILOGUE (dmxScreen);
dmxScreen->beDisplay = NULL;
return FALSE;
}
else
{
dmxGetColormaps(dmxScreen);
dmxGetPixmapFormats(dmxScreen);
}
}
return TRUE;
}
/* If this doesn't compile, just add || defined(yoursystem) to the line
@ -633,6 +731,15 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
"Dynamic screen addition/removal error (see above).\n");
}
if (!dmxConfigDisplaysFromCommandLine ())
{
char *displayName;
displayName = dmxLaunchDisplay (argc, argv, dmxLaunchIndex);
if (displayName)
dmxConfigStoreDisplay (displayName);
}
/* ddxProcessArgument has been called at this point, but any data
* from the configuration file has not been applied. Do so, and be
* sure we have at least one back-end display. */
@ -656,7 +763,10 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
/* Open each display and gather information about it. */
for (i = 0; i < dmxNumScreens; i++)
dmxDisplayInit(&dmxScreens[i]);
if (!dmxDisplayInit(&dmxScreens[i]) && i == 0)
dmxLog(dmxFatal,
"dmxOpenDisplay: Unable to open display %s\n",
dmxScreens[i].name);
#if PANORAMIX
/* Register a Xinerama callback which will run from within
@ -682,7 +792,11 @@ void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
* same as the behavior of SIGINT. However, leaving the modifier
* map of the input devices empty is even more unexpected.) --RF
*/
OsSignal(SIGQUIT, GiveUp);
OsSignal (SIGQUIT, GiveUp);
OsSignal (SIGSEGV, dmxSigHandler);
OsSignal (SIGILL, dmxSigHandler);
OsSignal (SIGFPE, dmxSigHandler);
OsSignal (SIGABRT, dmxSigHandler);
#ifdef GLXEXT
/* Check if GLX extension exists on all back-end servers */
@ -874,6 +988,9 @@ int ddxProcessArgument(int argc, char *argv[], int i)
if (!strcmp(argv[i], "-display")) {
if (++i < argc) dmxConfigStoreDisplay(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-numDetached")) {
if (++i < argc) dmxConfigStoreNumDetached(argv[i]);
retval = 2;
} else if (!strcmp(argv[i], "-inputfrom") || !strcmp(argv[i], "-input")) {
if (++i < argc) dmxConfigStoreInput(argv[i]);
retval = 2;
@ -945,6 +1062,11 @@ int ddxProcessArgument(int argc, char *argv[], int i)
} else if (!strcmp(argv[i], "-addremovescreens")) {
dmxAddRemoveScreens = TRUE;
retval = 1;
#ifdef DMXVNC
} else if (!strcmp(argv[i], "-novnc")) {
dmxVnc = FALSE;
retval = 1;
#endif
} else if (!strcmp(argv[i], "-param")) {
if ((i += 2) < argc) {
if (!strcasecmp(argv[i-1], "xkbrules"))
@ -964,6 +1086,11 @@ int ddxProcessArgument(int argc, char *argv[], int i)
}
retval = 3;
}
else if (!strcmp(argv[i], "--")) {
dmxLaunchIndex = i + 1;
retval = argc - i;
}
if (!serverGeneration) dmxConfigSetMaxScreens();
return retval;
}
@ -973,6 +1100,7 @@ void ddxUseMsg(void)
{
ErrorF("\n\nDevice Dependent Usage:\n");
ErrorF("-display string Specify the back-end display(s)\n");
ErrorF("-numDetached num Specify detached back-end display(s)\n");
ErrorF("-input string Specify input source for core device\n");
ErrorF("-xinput string Specify input source for XInput device\n");
ErrorF("-shadowfb Enable shadow frame buffer\n");
@ -999,6 +1127,9 @@ void ddxUseMsg(void)
#endif
ErrorF("-ignorebadfontpaths Ignore bad font paths during initialization\n");
ErrorF("-addremovescreens Enable dynamic screen addition/removal\n");
#ifdef DMXVNC
ErrorF("-novnc Disable VNC\n");
#endif
ErrorF("-param ... Specify configuration parameters (e.g.,\n");
ErrorF(" XkbRules, XkbModel, XkbLayout, etc.)\n");
ErrorF("\n");
@ -1029,5 +1160,7 @@ void ddxUseMsg(void)
ErrorF(" Ctrl-Alt-g Server grab/ungrab (console only)\n");
ErrorF(" Ctrl-Alt-f Fine (1-pixel) mouse mode (console only)\n");
ErrorF(" Ctrl-Alt-q Quit (core devices only)\n");
ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n");
ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n\n");
ErrorF("-- [ server ] [ display ] [ options ]\n");
}

View file

@ -127,6 +127,9 @@ struct _DMXInputInfo {
char *keycodes; /**< XKB keycodes from command line */
char *symbols; /**< XKB symbols from command line */
char *geometry; /**< XKB geometry from command line */
CARD8 history[DOWN_LENGTH];
int validHistory;
};
extern int dmxNumInputs; /**< Number of #dmxInputs */

384
hw/dmx/dmxlaunch.c Normal file
View file

@ -0,0 +1,384 @@
/*
* Copyright © 2005 Novell, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: David Reveman <davidr@novell.com>
* Matthias Hopf <mhopf@suse.de>
*/
#include "dmx.h"
#include "dmxlaunch.h"
#include <X11/Xauth.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <signal.h>
#include <setjmp.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <libgen.h>
#include <fcntl.h>
typedef void (*sighandler_t) (int);
#define XBE_DIE_TIMEOUT 3
#define XBE_DEV_RANDOM "/dev/urandom"
static char xbeAuthBuf[256];
static char *xbeAuthTempl = "/tmp/.Xdmx-auth-XXXXXX";
static char *xbeAuth = NULL;
static char *xbeProgs[] = { "/usr/bin/Xfake", "/usr/X11R6/bin/Xfake" };
static char *xbeProg = NULL;
static char *xbeDisplay = ":73";
static pid_t xbePid = 0;
static int receivedUsr1 = 0;
static jmp_buf jumpbuf;
static char **xbeArgv = 0;
static int nXbeArgv = 0;
static int
dmxAddXbeArguments (char **argv,
int n)
{
char **newArgv;
int i;
newArgv = xrealloc (xbeArgv, sizeof (char *) * (nXbeArgv + n));
if (!newArgv)
return 0;
for (i = 0; i < n; i++)
newArgv[nXbeArgv + i] = argv[i];
xbeArgv = newArgv;
nXbeArgv += n;
return n;
}
static void
sigAlarm (int sig)
{
ErrorF ("%s won't die, killing it\n", basename (xbeProg));
kill (xbePid, SIGKILL);
if (xbePid)
while (waitpid (xbePid, NULL, 0) == -1 && errno == EINTR);
}
void
dmxAbortDisplay (void)
{
sighandler_t oldSigAlarm;
unsigned int oldAlarm;
int status = 0;
char *name;
if (!xbePid)
return;
name = basename (xbeProg);
oldAlarm = alarm (0);
oldSigAlarm = signal (SIGALRM, sigAlarm);
kill (xbePid, SIGTERM);
alarm (XBE_DIE_TIMEOUT);
while (waitpid (xbePid, &status, 0) == -1 && errno == EINTR);
alarm (0);
signal (SIGALRM, oldSigAlarm);
alarm (oldAlarm);
if (WIFEXITED (status))
{
if (WEXITSTATUS (status))
ErrorF ("%s died, exit status %d\n", name, WEXITSTATUS (status));
}
else if (WIFSIGNALED (status))
ErrorF ("%s died, signal %d\n", name, WTERMSIG (status));
else
ErrorF ("%s died, dubious exit\n", name);
if (xbeAuth)
unlink (xbeAuth);
}
static void
sigUsr1Waiting (int sig)
{
signal (sig, sigUsr1Waiting);
receivedUsr1++;
}
static void
sigUsr1Jump (int sig)
{
#ifdef HAVE_SIGPROCMASK
sigset_t set;
#endif
signal (sig, sigUsr1Waiting);
#ifdef HAVE_SIGPROCMASK
sigemptyset (&set);
sigaddset (&set, SIGUSR1);
sigprocmask (SIG_UNBLOCK, &set, NULL);
#endif
longjmp (jumpbuf, 1);
}
#define AUTH_DATA_LEN 16 /* bytes of authorization data */
static Bool
dmxSetupAuth (char *name, int authFd)
{
Xauth auth;
int randomFd;
ssize_t bytes, size;
char authHost[256];
char authData[AUTH_DATA_LEN];
FILE *file;
auth.family = FamilyLocal;
gethostname (authHost, sizeof (authHost));
auth.address = authHost;
auth.address_length = strlen (authHost);
auth.number = strrchr (xbeDisplay, ':');
if (!auth.number)
{
ErrorF ("Bad back-end X display name: %s\n", xbeDisplay);
return FALSE;
}
auth.number++;
auth.number_length = strlen (auth.number);
if (!auth.number_length)
{
ErrorF ("Bad back-end X display name: %s\n", xbeDisplay);
return FALSE;
}
auth.name = "MIT-MAGIC-COOKIE-1";
auth.name_length = strlen (auth.name);
randomFd = open (XBE_DEV_RANDOM, O_RDONLY);
if (randomFd == -1)
{
ErrorF ("Failed to open " XBE_DEV_RANDOM "\n");
return FALSE;
}
bytes = 0;
do {
size = read (randomFd, authData + bytes, AUTH_DATA_LEN - bytes);
if (size <= 0)
break;
bytes += size;
} while (bytes != AUTH_DATA_LEN);
close (randomFd);
if (bytes != AUTH_DATA_LEN)
{
ErrorF ("Failed to read %d random bytes from " XBE_DEV_RANDOM "\n",
AUTH_DATA_LEN);
return FALSE;
}
auth.data = authData;
auth.data_length = AUTH_DATA_LEN;
file = fdopen (authFd, "w");
if (!file)
{
ErrorF ("Failed to open authorization file: %s\n", name);
close (authFd);
return FALSE;
}
XauWriteAuth (file, &auth);
fclose (file);
return TRUE;
}
char *
dmxLaunchDisplay (int argc, char *argv[], int index)
{
sighandler_t oldSigUsr1;
pid_t pid;
char *name;
char *auth[] = { "-auth", xbeAuthBuf };
char *defs[] = { "-nolisten", "tcp", "-screen",
"800/212x600/159x24" };
char *endArg = NULL;
int authFd;
int mask;
if (xbePid)
return xbeDisplay;
strcpy (xbeAuthBuf, xbeAuthTempl);
mask = umask (0077);
authFd = mkstemp (xbeAuthBuf);
umask (mask);
if (authFd == -1)
FatalError ("Failed to generate unique authorization file\n");
xbeAuth = xbeAuthBuf;
if (index && index < argc)
{
xbeProg = argv[index];
}
else
{
struct stat buf;
int i;
for (i = 0; i < sizeof (xbeProgs) / sizeof (char *); i++)
{
if (stat (xbeProgs[i], &buf) == 0)
{
xbeProg = xbeProgs[i];
break;
}
}
if (!xbeProg)
FatalError ("Can't find X server executable\n");
}
if (!dmxAddXbeArguments (&xbeProg, 1))
return 0;
if (!dmxAddXbeArguments (auth, sizeof (auth) / sizeof (char *)))
return 0;
if (index)
{
int i;
for (i = index + 1; i < argc; i++)
{
if (*argv[i] == ':')
{
xbeDisplay = argv[i];
break;
}
}
if (i >= argc)
if (!dmxAddXbeArguments (&xbeDisplay, 1))
return 0;
if (argc > index)
if (!dmxAddXbeArguments (&argv[index + 1], argc - index))
return 0;
}
else
{
if (!dmxAddXbeArguments (&xbeDisplay, 1))
return 0;
if (!dmxAddXbeArguments (defs, sizeof (defs) / sizeof (char *)))
return 0;
}
if (!dmxAddXbeArguments (&endArg, 1))
return 0;
name = basename (xbeProg);
if (!dmxSetupAuth (xbeAuth, authFd))
FatalError ("Failed to set up authorization: %s\n", xbeAuth);
oldSigUsr1 = signal (SIGUSR1, sigUsr1Waiting);
pid = fork ();
switch (pid) {
case -1:
perror ("fork");
FatalError ("fork");
break;
case 0:
signal (SIGUSR1, SIG_IGN);
execv (xbeArgv[0], xbeArgv);
perror (xbeArgv[0]);
exit (2);
break;
default:
xbePid = pid;
break;
}
for (;;)
{
int status;
signal (SIGUSR1, sigUsr1Waiting);
if (setjmp (jumpbuf))
break;
signal (SIGUSR1, sigUsr1Jump);
if (receivedUsr1)
break;
if (waitpid (xbePid, &status, 0) != -1)
{
if (WIFEXITED (status))
{
FatalError ("%s died, exit status %d\n", name,
WEXITSTATUS (status));
}
else if (WIFSIGNALED (status))
FatalError ("%s died, signal %d\n", name, WTERMSIG (status));
else
FatalError ("%s died, dubious exit\n", name);
}
}
signal (SIGUSR1, oldSigUsr1);
setenv ("XAUTHORITY", xbeAuth, 1);
return xbeDisplay;
}

32
hw/dmx/dmxlaunch.h Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright © 2008 Novell, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Novell, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* Novell, Inc. makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Authors: David Reveman <davidr@novell.com>
*/
#ifndef DMXLAUNCH_H
#define DMXLAUNCH_H
extern char *dmxLaunchDisplay (int argc, char *argv[], int index);
extern void dmxAbortDisplay (void);
#endif /* DMXLAUNCH_H */

View file

@ -130,6 +130,245 @@ void dmxResetRender(void)
ProcRenderVector[i] = dmxSaveRenderVector[i];
}
static int
dmxVisualDepth (ScreenPtr pScreen, VisualPtr pVisual)
{
DepthPtr pDepth;
int d, v;
for (d = 0; d < pScreen->numDepths; d++)
{
pDepth = &pScreen->allowedDepths[d];
for (v = 0; v < pDepth->numVids; v++)
if (pDepth->vids[v] == pVisual->vid)
return pDepth->depth;
}
return 0;
}
typedef struct _dmxformatInit {
CARD32 format;
CARD8 depth;
} dmxFormatInitRec, *dmxFormatInitPtr;
static int
dmxAddFormat (dmxFormatInitPtr formats,
int nformat,
CARD32 format,
CARD8 depth)
{
int n;
for (n = 0; n < nformat; n++)
if (formats[n].format == format && formats[n].depth == depth)
return nformat;
formats[nformat].format = format;
formats[nformat].depth = depth;
return ++nformat;
}
#define Mask(n) ((n) == 32 ? 0xffffffff : ((1 << (n)) - 1))
static PictFormatPtr
dmxCreateDefaultFormats (ScreenPtr pScreen, int *nformatp)
{
int f, nformats = 0;
PictFormatPtr pFormats;
dmxFormatInitRec formats[64];
CARD32 format;
CARD8 depth;
VisualPtr pVisual;
int v;
int bpp;
int r, g, b;
int d;
DepthPtr pDepth;
/* formats required by protocol */
formats[nformats].format = PICT_a1;
formats[nformats].depth = 1;
nformats++;
formats[nformats].format = PICT_a4;
formats[nformats].depth = 4;
nformats++;
formats[nformats].format = PICT_a8;
formats[nformats].depth = 8;
nformats++;
formats[nformats].format = PICT_a8r8g8b8;
formats[nformats].depth = 32;
nformats++;
/* now look through the depths and visuals adding other formats */
for (v = 0; v < pScreen->numVisuals; v++)
{
pVisual = &pScreen->visuals[v];
depth = dmxVisualDepth (pScreen, pVisual);
if (!depth || depth == 32)
continue;
bpp = BitsPerPixel (depth);
switch (pVisual->class) {
case DirectColor:
case TrueColor:
r = Ones (pVisual->redMask);
g = Ones (pVisual->greenMask);
b = Ones (pVisual->blueMask);
if (pVisual->offsetBlue == 0 &&
pVisual->offsetGreen == b &&
pVisual->offsetRed == b + g)
{
format = PICT_FORMAT (bpp, PICT_TYPE_ARGB, 0, r, g, b);
nformats = dmxAddFormat (formats, nformats, format, depth);
}
break;
case StaticColor:
case PseudoColor:
case StaticGray:
case GrayScale:
break;
}
}
/*
* Walk supported depths and add useful Direct formats
*/
for (d = 0; d < 0; d++)
{
pDepth = &pScreen->allowedDepths[d];
bpp = BitsPerPixel (pDepth->depth);
format = 0;
switch (bpp) {
case 16:
/* depth 12 formats */
if (pDepth->depth >= 12)
{
nformats = dmxAddFormat (formats, nformats,
PICT_x4r4g4b4, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_x4b4g4r4, pDepth->depth);
}
/* depth 15 formats */
if (pDepth->depth >= 15)
{
nformats = dmxAddFormat (formats, nformats,
PICT_x1r5g5b5, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_x1b5g5r5, pDepth->depth);
}
/* depth 16 formats */
if (pDepth->depth >= 16)
{
nformats = dmxAddFormat (formats, nformats,
PICT_a1r5g5b5, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_a1b5g5r5, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_r5g6b5, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_b5g6r5, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_a4r4g4b4, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_a4b4g4r4, pDepth->depth);
}
break;
case 24:
if (pDepth->depth >= 24)
{
nformats = dmxAddFormat (formats, nformats,
PICT_r8g8b8, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_b8g8r8, pDepth->depth);
}
break;
case 32:
if (pDepth->depth >= 24)
{
nformats = dmxAddFormat (formats, nformats,
PICT_x8r8g8b8, pDepth->depth);
nformats = dmxAddFormat (formats, nformats,
PICT_x8b8g8r8, pDepth->depth);
}
break;
}
}
pFormats = (PictFormatPtr) xalloc (nformats * sizeof (PictFormatRec));
if (!pFormats)
return 0;
memset (pFormats, '\0', nformats * sizeof (PictFormatRec));
for (f = 0; f < nformats; f++)
{
pFormats[f].id = FakeClientID (0);
pFormats[f].depth = formats[f].depth;
format = formats[f].format;
pFormats[f].format = format;
switch (PICT_FORMAT_TYPE(format)) {
case PICT_TYPE_ARGB:
pFormats[f].type = PictTypeDirect;
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
if (pFormats[f].direct.alphaMask)
pFormats[f].direct.alpha = (PICT_FORMAT_R(format) +
PICT_FORMAT_G(format) +
PICT_FORMAT_B(format));
pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
pFormats[f].direct.red = (PICT_FORMAT_G(format) +
PICT_FORMAT_B(format));
pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
pFormats[f].direct.green = PICT_FORMAT_B(format);
pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
pFormats[f].direct.blue = 0;
break;
case PICT_TYPE_ABGR:
pFormats[f].type = PictTypeDirect;
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
if (pFormats[f].direct.alphaMask)
pFormats[f].direct.alpha = (PICT_FORMAT_B(format) +
PICT_FORMAT_G(format) +
PICT_FORMAT_R(format));
pFormats[f].direct.blueMask = Mask(PICT_FORMAT_B(format));
pFormats[f].direct.blue = (PICT_FORMAT_G(format) +
PICT_FORMAT_R(format));
pFormats[f].direct.greenMask = Mask(PICT_FORMAT_G(format));
pFormats[f].direct.green = PICT_FORMAT_R(format);
pFormats[f].direct.redMask = Mask(PICT_FORMAT_R(format));
pFormats[f].direct.red = 0;
break;
case PICT_TYPE_A:
pFormats[f].type = PictTypeDirect;
pFormats[f].direct.alpha = 0;
pFormats[f].direct.alphaMask = Mask(PICT_FORMAT_A(format));
/* remaining fields already set to zero */
break;
case PICT_TYPE_COLOR:
case PICT_TYPE_GRAY:
pFormats[f].type = PictTypeIndexed;
pFormats[f].index.vid = pScreen->visuals[PICT_FORMAT_VIS(format)].vid;
break;
}
}
*nformatp = nformats;
return pFormats;
}
/** Initialize the RENDER extension, allocate the picture privates and
* wrap mi function hooks. If the shadow frame buffer is used, then
* call the appropriate fb initialization function. */
@ -138,8 +377,12 @@ Bool dmxPictureInit(ScreenPtr pScreen, PictFormatPtr formats, int nformats)
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps;
/* The shadow framebuffer only relies on FB to be initialized */
if (dmxShadowFB) return fbPictureInit(pScreen, formats, nformats);
if (!formats)
{
formats = dmxCreateDefaultFormats (pScreen, &nformats);
if (!formats)
return FALSE;
}
if (!miPictureInit(pScreen, formats, nformats))
return FALSE;
@ -184,7 +427,10 @@ static XRenderPictFormat *dmxFindFormat(DMXScreenInfo *dmxScreen,
if (!pFmt || !dmxScreen->beDisplay) return pFormat;
while (1) {
pFormat = NULL;
XLIB_PROLOGUE (dmxScreen);
pFormat = XRenderFindFormat(dmxScreen->beDisplay, 0, 0, i++);
XLIB_EPILOGUE (dmxScreen);
if (!pFormat) break;
if (pFormat->type != pFmt->type) continue;
@ -213,7 +459,9 @@ Bool dmxBEFreeGlyphSet(ScreenPtr pScreen, GlyphSetPtr glyphSet)
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
if (glyphPriv->glyphSets[idx]) {
XLIB_PROLOGUE (dmxScreen);
XRenderFreeGlyphSet(dmxScreen->beDisplay, glyphPriv->glyphSets[idx]);
XLIB_EPILOGUE (dmxScreen);
glyphPriv->glyphSets[idx] = (GlyphSet)0;
return TRUE;
}
@ -235,12 +483,16 @@ int dmxBECreateGlyphSet(int idx, GlyphSetPtr glyphSet)
return BadMatch;
}
glyphPriv->glyphSets[idx] = None;
dmxGlyphLastError = 0;
oldErrorHandler = XSetErrorHandler(dmxGlyphErrorHandler);
/* Catch when this fails */
XLIB_PROLOGUE (dmxScreen);
glyphPriv->glyphSets[idx]
= XRenderCreateGlyphSet(dmxScreen->beDisplay, pFormat);
XLIB_EPILOGUE (dmxScreen);
XSetErrorHandler(oldErrorHandler);
@ -376,6 +628,8 @@ static int dmxProcRenderAddGlyphs(ClientPtr client)
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
XRenderAddGlyphs(dmxScreen->beDisplay,
glyphPriv->glyphSets[i],
gidsCopy,
@ -383,6 +637,7 @@ static int dmxProcRenderAddGlyphs(ClientPtr client)
nglyphs,
(char *)bits,
nbytes);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
@ -418,8 +673,10 @@ static int dmxProcRenderFreeGlyphs(ClientPtr client)
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
XRenderFreeGlyphs(dmxScreen->beDisplay,
glyphPriv->glyphSets[i], gids, nglyphs);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
@ -578,6 +835,8 @@ static int dmxProcRenderCompositeGlyphs(ClientPtr client)
}
}
XLIB_PROLOGUE (dmxScreen);
switch (stuff->renderReqType) {
case X_RenderCompositeGlyphs8:
XRenderCompositeText8(dmxScreen->beDisplay, stuff->op,
@ -602,6 +861,8 @@ static int dmxProcRenderCompositeGlyphs(ClientPtr client)
break;
}
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
xfree(elts);
@ -627,24 +888,29 @@ static int dmxProcRenderSetPictureTransform(ClientPtr client)
/* For the following to work with PanoramiX, it assumes that Render
* wraps the ProcRenderVector after dmxRenderInit has been called.
*/
dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
pPictPriv = DMX_GET_PICT_PRIV(pPicture);
if (pPicture->pDrawable)
{
dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
pPictPriv = DMX_GET_PICT_PRIV(pPicture);
if (pPictPriv->pict) {
xform.matrix[0][0] = stuff->transform.matrix11;
xform.matrix[0][1] = stuff->transform.matrix12;
xform.matrix[0][2] = stuff->transform.matrix13;
xform.matrix[1][0] = stuff->transform.matrix21;
xform.matrix[1][1] = stuff->transform.matrix22;
xform.matrix[1][2] = stuff->transform.matrix23;
xform.matrix[2][0] = stuff->transform.matrix31;
xform.matrix[2][1] = stuff->transform.matrix32;
xform.matrix[2][2] = stuff->transform.matrix33;
if (pPictPriv->pict) {
xform.matrix[0][0] = stuff->transform.matrix11;
xform.matrix[0][1] = stuff->transform.matrix12;
xform.matrix[0][2] = stuff->transform.matrix13;
xform.matrix[1][0] = stuff->transform.matrix21;
xform.matrix[1][1] = stuff->transform.matrix22;
xform.matrix[1][2] = stuff->transform.matrix23;
xform.matrix[2][0] = stuff->transform.matrix31;
xform.matrix[2][1] = stuff->transform.matrix32;
xform.matrix[2][2] = stuff->transform.matrix33;
XRenderSetPictureTransform(dmxScreen->beDisplay,
pPictPriv->pict,
&xform);
dmxSync(dmxScreen, FALSE);
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureTransform(dmxScreen->beDisplay,
pPictPriv->pict,
&xform);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
return dmxSaveRenderVector[stuff->renderReqType](client);
@ -668,20 +934,31 @@ static int dmxProcRenderSetPictureFilter(ClientPtr client)
/* For the following to work with PanoramiX, it assumes that Render
* wraps the ProcRenderVector after dmxRenderInit has been called.
*/
dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
pPictPriv = DMX_GET_PICT_PRIV(pPicture);
if (pPicture->pDrawable)
{
dmxScreen = &dmxScreens[pPicture->pDrawable->pScreen->myNum];
pPictPriv = DMX_GET_PICT_PRIV(pPicture);
if (pPictPriv->pict) {
filter = (char *)(stuff + 1);
params = (XFixed *)(filter + ((stuff->nbytes + 3) & ~3));
nparams = ((XFixed *)stuff + client->req_len) - params;
if (pPictPriv->pict)
{
char name[256];
XRenderSetPictureFilter(dmxScreen->beDisplay,
pPictPriv->pict,
filter,
params,
nparams);
dmxSync(dmxScreen, FALSE);
filter = (char *)(stuff + 1);
params = (XFixed *)(filter + ((stuff->nbytes + 3) & ~3));
nparams = ((XFixed *)stuff + client->req_len) - params;
strncpy (name, filter, stuff->nbytes);
name[stuff->nbytes] = '\0';
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureFilter(dmxScreen->beDisplay,
pPictPriv->pict,
name,
params,
nparams);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
return dmxSaveRenderVector[stuff->renderReqType](client);
@ -698,9 +975,10 @@ static Picture dmxDoCreatePicture(PicturePtr pPicture)
ScreenPtr pScreen = pDraw->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
XRenderPictFormat *pFormat;
Drawable draw;
Drawable draw;
Picture pict = 0;
if (pPicture->pDrawable->type == DRAWABLE_WINDOW) {
if (pDraw->type == DRAWABLE_WINDOW) {
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV((WindowPtr)(pDraw));
if (!(draw = pWinPriv->window)) {
@ -729,7 +1007,161 @@ static Picture dmxDoCreatePicture(PicturePtr pPicture)
pFormat = dmxFindFormat(dmxScreen, pPicture->pFormat);
return XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0);
XLIB_PROLOGUE (dmxScreen);
pict = XRenderCreatePicture(dmxScreen->beDisplay, draw, pFormat, 0, 0);
XLIB_EPILOGUE (dmxScreen);
return pict;
}
static int
dmxGetSourceStops (SourcePictPtr pSourcePict,
XFixed **stops,
XRenderColor **colors)
{
if (pSourcePict->gradient.nstops)
{
int i;
*stops = xalloc (pSourcePict->gradient.nstops * sizeof (XFixed));
*colors = xalloc (pSourcePict->gradient.nstops *
sizeof (XRenderColor));
for (i = 0; i < pSourcePict->gradient.nstops; i++)
{
(*stops)[i] = pSourcePict->gradient.stops[i].x;
(*colors)[i].red = pSourcePict->gradient.stops[i].color.red;
(*colors)[i].green = pSourcePict->gradient.stops[i].color.green;
(*colors)[i].blue = pSourcePict->gradient.stops[i].color.blue;
(*colors)[i].alpha = pSourcePict->gradient.stops[i].color.alpha;
}
}
else
{
*stops = NULL;
*colors = NULL;
}
return pSourcePict->gradient.nstops;
}
static Picture
dmxDoCreateSourcePicture (ScreenPtr pScreen,
PicturePtr pPicture)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
Picture pict = None;
if (pPicture->pSourcePict)
{
SourcePictPtr pSourcePict = pPicture->pSourcePict;
XFixed *stops = NULL;
XRenderColor *colors = NULL;
int nstops = 0;
if (!dmxScreen->beDisplay)
return 0;
switch (pSourcePict->type) {
case SourcePictTypeSolidFill: {
XRenderColor c;
c.alpha = (pSourcePict->solidFill.color & 0xff000000) >> 16;
c.red = (pSourcePict->solidFill.color & 0x00ff0000) >> 8;
c.green = (pSourcePict->solidFill.color & 0x0000ff00) >> 0;
c.blue = (pSourcePict->solidFill.color & 0x000000ff) << 8;
XLIB_PROLOGUE (dmxScreen);
pict = XRenderCreateSolidFill (dmxScreen->beDisplay, &c);
XLIB_EPILOGUE (dmxScreen);
} break;
case SourcePictTypeLinear: {
XLinearGradient l;
l.p1.x = pSourcePict->linear.p1.x;
l.p1.y = pSourcePict->linear.p1.y;
l.p2.x = pSourcePict->linear.p2.x;
l.p2.y = pSourcePict->linear.p2.y;
nstops = dmxGetSourceStops (pSourcePict, &stops, &colors);
XLIB_PROLOGUE (dmxScreen);
pict = XRenderCreateLinearGradient (dmxScreen->beDisplay, &l,
stops, colors, nstops);
XLIB_EPILOGUE (dmxScreen);
} break;
case SourcePictTypeRadial: {
XRadialGradient r;
r.inner.x = pSourcePict->radial.c1.x;
r.inner.y = pSourcePict->radial.c1.y;
r.inner.radius = pSourcePict->radial.c1.radius;
r.outer.x = pSourcePict->radial.c2.x;
r.outer.y = pSourcePict->radial.c2.y;
r.outer.radius = pSourcePict->radial.c2.radius;
nstops = dmxGetSourceStops (pSourcePict, &stops, &colors);
XLIB_PROLOGUE (dmxScreen);
pict = XRenderCreateRadialGradient (dmxScreen->beDisplay, &r,
stops, colors, nstops);
XLIB_EPILOGUE (dmxScreen);
} break;
case SourcePictTypeConical: {
XConicalGradient c;
c.center.x = pSourcePict->conical.center.x;
c.center.y = pSourcePict->conical.center.y;
c.angle = pSourcePict->conical.angle;
nstops = dmxGetSourceStops (pSourcePict, &stops, &colors);
XLIB_PROLOGUE (dmxScreen);
pict = XRenderCreateConicalGradient (dmxScreen->beDisplay, &c,
stops, colors, nstops);
XLIB_EPILOGUE (dmxScreen);
} break;
}
if (nstops)
{
xfree (stops);
xfree (colors);
}
if (pict)
{
if (pPicture->repeatType != RepeatNone)
{
XRenderPictureAttributes attrib;
attrib.repeat = pPicture->repeatType;
XLIB_PROLOGUE (dmxScreen);
XRenderChangePicture (dmxScreen->beDisplay, pict, CPRepeat,
&attrib);
XLIB_EPILOGUE (dmxScreen);
}
if (pPicture->transform)
{
XTransform transform;
int i, j;
for (i = 0; i < 3; i++)
for (j = 0; j < 3; j++)
transform.matrix[i][j] =
pPicture->transform->matrix[i][j];
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureTransform (dmxScreen->beDisplay, pict,
&transform);
XLIB_EPILOGUE (dmxScreen);
}
}
}
return pict;
}
/** Create a list of pictures. This function is called by
@ -784,7 +1216,7 @@ int dmxCreatePicture(PicturePtr pPicture)
#endif
/* Create picture on back-end server */
pPictPriv->pict = dmxDoCreatePicture(pPicture);
pPictPriv->pict = dmxDoCreatePicture(pPicture);
pPictPriv->savedMask = 0;
DMX_WRAP(CreatePicture, dmxCreatePicture, dmxScreen, ps);
@ -800,7 +1232,9 @@ Bool dmxBEFreePicture(PicturePtr pPicture)
dmxPictPrivPtr pPictPriv = DMX_GET_PICT_PRIV(pPicture);
if (pPictPriv->pict) {
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture(dmxScreen->beDisplay, pPictPriv->pict);
XLIB_EPILOGUE (dmxScreen);
pPictPriv->pict = (Picture)0;
return TRUE;
}
@ -868,8 +1302,10 @@ int dmxChangePictureClip(PicturePtr pPicture, int clipType,
*/
if (clipType == CT_NONE) {
/* Disable clipping, show all */
XLIB_PROLOGUE (dmxScreen);
XFixesSetPictureClipRegion(dmxScreen->beDisplay,
pPictPriv->pict, 0, 0, None);
XLIB_EPILOGUE (dmxScreen);
} else if (pPicture->clientClip) {
RegionPtr pClip = pPicture->clientClip;
BoxPtr pBox = REGION_RECTS(pClip);
@ -890,16 +1326,20 @@ int dmxChangePictureClip(PicturePtr pPicture, int clipType,
pRect++;
}
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
0, 0,
pRects,
nRects);
XLIB_EPILOGUE (dmxScreen);
xfree(pRects);
} else {
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
0, 0, NULL, 0);
XLIB_EPILOGUE (dmxScreen);
}
dmxSync(dmxScreen, FALSE);
} else {
@ -927,9 +1367,11 @@ void dmxDestroyPictureClip(PicturePtr pPicture)
/* Destroy picture clip rects on back-end server */
if (pPictPriv->pict) {
XLIB_PROLOGUE (dmxScreen);
XRenderSetPictureClipRectangles(dmxScreen->beDisplay,
pPictPriv->pict,
0, 0, NULL, 0);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
} else {
/* FIXME: Handle destroying clip region when offscreen */
@ -973,6 +1415,9 @@ void dmxValidatePicture(PicturePtr pPicture, Mask mask)
DMX_UNWRAP(ValidatePicture, dmxScreen, ps);
if (!pPictPriv->pict && pPicture->pSourcePict)
pPictPriv->pict = dmxDoCreatePicture (pPicture);
/* Change picture attributes on back-end server */
if (pPictPriv->pict) {
XRenderPictureAttributes attribs;
@ -1017,8 +1462,10 @@ void dmxValidatePicture(PicturePtr pPicture, Mask mask)
if (mask & CPComponentAlpha)
attribs.component_alpha = pPicture->componentAlpha;
XLIB_PROLOGUE (dmxScreen);
XRenderChangePicture(dmxScreen->beDisplay, pPictPriv->pict,
mask, &attribs);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
} else {
pPictPriv->savedMask |= mask;
@ -1047,11 +1494,22 @@ void dmxComposite(CARD8 op,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pMaskPriv = NULL;
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
Picture src = None;
Picture mask = None;
if (pMask) pMaskPriv = DMX_GET_PICT_PRIV(pMask);
if (pSrc->pDrawable)
src = (DMX_GET_PICT_PRIV (pSrc))->pict;
else
src = dmxDoCreateSourcePicture (pScreen, pSrc);
if (pMask)
{
if (pMask->pDrawable)
mask = (DMX_GET_PICT_PRIV (pMask))->pict;
else
mask = dmxDoCreateSourcePicture (pScreen, pMask);
}
DMX_UNWRAP(Composite, dmxScreen, ps);
#if 0
@ -1062,20 +1520,35 @@ void dmxComposite(CARD8 op,
#endif
/* Composite on back-end server */
if (pSrcPriv->pict && pDstPriv->pict &&
((pMaskPriv && pMaskPriv->pict) || !pMaskPriv)) {
if (src && pDstPriv->pict)
{
XLIB_PROLOGUE (dmxScreen);
XRenderComposite(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
pMaskPriv ? pMaskPriv->pict : None,
src,
mask,
pDstPriv->pict,
xSrc, ySrc,
xMask, yMask,
xDst, yDst,
width, height);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
if (!pSrc->pDrawable && src)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, src);
XLIB_EPILOGUE (dmxScreen);
}
if (pMask && !pMask->pDrawable && mask)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, mask);
XLIB_EPILOGUE (dmxScreen);
}
DMX_WRAP(Composite, dmxComposite, dmxScreen, ps);
}
@ -1114,12 +1587,14 @@ void dmxCompositeRects(CARD8 op,
/* CompositeRects on back-end server */
if (pPictPriv->pict) {
XLIB_PROLOGUE (dmxScreen);
XRenderFillRectangles(dmxScreen->beDisplay,
op,
pPictPriv->pict,
(XRenderColor *)color,
(XRectangle *)rects,
nRect);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
@ -1154,8 +1629,8 @@ void dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
Picture src = None;
DMX_UNWRAP(Trapezoids, dmxScreen, ps);
#if 0
@ -1163,6 +1638,11 @@ void dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ps->Trapezoids(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntrap, *traps);
#endif
if (pSrc->pDrawable)
src = (DMX_GET_PICT_PRIV (pSrc))->pict;
else
src = dmxDoCreateSourcePicture (pScreen, pSrc);
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
@ -1172,17 +1652,26 @@ void dmxTrapezoids(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
/* FIXME: Error! */
}
XLIB_PROLOGUE (dmxScreen);
XRenderCompositeTrapezoids(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
src,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XTrapezoid *)traps,
ntrap);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
if (!pSrc->pDrawable && src)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, src);
XLIB_EPILOGUE (dmxScreen);
}
DMX_WRAP(Trapezoids, dmxTrapezoids, dmxScreen, ps);
}
@ -1197,8 +1686,8 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
Picture src = None;
DMX_UNWRAP(Triangles, dmxScreen, ps);
#if 0
@ -1206,6 +1695,11 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ps->Triangles(op, pSrc, pDst, maskFormat, xSrc, ySrc, ntri, *tris);
#endif
if (pSrc->pDrawable)
src = (DMX_GET_PICT_PRIV (pSrc))->pict;
else
src = dmxDoCreateSourcePicture (pScreen, pSrc);
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
@ -1215,17 +1709,26 @@ void dmxTriangles(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
/* FIXME: Error! */
}
XLIB_PROLOGUE (dmxScreen);
XRenderCompositeTriangles(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
src,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XTriangle *)tris,
ntri);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
if (!pSrc->pDrawable && src)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, src);
XLIB_EPILOGUE (dmxScreen);
}
DMX_WRAP(Triangles, dmxTriangles, dmxScreen, ps);
}
@ -1240,8 +1743,8 @@ void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
Picture src = None;
DMX_UNWRAP(TriStrip, dmxScreen, ps);
#if 0
@ -1249,6 +1752,11 @@ void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ps->TriStrip(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif
if (pSrc->pDrawable)
src = (DMX_GET_PICT_PRIV (pSrc))->pict;
else
src = dmxDoCreateSourcePicture (pScreen, pSrc);
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
@ -1258,17 +1766,26 @@ void dmxTriStrip(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
/* FIXME: Error! */
}
XLIB_PROLOGUE (dmxScreen);
XRenderCompositeTriStrip(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
src,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
if (!pSrc->pDrawable && src)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, src);
XLIB_EPILOGUE (dmxScreen);
}
DMX_WRAP(TriStrip, dmxTriStrip, dmxScreen, ps);
}
@ -1282,8 +1799,8 @@ void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ScreenPtr pScreen = pDst->pDrawable->pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PictureScreenPtr ps = GetPictureScreen(pScreen);
dmxPictPrivPtr pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
dmxPictPrivPtr pDstPriv = DMX_GET_PICT_PRIV(pDst);
Picture src = None;
DMX_UNWRAP(TriFan, dmxScreen, ps);
#if 0
@ -1291,6 +1808,11 @@ void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
ps->TriFan(op, pSrc, pDst, maskFormat, xSrc, ySrc, npoint, *points);
#endif
if (pSrc->pDrawable)
src = (DMX_GET_PICT_PRIV (pSrc))->pict;
else
src = dmxDoCreateSourcePicture (pScreen, pSrc);
/* Draw trapezoids on back-end server */
if (pDstPriv->pict) {
XRenderPictFormat *pFormat;
@ -1300,16 +1822,25 @@ void dmxTriFan(CARD8 op, PicturePtr pSrc, PicturePtr pDst,
/* FIXME: Error! */
}
XLIB_PROLOGUE (dmxScreen);
XRenderCompositeTriFan(dmxScreen->beDisplay,
op,
pSrcPriv->pict,
src,
pDstPriv->pict,
pFormat,
xSrc, ySrc,
(XPointFixed *)points,
npoint);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
if (!pSrc->pDrawable && src)
{
XLIB_PROLOGUE (dmxScreen);
XRenderFreePicture (dmxScreen->beDisplay, src);
XLIB_EPILOGUE (dmxScreen);
}
DMX_WRAP(TriFan, dmxTriFan, dmxScreen, ps);
}

View file

@ -70,11 +70,14 @@ void dmxBECreatePixmap(PixmapPtr pPixmap)
return;
if (pPixmap->drawable.width && pPixmap->drawable.height) {
pPixPriv->pixmap = None;
XLIB_PROLOGUE (dmxScreen);
pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay,
dmxScreen->scrnWin,
pPixmap->drawable.width,
pPixmap->drawable.height,
pPixmap->drawable.depth);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}
}
@ -142,7 +145,9 @@ Bool dmxBEFreePixmap(PixmapPtr pPixmap)
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
if (pPixPriv->pixmap) {
XLIB_PROLOGUE (dmxScreen);
XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap);
XLIB_EPILOGUE (dmxScreen);
pPixPriv->pixmap = (Pixmap)0;
return TRUE;
}
@ -150,6 +155,15 @@ Bool dmxBEFreePixmap(PixmapPtr pPixmap)
return FALSE;
}
static Bool FoundPix = False;
static void findPixmap (pointer value, XID id, RESTYPE type, pointer p)
{
if ((type & TypeMask) == (RT_PIXMAP & TypeMask))
if ((PixmapPtr) p == (PixmapPtr) value)
FoundPix = True;
}
/** Destroy the pixmap pointed to by \a pPixmap. */
Bool dmxDestroyPixmap(PixmapPtr pPixmap)
{
@ -162,8 +176,45 @@ Bool dmxDestroyPixmap(PixmapPtr pPixmap)
#endif
if (--pPixmap->refcnt)
{
int i;
return TRUE;
FoundPix = False;
for (i = currentMaxClients; --i >= 0; )
if (clients[i])
FindAllClientResources (clients[i], findPixmap,
(pointer) pPixmap);
if (!FoundPix)
{
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV (pPixmap);
if (!pPixPriv->detachedImage)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
pPixPriv->detachedImage = NULL;
XLIB_PROLOGUE (dmxScreen);
pPixPriv->detachedImage = XGetImage(dmxScreen->beDisplay,
pPixPriv->pixmap,
0, 0,
pPixmap->drawable.width,
pPixmap->drawable.height,
-1,
ZPixmap);
XLIB_EPILOGUE (dmxScreen);
if (!pPixPriv->detachedImage)
ErrorF ("Cannot save pixmap image\n");
}
}
return TRUE;
}
/* Destroy pixmap on back-end server */
if (dmxScreen->beDisplay) {
if (dmxBEFreePixmap(pPixmap)) {
@ -193,7 +244,7 @@ RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap)
ScreenPtr pScreen = pPixmap->drawable.pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap);
XImage *ximage;
XImage *ximage = NULL;
RegionPtr pReg, pTmpReg;
int x, y;
unsigned long previousPixel, currentPixel;
@ -205,9 +256,13 @@ RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap)
return pReg;
}
XLIB_PROLOGUE (dmxScreen);
ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0,
pPixmap->drawable.width, pPixmap->drawable.height,
1, XYPixmap);
XLIB_EPILOGUE (dmxScreen);
if (!ximage)
return NullRegion;
pReg = REGION_CREATE(pScreen, NullBox, 1);
pTmpReg = REGION_CREATE(pScreen, NullBox, 1);

File diff suppressed because it is too large Load diff

View file

@ -54,6 +54,7 @@ void dmxShadowUpdateProc(ScreenPtr pScreen, shadowBufPtr pBuf)
if (!dmxScreen->beDisplay)
return;
XLIB_PROLOGUE (dmxScreen);
while (nbox--) {
XPutImage(dmxScreen->beDisplay,
dmxScreen->scrnWin,
@ -66,6 +67,7 @@ void dmxShadowUpdateProc(ScreenPtr pScreen, shadowBufPtr pBuf)
pbox++;
}
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
}

View file

@ -54,6 +54,7 @@
#include "dmxsync.h"
#include "dmxstat.h"
#include "dmxlog.h"
#include "dmxextension.h"
#include <sys/time.h>
static int dmxSyncInterval = 100; /* Default interval in milliseconds */
@ -68,12 +69,16 @@ static void dmxDoSync(DMXScreenInfo *dmxScreen)
return; /* FIXME: Is this correct behavior for sync stats? */
if (!dmxStatInterval) {
XSync(dmxScreen->beDisplay, False);
XLIB_PROLOGUE (dmxScreen);
XSync (dmxScreen->beDisplay, False);
XLIB_EPILOGUE (dmxScreen);
} else {
struct timeval start, stop;
gettimeofday(&start, 0);
XLIB_PROLOGUE (dmxScreen);
XSync(dmxScreen->beDisplay, False);
XLIB_EPILOGUE (dmxScreen);
gettimeofday(&stop, 0);
dmxStatSync(dmxScreen, &stop, &start, dmxSyncPending);
}
@ -81,7 +86,7 @@ static void dmxDoSync(DMXScreenInfo *dmxScreen)
static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
{
int i;
int i;
if (dmxSyncPending) {
for (i = 0; i < dmxNumScreens; i++) {
@ -93,15 +98,38 @@ static CARD32 dmxSyncCallback(OsTimerPtr timer, CARD32 time, pointer arg)
return 0; /* Do not place on queue again */
}
static void dmxCheckScreens (void)
{
int i;
for (i = 0; i < dmxNumScreens; i++)
{
if (dmxScreens[i].beDisplay && !dmxScreens[i].alive)
{
if (i)
{
dmxLog (dmxInfo, "display dead, lets detach it\n");
dmxDetachScreen (i);
}
else
{
dmxLog (dmxFatal, "Default display dead, giving up...\n");
}
}
}
}
static void dmxSyncBlockHandler(pointer blockData, OSTimePtr pTimeout,
pointer pReadMask)
{
TimerForce(dmxSyncTimer);
if (dmxSyncInterval)
TimerForce(dmxSyncTimer);
}
static void dmxSyncWakeupHandler(pointer blockData, int result,
pointer pReadMask)
{
dmxCheckScreens ();
}
/** Request the XSync() batching optimization with the specified \a
@ -123,10 +151,11 @@ void dmxSyncActivate(const char *interval)
* #dmxSyncActivate was last called with a non-negative value. */
void dmxSyncInit(void)
{
RegisterBlockAndWakeupHandlers (dmxSyncBlockHandler,
dmxSyncWakeupHandler,
NULL);
if (dmxSyncInterval) {
RegisterBlockAndWakeupHandlers(dmxSyncBlockHandler,
dmxSyncWakeupHandler,
NULL);
dmxLog(dmxInfo, "XSync batching with %d ms interval\n",
dmxSyncInterval);
} else {

View file

@ -93,7 +93,7 @@ Visual *dmxLookupVisual(ScreenPtr pScreen, VisualPtr pVisual)
for (i = 0; i < dmxScreen->beNumVisuals; i++) {
if (pVisual->class == dmxScreen->beVisuals[i].class &&
pVisual->bitsPerRGBValue == dmxScreen->beVisuals[i].bits_per_rgb &&
pVisual->ColormapEntries == dmxScreen->beVisuals[i].colormap_size &&
// pVisual->ColormapEntries == dmxScreen->beVisuals[i].colormap_size &&
pVisual->nplanes == dmxScreen->beVisuals[i].depth &&
pVisual->redMask == dmxScreen->beVisuals[i].red_mask &&
pVisual->greenMask == dmxScreen->beVisuals[i].green_mask &&

View file

@ -80,6 +80,7 @@ Window dmxCreateRootWindow(WindowPtr pWindow)
XSetWindowAttributes attribs;
ColormapPtr pCmap;
dmxColormapPrivPtr pCmapPriv;
Window win = None;
/* Create root window */
@ -90,7 +91,7 @@ Window dmxCreateRootWindow(WindowPtr pWindow)
pCmapPriv = DMX_GET_COLORMAP_PRIV(pCmap);
mask = CWEventMask | CWBackingStore | CWColormap | CWBorderPixel;
attribs.event_mask = ExposureMask;
attribs.event_mask = ExposureMask | FocusChangeMask;
attribs.backing_store = NotUseful;
attribs.colormap = pCmapPriv->cmap;
attribs.border_pixel = 0;
@ -101,18 +102,22 @@ Window dmxCreateRootWindow(WindowPtr pWindow)
mask |= pWinPriv->attribMask;
}
return XCreateWindow(dmxScreen->beDisplay,
parent,
pWindow->origin.x - wBorderWidth(pWindow),
pWindow->origin.y - wBorderWidth(pWindow),
pWindow->drawable.width,
pWindow->drawable.height,
pWindow->borderWidth,
pWindow->drawable.depth,
pWindow->drawable.class,
visual,
mask,
&attribs);
XLIB_PROLOGUE (dmxScreen);
win = XCreateWindow(dmxScreen->beDisplay,
parent,
pWindow->origin.x - wBorderWidth(pWindow),
pWindow->origin.y - wBorderWidth(pWindow),
pWindow->drawable.width,
pWindow->drawable.height,
pWindow->borderWidth,
pWindow->drawable.depth,
pWindow->drawable.class,
visual,
mask,
&attribs);
XLIB_EPILOGUE (dmxScreen);
return win;
}
/** Change the location and size of the "screen" window. Called from
@ -134,7 +139,9 @@ void dmxResizeScreenWindow(ScreenPtr pScreen,
c.width = w;
c.height = h;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, dmxScreen->scrnWin, m, &c);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -156,18 +163,28 @@ void dmxResizeRootWindow(WindowPtr pRoot,
c.width = (w > 0) ? w : 1;
c.height = (h > 0) ? h : 1;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
}
if (w == 0 || h == 0) {
if (pWinPriv->mapped) {
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
}
pWinPriv->mapped = FALSE;
}
} else if (!pWinPriv->mapped) {
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
}
pWinPriv->mapped = TRUE;
}
@ -215,6 +232,7 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
unsigned long mask = 0L;
XSetWindowAttributes attribs;
dmxWinPrivPtr pParentPriv = DMX_GET_WINDOW_PRIV(pWindow->parent);
Window win = None;
/* Create window on back-end server */
@ -228,6 +246,9 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
parent = pParentPriv->window;
}
mask |= CWEventMask;
attribs.event_mask = FocusChangeMask;
/* Incorporate new attributes, if needed */
if (pWinPriv->attribMask) {
dmxDoChangeWindowAttributes(pWindow, &pWinPriv->attribMask, &attribs);
@ -254,18 +275,22 @@ static Window dmxCreateNonRootWindow(WindowPtr pWindow)
be created on top of the stack, so we must restack the windows */
pWinPriv->restacked = (pWindow->prevSib != NullWindow);
return XCreateWindow(dmxScreen->beDisplay,
parent,
pWindow->origin.x - wBorderWidth(pWindow),
pWindow->origin.y - wBorderWidth(pWindow),
pWindow->drawable.width,
pWindow->drawable.height,
pWindow->borderWidth,
pWindow->drawable.depth,
pWindow->drawable.class,
pWinPriv->visual,
mask,
&attribs);
XLIB_PROLOGUE (dmxScreen);
win = XCreateWindow(dmxScreen->beDisplay,
parent,
pWindow->origin.x - wBorderWidth(pWindow),
pWindow->origin.y - wBorderWidth(pWindow),
pWindow->drawable.width,
pWindow->drawable.height,
pWindow->borderWidth,
pWindow->drawable.depth,
pWindow->drawable.class,
pWinPriv->visual,
mask,
&attribs);
XLIB_EPILOGUE (dmxScreen);
return win;
}
/** This function handles lazy window creation and realization. Window
@ -291,8 +316,12 @@ void dmxCreateAndRealizeWindow(WindowPtr pWindow, Bool doSync)
#ifdef RENDER
if (pWinPriv->hasPict) dmxCreatePictureList(pWindow);
#endif
if (pWinPriv->mapped) XMapWindow(dmxScreen->beDisplay,
pWinPriv->window);
if (pWinPriv->mapped && MapUnmapEventsEnabled (pWindow))
{
XLIB_PROLOGUE (dmxScreen);
XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
}
if (doSync) dmxSync(dmxScreen, False);
}
@ -318,6 +347,7 @@ Bool dmxCreateWindow(WindowPtr pWindow)
pWinPriv->offscreen = TRUE;
pWinPriv->mapped = FALSE;
pWinPriv->restacked = FALSE;
pWinPriv->redirected = FALSE;
pWinPriv->attribMask = 0;
pWinPriv->isShaped = FALSE;
#ifdef RENDER
@ -383,7 +413,9 @@ Bool dmxBEDestroyWindow(WindowPtr pWindow)
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV(pWindow);
if (pWinPriv->window) {
XLIB_PROLOGUE (dmxScreen);
XDestroyWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
pWinPriv->window = (Window)0;
return TRUE;
}
@ -464,7 +496,9 @@ Bool dmxPositionWindow(WindowPtr pWindow, int x, int y)
c.border_width = pWindow->borderWidth;
}
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -585,8 +619,10 @@ Bool dmxChangeWindowAttributes(WindowPtr pWindow, unsigned long mask)
pWinPriv->attribMask |= mask;
if (mask && pWinPriv->window) {
XLIB_PROLOGUE (dmxScreen);
XChangeWindowAttributes(dmxScreen->beDisplay, pWinPriv->window,
mask, &attribs);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -624,8 +660,43 @@ Bool dmxRealizeWindow(WindowPtr pWindow)
if (pWinPriv->window) {
/* Realize window on back-end server */
XLIB_PROLOGUE (dmxScreen);
XMapWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
if (pWinPriv->redirected)
{
PixmapPtr pPixmap;
pPixmap = (*pScreen->GetWindowPixmap) (pWindow);
if (pPixmap)
{
dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV (pPixmap);
XLIB_PROLOGUE (dmxScreen);
XCompositeRedirectWindow (dmxScreen->beDisplay,
pWinPriv->window,
CompositeRedirectManual);
XLIB_EPILOGUE (dmxScreen);
if (pPixPriv->pixmap)
{
XLIB_PROLOGUE (dmxScreen);
XFreePixmap (dmxScreen->beDisplay, pPixPriv->pixmap);
XLIB_EPILOGUE (dmxScreen);
pPixPriv->pixmap = None;
}
XLIB_PROLOGUE (dmxScreen);
pPixPriv->pixmap =
XCompositeNameWindowPixmap (dmxScreen->beDisplay,
pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
}
}
}
/* Let the other functions know that the window is now mapped */
@ -653,7 +724,9 @@ Bool dmxUnrealizeWindow(WindowPtr pWindow)
if (pWinPriv->window) {
/* Unrealize window on back-end server */
XLIB_PROLOGUE (dmxScreen);
XUnmapWindow(dmxScreen->beDisplay, pWinPriv->window);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -687,7 +760,9 @@ static void dmxDoRestackWindow(WindowPtr pWindow)
m = CWStackMode;
c.sibling = (Window)0;
c.stack_mode = Below;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
} else {
/* Window is not at the bottom of the stack */
dmxWinPrivPtr pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
@ -706,7 +781,9 @@ static void dmxDoRestackWindow(WindowPtr pWindow)
m = CWStackMode;
c.sibling = (Window)0;
c.stack_mode = Below;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
return;
}
pNextSibPriv = DMX_GET_WINDOW_PRIV(pNextSib);
@ -715,7 +792,9 @@ static void dmxDoRestackWindow(WindowPtr pWindow)
m = CWStackMode | CWSibling;
c.sibling = pNextSibPriv->window;
c.stack_mode = Above;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
}
}
@ -768,7 +847,9 @@ void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
dmxSync(dmxScreen, False);
if (pWinPriv->window) {
if (pWinPriv->window && dmxScreen->beDisplay) {
XLIB_PROLOGUE (dmxScreen);
while (XCheckIfEvent(dmxScreen->beDisplay, &ev,
dmxWindowExposurePredicate,
(XPointer)&pWinPriv->window)) {
@ -780,6 +861,7 @@ void dmxWindowExposures(WindowPtr pWindow, RegionPtr prgn,
collect these events and send them to the client later
(e.g., during the block handler as Xnest does). */
}
XLIB_EPILOGUE (dmxScreen);
}
#if 1
@ -822,7 +904,9 @@ void dmxCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
c.width = pWindow->drawable.width;
c.height = pWindow->drawable.height;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -868,7 +952,9 @@ void dmxResizeWindow(WindowPtr pWindow, int x, int y,
c.width = pWindow->drawable.width;
c.height = pWindow->drawable.height;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -896,10 +982,12 @@ void dmxReparentWindow(WindowPtr pWindow, WindowPtr pPriorParent)
}
/* Handle reparenting on back-end server */
XLIB_PROLOGUE (dmxScreen);
XReparentWindow(dmxScreen->beDisplay, pWinPriv->window,
pParentPriv->window,
pWindow->origin.x - wBorderWidth(pWindow),
pWindow->origin.x - wBorderWidth(pWindow));
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -929,7 +1017,9 @@ void dmxChangeBorderWidth(WindowPtr pWindow, unsigned int width)
m = CWBorderWidth;
c.border_width = width;
XLIB_PROLOGUE (dmxScreen);
XConfigureWindow(dmxScreen->beDisplay, pWinPriv->window, m, &c);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, False);
}
@ -960,14 +1050,18 @@ static void dmxDoSetShape(WindowPtr pWindow)
pBox++;
pRect++;
}
XLIB_PROLOGUE (dmxScreen);
XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
ShapeBounding, 0, 0,
pRectFirst, nRect,
ShapeSet, YXBanded);
XLIB_EPILOGUE (dmxScreen);
xfree(pRectFirst);
} else {
XLIB_PROLOGUE (dmxScreen);
XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
ShapeBounding, 0, 0, None, ShapeSet);
XLIB_EPILOGUE (dmxScreen);
}
/* Next, set the clip shape */
@ -983,20 +1077,26 @@ static void dmxDoSetShape(WindowPtr pWindow)
pBox++;
pRect++;
}
XLIB_PROLOGUE (dmxScreen);
XShapeCombineRectangles(dmxScreen->beDisplay, pWinPriv->window,
ShapeClip, 0, 0,
pRectFirst, nRect,
ShapeSet, YXBanded);
XLIB_EPILOGUE (dmxScreen);
xfree(pRectFirst);
} else {
XLIB_PROLOGUE (dmxScreen);
XShapeCombineMask(dmxScreen->beDisplay, pWinPriv->window,
ShapeClip, 0, 0, None, ShapeSet);
XLIB_EPILOGUE (dmxScreen);
}
XLIB_PROLOGUE (dmxScreen);
if (XShapeInputSelected(dmxScreen->beDisplay, pWinPriv->window)) {
ErrorF("Input selected for window %x on Screen %d\n",
(unsigned int)pWinPriv->window, pScreen->myNum);
}
XLIB_EPILOGUE (dmxScreen);
}
/** Set shape of \a pWindow on the back-end server. */

View file

@ -45,6 +45,7 @@ typedef struct _dmxWinPriv {
Bool offscreen;
Bool mapped;
Bool restacked;
Bool redirected;
unsigned long attribMask;
Colormap cmap;
Visual *visual;

52
hw/dmx/dmxxlibio.h Normal file
View file

@ -0,0 +1,52 @@
/*
* Copyright © 2007 David Reveman
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* David Reveman not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior permission.
* David Reveman makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* DAVID REVEMAN DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
* NO EVENT SHALL DAVID REVEMAN BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: David Reveman <davidr@novell.com>
*/
#ifndef DMX_XLIBIO_H
#define DMX_XLIBIO_H
#include <setjmp.h>
extern jmp_buf _dmx_jumpbuf;
extern int _dmx_io_error;
extern int _dmx_jumpbuf_set;
#define XLIB_PROLOGUE(_dmxScreen) \
do { \
_dmx_io_error = 0; \
_dmx_jumpbuf_set = 1; \
setjmp (_dmx_jumpbuf); \
if (_dmx_io_error) \
{ \
(_dmxScreen)->alive = FALSE; \
} \
else if ((_dmxScreen)->alive) \
{
#define XLIB_EPILOGUE(_dmxScreen) \
} \
_dmx_jumpbuf_set = 0; \
} while (0)
#endif

View file

@ -74,6 +74,9 @@ Bool XCheckNotMaskEvent (Display *dpy, long mask, XEvent *event)
unsigned long qe_serial = 0;
int n; /* time through count */
if (dpy->flags & XlibDisplayIOError)
return False;
LockDisplay(dpy);
prev = NULL;
for (n = 3; --n >= 0;) {
@ -90,6 +93,9 @@ Bool XCheckNotMaskEvent (Display *dpy, long mask, XEvent *event)
}
if (prev)
qe_serial = prev->qserial_num;
if (!(dpy->flags & XlibDisplayIOError))
{
switch (n) {
case 2:
_XEventsQueued(dpy, QueuedAfterReading);
@ -98,6 +104,7 @@ Bool XCheckNotMaskEvent (Display *dpy, long mask, XEvent *event)
_XFlush(dpy);
break;
}
}
if (prev && prev->qserial_num != qe_serial)
/* another thread has snatched this event */
prev = NULL;

View file

@ -49,6 +49,7 @@
#include "dmxcursor.h"
#include "dmxprop.h"
#include "dmxsync.h"
#include "dmxxlibio.h"
#include "dmxcb.h" /* For dmxGlobalWidth and dmxGlobalHeight */
#include "dmxevents.h" /* For dmxGetGlobalPosition */
#include "ChkNotMaskEv.h"
@ -159,19 +160,23 @@ static int dmxBackendSameDisplay(myPrivate *priv, long screen)
static void *dmxBackendTestEvents(DMXScreenInfo *dmxScreen, void *closure)
{
XEvent *X = (XEvent *)closure;
int result = 0;
if (XCheckNotMaskEvent(dmxScreen->beDisplay, ExposureMask, X))
return dmxScreen;
return NULL;
XLIB_PROLOGUE (dmxScreen);
result = XCheckNotMaskEvent(dmxScreen->beDisplay, ExposureMask, X);
XLIB_EPILOGUE (dmxScreen);
return (result) ? dmxScreen : NULL;
}
static void *dmxBackendTestMotionEvent(DMXScreenInfo *dmxScreen, void *closure)
{
XEvent *X = (XEvent *)closure;
int result = 0;
if (XCheckTypedEvent(dmxScreen->beDisplay, MotionNotify, X))
return dmxScreen;
return NULL;
XLIB_PROLOGUE (dmxScreen);
result = XCheckTypedEvent(dmxScreen->beDisplay, MotionNotify, X);
XLIB_EPILOGUE (dmxScreen);
return (result) ? dmxScreen : NULL;
}
static DMXScreenInfo *dmxBackendGetEvent(myPrivate *priv, XEvent *X)
@ -190,7 +195,11 @@ static DMXScreenInfo *dmxBackendPendingMotionEvent(myPrivate *priv, int save)
if ((dmxScreen = dmxPropertyIterate(priv->be,
dmxBackendTestMotionEvent, &N))) {
if (save) XPutBackEvent(dmxScreen->beDisplay, &N);
if (save) {
XLIB_PROLOGUE (dmxScreen);
XPutBackEvent(dmxScreen->beDisplay, &N);
XLIB_EPILOGUE (dmxScreen);
}
return dmxScreen;
}
return NULL;
@ -303,7 +312,9 @@ void dmxBackendUpdatePosition(pointer private, int x, int y)
DMXDBG2(" *** force ungrab on %s, display=%p\n",
priv->grabbedScreen->name,
priv->grabbedScreen->beDisplay);
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer(priv->grabbedScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
dmxSync(priv->grabbedScreen, TRUE);
priv->grabbedScreen = NULL;
}
@ -319,8 +330,10 @@ void dmxBackendUpdatePosition(pointer private, int x, int y)
dmxHideCursor(dmxScreen);
priv->lastX = priv->centerX;
priv->lastY = priv->centerY;
XLIB_PROLOGUE (dmxScreen);
XWarpPointer(priv->display, None, priv->window,
0, 0, 0, 0, priv->lastX, priv->lastY);
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, TRUE);
} else {
DMXDBG0(" Check cursor\n");
@ -346,117 +359,159 @@ void dmxBackendCollectEvents(DevicePtr pDev,
int entered = priv->entered;
int ignoreLeave = 0;
int v[2];
int retcode;
Window window = None;
int x = 0, y = 0;
while ((dmxScreen = dmxBackendGetEvent(priv, &X))) {
switch (X.type) {
case EnterNotify:
dmxCommonSaveState(priv);
if (entered++)
continue;
priv->entered = 1;
ignoreLeave = 1;
DMXDBG5("dmxBackendCollectEvents: Enter %lu %d,%d; GRAB %s %p\n",
X.xcrossing.root, X.xcrossing.x, X.xcrossing.y,
dmxScreen->name, dmxScreen->beDisplay);
XRaiseWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
priv->grabbedScreen = dmxScreen;
if ((retcode = XGrabPointer(dmxScreen->beDisplay,
dmxScreen->scrnWin,
True, 0, GrabModeAsync,
GrabModeAsync, None, None,
CurrentTime))) {
dmxLog(dmxError,
"XGrabPointer failed during backend enter (%d)\n",
retcode);
}
break;
case LeaveNotify:
if (ignoreLeave) {
ignoreLeave = 0;
continue;
}
dmxCommonRestoreState(priv);
if (left++)
continue;
DMXDBG7("dmxBackendCollectEvents: Leave %lu %d,%d %d %d %s %s\n",
X.xcrossing.root, X.xcrossing.x, X.xcrossing.y,
X.xcrossing.detail, X.xcrossing.focus,
priv->grabbedScreen ? "UNGRAB" : "",
dmxScreen->name);
if (priv->grabbedScreen) {
XUngrabPointer(priv->grabbedScreen->beDisplay, CurrentTime);
dmxSync(priv->grabbedScreen, TRUE);
priv->grabbedScreen = NULL;
}
break;
case MotionNotify:
DMXDBG9("dmxBackendCollectEvents: MotionNotify %d/%d (mi %d)"
" newscreen=%d: %d %d (e=%d; last=%d,%d)\n",
dmxScreen->index, priv->myScreen,
miPointerCurrentScreen()->myNum,
priv->newscreen,
X.xmotion.x, X.xmotion.y,
entered, priv->lastX, priv->lastY);
if (dmxBackendPendingMotionEvent(priv, TRUE))
continue;
if (!(dmxScreen = dmxBackendFindWindow(priv, X.xmotion.window)))
dmxLog(dmxFatal,
" Event on non-existant window %lu\n",
X.xmotion.window);
if (!priv->relative || dmxInput->console) {
int newX = X.xmotion.x - dmxScreen->rootX;
int newY = X.xmotion.y - dmxScreen->rootY;
if (!priv->newscreen) {
int width = dmxScreen->rootWidth;
int height = dmxScreen->rootHeight;
if (!newX) newX = -1;
if (newX == width - 1) newX = width;
if (!newY) newY = -1;
if (newY == height - 1) newY = height;
}
priv->newscreen = 0;
v[0] = dmxScreen->rootXOrigin + newX;
v[1] = dmxScreen->rootYOrigin + newY;
DMXDBG8(" Absolute move: %d,%d (r=%dx%d+%d+%d s=%dx%d)\n",
v[0], v[1],
priv->be->rootWidth, priv->be->rootHeight,
priv->be->rootX, priv->be->rootY,
priv->be->scrnWidth, priv->be->scrnHeight);
motion(priv->mou, v, 0, 2, DMX_ABSOLUTE, block);
priv->entered = 0;
} else {
int newX = priv->lastX - X.xmotion.x;
int newY = priv->lastY - X.xmotion.y;
priv->lastX = X.xmotion.x;
priv->lastY = X.xmotion.y;
v[0] = newX;
v[1] = newY;
DMXDBG2(" Relative move: %d, %d\n", v[0], v[1]);
motion(priv->mou, v, 0, 2, DMX_RELATIVE, block);
}
if (entered && priv->relative) {
DMXDBG4(" **** Relative %d %d instead of absolute %d %d\n",
v[0], v[1],
(dmxScreen->rootXOrigin + X.xmotion.x
- dmxScreen->rootX),
(dmxScreen->rootYOrigin + X.xmotion.y
- dmxScreen->rootY));
}
case FocusIn:
dmxUnpauseCoreInput ();
break;
case FocusOut:
dmxPauseCoreInput ();
break;
case LeaveNotify:
if (ignoreLeave) {
ignoreLeave = 0;
continue;
}
if (left++)
continue;
if (priv->grabbedScreen) {
priv->grabbedScreen = NULL;
}
break;
case EnterNotify:
priv->entered = 1;
ignoreLeave = 1;
priv->grabbedScreen = dmxScreen;
case KeyPress:
case KeyRelease:
enqueue(priv->kbd, X.type, X.xkey.keycode, 0, NULL, block);
break;
case ButtonPress:
case ButtonRelease:
/* fall-through */
if (X.xcrossing.mode != NotifyUngrab)
break;
window = X.xcrossing.window;
x = X.xcrossing.x;
y = X.xcrossing.y;
/* fall through */
case MotionNotify:
if (X.type == MotionNotify)
{
DMXDBG9("dmxBackendCollectEvents: MotionNotify %d/%d (mi %d)"
" newscreen=%d: %d %d (e=%d; last=%d,%d)\n",
dmxScreen->index, priv->myScreen,
miPointerCurrentScreen()->myNum,
priv->newscreen,
X.xmotion.x, X.xmotion.y,
entered, priv->lastX, priv->lastY);
if (dmxBackendPendingMotionEvent(priv, TRUE))
continue;
window = X.xmotion.window;
x = X.xmotion.x;
y = X.xmotion.y;
}
if (!(dmxScreen = dmxBackendFindWindow(priv, window)))
dmxLog(dmxFatal,
" Event on non-existant window %lu\n",
X.xmotion.window);
if (!priv->relative || dmxInput->console) {
int newX = x - dmxScreen->rootX;
int newY = y - dmxScreen->rootY;
if (!priv->newscreen) {
int width = dmxScreen->rootWidth;
int height = dmxScreen->rootHeight;
if (!newX) newX = -1;
if (newX == width - 1) newX = width;
if (!newY) newY = -1;
if (newY == height - 1) newY = height;
}
priv->newscreen = 0;
v[0] = dmxScreen->rootXOrigin + newX;
v[1] = dmxScreen->rootYOrigin + newY;
DMXDBG8(" Absolute move: %d,%d (r=%dx%d+%d+%d s=%dx%d)\n",
v[0], v[1],
priv->be->rootWidth, priv->be->rootHeight,
priv->be->rootX, priv->be->rootY,
priv->be->scrnWidth, priv->be->scrnHeight);
motion (priv->mou, v, 0, 2, DMX_ABSOLUTE, block);
priv->entered = 0;
} else {
int newX = priv->lastX - x;
int newY = priv->lastY - y;
priv->lastX = x;
priv->lastY = y;
v[0] = newX;
v[1] = newY;
DMXDBG2(" Relative move: %d, %d\n", v[0], v[1]);
motion (priv->mou, v, 0, 2, DMX_RELATIVE, block);
}
if (entered && priv->relative) {
DMXDBG4(" **** Relative %d %d instead of absolute %d %d\n",
v[0], v[1],
(dmxScreen->rootXOrigin + x
- dmxScreen->rootX),
(dmxScreen->rootYOrigin + y
- dmxScreen->rootY));
}
break;
case KeyPress:
case KeyRelease:
if (X.xany.send_event)
{
BYTE *kptr = &dmxInput->history[X.xkey.keycode >> 3];
int bit = 1 << (X.xkey.keycode & 7);
switch (X.type) {
case KeyPress: *kptr |= bit; break;
case KeyRelease: *kptr &= ~bit; break;
}
}
else
{
dmxInput->validHistory = FALSE;
enqueue (priv->kbd, X.type, X.xkey.keycode, 0, NULL, block);
}
break;
case ButtonPress:
if (!X.xany.send_event)
{
XLIB_PROLOGUE (dmxScreen);
XUngrabPointer (dmxScreen->beDisplay, CurrentTime);
XUngrabKeyboard (dmxScreen->beDisplay, CurrentTime);
XLIB_EPILOGUE (dmxScreen);
}
/* fall-through */
case ButtonRelease:
if (X.xany.send_event)
{
BYTE *bptr = &dmxInput->history[X.xbutton.button >> 3];
int bit = 1 << (X.xbutton.button & 7);
switch (X.type) {
case ButtonPress: *bptr |= bit; break;
case ButtonRelease:*bptr &= ~bit; break;
}
}
else
{
dmxInput->validHistory = FALSE;
enqueue (priv->mou, X.type, X.xbutton.button, 0, &X, block);
}
break;
case MappingNotify:
if (dmxLocal && dmxLocal->pDevice && dmxLocal->pDevice->key)
{
DMXLocalInitInfo info;
memset (&info, 0, sizeof (info));
dmxCommonKbdGetMap (pDev, &info.keySyms, info.modMap);
SetKeySymsMap (&dmxLocal->pDevice->key->curKeySyms,
&info.keySyms);
}
default:
/* Pass the whole event here, because
* this may be an extension event. */
enqueue(priv->mou, X.type, X.xbutton.button, 0, &X, block);
break;
}
}
@ -482,8 +537,10 @@ void dmxBackendProcessInput(pointer private)
priv->lastX, priv->lastY, priv->centerX, priv->centerY);
priv->lastX = priv->centerX;
priv->lastY = priv->centerY;
XLIB_PROLOGUE (&dmxScreens[priv->myScreen]);
XWarpPointer(priv->display, None, priv->window,
0, 0, 0, 0, priv->lastX, priv->lastY);
XLIB_EPILOGUE (&dmxScreens[priv->myScreen]);
dmxSync(&dmxScreens[priv->myScreen], TRUE);
}
}
@ -514,7 +571,8 @@ static DMXScreenInfo *dmxBackendInitPrivate(DevicePtr pDev)
/* Fill in myPrivate */
for (i = 0,dmxScreen = &dmxScreens[0]; i<dmxNumScreens; i++,dmxScreen++) {
if (dmxPropertySameDisplay(dmxScreen, dmxInput->name)) {
if ((dmxInput->scrnIdx != -1 && dmxInput->scrnIdx == i) ||
dmxPropertySameDisplay(dmxScreen, dmxInput->name)) {
priv->display = dmxScreen->beDisplay;
priv->window = dmxScreen->scrnWin;
priv->be = dmxScreen;
@ -564,7 +622,15 @@ void dmxBackendInit(DevicePtr pDev)
/* Finish initialization using computed values or constants. */
dmxBackendComputeCenter(priv);
priv->eventMask = (EnterWindowMask|LeaveWindowMask);
priv->eventMask = (KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
| KeymapStateMask
| FocusChangeMask);
priv->myScreen = dmxScreen->index;
priv->lastX = priv->centerX;
priv->lastY = priv->centerY;

View file

@ -237,7 +237,6 @@ void dmxCommonKbdGetMap(DevicePtr pDev, KeySymsPtr pKeySyms, CARD8 *pModMap)
pKeySyms->mapWidth = map_width;
pKeySyms->map = keyboard_mapping;
/* Compute pModMap */
modifier_mapping = XGetModifierMapping(priv->display);
for (i = 0; i < MAP_LENGTH; i++)
@ -293,10 +292,10 @@ int dmxCommonKbdOn(DevicePtr pDev)
GETPRIVFROMPDEV;
if (priv->be) dmxCommonSaveState(priv);
priv->eventMask |= DMX_KEYBOARD_EVENT_MASK;
XSelectInput(priv->display, priv->window, priv->eventMask);
if (priv->be)
XSetInputFocus(priv->display, priv->window, RevertToPointerRoot,
CurrentTime);
//XSelectInput(priv->display, priv->window, priv->eventMask);
// if (priv->be)
// XSetInputFocus(priv->display, priv->window, RevertToPointerRoot,
// CurrentTime);
return -1;
}
@ -305,7 +304,7 @@ void dmxCommonKbdOff(DevicePtr pDev)
{
GETPRIVFROMPDEV;
priv->eventMask &= ~DMX_KEYBOARD_EVENT_MASK;
XSelectInput(priv->display, priv->window, priv->eventMask);
//XSelectInput(priv->display, priv->window, priv->eventMask);
dmxCommonRestoreState(priv);
}
@ -348,6 +347,7 @@ int dmxCommonOthOn(DevicePtr pDev)
ADD(DeviceStateNotify);
ADD(DeviceMappingNotify);
ADD(ChangeDeviceNotify);
XSelectExtensionEvent(priv->display, priv->window, event_list, count);
return -1;
@ -460,8 +460,10 @@ void dmxCommonMouGetMap(DevicePtr pDev, unsigned char *map, int *nButtons)
static void *dmxCommonXSelect(DMXScreenInfo *dmxScreen, void *closure)
{
myPrivate *priv = closure;
/* myPrivate *priv = closure;
XLIB_PROLOGUE (dmxScreen);
XSelectInput(dmxScreen->beDisplay, dmxScreen->scrnWin, priv->eventMask);
XLIB_EPILOGUE (dmxScreen);*/
return NULL;
}
@ -486,14 +488,18 @@ int dmxCommonMouOn(DevicePtr pDev)
priv->eventMask |= DMX_POINTER_EVENT_MASK;
if (dmxShadowFB) {
XLIB_PROLOGUE (&dmxScreens[dmxInput->scrnIdx]);
XWarpPointer(priv->display, priv->window, priv->window,
0, 0, 0, 0,
priv->initPointerX,
priv->initPointerY);
XLIB_EPILOGUE (&dmxScreens[dmxInput->scrnIdx]);
dmxSync(&dmxScreens[dmxInput->scrnIdx], TRUE);
}
if (!priv->be) {
XLIB_PROLOGUE (&dmxScreens[dmxInput->scrnIdx]);
XSelectInput(priv->display, priv->window, priv->eventMask);
XLIB_EPILOGUE (&dmxScreens[dmxInput->scrnIdx]);
AddEnabledDevice(XConnectionNumber(priv->display));
} else {
dmxPropertyIterate(priv->be, dmxCommonXSelect, priv);
@ -512,7 +518,9 @@ void dmxCommonMouOff(DevicePtr pDev)
priv->eventMask &= ~DMX_POINTER_EVENT_MASK;
if (!priv->be) {
RemoveEnabledDevice(XConnectionNumber(priv->display));
XLIB_PROLOGUE (&dmxScreens[dmxInput->scrnIdx]);
XSelectInput(priv->display, priv->window, priv->eventMask);
XLIB_EPILOGUE (&dmxScreens[dmxInput->scrnIdx]);
} else {
dmxPropertyIterate(priv->be, dmxCommonRemoveEnabledDevice, dmxInput);
dmxPropertyIterate(priv->be, dmxCommonXSelect, priv);
@ -574,6 +582,8 @@ void dmxCommonSaveState(pointer private)
unsigned long i;
XModifierKeymap *modmap;
return;
if (dmxInput->console) priv = dmxInput->devs[0]->private;
if (!priv->display || priv->stateSaved) return;
DMXDBG0("dmxCommonSaveState\n");
@ -629,6 +639,8 @@ void dmxCommonRestoreState(pointer private)
int retcode = -1;
CARD32 start;
return;
if (dmxInput->console)
priv = dmxInput->devs[0]->private;
if (!priv->stateSaved)

View file

@ -101,6 +101,8 @@ static int dmxCheckFunctionKeys(DMXLocalInputInfoPtr dmxLocal,
DMXInputInfo *dmxInput = &dmxInputs[dmxLocal->inputIdx];
unsigned short state = 0;
return 0;
#if 1 /* hack to detect ctrl-alt-q, etc */
static int ctrl = 0, alt = 0;
/* keep track of ctrl/alt key status */
@ -643,7 +645,7 @@ static KeyCode dmxKeySymToKeyCode(DMXLocalInputInfoPtr dmxLocal, KeySym keySym,
return 0;
}
static int dmxFixup(DevicePtr pDev, int detail, KeySym keySym)
static Bool dmxFixup(DevicePtr pDev, int detail, KeySym keySym, int *keycode)
{
GETDMXLOCALFROMPDEV;
int keyCode;
@ -651,15 +653,19 @@ static int dmxFixup(DevicePtr pDev, int detail, KeySym keySym)
if (!dmxLocal->pDevice->key) {
dmxLog(dmxWarning, "dmxFixup: not a keyboard device (%s)\n",
dmxLocal->pDevice->name);
return NoSymbol;
return FALSE;
}
if (!keySym)
keySym = dmxKeyCodeToKeySym(dmxLocal, detail);
if (keySym == NoSymbol)
return detail;
keyCode = dmxKeySymToKeyCode(dmxLocalCoreKeyboard, keySym, detail);
return FALSE;
return keyCode ? keyCode : detail;
keyCode = dmxKeySymToKeyCode(dmxLocalCoreKeyboard, keySym, detail);
if (!keyCode)
return FALSE;
*keycode = keyCode;
return TRUE;
}
/** Enqueue an event from the \a pDev device with the
@ -685,10 +691,23 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
case KeyRelease:
if (!keySym)
keySym = dmxKeyCodeToKeySym(dmxLocal, detail);
#if 0
if (dmxCheckFunctionKeys(dmxLocal, type, keySym))
return;
if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
xE.u.u.detail = dmxFixup(pDev, detail, keySym);
#endif
/* translate keycodes from keyboard devices that send core
events but is not the core keyboard */
if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
{
int keyCode;
if (dmxFixup (pDev, detail, keySym, &keyCode))
detail = keyCode;
}
if (dmxCheckSpecialKeys (pDev, keySym))
return;
GetEventList(&events);
/*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/
@ -804,8 +823,10 @@ int dmxCheckSpecialKeys(DevicePtr pDev, KeySym keySym)
case XK_BackSpace:
case XK_Delete:
case XK_KP_Delete:
#if 0
dmxLog(dmxInfo, "User request for termination\n");
dispatchException |= DE_TERMINATE;
#endif
return -1; /* Terminate */
}

View file

@ -220,6 +220,85 @@ static DMXLocalInputInfoRec DMXLocalDevices[] = {
{ NULL } /* Must be last */
};
static void
dmxSyncKeys (DeviceIntPtr pDevice)
{
DevicePtr pDev = &pDevice->public;
DeviceIntPtr keyDev = inputInfo.keyboard;
KeyClassPtr keyc = keyDev->key;
xEvent ke;
int i, x, y;
GETDMXINPUTFROMPDEV;
miPointerGetPosition (inputInfo.pointer, &x, &y);
ke.u.keyButtonPointer.time = GetTimeInMillis ();
ke.u.keyButtonPointer.rootX = x;
ke.u.keyButtonPointer.rootY = y;
for (i = keyc->curKeySyms.minKeyCode; i < keyc->curKeySyms.maxKeyCode; i++)
{
ke.u.u.detail = i;
if (dmxInput->validHistory && BitIsOn (dmxInput->history, i))
{
if (!BitIsOn (keyc->down, i))
{
ke.u.u.type = KeyPress;
(*keyDev->public.processInputProc) (&ke, keyDev, 1);
}
}
else
{
if (BitIsOn (keyc->down, i))
{
ke.u.u.type = KeyRelease;
(*keyDev->public.processInputProc) (&ke, keyDev, 1);
}
}
}
}
static void
dmxSyncButtons (DeviceIntPtr pDevice)
{
DevicePtr pDev = &pDevice->public;
DeviceIntPtr buttonDev = inputInfo.pointer;
ButtonClassPtr buttonc = buttonDev->button;
xEvent be;
int i, x, y;
GETDMXINPUTFROMPDEV;
miPointerGetPosition (inputInfo.pointer, &x, &y);
be.u.keyButtonPointer.time = GetTimeInMillis ();
be.u.keyButtonPointer.rootX = x;
be.u.keyButtonPointer.rootY = y;
for (i = 1; i < DOWN_LENGTH; i++)
{
be.u.u.detail = i;
if (dmxInput->validHistory && BitIsOn (dmxInput->history, i))
{
if (!BitIsOn (buttonc->down, i))
{
be.u.u.type = ButtonPress;
(*buttonDev->public.processInputProc) (&be, buttonDev, 1);
}
}
else
{
if (BitIsOn (buttonc->down, i))
{
be.u.u.type = ButtonRelease;
(*buttonDev->public.processInputProc) (&be, buttonDev, 1);
}
}
}
}
#if 11 /*BP*/
void
@ -620,6 +699,7 @@ static void dmxCollectAll(DMXInputInfo *dmxInput)
if (dmxInput->detached)
return;
for (i = 0; i < dmxInput->numDevs; i += dmxInput->devs[i]->binding)
if (dmxInput->devs[i]->collect_events)
dmxInput->devs[i]->collect_events(&dmxInput->devs[i]
@ -657,6 +737,11 @@ static void dmxSwitchReturn(pointer p)
dmxInput->vt_switched = 0;
}
#include <setjmp.h>
extern jmp_buf dmx_jumpbuf;
extern int dmx_jumpbuf_set;
static void dmxWakeupHandler(pointer blockData, int result, pointer pReadMask)
{
DMXInputInfo *dmxInput = &dmxInputs[(int)blockData];
@ -681,6 +766,7 @@ static void dmxWakeupHandler(pointer blockData, int result, pointer pReadMask)
}
}
}
dmxCollectAll(dmxInput);
}
@ -1032,7 +1118,8 @@ void dmxInputInit(DMXInputInfo *dmxInput)
int found;
for (found = 0, i = 0; i < dmxNumScreens; i++) {
if (dmxPropertySameDisplay(&dmxScreens[i], name)) {
if ((dmxInput->scrnIdx != -1 && dmxInput->scrnIdx == i) ||
dmxPropertySameDisplay(&dmxScreens[i], name)) {
if (dmxScreens[i].shared)
dmxLog(dmxFatal,
"Cannot take input from shared backend (%s)\n",
@ -1049,7 +1136,7 @@ void dmxInputInit(DMXInputInfo *dmxInput)
dmxInputCopyLocal(dmxInput, &DMXBackendKbd);
dmxInput->scrnIdx = i;
dmxLogInput(dmxInput,
"Using backend input from %s\n", name);
"Using backend input from %s at %d\n", name, i);
}
++found;
break;
@ -1096,6 +1183,8 @@ void dmxInputInit(DMXInputInfo *dmxInput)
dmxInput->processInputEvents = dmxProcessInputEvents;
dmxInput->detached = False;
dmxInput->validHistory = FALSE;
RegisterBlockAndWakeupHandlers(dmxBlockHandler,
dmxWakeupHandler,
@ -1212,6 +1301,8 @@ int dmxInputDetach(DMXInputInfo *dmxInput)
: (dmxLocal->sendsCore
? " [sends core events]"
: ""));
dmxSyncKeys (dmxLocal->pDevice);
dmxSyncButtons (dmxLocal->pDevice);
DisableDevice(dmxLocal->pDevice);
}
dmxInput->detached = True;
@ -1226,6 +1317,11 @@ void dmxInputDetachAll(DMXScreenInfo *dmxScreen)
for (i = 0; i < dmxNumInputs; i++) {
DMXInputInfo *dmxInput = &dmxInputs[i];
dmxLogInput(dmxInput, "Detaching input: %d - %d -- %d %d\n",
i, dmxInput->numDevs, dmxInput->scrnIdx,
dmxInput->detached);
if (dmxInput->scrnIdx == dmxScreen->index) dmxInputDetach(dmxInput);
}
}
@ -1280,7 +1376,8 @@ static int dmxInputAttachOld(DMXInputInfo *dmxInput, int *id)
: (dmxLocal->sendsCore
? " [sends core events]"
: ""));
EnableDevice(dmxLocal->pDevice);
/* EnableDevice(dmxLocal->pDevice); call InitAndStartDevices instead */
InitAndStartDevices();
}
dmxInputLogDevices();
return 0;
@ -1331,6 +1428,91 @@ int dmxInputAttachBackend(int physicalScreen, int isCore, int *id)
dmxScreen = &dmxScreens[physicalScreen];
if (!dmxScreen->beDisplay) return BadAccess; /* Screen detached */
dmxInput = dmxConfigAddInput(dmxScreen->name, isCore);
dmxInput->scrnIdx = physicalScreen;
dmxLogInput(dmxInput, "Attaching new backend input\n");
return dmxInputAttachNew(dmxInput, id);
}
void
dmxPauseCoreInput (void)
{
int i, j;
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
for (j = 0; j < dmxInput->numDevs; j++)
{
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
DeviceIntPtr pDevice = (DeviceIntPtr) dmxLocal->pDevice;
if (!dmxInput->devs[j]->sendsCore)
continue;
if (pDevice->button)
{
if (inputInfo.pointer->enabled)
{
memcpy (dmxInput->history,
inputInfo.pointer->button->down,
sizeof (CARD8) * DOWN_LENGTH);
dmxInput->validHistory = TRUE;
}
}
else if (pDevice->key)
{
if (inputInfo.keyboard->enabled)
{
memcpy (dmxInput->history,
inputInfo.keyboard->key->down,
sizeof (CARD8) * DOWN_LENGTH);
dmxInput->validHistory = TRUE;
}
}
}
}
if (inputInfo.pointer->enabled)
DisableDevice (inputInfo.pointer);
if (inputInfo.keyboard->enabled)
DisableDevice (inputInfo.keyboard);
}
void
dmxUnpauseCoreInput (void)
{
int i, j;
for (i = 0; i < dmxNumInputs; i++)
{
DMXInputInfo *dmxInput = &dmxInputs[i];
for (j = 0; j < dmxInput->numDevs; j++)
{
DMXLocalInputInfoPtr dmxLocal = dmxInput->devs[j];
DeviceIntPtr pDevice = (DeviceIntPtr) dmxLocal->pDevice;
if (!dmxInput->devs[j]->sendsCore)
continue;
if (pDevice->button)
{
if (!inputInfo.pointer->enabled)
EnableDevice (inputInfo.pointer);
}
else if (pDevice->key)
{
if (!inputInfo.keyboard->enabled)
dmxSyncKeys (pDevice);
}
}
}
if (!inputInfo.pointer->enabled)
EnableDevice (inputInfo.pointer);
if (!inputInfo.keyboard->enabled)
EnableDevice (inputInfo.keyboard);
}

View file

@ -290,4 +290,7 @@ extern int dmxInputAttachConsole(const char *name, int isCore,
extern int dmxInputAttachBackend(int physicalScreen, int isCore,
int *id);
extern void dmxPauseCoreInput (void);
extern void dmxUnpauseCoreInput (void);
#endif