summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Reveman <davidr@novell.com>2008-11-07 11:22:44 -0500
committerDavid Reveman <davidr@novell.com>2008-11-07 11:22:44 -0500
commit2fa16f2e292c010a2c5a002b1ea1a9ff191e4cfb (patch)
treebb2e29f000e35a57b1c35e25b8fae6abd0df5042
parentfc99433dbd7b3c89c84da9d6d61d085983160b7a (diff)
Add alternative window support to dmxGetImage.
-rw-r--r--hw/dmx/dmxgcops.c206
1 files changed, 126 insertions, 80 deletions
diff --git a/hw/dmx/dmxgcops.c b/hw/dmx/dmxgcops.c
index df86f5862..3499c863c 100644
--- a/hw/dmx/dmxgcops.c
+++ b/hw/dmx/dmxgcops.c
@@ -545,39 +545,67 @@ 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)
+static DMXScreenInfo *
+dmxGetAlternateWindow (DrawablePtr pDrawable,
+ int i,
+ XID *draw)
{
+
+#ifdef PANORAMIX
+ PanoramiXRes *pXinWin;
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+
+ if (noPanoramiXExtension) return NULL;
+ if (!dmxScreen->beDisplay) return NULL;
+
+ if ((pXinWin = (PanoramiXRes *) LookupIDByType (pDrawable->id,
+ XRT_WINDOW)))
+ {
+ WindowPtr pSrc;
+ dmxWinPrivPtr pSrcPriv;
+
+ pSrc = (WindowPtr) LookupIDByType (pXinWin->info[i].id, RT_WINDOW);
+ pSrcPriv = DMX_GET_WINDOW_PRIV (pSrc);
+ if (pSrcPriv->window)
+ {
+ *draw = pSrcPriv->window;
+ return dmxScreen;
+ }
+ }
+#endif
+
+ return NULL;
+}
+
+static DMXScreenInfo *
+dmxGetAlternatePixmap (DrawablePtr pDrawable,
+ int i,
+ XID *draw)
+{
+
#ifdef PANORAMIX
PanoramiXRes *pXinPix;
- int i;
- DMXScreenInfo *dmxScreen;
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
- if (noPanoramiXExtension) return NULL;
- if (pDrawable->type != DRAWABLE_PIXMAP) return NULL;
+ if (noPanoramiXExtension) return NULL;
+ if (!dmxScreen->beDisplay) 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;
+ if ((pXinPix = (PanoramiXRes *) LookupIDByType (pDrawable->id,
+ XRT_PIXMAP)))
+ {
+ 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;
- }
- }
+ 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;
}
@@ -589,9 +617,9 @@ static DMXScreenInfo *dmxFindAlternatePixmap(DrawablePtr pDrawable, XID *draw)
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];
- Drawable draw;
- xcb_get_image_reply_t *reply;
+ DMXScreenInfo *dmxScreen = &dmxScreens[pDrawable->pScreen->myNum];
+ Drawable draw;
+ int i = 0;
/* Cannot get image from unviewable window */
if (pDrawable->type == DRAWABLE_WINDOW) {
@@ -606,72 +634,90 @@ void dmxGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h,
return;
}
}
- DMX_GCOPS_SET_DRAWABLE(&pWindow->drawable, draw);
+ DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
if (DMX_GCOPS_OFFSCREEN(&pWindow->drawable))
- return;
+ draw = None;
} else {
DMX_GCOPS_SET_DRAWABLE(pDrawable, draw);
- if (DMX_GCOPS_OFFSCREEN(pDrawable)) {
- /* Try to find the pixmap on a non-detached Xinerama screen */
- dmxScreen = dmxFindAlternatePixmap(pDrawable, &draw);
- if (!dmxScreen) return;
- }
+ if (DMX_GCOPS_OFFSCREEN(pDrawable))
+ draw = None;
}
-
- reply = xcb_get_image_reply (dmxScreen->connection,
- xcb_get_image (dmxScreen->connection,
- format,
- draw,
- sx, sy, w, h,
- planeMask),
- NULL);
- if (reply)
+
+ while (i < dmxNumScreens)
{
- const xcb_setup_t *setup = xcb_get_setup (dmxScreen->connection);
- uint32_t bytes = xcb_get_image_data_length (reply);
- uint8_t *data = xcb_get_image_data (reply);
-
- /* based on code in xcb_image.c, Copyright (C) 2007 Bart Massey */
- switch (format) {
- case XCB_IMAGE_FORMAT_XY_PIXMAP:
- planeMask &= xcb_mask (reply->depth);
- if (planeMask != xcb_mask (reply->depth))
- {
- uint32_t rpm = planeMask;
- uint8_t *src_plane = data;
- uint8_t *dst_plane = (uint8_t *) pdstLine;
- uint32_t scanline_pad = setup->bitmap_format_scanline_pad;
- uint32_t stride = xcb_roundup (w, scanline_pad) >> 3;
- uint32_t size = h * stride;
- int i;
-
- if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
- rpm = xcb_bit_reverse (planeMask, reply->depth);
-
- for (i = 0; i < reply->depth; i++)
+ xcb_get_image_reply_t *reply;
+
+ if (!draw)
+ {
+ if (pDrawable->type == DRAWABLE_WINDOW)
+ dmxScreen = dmxGetAlternateWindow (pDrawable, i++, &draw);
+ else
+ dmxScreen = dmxGetAlternatePixmap (pDrawable, i++, &draw);
+
+ if (!dmxScreen) continue;
+ }
+
+ reply = xcb_get_image_reply (dmxScreen->connection,
+ xcb_get_image (dmxScreen->connection,
+ format,
+ draw,
+ sx, sy, w, h,
+ planeMask),
+ NULL);
+ if (reply)
+ {
+ const xcb_setup_t *setup = xcb_get_setup (dmxScreen->connection);
+ uint32_t bytes = xcb_get_image_data_length (reply);
+ uint8_t *data = xcb_get_image_data (reply);
+
+ /* based on code in xcb_image.c, Copyright (C) 2007 Bart Massey */
+ switch (format) {
+ case XCB_IMAGE_FORMAT_XY_PIXMAP:
+ planeMask &= xcb_mask (reply->depth);
+ if (planeMask != xcb_mask (reply->depth))
{
- if (rpm & 1)
- {
- memcpy (dst_plane, src_plane, size);
- src_plane += size;
- }
- else
+ uint32_t rpm = planeMask;
+ uint8_t *src_plane = data;
+ uint8_t *dst_plane = (uint8_t *) pdstLine;
+ uint32_t scanline_pad = setup->bitmap_format_scanline_pad;
+ uint32_t stride = xcb_roundup (w, scanline_pad) >> 3;
+ uint32_t size = h * stride;
+ int i;
+
+ if (setup->image_byte_order == XCB_IMAGE_ORDER_MSB_FIRST)
+ rpm = xcb_bit_reverse (planeMask, reply->depth);
+
+ for (i = 0; i < reply->depth; i++)
{
- memset (dst_plane, 0, size);
+ if (rpm & 1)
+ {
+ memcpy (dst_plane, src_plane, size);
+ src_plane += size;
+ }
+ else
+ {
+ memset (dst_plane, 0, size);
+ }
+
+ dst_plane += size;
}
-
- dst_plane += size;
+ break;
}
+
+ /* fall through */
+ case XCB_IMAGE_FORMAT_Z_PIXMAP:
+ memmove (pdstLine, data, bytes);
+ default:
break;
}
- /* fall through */
- case XCB_IMAGE_FORMAT_Z_PIXMAP:
- memmove (pdstLine, data, bytes);
- default:
+ free (reply);
break;
}
- free (reply);
+ if (pDrawable->type != DRAWABLE_WINDOW)
+ break;
+
+ draw = None;
}
}