From c04264727860cbe2e276e1934d6700d0baaf9f73 Mon Sep 17 00:00:00 2001 From: Rik Faith Date: Sun, 18 Jul 2004 22:19:33 +0000 Subject: [PATCH] Addition of console input after removal of core backend input that is not on screen 0 can cause a segfault. Fix by preventing reinitialization of detached inputs. When Xinerama is active and screen 0 is detached, pixmaps for XGetImage must be obtained from another screen. --- hw/dmx/dmxextension.c | 4 ++-- hw/dmx/dmxgcops.c | 45 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/hw/dmx/dmxextension.c b/hw/dmx/dmxextension.c index f573ec9e3..5d57452a1 100644 --- a/hw/dmx/dmxextension.c +++ b/hw/dmx/dmxextension.c @@ -227,14 +227,14 @@ static void dmxAdjustCursorBoundaries(void) dmxConnectionBlockCallback(); for (i = 0; i < dmxNumInputs; i++) { DMXInputInfo *dmxInput = &dmxInputs[i]; - dmxInputReInit(dmxInput); + if (!dmxInput->detached) dmxInputReInit(dmxInput); } dmxCheckCursor(); for (i = 0; i < dmxNumInputs; i++) { DMXInputInfo *dmxInput = &dmxInputs[i]; - dmxInputLateReInit(dmxInput); + if (!dmxInput->detached) dmxInputLateReInit(dmxInput); } } diff --git a/hw/dmx/dmxgcops.c b/hw/dmx/dmxgcops.c index 37d7e7900..fd0c70d4d 100644 --- a/hw/dmx/dmxgcops.c +++ b/hw/dmx/dmxgcops.c @@ -47,6 +47,8 @@ #include "pixmapstr.h" #include "dixfontstr.h" +#include "panoramiXsrv.h" + #define DMX_GCOPS_SET_DRAWABLE(_pDraw, _draw) \ do { \ if ((_pDraw)->type == DRAWABLE_WINDOW) { \ @@ -503,6 +505,42 @@ void dmxPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDst, * Miscellaneous drawing commands */ +/** When Xinerama is active, the client pixmaps are always obtained from + * screen 0. When screen 0 is detached, the pixmaps must be obtained + * from any other screen that is not detached. Usually, this is screen + * 1. */ +static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw) +{ +#ifdef PANORAMIX + PanoramiXRes *pXinPix; + int i; + DMXScreenInfo *dmxScreen; + + if (noPanoramiXExtension) return NULL; + if (pDrawable->type != DRAWABLE_PIXMAP) return NULL; + + if (!(pXinPix = (PanoramiXRes *)LookupIDByType(pDrawable->id, XRT_PIXMAP))) + return NULL; + + for (i = 1; i < PanoramiXNumScreens; i++) { + dmxScreen = &dmxScreens[i]; + if (dmxScreen->beDisplay) { + PixmapPtr pSrc; + dmxPixPrivPtr pSrcPriv; + + pSrc = (PixmapPtr)LookupIDByType(pXinPix->info[i].id, + RT_PIXMAP); + pSrcPriv = DMX_GET_PIXMAP_PRIV(pSrc); + if (pSrcPriv->pixmap) { + *draw = pSrcPriv->pixmap; + return dmxScreen; + } + } + } +#endif + return NULL; +} + /** Get an image from the back-end server associated with \a pDrawable's * screen. If \a pDrawable is a window, it must be viewable to get an * image from it. If it is not viewable, then get the image from the @@ -533,8 +571,11 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, return; } else { DMX_GCOPS_SET_DRAWABLE(pDrawable, draw); - if (DMX_GCOPS_OFFSCREEN(pDrawable)) - return; + if (DMX_GCOPS_OFFSCREEN(pDrawable)) { + /* Try to find the pixmap on a non-detached Xinerama screen */ + dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw); + if (!dmxScreen) return; + } } img = XGetImage(dmxScreen->beDisplay, draw,