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