mirror of
https://gitlab.freedesktop.org/xorg/xserver.git
synced 2025-12-20 22:10:03 +01:00
1499 lines
38 KiB
C
1499 lines
38 KiB
C
/*
|
|
* 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"
|
|
#include "dmxextension.h"
|
|
#include "dmxsync.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"
|
|
#include "dmxlog.h"
|
|
#include "dmxcb.h"
|
|
#include "dmxinit.h"
|
|
#include "dmxgrab.h"
|
|
#include "dmxselection.h"
|
|
#include "dmxatom.h"
|
|
#include "dmxshm.h"
|
|
#include "dmxdnd.h"
|
|
#include "dmxlaunch.h"
|
|
|
|
#ifdef PANORAMIX
|
|
#include "panoramiX.h"
|
|
#include "panoramiXsrv.h"
|
|
#endif
|
|
|
|
#ifdef RENDER
|
|
#include "dmxpict.h"
|
|
#endif
|
|
|
|
#ifdef COMPOSITE
|
|
#include "dmxcomp.h"
|
|
#endif
|
|
|
|
#ifdef RANDR
|
|
#include "dmxrandr.h"
|
|
#endif
|
|
|
|
#ifdef XV
|
|
#include "dmxxv.h"
|
|
#endif
|
|
|
|
#include "fb.h"
|
|
#include "mipointer.h"
|
|
#include "micmap.h"
|
|
#include "mivalidate.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 = &dmxGCPrivateKeyIndex; /**< 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 */
|
|
static int dmxDevicePrivateKeyIndex;
|
|
DevPrivateKey dmxDevicePrivateKey = &dmxDevicePrivateKeyIndex; /**< Private index for Devices */
|
|
#ifdef RENDER
|
|
static int dmxPictPrivateKeyIndex;
|
|
DevPrivateKey dmxPictPrivateKey = &dmxPictPrivateKeyIndex; /**< Private index for Picts */
|
|
static int dmxGlyphSetPrivateKeyIndex;
|
|
DevPrivateKey dmxGlyphSetPrivateKey = &dmxGlyphSetPrivateKeyIndex; /**< Private index for GlyphSets */
|
|
static int dmxGlyphPrivateKeyIndex;
|
|
DevPrivateKey dmxGlyphPrivateKey = &dmxGlyphPrivateKeyIndex; /**< Private index for Glyphs */
|
|
#endif
|
|
|
|
/** Initialize the parts of screen \a idx that require access to the
|
|
* back-end server. */
|
|
void dmxBEScreenInit(ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
char buf[256];
|
|
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;
|
|
|
|
dmxScreen->selectionOwner = None;
|
|
|
|
sprintf(buf, "DMX_%s", dmxDigest);
|
|
|
|
/* prefetch all valid atoms */
|
|
for (i = 1; ValidAtom ((Atom) i); i++);
|
|
while (--i)
|
|
dmxBEPrefetchAtom (dmxScreen, (Atom) i);
|
|
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
dmxScreen->beSelectionAtom = XInternAtom (dmxScreen->beDisplay, buf, 0);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
|
|
/* Handle screen savers and DPMS on the backend */
|
|
dmxBEDPMSScreenInit (pScreen);
|
|
|
|
#ifdef MITSHM
|
|
dmxBEShmScreenInit (pScreen);
|
|
#endif
|
|
|
|
#ifdef RANDR
|
|
dmxBERRScreenInit (pScreen);
|
|
#endif
|
|
|
|
#ifdef XV
|
|
dmxBEXvScreenInit (pScreen);
|
|
#endif
|
|
|
|
/* 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])) {
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
dmxScreen->scrnDefDrawables[i] = (Drawable)
|
|
XCreatePixmap(dmxScreen->beDisplay, dmxScreen->scrnWin,
|
|
1, 1, dmxScreen->bePixmapFormats[i].depth);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
break;
|
|
}
|
|
}
|
|
|
|
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 && (*pScreen->GetWindowPixmap) (pWin->parent) != pPixmap)
|
|
pWinPriv->redirected = TRUE;
|
|
else
|
|
pWinPriv->redirected = FALSE;
|
|
}
|
|
|
|
DMX_UNWRAP(SetWindowPixmap, dmxScreen, pScreen);
|
|
if (pScreen->SetWindowPixmap)
|
|
(*pScreen->SetWindowPixmap) (pWin, pPixmap);
|
|
DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen);
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckInput (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
return dmxInputEventCheck (&dmxScreen->input, event);
|
|
}
|
|
|
|
static void
|
|
dmxScreenGetSelectionOwner (ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
dmxScreen->selectionOwner = None;
|
|
while (dmxScreen->selectionOwner == None)
|
|
{
|
|
xcb_connection_t *c = dmxScreen->connection;
|
|
xcb_atom_t a = dmxScreen->beSelectionAtom;
|
|
xcb_get_selection_owner_reply_t *reply;
|
|
|
|
reply = xcb_get_selection_owner_reply (c,
|
|
xcb_get_selection_owner (c, a),
|
|
NULL);
|
|
if (!reply)
|
|
break;
|
|
|
|
if (reply->owner)
|
|
{
|
|
if (reply->owner != dmxScreen->rootWin)
|
|
{
|
|
const uint32_t value = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
|
|
xcb_void_cookie_t r;
|
|
xcb_generic_error_t *error;
|
|
|
|
r = xcb_change_window_attributes_checked (c,
|
|
reply->owner,
|
|
XCB_CW_EVENT_MASK,
|
|
&value);
|
|
error = xcb_request_check (c, r);
|
|
if (error)
|
|
{
|
|
if (error->error_code != BadWindow)
|
|
dmxScreen->selectionOwner = reply->owner;
|
|
|
|
free (error);
|
|
}
|
|
else
|
|
{
|
|
dmxScreen->selectionOwner = reply->owner;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dmxScreen->selectionOwner = dmxScreen->rootWin;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
xcb_set_selection_owner (dmxScreen->connection,
|
|
dmxScreen->rootWin,
|
|
dmxScreen->beSelectionAtom,
|
|
0);
|
|
}
|
|
|
|
free (reply);
|
|
}
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckSelection (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_DESTROY_NOTIFY: {
|
|
xcb_destroy_notify_event_t *xdestroy =
|
|
(xcb_destroy_notify_event_t *) event;
|
|
|
|
if (dmxSelectionDestroyNotify (pScreen, xdestroy->window))
|
|
return TRUE;
|
|
|
|
if (xdestroy->window != dmxScreen->selectionOwner)
|
|
return FALSE;
|
|
|
|
if (dmxScreen->selectionOwner == dmxScreen->rootWin)
|
|
return FALSE;
|
|
|
|
dmxScreenGetSelectionOwner (pScreen);
|
|
} break;
|
|
case XCB_PROPERTY_NOTIFY: {
|
|
xcb_property_notify_event_t *xproperty =
|
|
(xcb_property_notify_event_t *) event;
|
|
|
|
if (!dmxSelectionPropertyNotify (pScreen,
|
|
xproperty->window,
|
|
xproperty->state,
|
|
xproperty->atom,
|
|
xproperty->time))
|
|
return FALSE;
|
|
} break;
|
|
case XCB_SELECTION_CLEAR: {
|
|
xcb_selection_clear_event_t *xclear =
|
|
(xcb_selection_clear_event_t *) event;
|
|
|
|
if (xclear->selection == dmxScreen->beSelectionAtom)
|
|
{
|
|
dmxScreenGetSelectionOwner (pScreen);
|
|
}
|
|
else
|
|
{
|
|
dmxSelectionClear (pScreen,
|
|
xclear->owner,
|
|
xclear->selection);
|
|
}
|
|
} break;
|
|
case XCB_SELECTION_NOTIFY: {
|
|
xcb_selection_notify_event_t *xnotify =
|
|
(xcb_selection_notify_event_t *) event;
|
|
|
|
dmxSelectionNotify (pScreen,
|
|
xnotify->requestor,
|
|
xnotify->selection,
|
|
xnotify->target,
|
|
xnotify->property,
|
|
xnotify->time);
|
|
} break;
|
|
case XCB_SELECTION_REQUEST: {
|
|
xcb_selection_request_event_t *xrequest =
|
|
(xcb_selection_request_event_t *) event;
|
|
|
|
dmxSelectionRequest (pScreen,
|
|
xrequest->owner,
|
|
xrequest->requestor,
|
|
xrequest->selection,
|
|
xrequest->target,
|
|
xrequest->property,
|
|
xrequest->time);
|
|
} break;
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
dmxDiscardIgnore (DMXScreenInfo *dmxScreen,
|
|
unsigned long sequence)
|
|
{
|
|
while (dmxScreen->ignore.head)
|
|
{
|
|
if ((long) (sequence - dmxScreen->ignore.head->sequence) > 0)
|
|
{
|
|
DMXSequence *next = dmxScreen->ignore.head->next;
|
|
|
|
free (dmxScreen->ignore.head);
|
|
|
|
dmxScreen->ignore.head = next;
|
|
if (!dmxScreen->ignore.head)
|
|
dmxScreen->ignore.tail = &dmxScreen->ignore.head;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
static Bool
|
|
dmxShouldIgnore (DMXScreenInfo *dmxScreen,
|
|
unsigned long sequence)
|
|
{
|
|
dmxDiscardIgnore (dmxScreen, sequence);
|
|
|
|
if (!dmxScreen->ignore.head)
|
|
return FALSE;
|
|
|
|
return dmxScreen->ignore.head->sequence == sequence;
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckExpose (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
xcb_expose_event_t *xexpose = (xcb_expose_event_t *) event;
|
|
WindowPtr pChild0, pChildN;
|
|
|
|
if ((event->response_type & ~0x80) != XCB_EXPOSE)
|
|
return FALSE;
|
|
|
|
if (dmxShouldIgnore (dmxScreen, xexpose->sequence))
|
|
return TRUE;
|
|
|
|
pChild0 = WindowTable[0];
|
|
pChildN = WindowTable[pScreen->myNum];
|
|
|
|
for (;;)
|
|
{
|
|
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pChildN);
|
|
|
|
if (pWinPriv->window == xexpose->window)
|
|
break;
|
|
|
|
if (pChild0->firstChild)
|
|
{
|
|
assert (pChildN->firstChild);
|
|
pChild0 = pChild0->firstChild;
|
|
pChildN = pChildN->firstChild;
|
|
continue;
|
|
}
|
|
|
|
while (!pChild0->nextSib && (pChild0 != WindowTable[0]))
|
|
{
|
|
assert (!pChildN->nextSib &&
|
|
(pChildN != WindowTable[pScreen->myNum]));
|
|
pChild0 = pChild0->parent;
|
|
pChildN = pChildN->parent;
|
|
}
|
|
|
|
if (pChild0 == WindowTable[0])
|
|
{
|
|
assert (pChildN == WindowTable[pScreen->myNum]);
|
|
break;
|
|
}
|
|
|
|
pChild0 = pChild0->nextSib;
|
|
pChildN = pChildN->nextSib;
|
|
}
|
|
|
|
if (pChild0)
|
|
{
|
|
RegionRec region;
|
|
BoxRec box;
|
|
|
|
box.x1 = pChild0->drawable.x + xexpose->x;
|
|
box.y1 = pChild0->drawable.y + xexpose->y;
|
|
box.x2 = box.x1 + xexpose->width;
|
|
box.y2 = box.y1 + xexpose->height;
|
|
|
|
REGION_INIT (screenInfo.screens[0], ®ion, &box, 1);
|
|
(*pScreen->WindowExposures) (pChild0, ®ion, NullRegion);
|
|
REGION_UNINIT (screenInfo.screens[0], ®ion);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckOutputWindow (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_DESTROY_NOTIFY: {
|
|
xcb_destroy_notify_event_t *xdestroy =
|
|
(xcb_destroy_notify_event_t *) event;
|
|
|
|
if (xdestroy->window != dmxScreen->scrnWin)
|
|
return FALSE;
|
|
|
|
/* output window has been destroyed, detach screen when we reach
|
|
the block handler */
|
|
dmxScreen->scrnWin = None;
|
|
return TRUE;
|
|
} break;
|
|
case XCB_MAP_NOTIFY: {
|
|
xcb_map_notify_event_t *xmap = (xcb_map_notify_event_t *) event;
|
|
|
|
if (xmap->window == dmxScreen->scrnWin)
|
|
return TRUE;
|
|
} break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckManageRoot (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
WindowPtr pChild = WindowTable[pScreen->myNum];
|
|
Window xWindow;
|
|
|
|
#ifdef PANORAMIX
|
|
PanoramiXRes *win = NULL;
|
|
WindowPtr pWin;
|
|
#endif
|
|
|
|
xcb_circulate_request_event_t *xcirculaterequest =
|
|
(xcb_circulate_request_event_t *) event;
|
|
xcb_configure_request_event_t *xconfigurerequest =
|
|
(xcb_configure_request_event_t *) event;
|
|
xcb_map_request_event_t *xmaprequest =
|
|
(xcb_map_request_event_t *) event;
|
|
xcb_client_message_event_t *xclient =
|
|
(xcb_client_message_event_t *) event;
|
|
xcb_map_notify_event_t *xmap =
|
|
(xcb_map_notify_event_t *) event;
|
|
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_CIRCULATE_REQUEST:
|
|
xWindow = xcirculaterequest->window;
|
|
break;
|
|
case XCB_CONFIGURE_REQUEST:
|
|
xWindow = xconfigurerequest->window;
|
|
break;
|
|
case XCB_MAP_REQUEST:
|
|
xWindow = xmaprequest->window;
|
|
break;
|
|
case XCB_CLIENT_MESSAGE:
|
|
xWindow = xclient->window;
|
|
break;
|
|
case XCB_MAP_NOTIFY:
|
|
if (xmap->window == dmxScreen->rootWin)
|
|
{
|
|
dmxScreenGetSelectionOwner (pScreen);
|
|
return TRUE;
|
|
}
|
|
|
|
/* fall-through */
|
|
default:
|
|
return FALSE;
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
dmxWinPrivPtr pWinPriv = DMX_GET_WINDOW_PRIV (pChild);
|
|
|
|
if (pWinPriv->window == xWindow)
|
|
{
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
win = PanoramiXFindIDByScrnum (XRT_WINDOW,
|
|
pChild->drawable.id,
|
|
pScreen->myNum);
|
|
#endif
|
|
|
|
break;
|
|
}
|
|
|
|
if (pChild->firstChild)
|
|
{
|
|
pChild = pChild->firstChild;
|
|
continue;
|
|
}
|
|
|
|
while (!pChild->nextSib &&
|
|
(pChild != WindowTable[pScreen->myNum]))
|
|
pChild = pChild->parent;
|
|
|
|
if (pChild == WindowTable[pScreen->myNum])
|
|
break;
|
|
|
|
pChild = pChild->nextSib;
|
|
}
|
|
|
|
if (pChild
|
|
|
|
#ifdef PANORAMIX
|
|
&& win
|
|
#endif
|
|
|
|
)
|
|
{
|
|
XID vlist[8];
|
|
Atom type;
|
|
int mask, i = 0;
|
|
int status = Success;
|
|
xEvent x;
|
|
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_CIRCULATE_REQUEST:
|
|
vlist[0] = None;
|
|
|
|
if (xcirculaterequest->place == XCB_PLACE_ON_TOP)
|
|
vlist[1] = Above;
|
|
else
|
|
vlist[1] = Below;
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
int j;
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
if (dixLookupWindow (&pWin,
|
|
win->info[j].id,
|
|
serverClient,
|
|
DixReadAccess) == Success)
|
|
status |= ConfigureWindow (pWin,
|
|
CWSibling |
|
|
CWStackMode,
|
|
vlist,
|
|
serverClient);
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
status = ConfigureWindow (pChild,
|
|
CWSibling | CWStackMode,
|
|
vlist,
|
|
serverClient);
|
|
break;
|
|
case XCB_CONFIGURE_REQUEST:
|
|
mask = xconfigurerequest->value_mask;
|
|
|
|
if (mask & (XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y))
|
|
{
|
|
vlist[i++] = xconfigurerequest->x;
|
|
vlist[i++] = xconfigurerequest->y;
|
|
}
|
|
|
|
if (mask & (XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT))
|
|
{
|
|
vlist[i++] = xconfigurerequest->width;
|
|
vlist[i++] = xconfigurerequest->height;
|
|
}
|
|
|
|
if (mask & XCB_CONFIG_WINDOW_BORDER_WIDTH)
|
|
vlist[i++] = xconfigurerequest->border_width;
|
|
|
|
if (mask & XCB_CONFIG_WINDOW_SIBLING)
|
|
{
|
|
/* ignore stacking requests with sibling */
|
|
if (xconfigurerequest->sibling == None)
|
|
vlist[i++] = None;
|
|
else
|
|
mask &= ~(XCB_CONFIG_WINDOW_SIBLING |
|
|
XCB_CONFIG_WINDOW_STACK_MODE);
|
|
}
|
|
|
|
if (mask & XCB_CONFIG_WINDOW_STACK_MODE)
|
|
vlist[i++] = xconfigurerequest->stack_mode;
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
int j;
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
if (dixLookupWindow (&pWin,
|
|
win->info[j].id,
|
|
serverClient,
|
|
DixReadAccess) == Success)
|
|
status |= ConfigureWindow (pWin,
|
|
mask,
|
|
vlist,
|
|
serverClient);
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
|
|
status = ConfigureWindow (pChild,
|
|
mask,
|
|
vlist,
|
|
serverClient);
|
|
break;
|
|
case XCB_MAP_REQUEST:
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
int j;
|
|
|
|
FOR_NSCREENS_FORWARD(j) {
|
|
if (dixLookupWindow (&pWin,
|
|
win->info[j].id,
|
|
serverClient,
|
|
DixReadAccess) == Success)
|
|
status |= MapWindow (pWin, serverClient);
|
|
}
|
|
}
|
|
else
|
|
#endif
|
|
|
|
status = MapWindow (pChild, serverClient);
|
|
break;
|
|
case XCB_CLIENT_MESSAGE:
|
|
x.u.u.type = ClientMessage | 0x80;
|
|
x.u.u.detail = xclient->format;
|
|
x.u.clientMessage.window = pChild->drawable.id;
|
|
|
|
type = dmxAtom (dmxScreen, xclient->type);
|
|
|
|
switch (xclient->format) {
|
|
case 8:
|
|
x.u.clientMessage.u.b.type = type;
|
|
|
|
for (i = 0; i < 20; i++)
|
|
x.u.clientMessage.u.b.bytes[i] = xclient->data.data8[i];
|
|
break;
|
|
case 16:
|
|
x.u.clientMessage.u.s.type = type;
|
|
|
|
x.u.clientMessage.u.s.shorts0 = xclient->data.data16[0];
|
|
x.u.clientMessage.u.s.shorts1 = xclient->data.data16[1];
|
|
x.u.clientMessage.u.s.shorts2 = xclient->data.data16[2];
|
|
x.u.clientMessage.u.s.shorts3 = xclient->data.data16[3];
|
|
x.u.clientMessage.u.s.shorts4 = xclient->data.data16[4];
|
|
x.u.clientMessage.u.s.shorts5 = xclient->data.data16[5];
|
|
x.u.clientMessage.u.s.shorts6 = xclient->data.data16[6];
|
|
x.u.clientMessage.u.s.shorts7 = xclient->data.data16[7];
|
|
x.u.clientMessage.u.s.shorts8 = xclient->data.data16[8];
|
|
x.u.clientMessage.u.s.shorts9 = xclient->data.data16[9];
|
|
break;
|
|
case 32:
|
|
x.u.clientMessage.u.l.type = type;
|
|
|
|
x.u.clientMessage.u.l.longs0 = xclient->data.data32[0];
|
|
x.u.clientMessage.u.l.longs1 = xclient->data.data32[1];
|
|
x.u.clientMessage.u.l.longs2 = xclient->data.data32[2];
|
|
x.u.clientMessage.u.l.longs3 = xclient->data.data32[3];
|
|
x.u.clientMessage.u.l.longs4 = xclient->data.data32[4];
|
|
break;
|
|
}
|
|
|
|
/* client messages are always forwarded to the root
|
|
window as there's no way for us to know which
|
|
windows they were originally intended for */
|
|
pWin = WindowTable[pScreen->myNum];
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
x.u.clientMessage.window = win->info[0].id;
|
|
pWin = WindowTable[0];
|
|
}
|
|
#endif
|
|
|
|
DeliverEventsToWindow (PickPointer (serverClient),
|
|
pWin,
|
|
&x,
|
|
1,
|
|
SubstructureRedirectMask |
|
|
SubstructureNotifyMask,
|
|
NullGrab, 0);
|
|
break;
|
|
}
|
|
|
|
if (status != Success)
|
|
dmxLog (dmxWarning,
|
|
"dmxScreenManage: failed to handle "
|
|
"request type %d\n",
|
|
event->response_type & ~0x80);
|
|
}
|
|
else
|
|
{
|
|
XWindowChanges xwc;
|
|
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_CIRCULATE_REQUEST:
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
if (xcirculaterequest->place == XCB_PLACE_ON_TOP)
|
|
XRaiseWindow (dmxScreen->beDisplay,
|
|
xcirculaterequest->window);
|
|
else
|
|
XLowerWindow (dmxScreen->beDisplay,
|
|
xcirculaterequest->window);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
break;
|
|
case XCB_CONFIGURE_REQUEST:
|
|
xwc.x = xconfigurerequest->x;
|
|
xwc.y = xconfigurerequest->y;
|
|
xwc.width = xconfigurerequest->width;
|
|
xwc.height = xconfigurerequest->height;
|
|
xwc.border_width = xconfigurerequest->border_width;
|
|
xwc.sibling = xconfigurerequest->sibling;
|
|
xwc.stack_mode = xconfigurerequest->stack_mode;
|
|
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XConfigureWindow (dmxScreen->beDisplay,
|
|
xconfigurerequest->window,
|
|
xconfigurerequest->value_mask,
|
|
&xwc);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
break;
|
|
case XCB_MAP_REQUEST:
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XMapWindow (dmxScreen->beDisplay, xmaprequest->window);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
break;
|
|
case XCB_CLIENT_MESSAGE:
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static Bool
|
|
dmxScreenEventCheckIgnore (ScreenPtr pScreen,
|
|
xcb_generic_event_t *event)
|
|
{
|
|
switch (event->response_type & ~0x80) {
|
|
case XCB_MAPPING_NOTIFY:
|
|
return TRUE;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
void
|
|
dmxBEDispatch (ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
xcb_generic_event_t *event;
|
|
xcb_generic_error_t *error;
|
|
void *reply;
|
|
|
|
assert (dmxScreen->inDispatch == FALSE);
|
|
dmxScreen->inDispatch = TRUE;
|
|
|
|
while ((event = xcb_poll_for_event (dmxScreen->connection)))
|
|
{
|
|
if (!dmxScreenEventCheckInput (pScreen, event) &&
|
|
!dmxScreenEventCheckSelection (pScreen, event) &&
|
|
!dmxScreenEventCheckDnD (pScreen, event) &&
|
|
!dmxScreenEventCheckOutputWindow (pScreen, event) &&
|
|
!dmxScreenEventCheckManageRoot (pScreen, event) &&
|
|
!dmxScreenEventCheckExpose (pScreen, event) &&
|
|
|
|
#ifdef MITSHM
|
|
!dmxScreenEventCheckShm (pScreen, event) &&
|
|
#endif
|
|
|
|
#ifdef RANDR
|
|
!dmxScreenEventCheckRR (pScreen, event) &&
|
|
#endif
|
|
|
|
!dmxScreenEventCheckIgnore (pScreen, event))
|
|
{
|
|
if (event->response_type == 0)
|
|
{
|
|
xcb_generic_error_t *error = (xcb_generic_error_t *) event;
|
|
|
|
dmxLogOutput (dmxScreen, "unhandled error type %d\n",
|
|
error->error_code);
|
|
}
|
|
else
|
|
{
|
|
dmxLogOutput (dmxScreen, "unhandled event type %d\n",
|
|
event->response_type);
|
|
}
|
|
}
|
|
|
|
free (event);
|
|
}
|
|
|
|
while (dmxScreen->request.head &&
|
|
xcb_poll_for_reply (dmxScreen->connection,
|
|
dmxScreen->request.head->sequence,
|
|
(void **) &reply,
|
|
&error))
|
|
{
|
|
DMXRequest *head = (DMXRequest *) dmxScreen->request.head;
|
|
|
|
dmxScreen->request.head = head->base.next;
|
|
if (!dmxScreen->request.head)
|
|
dmxScreen->request.tail = &dmxScreen->request.head;
|
|
|
|
(*head->reply) (pScreen,
|
|
head->base.sequence,
|
|
reply,
|
|
error,
|
|
head->data);
|
|
|
|
if (reply)
|
|
free (reply);
|
|
if (error)
|
|
free (error);
|
|
|
|
free (head);
|
|
}
|
|
|
|
if (!dmxScreen->scrnWin ||
|
|
xcb_connection_has_error (dmxScreen->connection))
|
|
{
|
|
static xcb_generic_error_t detached_error = { 0, DMX_DETACHED };
|
|
|
|
while (dmxScreen->request.head)
|
|
{
|
|
DMXRequest *head = (DMXRequest *) dmxScreen->request.head;
|
|
|
|
dmxScreen->request.head = head->base.next;
|
|
if (!dmxScreen->request.head)
|
|
dmxScreen->request.tail = &dmxScreen->request.head;
|
|
|
|
(*head->reply) (pScreen,
|
|
head->base.sequence,
|
|
NULL,
|
|
&detached_error,
|
|
head->data);
|
|
|
|
free (head);
|
|
}
|
|
|
|
dmxScreen->broken = TRUE;
|
|
}
|
|
|
|
dmxScreen->inDispatch = FALSE;
|
|
}
|
|
|
|
static void
|
|
dmxScreenCheckForIOError (ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
if (!dmxScreen->scrnWin ||
|
|
xcb_connection_has_error (dmxScreen->connection))
|
|
{
|
|
int i;
|
|
|
|
if (dmxScreen->scrnWin)
|
|
{
|
|
dmxLogOutput (dmxScreen, "Detected broken connection\n");
|
|
dmxScreen->alive = FALSE;
|
|
}
|
|
|
|
if (!dmxScreen->broken)
|
|
dmxBEDispatch (pScreen);
|
|
|
|
dmxDetachScreen (pScreen->myNum);
|
|
|
|
for (i = 0; i < dmxNumScreens; i++)
|
|
if (i != pScreen->myNum && dmxScreens[i].beDisplay)
|
|
break;
|
|
|
|
if (i == dmxNumScreens)
|
|
dmxLog (dmxFatal, "No back-end server connection, "
|
|
"giving up\n");
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxScreenBlockHandler (pointer blockData,
|
|
OSTimePtr pTimeout,
|
|
pointer pReadMask)
|
|
{
|
|
ScreenPtr pScreen = (ScreenPtr) blockData;
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
if (dmxScreen->alive)
|
|
{
|
|
xcb_flush (dmxScreen->connection);
|
|
dmxScreenCheckForIOError (pScreen);
|
|
}
|
|
}
|
|
|
|
static void
|
|
dmxScreenWakeupHandler (pointer blockData,
|
|
int result,
|
|
pointer pReadMask)
|
|
{
|
|
ScreenPtr pScreen = (ScreenPtr) blockData;
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
|
|
if (dmxScreen->alive)
|
|
dmxBEDispatch (pScreen);
|
|
}
|
|
|
|
static void
|
|
dmxHandleExposures (WindowPtr pWin)
|
|
{
|
|
WindowPtr pChild;
|
|
ValidatePtr val;
|
|
ScreenPtr pScreen;
|
|
WindowExposuresProcPtr WindowExposures;
|
|
|
|
pScreen = pWin->drawable.pScreen;
|
|
|
|
pChild = pWin;
|
|
WindowExposures = pChild->drawable.pScreen->WindowExposures;
|
|
while (1)
|
|
{
|
|
if ( (val = pChild->valdata) )
|
|
{
|
|
REGION_UNINIT(pScreen, &val->after.borderExposed);
|
|
(*WindowExposures)(pChild, &val->after.exposed, NullRegion);
|
|
REGION_UNINIT(pScreen, &val->after.exposed);
|
|
xfree(val);
|
|
pChild->valdata = (ValidatePtr)NULL;
|
|
if (pChild->firstChild)
|
|
{
|
|
pChild = pChild->firstChild;
|
|
continue;
|
|
}
|
|
}
|
|
while (!pChild->nextSib && (pChild != pWin))
|
|
pChild = pChild->parent;
|
|
if (pChild == pWin)
|
|
break;
|
|
pChild = pChild->nextSib;
|
|
}
|
|
}
|
|
|
|
/** 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;
|
|
}
|
|
|
|
dmxInputInit (&dmxScreen->input);
|
|
|
|
dmxScreen->ignore.head = NULL;
|
|
dmxScreen->ignore.tail = &dmxScreen->ignore.head;
|
|
|
|
dmxScreen->request.head = NULL;
|
|
dmxScreen->request.tail = &dmxScreen->request.head;
|
|
|
|
dmxScreen->scrnEventMask = 0;
|
|
|
|
dmxScreen->rootEventMask = ExposureMask | StructureNotifyMask |
|
|
SubstructureRedirectMask;
|
|
|
|
dmxScreen->multipleAtom = MakeAtom ("MULTIPLE", strlen ("MULTIPLE"), TRUE);
|
|
dmxScreen->atomPairAtom = MakeAtom ("ATOM_PAIR", strlen ("ATOM_PAIR"), TRUE);
|
|
dmxScreen->incrAtom = MakeAtom ("INCR", strlen ("INCR"), TRUE);
|
|
|
|
if (!dmxInitGC(pScreen)) return FALSE;
|
|
if (!dmxInitWindow(pScreen)) return FALSE;
|
|
if (!dmxInitPixmap(pScreen)) return FALSE;
|
|
if (!dmxInitCursor(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.
|
|
*/
|
|
if (dmxScreen->beAttachedDisplay)
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
/* avoid additional DirectColor visuals for better
|
|
back-end server support */
|
|
if (preferredClass != DirectColor)
|
|
visuals &= ~(1 << DirectColor);
|
|
}
|
|
#endif
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
/* avoid additional DirectColor visuals for better
|
|
back-end server support */
|
|
if (preferredClass != DirectColor)
|
|
visuals &= ~(1 << DirectColor);
|
|
}
|
|
#endif
|
|
|
|
miSetVisualTypesAndMasks(depth, visuals, bitsPerRgb,
|
|
preferredClass,
|
|
redMask, greenMask, blueMask);
|
|
}
|
|
}
|
|
|
|
fbScreenInit(pScreen,
|
|
NULL,
|
|
dmxScreen->scrnWidth,
|
|
dmxScreen->scrnHeight,
|
|
dmxScreen->beXDPI,
|
|
dmxScreen->beYDPI,
|
|
dmxScreen->scrnWidth,
|
|
dmxScreen->beBPP);
|
|
|
|
if (!dmxScreen->scrnWin && dmxScreen->beDisplay)
|
|
{
|
|
dmxScreen->scrnWin = DefaultRootWindow (dmxScreen->beDisplay);
|
|
dmxScreen->scrnEventMask |= StructureNotifyMask;
|
|
XSelectInput (dmxScreen->beDisplay,
|
|
dmxScreen->scrnWin,
|
|
dmxScreen->scrnEventMask);
|
|
}
|
|
|
|
#ifdef MITSHM
|
|
ShmRegisterDmxFuncs (pScreen);
|
|
#endif
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
{
|
|
for (i = 0; i < pScreen->numVisuals; i++)
|
|
if (pScreen->visuals[i].ColormapEntries > 256)
|
|
pScreen->visuals[i].ColormapEntries = 256;
|
|
}
|
|
#endif
|
|
|
|
#ifdef RENDER
|
|
if (!dmxPictureInit (pScreen, 0, 0))
|
|
return FALSE;
|
|
#endif
|
|
|
|
#ifdef RANDR
|
|
if (!dmxRRScreenInit (pScreen))
|
|
return FALSE;
|
|
#endif
|
|
|
|
#ifdef XV
|
|
if (!dmxXvScreenInit (pScreen))
|
|
return FALSE;
|
|
#endif
|
|
|
|
if (!dmxDnDScreenInit (pScreen))
|
|
return FALSE;
|
|
|
|
miInitializeBackingStore(pScreen);
|
|
|
|
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);
|
|
|
|
/* 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(CopyWindow, dmxCopyWindow, dmxScreen, pScreen);
|
|
|
|
DMX_WRAP(ResizeWindow, dmxResizeWindow, dmxScreen, pScreen);
|
|
DMX_WRAP(HandleExposures, dmxHandleExposures, dmxScreen, pScreen);
|
|
DMX_WRAP(ReparentWindow, dmxReparentWindow, dmxScreen, pScreen);
|
|
|
|
DMX_WRAP(ChangeBorderWidth, dmxChangeBorderWidth, dmxScreen, pScreen);
|
|
|
|
DMX_WRAP(ModifyPixmapHeader, dmxModifyPixmapHeader, dmxScreen, pScreen);
|
|
|
|
DMX_WRAP(SetWindowPixmap, dmxSetWindowPixmap, dmxScreen, pScreen);
|
|
|
|
/* Wrap Image functions */
|
|
DMX_WRAP(GetImage, dmxGetImage, dmxScreen, pScreen);
|
|
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;
|
|
|
|
RegisterBlockAndWakeupHandlers (dmxScreenBlockHandler,
|
|
dmxScreenWakeupHandler,
|
|
pScreen);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/** Close the \a pScreen resources on the back-end server. */
|
|
void dmxBECloseScreen(ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum];
|
|
int i;
|
|
|
|
#ifdef XV
|
|
dmxBEXvScreenFini (pScreen);
|
|
#endif
|
|
|
|
#ifdef RANDR
|
|
dmxBERRScreenFini (pScreen);
|
|
#endif
|
|
|
|
/* Restore the back-end screen-saver and DPMS state. */
|
|
dmxBEDPMSScreenFini (pScreen);
|
|
|
|
/* Free the screen resources */
|
|
dmxScreen->scrnWin = (Window)0;
|
|
|
|
/* Free the default drawables */
|
|
for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XFreePixmap(dmxScreen->beDisplay, dmxScreen->scrnDefDrawables[i]);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
dmxScreen->scrnDefDrawables[i] = (Drawable)0;
|
|
}
|
|
|
|
/* Free resources allocated during initialization (in dmxinit.c) */
|
|
for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
|
|
{
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XFreeColormap(dmxScreen->beDisplay, dmxScreen->beDefColormaps[i]);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
}
|
|
xfree(dmxScreen->beDefColormaps);
|
|
dmxScreen->beDefColormaps = NULL;
|
|
|
|
#ifdef GLXEXT
|
|
if (dmxScreen->glxVisuals) {
|
|
XFree(dmxScreen->glxVisuals);
|
|
dmxScreen->glxVisuals = NULL;
|
|
dmxScreen->numGlxVisuals = 0;
|
|
}
|
|
#endif
|
|
|
|
dmxClearQueue (&dmxScreen->request);
|
|
dmxClearQueue (&dmxScreen->ignore);
|
|
}
|
|
|
|
/** Close screen number \a idx. */
|
|
Bool dmxCloseScreen(int idx, ScreenPtr pScreen)
|
|
{
|
|
DMXScreenInfo *dmxScreen = &dmxScreens[idx];
|
|
|
|
/* Free input overlay window tree */
|
|
if (dmxScreen->inputOverlayWid)
|
|
FreeResource (dmxScreen->inputOverlayWid, RT_NONE);
|
|
|
|
/* Reset the proc vectors */
|
|
if (idx == 0) {
|
|
#ifdef COMPOSITE
|
|
if (!noCompositeExtension)
|
|
dmxResetComposite();
|
|
#endif
|
|
#ifdef RENDER
|
|
if (!noRenderExtension)
|
|
dmxResetRender();
|
|
#endif
|
|
#ifdef MITSHM
|
|
dmxResetShm();
|
|
#endif
|
|
dmxResetSelections();
|
|
dmxResetGrabs();
|
|
dmxResetProps();
|
|
}
|
|
|
|
/* 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(CopyWindow, dmxScreen, pScreen);
|
|
|
|
DMX_UNWRAP(ResizeWindow, dmxScreen, pScreen);
|
|
DMX_UNWRAP(HandleExposures, dmxScreen, pScreen);
|
|
DMX_UNWRAP(ReparentWindow, dmxScreen, pScreen);
|
|
|
|
DMX_UNWRAP(ChangeBorderWidth, dmxScreen, pScreen);
|
|
|
|
DMX_UNWRAP(ModifyPixmapHeader, dmxScreen, pScreen);
|
|
|
|
DMX_UNWRAP(SetWindowPixmap, 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);
|
|
|
|
/* Close display */
|
|
dmxCloseDisplay (dmxScreen);
|
|
dmxScreen->beDisplay = NULL;
|
|
|
|
/* 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;
|
|
}
|
|
|
|
if (idx == 0)
|
|
dmxAbortDisplay ();
|
|
|
|
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) {
|
|
if (dmxScreen->scrnWin != DefaultRootWindow (dmxScreen->beDisplay))
|
|
return TRUE;
|
|
switch (what) {
|
|
case SCREEN_SAVER_OFF:
|
|
case SCREEN_SAVER_FORCER:
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XResetScreenSaver(dmxScreen->beDisplay);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
dmxSync(dmxScreen, FALSE);
|
|
break;
|
|
case SCREEN_SAVER_ON:
|
|
case SCREEN_SAVER_CYCLE:
|
|
XLIB_PROLOGUE (dmxScreen);
|
|
XActivateScreenSaver(dmxScreen->beDisplay);
|
|
XLIB_EPILOGUE (dmxScreen);
|
|
dmxSync(dmxScreen, FALSE);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
Bool
|
|
dmxAddSequence (DMXQueue *q,
|
|
unsigned long sequence)
|
|
{
|
|
DMXSequence *s;
|
|
|
|
s = malloc (sizeof (DMXSequence));
|
|
if (!s)
|
|
return FALSE;
|
|
|
|
s->sequence = sequence;
|
|
s->next = 0;
|
|
|
|
*(q->tail) = s;
|
|
q->tail = &s->next;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
dmxClearQueue (DMXQueue *q)
|
|
{
|
|
while (q->head)
|
|
{
|
|
DMXSequence *head = q->head;
|
|
|
|
q->head = head->next;
|
|
free (head);
|
|
}
|
|
|
|
q->tail = &q->head;
|
|
}
|
|
|
|
Bool
|
|
dmxAddRequest (DMXQueue *q,
|
|
ReplyProcPtr reply,
|
|
unsigned long sequence,
|
|
void *data)
|
|
{
|
|
DMXRequest *r;
|
|
|
|
r = malloc (sizeof (DMXRequest));
|
|
if (!r)
|
|
return FALSE;
|
|
|
|
r->base.sequence = sequence;
|
|
r->base.next = 0;
|
|
r->reply = reply;
|
|
r->data = data;
|
|
|
|
*(q->tail) = &r->base;
|
|
q->tail = &r->base.next;
|
|
|
|
return TRUE;
|
|
}
|
|
|