Pixmap.c revision 706f2543
1706f2543Smrg/* 2706f2543Smrg 3706f2543SmrgCopyright 1993 by Davor Matic 4706f2543Smrg 5706f2543SmrgPermission to use, copy, modify, distribute, and sell this software 6706f2543Smrgand its documentation for any purpose is hereby granted without fee, 7706f2543Smrgprovided that the above copyright notice appear in all copies and that 8706f2543Smrgboth that copyright notice and this permission notice appear in 9706f2543Smrgsupporting documentation. Davor Matic makes no representations about 10706f2543Smrgthe suitability of this software for any purpose. It is provided "as 11706f2543Smrgis" without express or implied warranty. 12706f2543Smrg 13706f2543Smrg*/ 14706f2543Smrg 15706f2543Smrg#ifdef HAVE_XNEST_CONFIG_H 16706f2543Smrg#include <xnest-config.h> 17706f2543Smrg#endif 18706f2543Smrg 19706f2543Smrg#include <X11/X.h> 20706f2543Smrg#include <X11/Xproto.h> 21706f2543Smrg#include "regionstr.h" 22706f2543Smrg#include "pixmapstr.h" 23706f2543Smrg#include "scrnintstr.h" 24706f2543Smrg#include "regionstr.h" 25706f2543Smrg#include "gc.h" 26706f2543Smrg#include "servermd.h" 27706f2543Smrg#include "privates.h" 28706f2543Smrg#include "mi.h" 29706f2543Smrg 30706f2543Smrg#include "Xnest.h" 31706f2543Smrg 32706f2543Smrg#include "Display.h" 33706f2543Smrg#include "Screen.h" 34706f2543Smrg#include "XNPixmap.h" 35706f2543Smrg 36706f2543SmrgDevPrivateKeyRec xnestPixmapPrivateKeyRec; 37706f2543Smrg 38706f2543SmrgPixmapPtr 39706f2543SmrgxnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, 40706f2543Smrg unsigned usage_hint) 41706f2543Smrg{ 42706f2543Smrg PixmapPtr pPixmap; 43706f2543Smrg 44706f2543Smrg pPixmap = AllocatePixmap(pScreen, 0); 45706f2543Smrg if (!pPixmap) 46706f2543Smrg return NullPixmap; 47706f2543Smrg pPixmap->drawable.type = DRAWABLE_PIXMAP; 48706f2543Smrg pPixmap->drawable.class = 0; 49706f2543Smrg pPixmap->drawable.depth = depth; 50706f2543Smrg pPixmap->drawable.bitsPerPixel = depth; 51706f2543Smrg pPixmap->drawable.id = 0; 52706f2543Smrg pPixmap->drawable.x = 0; 53706f2543Smrg pPixmap->drawable.y = 0; 54706f2543Smrg pPixmap->drawable.width = width; 55706f2543Smrg pPixmap->drawable.height = height; 56706f2543Smrg pPixmap->drawable.pScreen = pScreen; 57706f2543Smrg pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 58706f2543Smrg pPixmap->refcnt = 1; 59706f2543Smrg pPixmap->devKind = PixmapBytePad(width, depth); 60706f2543Smrg pPixmap->usage_hint = usage_hint; 61706f2543Smrg if (width && height) 62706f2543Smrg xnestPixmapPriv(pPixmap)->pixmap = 63706f2543Smrg XCreatePixmap(xnestDisplay, 64706f2543Smrg xnestDefaultWindows[pScreen->myNum], 65706f2543Smrg width, height, depth); 66706f2543Smrg else 67706f2543Smrg xnestPixmapPriv(pPixmap)->pixmap = 0; 68706f2543Smrg 69706f2543Smrg return pPixmap; 70706f2543Smrg} 71706f2543Smrg 72706f2543SmrgBool 73706f2543SmrgxnestDestroyPixmap(PixmapPtr pPixmap) 74706f2543Smrg{ 75706f2543Smrg if(--pPixmap->refcnt) 76706f2543Smrg return TRUE; 77706f2543Smrg XFreePixmap(xnestDisplay, xnestPixmap(pPixmap)); 78706f2543Smrg FreePixmap(pPixmap); 79706f2543Smrg return TRUE; 80706f2543Smrg} 81706f2543Smrg 82706f2543SmrgRegionPtr 83706f2543SmrgxnestPixmapToRegion(PixmapPtr pPixmap) 84706f2543Smrg{ 85706f2543Smrg XImage *ximage; 86706f2543Smrg register RegionPtr pReg, pTmpReg; 87706f2543Smrg register int x, y; 88706f2543Smrg unsigned long previousPixel, currentPixel; 89706f2543Smrg BoxRec Box = { 0, 0, 0, 0 }; 90706f2543Smrg Bool overlap; 91706f2543Smrg 92706f2543Smrg ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0, 93706f2543Smrg pPixmap->drawable.width, pPixmap->drawable.height, 94706f2543Smrg 1, XYPixmap); 95706f2543Smrg 96706f2543Smrg pReg = RegionCreate(NULL, 1); 97706f2543Smrg pTmpReg = RegionCreate(NULL, 1); 98706f2543Smrg if(!pReg || !pTmpReg) { 99706f2543Smrg XDestroyImage(ximage); 100706f2543Smrg return NullRegion; 101706f2543Smrg } 102706f2543Smrg 103706f2543Smrg for (y = 0; y < pPixmap->drawable.height; y++) { 104706f2543Smrg Box.y1 = y; 105706f2543Smrg Box.y2 = y + 1; 106706f2543Smrg previousPixel = 0L; 107706f2543Smrg for (x = 0; x < pPixmap->drawable.width; x++) { 108706f2543Smrg currentPixel = XGetPixel(ximage, x, y); 109706f2543Smrg if (previousPixel != currentPixel) { 110706f2543Smrg if (previousPixel == 0L) { 111706f2543Smrg /* left edge */ 112706f2543Smrg Box.x1 = x; 113706f2543Smrg } 114706f2543Smrg else if (currentPixel == 0L) { 115706f2543Smrg /* right edge */ 116706f2543Smrg Box.x2 = x; 117706f2543Smrg RegionReset(pTmpReg, &Box); 118706f2543Smrg RegionAppend(pReg, pTmpReg); 119706f2543Smrg } 120706f2543Smrg previousPixel = currentPixel; 121706f2543Smrg } 122706f2543Smrg } 123706f2543Smrg if (previousPixel != 0L) { 124706f2543Smrg /* right edge because of the end of pixmap */ 125706f2543Smrg Box.x2 = pPixmap->drawable.width; 126706f2543Smrg RegionReset(pTmpReg, &Box); 127706f2543Smrg RegionAppend(pReg, pTmpReg); 128706f2543Smrg } 129706f2543Smrg } 130706f2543Smrg 131706f2543Smrg RegionDestroy(pTmpReg); 132706f2543Smrg XDestroyImage(ximage); 133706f2543Smrg 134706f2543Smrg RegionValidate(pReg, &overlap); 135706f2543Smrg 136706f2543Smrg return pReg; 137706f2543Smrg} 138