xserver/hw/dmx/dmxscrinit.c

1838 lines
45 KiB
C
Raw Normal View History

/*
* Copyright 2001-2004 Red Hat Inc., Durham, North Carolina.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation on the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
/*
* Authors:
* Kevin E. Martin <kem@redhat.com>
* David H. Dawes <dawes@xfree86.org>
*
*/
/** \file
* This file provides support for screen initialization. */
#ifdef HAVE_DMX_CONFIG_H
#include <dmx-config.h>
#endif
#include "dmx.h"
2008-06-03 18:18:04 -04:00
#include "dmxextension.h"
#include "dmxsync.h"
#include "dmxshadow.h"
#include "dmxscrinit.h"
#include "dmxcursor.h"
#include "dmxgc.h"
#include "dmxgcops.h"
#include "dmxwindow.h"
#include "dmxpixmap.h"
#include "dmxfont.h"
#include "dmxcmap.h"
#include "dmxprop.h"
#include "dmxdpms.h"
2008-06-03 18:18:04 -04:00
#include "dmxlog.h"
#ifdef RENDER
#include "dmxpict.h"
#endif
2008-06-03 18:18:04 -04:00
#ifdef RANDR
#include "randrstr.h"
#endif
#include "fb.h"
#include "mipointer.h"
#include "micmap.h"
extern Bool dmxCloseScreen(int idx, ScreenPtr pScreen);
static Bool dmxSaveScreen(ScreenPtr pScreen, int what);
static unsigned long dmxGeneration;
static unsigned long *dmxCursorGeneration;
static int dmxGCPrivateKeyIndex;
DevPrivateKey dmxGCPrivateKey = &dmxGCPrivateKey; /**< Private index for GCs */
static int dmxWinPrivateKeyIndex;
DevPrivateKey dmxWinPrivateKey = &dmxWinPrivateKeyIndex; /**< Private index for Windows */
static int dmxPixPrivateKeyIndex;
DevPrivateKey dmxPixPrivateKey = &dmxPixPrivateKeyIndex; /**< Private index for Pixmaps */
int dmxFontPrivateIndex; /**< Private index for Fonts */
static int dmxScreenPrivateKeyIndex;
DevPrivateKey dmxScreenPrivateKey = &dmxScreenPrivateKeyIndex; /**< Private index for Screens */
static int dmxColormapPrivateKeyIndex;
DevPrivateKey dmxColormapPrivateKey = &dmxColormapPrivateKeyIndex; /**< Private index for Colormaps */
#ifdef RENDER
static int dmxPictPrivateKeyIndex;
DevPrivateKey dmxPictPrivateKey = &dmxPictPrivateKeyIndex; /**< Private index for Picts */
static int dmxGlyphSetPrivateKeyIndex;
DevPrivateKey dmxGlyphSetPrivateKey = &dmxGlyphSetPrivateKeyIndex; /**< Private index for GlyphSets */
#endif
2008-06-03 18:18:04 -04:00
#ifdef RANDR
2008-05-30 23:00:52 -04:00
static int xRROutputsForFirstScreen = 1;
static int xRRCrtcsForFirstScreen = 1;
2008-06-03 18:18:04 -04:00
static int xRROutputsPerScreen = 2;
2008-05-30 23:00:52 -04:00
static int xRRCrtcsPerScreen = 2;
static DMXScreenInfo *
dmxRRGetScreenForCrtc (ScreenPtr pScreen,
RRCrtcPtr crtc)
{
int i;
rrScrPriv (pScreen);
for (i = 0; i < pScrPriv->numCrtcs; i++)
if (pScrPriv->crtcs[i] == crtc)
break;
if (i == pScrPriv->numCrtcs)
return NULL;
if (i < xRRCrtcsForFirstScreen)
return dmxScreens;
return &dmxScreens[((i - xRRCrtcsForFirstScreen) / xRRCrtcsPerScreen) + 1];
}
static DMXScreenInfo *
dmxRRGetScreenForOutput (ScreenPtr pScreen,
RROutputPtr output)
{
int i;
rrScrPriv (pScreen);
for (i = 0; i < pScrPriv->numOutputs; i++)
if (pScrPriv->outputs[i] == output)
break;
if (i == pScrPriv->numOutputs)
return NULL;
if (i < xRROutputsForFirstScreen)
return dmxScreens;
return &dmxScreens[((i - xRROutputsForFirstScreen) / xRROutputsPerScreen) +
1];
}
2008-06-03 18:18:04 -04:00
static RRModePtr
dmxRRGetMode (XRRScreenResources *r,
unsigned long mode)
{
xRRModeInfo modeInfo;
int i;
for (i = 0; i < r->nmode; i++)
{
if (r->modes[i].id == mode)
{
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = r->modes[i].width;
modeInfo.height = r->modes[i].height;
modeInfo.dotClock = r->modes[i].dotClock;
modeInfo.hSyncStart = r->modes[i].hSyncStart;
modeInfo.hSyncEnd = r->modes[i].hSyncEnd;
modeInfo.hTotal = r->modes[i].hTotal;
modeInfo.hSkew = r->modes[i].hSkew;
modeInfo.vSyncStart = r->modes[i].vSyncStart;
modeInfo.vSyncEnd = r->modes[i].vSyncEnd;
modeInfo.vTotal = r->modes[i].vTotal;
modeInfo.nameLength = strlen (r->modes[i].name);
modeInfo.modeFlags = r->modes[i].modeFlags;
return RRModeGet (&modeInfo, r->modes[i].name);
}
}
return NULL;
}
static RRCrtcPtr
2008-05-30 23:00:52 -04:00
dmxRRGetCrtc (ScreenPtr pScreen,
DMXScreenInfo *dmxScreen,
unsigned long crtc)
2008-06-03 18:18:04 -04:00
{
2008-05-30 23:00:52 -04:00
int baseCrtc = 0;
int numCrtc = xRRCrtcsForFirstScreen;
int i;
2008-06-03 18:18:04 -04:00
2008-05-30 23:00:52 -04:00
rrScrPriv (pScreen);
2008-06-03 18:18:04 -04:00
if (!crtc)
return NULL;
2008-05-30 23:00:52 -04:00
if (dmxScreen != dmxScreens)
2008-06-03 18:18:04 -04:00
{
2008-05-30 23:00:52 -04:00
baseCrtc = xRRCrtcsForFirstScreen +
((dmxScreen - dmxScreens) - 1) * xRRCrtcsPerScreen;
numCrtc = xRRCrtcsPerScreen;
2008-06-03 18:18:04 -04:00
}
2008-05-30 23:00:52 -04:00
for (i = 0; i < numCrtc; i++)
if (pScrPriv->crtcs[baseCrtc + i]->devPrivate == (void *) crtc)
return pScrPriv->crtcs[baseCrtc + i];
2008-06-03 18:18:04 -04:00
return NULL;
}
static RROutputPtr
2008-05-30 23:00:52 -04:00
dmxRRGetOutput (ScreenPtr pScreen,
DMXScreenInfo *dmxScreen,
unsigned long output)
2008-06-03 18:18:04 -04:00
{
2008-05-30 23:00:52 -04:00
int baseOutput = 0;
int numOutput = xRROutputsForFirstScreen;
int i;
2008-06-03 18:18:04 -04:00
2008-05-30 23:00:52 -04:00
rrScrPriv (pScreen);
2008-06-03 18:18:04 -04:00
if (!output)
return NULL;
2008-05-30 23:00:52 -04:00
if (dmxScreen != dmxScreens)
2008-06-03 18:18:04 -04:00
{
2008-05-30 23:00:52 -04:00
baseOutput = xRROutputsForFirstScreen +
((dmxScreen - dmxScreens) - 1) * xRROutputsPerScreen;
numOutput = xRROutputsPerScreen;
2008-06-03 18:18:04 -04:00
}
2008-05-30 23:00:52 -04:00
for (i = 0; i < numOutput; i++)
if (pScrPriv->outputs[baseOutput + i]->devPrivate == (void *) output)
return pScrPriv->outputs[baseOutput + i];
2008-06-03 18:18:04 -04:00
return NULL;
}
static Bool
dmxRRUpdateCrtc (ScreenPtr pScreen,
2008-05-30 23:00:52 -04:00
DMXScreenInfo *dmxScreen,
2008-06-03 18:18:04 -04:00
XRRScreenResources *r,
unsigned long xcrtc)
{
XRRCrtcInfo *c = NULL;
RRCrtcPtr crtc;
RRModePtr mode = NULL;
RROutputPtr *outputs = NULL;
XRRCrtcGamma *gamma = NULL;
int i;
2008-05-30 23:00:52 -04:00
crtc = dmxRRGetCrtc (pScreen, dmxScreen, xcrtc);
2008-06-03 18:18:04 -04:00
if (!crtc)
return FALSE;
XLIB_PROLOGUE (dmxScreen);
c = XRRGetCrtcInfo (dmxScreen->beDisplay, r, xcrtc);
XLIB_EPILOGUE (dmxScreen);
if (!c)
return FALSE;
if (c->noutput)
{
outputs = xalloc (sizeof (RROutputPtr) * c->noutput);
if (!outputs)
return FALSE;
}
if (c->mode)
mode = dmxRRGetMode (r, c->mode);
for (i = 0; i < c->noutput; i++)
2008-05-30 23:00:52 -04:00
outputs[i] = dmxRRGetOutput (pScreen, dmxScreen, c->outputs[i]);
if (!outputs[i])
2008-06-03 18:18:04 -04:00
return FALSE;
XLIB_PROLOGUE (dmxScreen);
gamma = XRRGetCrtcGamma (dmxScreen->beDisplay, xcrtc);
XLIB_EPILOGUE (dmxScreen);
if (!gamma)
return FALSE;
RRCrtcGammaSet (crtc, gamma->red, gamma->green, gamma->blue);
XRRFreeGamma (gamma);
RRCrtcNotify (crtc, mode, c->x, c->y, c->rotation, c->noutput, outputs);
if (outputs)
xfree (outputs);
XRRFreeCrtcInfo (c);
return TRUE;
}
static Bool
dmxRRUpdateOutput (ScreenPtr pScreen,
2008-05-30 23:00:52 -04:00
DMXScreenInfo *dmxScreen,
2008-06-03 18:18:04 -04:00
XRRScreenResources *r,
unsigned long xoutput)
{
XRROutputInfo *o = NULL;
RROutputPtr output, *clones = NULL;
RRModePtr *modes = NULL;
RRCrtcPtr *crtcs = NULL;
int i;
2008-05-30 23:00:52 -04:00
output = dmxRRGetOutput (pScreen, dmxScreen, xoutput);
2008-06-03 18:18:04 -04:00
if (!output)
return FALSE;
XLIB_PROLOGUE (dmxScreen);
o = XRRGetOutputInfo (dmxScreen->beDisplay, r, xoutput);
XLIB_EPILOGUE (dmxScreen);
if (!o)
return FALSE;
if (o->nclone)
{
clones = xalloc (sizeof (RROutputPtr) * o->nclone);
if (!clones)
return FALSE;
}
if (o->nmode)
{
modes = xalloc (sizeof (RRModePtr) * o->nmode);
if (!modes)
return FALSE;
}
if (o->ncrtc)
{
crtcs = xalloc (sizeof (RRCrtcPtr) * o->ncrtc);
if (!crtcs)
return FALSE;
}
for (i = 0; i < o->nclone; i++)
{
2008-05-30 23:00:52 -04:00
clones[i] = dmxRRGetOutput (pScreen, dmxScreen, o->clones[i]);
if (!clones[i])
2008-06-03 18:18:04 -04:00
return FALSE;
}
for (i = 0; i < o->ncrtc; i++)
{
2008-05-30 23:00:52 -04:00
crtcs[i] = dmxRRGetCrtc (pScreen, dmxScreen, o->crtcs[i]);
if (!crtcs[i])
2008-06-03 18:18:04 -04:00
return FALSE;
}
if (!RROutputSetClones (output, clones, o->nclone))
return FALSE;
for (i = 0; i < o->nmode; i++)
{
modes[i] = dmxRRGetMode (r, o->modes[i]);
if (!modes[i])
return FALSE;
}
if (!RROutputSetModes (output, modes, o->nmode, o->npreferred))
return FALSE;
if (!RROutputSetCrtcs (output, crtcs, o->ncrtc))
return FALSE;
if (!RROutputSetConnection (output, o->connection))
return FALSE;
if (!RROutputSetSubpixelOrder (output, o->subpixel_order))
return FALSE;
if (!RROutputSetPhysicalSize (output, o->mm_width, o->mm_height))
return FALSE;
if (clones)
xfree (clones);
if (modes)
xfree (modes);
if (crtcs)
xfree (crtcs);
XRRFreeOutputInfo (o);
return TRUE;
}
static Bool
dmxRRUpdateOutputProperty (ScreenPtr pScreen,
2008-05-30 23:00:52 -04:00
DMXScreenInfo *dmxScreen,
2008-06-03 18:18:04 -04:00
XRRScreenResources *r,
unsigned long xoutput,
unsigned long xproperty)
{
RROutputPtr output;
XRRPropertyInfo *info = NULL;
unsigned char *prop;
int format, status = !Success;
unsigned long nElements, bytesAfter;
Atom type, atom;
char *name = NULL;
INT32 *values = NULL;
2008-05-30 23:00:52 -04:00
output = dmxRRGetOutput (pScreen, dmxScreen, xoutput);
2008-06-03 18:18:04 -04:00
if (!output)
return FALSE;
XLIB_PROLOGUE (dmxScreen);
name = XGetAtomName (dmxScreen->beDisplay, xproperty);
XLIB_EPILOGUE (dmxScreen);
if (!name)
return FALSE;
atom = MakeAtom (name, strlen (name), TRUE);
XFree (name);
XLIB_PROLOGUE (dmxScreen);
status = XRRGetOutputProperty (dmxScreen->beDisplay, xoutput, xproperty,
0, 8192, FALSE, FALSE,
AnyPropertyType, &type, &format,
&nElements, &bytesAfter, &prop);
XLIB_EPILOGUE (dmxScreen);
if (status != Success)
return FALSE;
XLIB_PROLOGUE (dmxScreen);
info = XRRQueryOutputProperty (dmxScreen->beDisplay, xoutput, xproperty);
XLIB_EPILOGUE (dmxScreen);
if (!info)
return FALSE;
if (info->num_values)
{
int i;
values = xalloc (info->num_values * sizeof (INT32));
if (!values)
return FALSE;
for (i = 0; i < info->num_values; i++)
values[i] = info->values[i];
}
if (type == XA_ATOM && format == 32)
{
INT32 *atoms = (INT32 *) prop;
int i;
for (i = 0; i < nElements; i++)
{
name = NULL;
XLIB_PROLOGUE (dmxScreen);
name = XGetAtomName (dmxScreen->beDisplay, atoms[i]);
XLIB_EPILOGUE (dmxScreen);
if (!name)
return FALSE;
atoms[i] = MakeAtom (name, strlen (name), TRUE);
XFree (name);
}
if (!info->range && info->num_values > 0)
{
for (i = 0; i < info->num_values; i++)
{
name = NULL;
XLIB_PROLOGUE (dmxScreen);
name = XGetAtomName (dmxScreen->beDisplay, values[i]);
XLIB_EPILOGUE (dmxScreen);
if (!name)
return FALSE;
values[i] = MakeAtom (name, strlen (name), TRUE);
XFree (name);
}
}
}
RRConfigureOutputProperty (output, atom, FALSE,
info->range, info->immutable, info->num_values,
values);
RRChangeOutputProperty (output, atom, type, format, PropModeReplace,
nElements, prop, FALSE, TRUE);
if (values)
xfree (values);
XFree (info);
XFree (prop);
return TRUE;
}
static Bool
dmxRRGetInfo (ScreenPtr pScreen,
Rotation *rotations)
{
int i;
rrScrPriv (pScreen);
if (pScreen->myNum)
{
*rotations = RR_Rotate_0;
return TRUE;
}
for (i = 0; i < dmxNumScreens; i++)
{
DMXScreenInfo *dmxScreen = &dmxScreens[i];
XRRScreenResources *r = NULL;
2008-05-30 23:00:52 -04:00
int outputsPerScreen = xRROutputsForFirstScreen;
2008-06-03 18:18:04 -04:00
int baseOutput = 0;
2008-05-30 23:00:52 -04:00
int crtcsPerScreen = xRRCrtcsForFirstScreen;
int baseCrtc = 0;
2008-06-03 18:18:04 -04:00
int j;
if (i)
{
outputsPerScreen = xRROutputsPerScreen;
2008-05-30 23:00:52 -04:00
baseOutput = xRROutputsForFirstScreen +
(i - 1) * xRROutputsPerScreen;
crtcsPerScreen = xRRCrtcsPerScreen;
baseCrtc = xRRCrtcsForFirstScreen +
(i - 1) * xRRCrtcsPerScreen;
2008-06-03 18:18:04 -04:00
}
assert (baseOutput + outputsPerScreen <= pScrPriv->numOutputs);
2008-05-30 23:00:52 -04:00
assert (baseCrtc + crtcsPerScreen <= pScrPriv->numCrtcs);
2008-06-03 18:18:04 -04:00
dmxScreen->beRandrPending = TRUE;
if (dmxScreen->beRandr && dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
r = XRRGetScreenResources (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay));
XLIB_EPILOGUE (dmxScreen);
if (r)
{
2008-05-30 23:00:52 -04:00
if (r->noutput > outputsPerScreen)
2008-06-03 18:18:04 -04:00
dmxLog (dmxWarning,
"dmxRRGetInfo: ignoring %d BE server outputs\n",
r->noutput - outputsPerScreen);
2008-05-30 23:00:52 -04:00
if (r->ncrtc > crtcsPerScreen)
2008-06-03 18:18:04 -04:00
dmxLog (dmxWarning,
"dmxRRGetInfo: ignoring %d BE server crtcs\n",
2008-05-30 23:00:52 -04:00
r->ncrtc - crtcsPerScreen);
2008-06-03 18:18:04 -04:00
}
}
for (j = 0; j < outputsPerScreen; j++)
{
RROutputPtr output = pScrPriv->outputs[baseOutput + j];
2008-05-30 23:00:52 -04:00
if (r && j < r->noutput)
output->devPrivate = (void *) r->outputs[j];
else
output->devPrivate = NULL;
}
2008-06-03 18:18:04 -04:00
2008-05-30 23:00:52 -04:00
for (j = 0; j < crtcsPerScreen; j++)
{
RRCrtcPtr crtc = pScrPriv->crtcs[baseCrtc + j];
crtc->devPrivate = NULL;
if (r && j < r->ncrtc)
crtc->devPrivate = (void *) r->crtcs[j];
else
crtc->devPrivate = NULL;
2008-06-03 18:18:04 -04:00
}
for (j = 0; j < outputsPerScreen; j++)
{
RROutputPtr output = pScrPriv->outputs[baseOutput + j];
if (r)
{
if (j < r->noutput)
{
#ifdef _XSERVER64
Atom64 *props = NULL;
#else
Atom *props = NULL;
#endif
int nProp = 0, k;
2008-05-30 23:00:52 -04:00
if (!dmxRRUpdateOutput (pScreen,
dmxScreen,
r,
r->outputs[j]))
2008-06-03 18:18:04 -04:00
return (dmxScreen->beRandrPending = FALSE);
XLIB_PROLOGUE (dmxScreen);
props = XRRListOutputProperties (dmxScreen->beDisplay,
r->outputs[j],
&nProp);
XLIB_EPILOGUE (dmxScreen);
if (nProp)
{
for (k = 0; k < nProp; k++)
if (!dmxRRUpdateOutputProperty (pScreen,
2008-05-30 23:00:52 -04:00
dmxScreen,
2008-06-03 18:18:04 -04:00
r,
r->outputs[j],
props[k]))
return (dmxScreen->beRandrPending = FALSE);
XFree (props);
}
}
else
{
if (!RROutputSetModes (output, NULL, 0, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetClones (output, NULL, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetCrtcs (output, NULL, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetConnection (output, RR_Disconnected))
return (dmxScreen->beRandrPending = FALSE);
}
}
else if (dmxScreen->beDisplay)
{
RRModePtr mode;
xRRModeInfo modeInfo;
char name[64];
sprintf (name,
"%dx%d",
dmxScreen->scrnWidth, dmxScreen->scrnHeight);
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = dmxScreen->scrnWidth;
modeInfo.height = dmxScreen->scrnHeight;
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
if (!mode)
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetModes (output, &mode, 1, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetClones (output, NULL, 0))
return (dmxScreen->beRandrPending = FALSE);
2008-05-30 23:00:52 -04:00
if (!RROutputSetCrtcs (output, &pScrPriv->crtcs[baseCrtc], 1))
2008-06-03 18:18:04 -04:00
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetConnection (output, RR_Connected))
return (dmxScreen->beRandrPending = FALSE);
}
else
{
if (!RROutputSetModes (output, NULL, 0, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetClones (output, NULL, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetCrtcs (output, NULL, 0))
return (dmxScreen->beRandrPending = FALSE);
if (!RROutputSetConnection (output, RR_Disconnected))
return FALSE;
2008-05-30 23:00:52 -04:00
}
}
for (j = 0; j < crtcsPerScreen; j++)
{
RRCrtcPtr crtc = pScrPriv->crtcs[baseCrtc + j];
2008-06-03 18:18:04 -04:00
2008-05-30 23:00:52 -04:00
if (r)
{
if (j < r->ncrtc)
{
if (!dmxRRUpdateCrtc (pScreen, dmxScreen, r, r->crtcs[j]))
return (dmxScreen->beRandrPending = FALSE);
}
else
{
RRCrtcNotify (crtc, NULL, 0, 0, RR_Rotate_0, 0, NULL);
}
}
else if (dmxScreen->beDisplay)
{
RRModePtr mode;
xRRModeInfo modeInfo;
char name[64];
sprintf (name,
"%dx%d",
dmxScreen->scrnWidth, dmxScreen->scrnHeight);
memset (&modeInfo, '\0', sizeof (modeInfo));
modeInfo.width = dmxScreen->scrnWidth;
modeInfo.height = dmxScreen->scrnHeight;
modeInfo.nameLength = strlen (name);
mode = RRModeGet (&modeInfo, name);
if (!mode)
return (dmxScreen->beRandrPending = FALSE);
RRCrtcNotify (crtc, mode, 0, 0, RR_Rotate_0, 1,
&pScrPriv->outputs[baseOutput]);
}
else
{
2008-06-03 18:18:04 -04:00
RRCrtcNotify (crtc, NULL, 0, 0, RR_Rotate_0, 0, NULL);
}
}
if (r)
XRRFreeScreenResources (r);
dmxScreen->beRandrPending = FALSE;
}
2008-05-30 23:00:52 -04:00
*rotations = RR_Rotate_0;
for (i = 0; i < pScrPriv->numCrtcs; i++)
*rotations |= pScrPriv->crtcs[i]->rotations;
2008-06-03 18:18:04 -04:00
return TRUE;
}
static unsigned long
dmxRRGetXMode (XRRScreenResources *r,
RRModePtr mode)
{
xRRModeInfo modeInfo = mode->mode;
int i;
for (i = 0; i < r->nmode; i++)
{
if (modeInfo.width == r->modes[i].width &&
modeInfo.height == r->modes[i].height &&
modeInfo.dotClock == r->modes[i].dotClock &&
modeInfo.hSyncStart == r->modes[i].hSyncStart &&
modeInfo.hSyncEnd == r->modes[i].hSyncEnd &&
modeInfo.hTotal == r->modes[i].hTotal &&
modeInfo.hSkew == r->modes[i].hSkew &&
modeInfo.vSyncStart == r->modes[i].vSyncStart &&
modeInfo.vSyncEnd == r->modes[i].vSyncEnd &&
modeInfo.vTotal == r->modes[i].vTotal &&
modeInfo.nameLength == r->modes[i].nameLength &&
modeInfo.modeFlags == r->modes[i].modeFlags)
{
if (!memcmp (r->modes[i].name, mode->name, modeInfo.nameLength))
return r->modes[i].id;
}
}
return None;
}
static Bool
dmxRRScreenSetSize (ScreenPtr pScreen,
CARD16 width,
CARD16 height,
CARD32 mmWidth,
CARD32 mmHeight)
{
DMXDesktopAttributesRec attr;
dmxGetDesktopAttributes (&attr);
if (attr.width != width || attr.height != height)
{
attr.width = width;
attr.height = height;
if (dmxConfigureDesktop (&attr) != Success)
return FALSE;
}
pScreen->mmWidth = mmWidth;
pScreen->mmHeight = mmHeight;
RRScreenSizeNotify (pScreen);
return TRUE;
}
static Bool
dmxRRCrtcSet (ScreenPtr pScreen,
RRCrtcPtr crtc,
RRModePtr mode,
int x,
int y,
Rotation rotation,
int numOutputs,
RROutputPtr *outputs)
{
XRRScreenResources *r = NULL;
#ifdef _XSERVER64
RROutput64 *o = NULL;
#else
RROutput *o = NULL;
#endif
RRMode m = None;
Status status = !RRSetConfigSuccess;
int i;
DMXScreenInfo *dmxScreen;
2008-05-30 23:00:52 -04:00
dmxScreen = dmxRRGetScreenForCrtc (pScreen, crtc);
if (!dmxScreen)
2008-06-03 18:18:04 -04:00
return FALSE;
if (dmxScreen->beRandrPending)
return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
for (i = 0; i < numOutputs; i++)
2008-05-30 23:00:52 -04:00
if (!dmxRRGetOutput (pScreen,
dmxScreen,
(unsigned long) outputs[i]->devPrivate))
2008-06-03 18:18:04 -04:00
return FALSE;
if (numOutputs)
{
o = xalloc (sizeof (*o) * numOutputs);
if (!o)
return FALSE;
}
XLIB_PROLOGUE (dmxScreen);
r = XRRGetScreenResources (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay));
XLIB_EPILOGUE (dmxScreen);
if (!r)
return FALSE;
if (mode)
{
m = dmxRRGetXMode (r, mode);
if (!m)
{
XRRFreeScreenResources (r);
if (o)
xfree (o);
return FALSE;
}
}
for (i = 0; i < numOutputs; i++)
o[i] = (unsigned long) outputs[i]->devPrivate;
XLIB_PROLOGUE (dmxScreen);
status = XRRSetCrtcConfig (dmxScreen->beDisplay, r,
(unsigned long) crtc->devPrivate,
CurrentTime,
x, y,
m,
rotation,
o, numOutputs);
XLIB_EPILOGUE (dmxScreen);
XRRFreeScreenResources (r);
if (o)
xfree (o);
if (status != RRSetConfigSuccess)
return FALSE;
return RRCrtcNotify (crtc, mode, x, y, rotation, numOutputs, outputs);
}
static Bool
dmxRRCrtcSetGamma (ScreenPtr pScreen,
RRCrtcPtr crtc)
{
XRRCrtcGamma *gamma;
DMXScreenInfo *dmxScreen;
2008-05-30 23:00:52 -04:00
dmxScreen = dmxRRGetScreenForCrtc (pScreen, crtc);
if (!dmxScreen)
2008-06-03 18:18:04 -04:00
return FALSE;
if (dmxScreen->beRandrPending)
return TRUE;
gamma = XRRAllocGamma (crtc->gammaSize);
if (!gamma)
return FALSE;
memcpy (gamma->red, crtc->gammaRed, gamma->size * sizeof (CARD16));
memcpy (gamma->green, crtc->gammaGreen, gamma->size * sizeof (CARD16));
memcpy (gamma->blue, crtc->gammaBlue, gamma->size * sizeof (CARD16));
XLIB_PROLOGUE (dmxScreen);
XRRSetCrtcGamma (dmxScreen->beDisplay, (unsigned long) crtc->devPrivate,
gamma);
XLIB_EPILOGUE (dmxScreen);
XRRFreeGamma (gamma);
return TRUE;
}
static Bool
dmxRROutputSetProperty (ScreenPtr pScreen,
RROutputPtr output,
Atom property,
RRPropertyValuePtr value)
{
RRPropertyPtr p;
#ifdef _XSERVER64
Atom64 atom = 0, type = 0;
#else
Atom atom = 0, type = 0;
#endif
long *values = value->data;
long *validValues;
int i;
DMXScreenInfo *dmxScreen;
2008-05-30 23:00:52 -04:00
dmxScreen = dmxRRGetScreenForOutput (pScreen, output);
if (!dmxScreen)
2008-06-03 18:18:04 -04:00
return FALSE;
if (dmxScreen->beRandrPending)
return TRUE;
p = RRQueryOutputProperty (output, property);
if (!p)
return FALSE;
validValues = p->valid_values;
XLIB_PROLOGUE (dmxScreen);
atom = XInternAtom (dmxScreen->beDisplay, NameForAtom (property), FALSE);
type = XInternAtom (dmxScreen->beDisplay, NameForAtom (value->type),
FALSE);
XLIB_EPILOGUE (dmxScreen);
if (type == XA_ATOM && value->format == 32)
{
INT32 *atoms = (INT32 *) value->data;
for (i = 0; i < value->size; i++)
if (!ValidAtom (atoms[i]))
return FALSE;
if (p->num_valid > 0)
{
for (i = 0; i < p->num_valid; i++)
if (!ValidAtom (p->valid_values[i]))
return FALSE;
for (i = 0; i < value->size; i++)
{
int j;
for (j = 0; j < p->num_valid; j++)
if (p->valid_values[j] == atoms[i])
break;
if (j == p->num_valid)
return FALSE;
}
validValues = xalloc (p->num_valid * sizeof (long));
if (!validValues)
return FALSE;
for (i = 0; i < p->num_valid; i++)
{
XLIB_PROLOGUE (dmxScreen);
validValues[i] = XInternAtom (dmxScreen->beDisplay,
NameForAtom (p->valid_values[i]),
FALSE);
XLIB_EPILOGUE (dmxScreen);
}
}
if (value->size)
{
int size = value->size * (value->format / 8);
values = xalloc (size);
if (!values)
return FALSE;
for (i = 0; i < value->size; i++)
{
XLIB_PROLOGUE (dmxScreen);
values[i] = XInternAtom (dmxScreen->beDisplay,
NameForAtom (atoms[i]),
FALSE);
XLIB_EPILOGUE (dmxScreen);
}
}
}
else
{
if (p->num_valid > 0)
{
validValues = xalloc (p->num_valid * sizeof (long));
if (!validValues)
return FALSE;
for (i = 0; i < p->num_valid; i++)
validValues[i] = p->valid_values[i];
}
}
XLIB_PROLOGUE (dmxScreen);
XRRConfigureOutputProperty (dmxScreen->beDisplay,
(unsigned long) output->devPrivate,
atom, p->is_pending, p->range, p->num_valid,
validValues);
XRRChangeOutputProperty (dmxScreen->beDisplay,
(unsigned long) output->devPrivate,
atom, type, value->format, PropModeReplace,
(unsigned char *) values, value->size);
XLIB_EPILOGUE (dmxScreen);
if (validValues != p->valid_values)
xfree (validValues);
if (values != value->data)
xfree (values);
return TRUE;
}
static Bool
dmxRROutputValidateMode (ScreenPtr pScreen,
RROutputPtr output,
RRModePtr mode)
{
XRRModeInfo *modeInfo;
#ifdef _XSERVER64
RRMode64 m = 0;
#else
RRMode m = 0;
#endif
DMXScreenInfo *dmxScreen;
2008-05-30 23:00:52 -04:00
dmxScreen = dmxRRGetScreenForOutput (pScreen, output);
if (!dmxScreen)
2008-06-03 18:18:04 -04:00
return FALSE;
if (dmxScreen->beRandrPending)
return TRUE;
modeInfo = XRRAllocModeInfo (mode->name, mode->mode.nameLength);
if (!modeInfo)
return FALSE;
modeInfo->width = mode->mode.width;
modeInfo->height = mode->mode.height;
modeInfo->dotClock = mode->mode.dotClock;
modeInfo->hSyncStart = mode->mode.hSyncStart;
modeInfo->hSyncEnd = mode->mode.hSyncEnd;
modeInfo->hTotal = mode->mode.hTotal;
modeInfo->hSkew = mode->mode.hSkew;
modeInfo->vSyncStart = mode->mode.vSyncStart;
modeInfo->vSyncEnd = mode->mode.vSyncEnd;
modeInfo->vTotal = mode->mode.vTotal;
modeInfo->modeFlags = mode->mode.modeFlags;
XLIB_PROLOGUE (dmxScreen);
m = XRRCreateMode (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay),
modeInfo);
XLIB_EPILOGUE (dmxScreen);
if (!m)
return FALSE;
XRRFreeModeInfo (modeInfo);
XLIB_PROLOGUE (dmxScreen);
XRRAddOutputMode (dmxScreen->beDisplay,
(unsigned long) output->devPrivate, m);
XLIB_EPILOGUE (dmxScreen);
return TRUE;
}
static void
dmxRRModeDestroy (ScreenPtr pScreen,
RRModePtr mode)
{
XRRScreenResources *r;
int i;
for (i = 0; i < dmxNumScreens; i++)
{
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (!dmxScreen->beRandr)
continue;
if (dmxScreen->beRandrPending)
continue;
r = NULL;
XLIB_PROLOGUE (dmxScreen);
r = XRRGetScreenResources (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay));
XLIB_EPILOGUE (dmxScreen);
if (r)
{
#ifdef _XSERVER64
RRMode64 m;
#else
RRMode m;
#endif
m = dmxRRGetXMode (r, mode);
if (m)
{
XLIB_PROLOGUE (dmxScreen);
XRRDestroyMode (dmxScreen->beDisplay, m);
XLIB_EPILOGUE (dmxScreen);
}
XRRFreeScreenResources (r);
}
}
}
static void
dmxRRCheckScreens (void)
{
int i;
for (i = 0; i < dmxNumScreens; i++)
{
DMXScreenInfo *dmxScreen = &dmxScreens[i];
if (dmxScreen->beDisplay && dmxScreen->beRandr)
{
XEvent event;
XLIB_PROLOGUE (dmxScreen);
while (XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase +
RRScreenChangeNotify,
&event))
{
dmxScreen->beRandrPending = TRUE;
RRTellChanged (screenInfo.screens[0]);
}
while (XCheckTypedEvent (dmxScreen->beDisplay,
dmxScreen->beRandrEventBase + RRNotify,
&event))
{
dmxScreen->beRandrPending = TRUE;
RRTellChanged (screenInfo.screens[0]);
}
XLIB_EPILOGUE (dmxScreen);
}
}
}
static void
dmxRRBlockHandler (pointer blockData,
OSTimePtr pTimeout,
pointer pReadMask)
{
dmxRRCheckScreens ();
}
static void
dmxRRWakeupHandler (pointer blockData,
int result,
pointer pReadMask)
{
dmxRRCheckScreens ();
}
static Bool
dmxRRInit (ScreenPtr pScreen)
{
RROutputPtr output;
RRCrtcPtr crtc;
rrScrPrivPtr pScrPriv;
if (!RRScreenInit (pScreen))
return FALSE;
pScrPriv = rrGetScrPriv (pScreen);
pScrPriv->rrGetInfo = dmxRRGetInfo;
pScrPriv->rrScreenSetSize = dmxRRScreenSetSize;
pScrPriv->rrCrtcSet = dmxRRCrtcSet;
pScrPriv->rrCrtcSetGamma = dmxRRCrtcSetGamma;
pScrPriv->rrOutputSetProperty = dmxRROutputSetProperty;
pScrPriv->rrOutputValidateMode = dmxRROutputValidateMode;
pScrPriv->rrModeDestroy = dmxRRModeDestroy;
RRScreenSetSizeRange (pScreen, 1, 1, SHRT_MAX, SHRT_MAX);
if (pScreen->myNum)
{
char name[64];
int i;
for (i = 0; i < xRROutputsPerScreen; i++)
{
sprintf (name,
"dmx%d",
(pScreen->myNum - 1) * xRROutputsPerScreen + i);
output = RROutputCreate (screenInfo.screens[0],
name,
strlen (name),
NULL);
if (!output)
return FALSE;
2008-05-30 23:00:52 -04:00
}
2008-06-03 18:18:04 -04:00
2008-05-30 23:00:52 -04:00
for (i = 0; i < xRRCrtcsPerScreen; i++)
{
2008-06-03 18:18:04 -04:00
crtc = RRCrtcCreate (screenInfo.screens[0], NULL);
if (!crtc)
return FALSE;
}
}
else
{
output = RROutputCreate (screenInfo.screens[0], "default", 7, NULL);
if (!output)
return FALSE;
crtc = RRCrtcCreate (screenInfo.screens[0], NULL);
if (!crtc)
return FALSE;
}
RegisterBlockAndWakeupHandlers (dmxRRBlockHandler,
dmxRRWakeupHandler,
NULL);
return TRUE;
}
#endif
/** Initialize the parts of screen \a idx that require access to the
* back-end server. */
void dmxBEScreenInit(int idx, ScreenPtr pScreen)
{
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
XSetWindowAttributes attribs;
XGCValues gcvals;
unsigned long mask;
int i, j;
/* FIXME: The dmxScreenInit() code currently assumes that it will
* not be called if the Xdmx server is started with this screen
* detached -- i.e., it assumes that dmxScreen->beDisplay is always
* valid. This is not necessarily a valid assumption when full
* addition/removal of screens is implemented, but when this code is
* broken out for screen reattachment, then we will reevaluate this
* assumption.
*/
pScreen->mmWidth = DisplayWidthMM(dmxScreen->beDisplay,
DefaultScreen(dmxScreen->beDisplay));
pScreen->mmHeight = DisplayHeightMM(dmxScreen->beDisplay,
DefaultScreen(dmxScreen->beDisplay));
pScreen->whitePixel = dmxScreen->beWhitePixel;
pScreen->blackPixel = dmxScreen->beBlackPixel;
/* Handle screen savers and DPMS on the backend */
dmxDPMSInit(dmxScreen);
/* Create root window for screen */
mask = CWBackPixel | CWEventMask | CWColormap | CWOverrideRedirect;
attribs.background_pixel = dmxScreen->beBlackPixel;
attribs.event_mask = (KeyPressMask
| KeyReleaseMask
| ButtonPressMask
| ButtonReleaseMask
| EnterWindowMask
| LeaveWindowMask
| PointerMotionMask
| KeymapStateMask
| FocusChangeMask);
attribs.colormap = dmxScreen->beDefColormaps[dmxScreen->beDefVisualIndex];
attribs.override_redirect = True;
2008-06-03 18:18:04 -04:00
dmxScreen->scrnWin =
XCreateWindow(dmxScreen->beDisplay,
DefaultRootWindow(dmxScreen->beDisplay),
dmxScreen->scrnX,
dmxScreen->scrnY,
dmxScreen->scrnWidth,
dmxScreen->scrnHeight,
0,
pScreen->rootDepth,
InputOutput,
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
mask,
&attribs);
dmxPropertyWindow(dmxScreen);
/*
* This turns off the cursor by defining a cursor with no visible
* components.
*/
2008-06-03 18:18:04 -04:00
if (1) {
char noCursorData[] = {0, 0, 0, 0,
0, 0, 0, 0};
Pixmap pixmap;
XColor color, tmp;
pixmap = XCreateBitmapFromData(dmxScreen->beDisplay, dmxScreen->scrnWin,
noCursorData, 8, 8);
XAllocNamedColor(dmxScreen->beDisplay, dmxScreen->beDefColormaps[0],
"black", &color, &tmp);
dmxScreen->noCursor = XCreatePixmapCursor(dmxScreen->beDisplay,
pixmap, pixmap,
&color, &color, 0, 0);
XDefineCursor(dmxScreen->beDisplay, dmxScreen->scrnWin,
dmxScreen->noCursor);
XFreePixmap(dmxScreen->beDisplay, pixmap);
}
2008-06-03 18:18:04 -04:00
#ifdef RANDR
if (dmxScreen->beRandr)
XRRSelectInput (dmxScreen->beDisplay,
DefaultRootWindow (dmxScreen->beDisplay),
RRScreenChangeNotifyMask |
RRCrtcChangeNotifyMask |
RROutputChangeNotifyMask |
RROutputPropertyNotifyMask);
#endif
XMapWindow (dmxScreen->beDisplay, dmxScreen->scrnWin);
XSetInputFocus (dmxScreen->beDisplay, dmxScreen->scrnWin,
RevertToPointerRoot,
CurrentTime);
if (dmxShadowFB) {
mask = (GCFunction
| GCPlaneMask
| GCClipMask);
gcvals.function = GXcopy;
gcvals.plane_mask = AllPlanes;
gcvals.clip_mask = None;
dmxScreen->shadowGC = XCreateGC(dmxScreen->beDisplay,
dmxScreen->scrnWin,
mask, &gcvals);
dmxScreen->shadowFBImage =
XCreateImage(dmxScreen->beDisplay,
dmxScreen->beVisuals[dmxScreen->beDefVisualIndex].visual,
dmxScreen->beDepth,
ZPixmap,
0,
(char *)dmxScreen->shadow,
dmxScreen->scrnWidth, dmxScreen->scrnHeight,
dmxScreen->beBPP,
PixmapBytePad(dmxScreen->scrnWidth,
dmxScreen->beBPP));
} else {
/* Create default drawables (used during GC creation) */
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++)
for (j = 0; j < dmxScreen->beNumDepths; j++)
if ((dmxScreen->bePixmapFormats[i].depth == 1) ||
(dmxScreen->bePixmapFormats[i].depth ==
dmxScreen->beDepths[j])) {
dmxScreen->scrnDefDrawables[i] = (Drawable)
XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
1, 1, dmxScreen->bePixmapFormats[i].depth);
break;
}
}
}
2008-06-03 18:18:04 -04:00
static void
dmxSetWindowPixmap (WindowPtr pWin, PixmapPtr pPixmap)
{
ScreenPtr pScreen = pWin->drawable.pScreen;
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
if (pPixmap != pOld)
{
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pWin);
if (pPixmap)
{
if ((*pScreen->GetWindowPixmap) (pWin->parent) != pPixmap)
{
pWinPriv->redirected = TRUE;
}
else if (pWinPriv->redirected)
{
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XCompositeUnredirectWindow (dmxScreen->beDisplay,
pWinPriv->window,
CompositeRedirectManual);
XLIB_EPILOGUE (dmxScreen);
}
pWinPriv->redirected = FALSE;
}
}
else if (pWinPriv->redirected)
{
if (dmxScreen->beDisplay)
{
XLIB_PROLOGUE (dmxScreen);
XCompositeUnredirectWindow (dmxScreen->beDisplay,
pWinPriv->window,
CompositeRedirectManual);
XLIB_EPILOGUE (dmxScreen);
}
pWinPriv->redirected = FALSE;
}
}
DMX_UNWRAP(SetWindowPixmap, dmxScreen, pScreen);
if (pScreen->SetWindowPixmap)
(*pScreen->SetWindowPixmap) (pWin, pPixmap);
DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen);
}
/** Initialize screen number \a idx. */
Bool dmxScreenInit(int idx, ScreenPtr pScreen, int argc, char *argv[])
{
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
int i, j;
if (dmxGeneration != serverGeneration) {
/* Allocate font private index */
dmxFontPrivateIndex = AllocateFontPrivateIndex();
if (dmxFontPrivateIndex == -1)
return FALSE;
dmxGeneration = serverGeneration;
}
2008-06-03 18:18:04 -04:00
#ifdef RANDR
dmxScreen->beRandr = FALSE;
dmxScreen->beRandrPending = FALSE;
#endif
if (dmxShadowFB) {
dmxScreen->shadow = shadowAlloc(dmxScreen->scrnWidth,
dmxScreen->scrnHeight,
dmxScreen->beBPP);
} else {
if (!dmxInitGC(pScreen)) return FALSE;
if (!dmxInitWindow(pScreen)) return FALSE;
if (!dmxInitPixmap(pScreen)) return FALSE;
}
/*
* Initalise the visual types. miSetVisualTypesAndMasks() requires
* that all of the types for each depth be collected together. It's
* intended for slightly different usage to what we would like here.
* Maybe a miAddVisualTypeAndMask() function will be added to make
* things easier here.
*/
2008-06-03 18:18:04 -04:00
if (dmxScreen->beDisplay)
{
for (i = 0; i < dmxScreen->beNumDepths; i++) {
int depth;
int visuals = 0;
int bitsPerRgb = 0;
int preferredClass = -1;
Pixel redMask = 0;
Pixel greenMask = 0;
Pixel blueMask = 0;
depth = dmxScreen->beDepths[i];
for (j = 0; j < dmxScreen->beNumVisuals; j++) {
XVisualInfo *vi;
vi = &dmxScreen->beVisuals[j];
if (vi->depth == depth) {
/* Assume the masks are all the same. */
visuals |= (1 << vi->class);
bitsPerRgb = vi->bits_per_rgb;
redMask = vi->red_mask;
greenMask = vi->green_mask;
blueMask = vi->blue_mask;
if (j == dmxScreen->beDefVisualIndex) {
preferredClass = vi->class;
}
}
}
2008-06-03 18:18:04 -04:00
miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb,
preferredClass,
redMask, greenMask, blueMask);
}
}
else
{
for (i = 0; i < dmxScreens[0].beNumDepths; i++) {
int depth;
int visuals = 0;
int bitsPerRgb = 0;
int preferredClass = -1;
Pixel redMask = 0;
Pixel greenMask = 0;
Pixel blueMask = 0;
depth = dmxScreens[0].beDepths[i];
for (j = 0; j < dmxScreens[0].beNumVisuals; j++) {
XVisualInfo *vi;
vi = &dmxScreens[0].beVisuals[j];
if (vi->depth == depth) {
/* Assume the masks are all the same. */
visuals |= (1 << vi->class);
bitsPerRgb = vi->bits_per_rgb;
redMask = vi->red_mask;
greenMask = vi->green_mask;
blueMask = vi->blue_mask;
if (j == dmxScreens[0].beDefVisualIndex) {
preferredClass = vi->class;
}
}
}
miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb,
preferredClass,
redMask, greenMask, blueMask);
}
}
fbScreenInit(pScreen,
dmxShadowFB ? dmxScreen->shadow : NULL,
dmxScreen->scrnWidth,
dmxScreen->scrnHeight,
dmxScreen->beXDPI,
2008-06-03 18:18:04 -04:00
dmxScreen->beYDPI,
dmxScreen->scrnWidth,
dmxScreen->beBPP);
#ifdef RENDER
(void)dmxPictureInit(pScreen, 0, 0);
#endif
2008-06-03 18:18:04 -04:00
#ifdef RANDR
if (!dmxRRInit (pScreen))
return FALSE;
#endif
if (dmxShadowFB && !shadowInit(pScreen, dmxShadowUpdateProc, NULL))
return FALSE;
miInitializeBackingStore(pScreen);
if (dmxShadowFB) {
miDCInitialize(pScreen, &dmxPointerCursorFuncs);
} else {
MAXSCREENSALLOC(dmxCursorGeneration);
if (dmxCursorGeneration[idx] != serverGeneration) {
if (!(miPointerInitialize(pScreen,
&dmxPointerSpriteFuncs,
&dmxPointerCursorFuncs,
FALSE)))
return FALSE;
dmxCursorGeneration[idx] = serverGeneration;
}
}
DMX_WRAP(CloseScreen, dmxCloseScreen, dmxScreen, pScreen);
DMX_WRAP(SaveScreen, dmxSaveScreen, dmxScreen, pScreen);
2008-06-03 18:18:04 -04:00
if (dmxScreen->beDisplay)
dmxBEScreenInit(idx, pScreen);
if (!dmxShadowFB) {
/* Wrap GC functions */
DMX_WRAP(CreateGC, dmxCreateGC, dmxScreen, pScreen);
/* Wrap Window functions */
DMX_WRAP(CreateWindow, dmxCreateWindow, dmxScreen, pScreen);
DMX_WRAP(DestroyWindow, dmxDestroyWindow, dmxScreen, pScreen);
DMX_WRAP(PositionWindow, dmxPositionWindow, dmxScreen, pScreen);
DMX_WRAP(ChangeWindowAttributes, dmxChangeWindowAttributes, dmxScreen,
pScreen);
DMX_WRAP(RealizeWindow, dmxRealizeWindow, dmxScreen, pScreen);
DMX_WRAP(UnrealizeWindow, dmxUnrealizeWindow, dmxScreen, pScreen);
DMX_WRAP(RestackWindow, dmxRestackWindow, dmxScreen, pScreen);
DMX_WRAP(WindowExposures, dmxWindowExposures, dmxScreen, pScreen);
DMX_WRAP(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
2008-06-03 18:18:04 -04:00
DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen);
/* Wrap Image functions */
DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
2008-06-03 18:27:49 -04:00
DMX_WRAP(GetSpans, NULL, dmxScreen, pScreen);
/* Wrap Pixmap functions */
DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen);
DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen);
DMX_WRAP(BitmapToRegion, dmxBitmapToRegion, dmxScreen, pScreen);
/* Wrap Font functions */
DMX_WRAP(RealizeFont, dmxRealizeFont, dmxScreen, pScreen);
DMX_WRAP(UnrealizeFont, dmxUnrealizeFont, dmxScreen, pScreen);
/* Wrap Colormap functions */
DMX_WRAP(CreateColormap, dmxCreateColormap, dmxScreen, pScreen);
DMX_WRAP(DestroyColormap, dmxDestroyColormap, dmxScreen, pScreen);
DMX_WRAP(InstallColormap, dmxInstallColormap, dmxScreen, pScreen);
DMX_WRAP(StoreColors, dmxStoreColors, dmxScreen, pScreen);
/* Wrap Shape functions */
DMX_WRAP(SetShape, dmxSetShape, dmxScreen, pScreen);
}
if (!dmxCreateDefColormap(pScreen))
return FALSE;
return TRUE;
}
/** Close the \a pScreen resources on the back-end server. */
void dmxBECloseScreen(ScreenPtr pScreen)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
int i;
/* Restore the back-end screen-saver and DPMS state. */
dmxDPMSTerm(dmxScreen);
/* Free the screen resources */
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XFreeCursor(dmxScreen->beDisplay, dmxScreen->noCursor);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxScreen->noCursor = (Cursor)0;
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XUnmapWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
XDestroyWindow(dmxScreen->beDisplay, dmxScreen->scrnWin);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxScreen->scrnWin = (Window)0;
if (dmxShadowFB) {
/* Free the shadow GC and image assocated with the back-end server */
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XFreeGC(dmxScreen->beDisplay, dmxScreen->shadowGC);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxScreen->shadowGC = NULL;
XFree(dmxScreen->shadowFBImage);
dmxScreen->shadowFBImage = NULL;
} else {
/* Free the default drawables */
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XFreePixmap(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i]);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxScreen->scrnDefDrawables[i] = (Drawable)0;
}
}
/* Free resources allocated during initialization (in dmxinit.c) */
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
2008-06-03 18:18:04 -04:00
{
XLIB_PROLOGUE (dmxScreen);
XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
}
xfree(dmxScreen->beDefColormaps);
dmxScreen->beDefColormaps = NULL;
#if 0
/* Do not free visuals, depths and pixmap formats here. Free them
* in dmxCloseScreen() instead -- see comment below. */
XFree(dmxScreen->beVisuals);
dmxScreen->beVisuals = NULL;
XFree(dmxScreen->beDepths);
dmxScreen->beDepths = NULL;
XFree(dmxScreen->bePixmapFormats);
dmxScreen->bePixmapFormats = NULL;
#endif
#ifdef GLXEXT
if (dmxScreen->glxVisuals) {
XFree(dmxScreen->glxVisuals);
dmxScreen->glxVisuals = NULL;
dmxScreen->numGlxVisuals = 0;
}
#endif
/* Close display */
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XCloseDisplay(dmxScreen->beDisplay);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxScreen->beDisplay = NULL;
}
/** Close screen number \a idx. */
Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
{
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
/* Reset the proc vectors */
if (idx == 0) {
#ifdef RENDER
dmxResetRender();
#endif
dmxResetFonts();
}
if (dmxShadowFB) {
/* Free the shadow framebuffer */
xfree(dmxScreen->shadow);
} else {
/* Unwrap Shape functions */
DMX_UNWRAP(SetShape, dmxScreen, pScreen);
/* Unwrap the pScreen functions */
DMX_UNWRAP(CreateGC, dmxScreen, pScreen);
DMX_UNWRAP(CreateWindow, dmxScreen, pScreen);
DMX_UNWRAP(DestroyWindow, dmxScreen, pScreen);
DMX_UNWRAP(PositionWindow, dmxScreen, pScreen);
DMX_UNWRAP(ChangeWindowAttributes, dmxScreen, pScreen);
DMX_UNWRAP(RealizeWindow, dmxScreen, pScreen);
DMX_UNWRAP(UnrealizeWindow, dmxScreen, pScreen);
DMX_UNWRAP(RestackWindow, dmxScreen, pScreen);
DMX_UNWRAP(WindowExposures, dmxScreen, pScreen);
DMX_UNWRAP(CopyWindow, dmxScreen, pScreen);
DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
DMX_UNWRAP(GetImage, dmxScreen, pScreen);
DMX_UNWRAP(GetSpans, dmxScreen, pScreen);
DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen);
DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen);
DMX_UNWRAP(BitmapToRegion, dmxScreen, pScreen);
DMX_UNWRAP(RealizeFont, dmxScreen, pScreen);
DMX_UNWRAP(UnrealizeFont, dmxScreen, pScreen);
DMX_UNWRAP(CreateColormap, dmxScreen, pScreen);
DMX_UNWRAP(DestroyColormap, dmxScreen, pScreen);
DMX_UNWRAP(InstallColormap, dmxScreen, pScreen);
DMX_UNWRAP(StoreColors, dmxScreen, pScreen);
}
DMX_UNWRAP(SaveScreen, dmxScreen, pScreen);
if (dmxScreen->beDisplay) {
dmxBECloseScreen(pScreen);
#if 1
/* Free visuals, depths and pixmap formats here so that they
* won't be freed when a screen is detached, thereby allowing
* the screen to be reattached to be compared to the one
* previously removed.
*/
XFree(dmxScreen->beVisuals);
dmxScreen->beVisuals = NULL;
XFree(dmxScreen->beDepths);
dmxScreen->beDepths = NULL;
XFree(dmxScreen->bePixmapFormats);
dmxScreen->bePixmapFormats = NULL;
#endif
}
DMX_UNWRAP(CloseScreen, dmxScreen, pScreen);
return pScreen->CloseScreen(idx, pScreen);
}
static Bool dmxSaveScreen(ScreenPtr pScreen, int what)
{
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
if (dmxScreen->beDisplay) {
switch (what) {
case SCREEN_SAVER_OFF:
case SCREEN_SAVER_FORCER:
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XResetScreenSaver(dmxScreen->beDisplay);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
break;
case SCREEN_SAVER_ON:
case SCREEN_SAVER_CYCLE:
2008-06-03 18:18:04 -04:00
XLIB_PROLOGUE (dmxScreen);
XActivateScreenSaver(dmxScreen->beDisplay);
2008-06-03 18:18:04 -04:00
XLIB_EPILOGUE (dmxScreen);
dmxSync(dmxScreen, FALSE);
break;
}
}
return TRUE;
}