1706f2543Smrg/* 2706f2543Smrg * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. 3706f2543Smrg * 4706f2543Smrg * All Rights Reserved. 5706f2543Smrg * 6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining 7706f2543Smrg * a copy of this software and associated documentation files (the 8706f2543Smrg * "Software"), to deal in the Software without restriction, including 9706f2543Smrg * without limitation on the rights to use, copy, modify, merge, 10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software, 11706f2543Smrg * and to permit persons to whom the Software is furnished to do so, 12706f2543Smrg * subject to the following conditions: 13706f2543Smrg * 14706f2543Smrg * The above copyright notice and this permission notice (including the 15706f2543Smrg * next paragraph) shall be included in all copies or substantial 16706f2543Smrg * portions of the Software. 17706f2543Smrg * 18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21706f2543Smrg * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS 22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25706f2543Smrg * SOFTWARE. 26706f2543Smrg */ 27706f2543Smrg 28706f2543Smrg/* 29706f2543Smrg * Authors: 30706f2543Smrg * Kevin E. Martin <kem@redhat.com> 31706f2543Smrg * 32706f2543Smrg */ 33706f2543Smrg 34706f2543Smrg/** \file 35706f2543Smrg * Provides pixmap support. */ 36706f2543Smrg 37706f2543Smrg#ifdef HAVE_DMX_CONFIG_H 38706f2543Smrg#include <dmx-config.h> 39706f2543Smrg#endif 40706f2543Smrg 41706f2543Smrg#include "dmx.h" 42706f2543Smrg#include "dmxsync.h" 43706f2543Smrg#include "dmxpixmap.h" 44706f2543Smrg 45706f2543Smrg#include "pixmapstr.h" 46706f2543Smrg#include "servermd.h" 47706f2543Smrg#include "privates.h" 48706f2543Smrg 49706f2543Smrg/** Initialize a private area in \a pScreen for pixmap information. */ 50706f2543SmrgBool dmxInitPixmap(ScreenPtr pScreen) 51706f2543Smrg{ 52706f2543Smrg if (!dixRegisterPrivateKey(&dmxPixPrivateKeyRec, PRIVATE_PIXMAP, sizeof(dmxPixPrivRec))) 53706f2543Smrg return FALSE; 54706f2543Smrg 55706f2543Smrg return TRUE; 56706f2543Smrg} 57706f2543Smrg 58706f2543Smrg/** Create a pixmap on the back-end server. */ 59706f2543Smrgvoid dmxBECreatePixmap(PixmapPtr pPixmap) 60706f2543Smrg{ 61706f2543Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 62706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 63706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); 64706f2543Smrg 65706f2543Smrg /* Make sure we haven't already created this pixmap. This can 66706f2543Smrg * happen when the pixmap is used elsewhere (e.g., as a background 67706f2543Smrg * or border for a window) and the refcnt > 1. 68706f2543Smrg */ 69706f2543Smrg if (pPixPriv->pixmap) 70706f2543Smrg return; 71706f2543Smrg 72706f2543Smrg if (pPixmap->drawable.width && pPixmap->drawable.height) { 73706f2543Smrg pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay, 74706f2543Smrg dmxScreen->scrnWin, 75706f2543Smrg pPixmap->drawable.width, 76706f2543Smrg pPixmap->drawable.height, 77706f2543Smrg pPixmap->drawable.depth); 78706f2543Smrg dmxSync(dmxScreen, FALSE); 79706f2543Smrg } 80706f2543Smrg} 81706f2543Smrg 82706f2543Smrg/** Create a pixmap for \a pScreen with the specified \a width, \a 83706f2543Smrg * height, and \a depth. */ 84706f2543SmrgPixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, 85706f2543Smrg unsigned usage_hint) 86706f2543Smrg{ 87706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 88706f2543Smrg PixmapPtr pPixmap; 89706f2543Smrg int bpp; 90706f2543Smrg dmxPixPrivPtr pPixPriv; 91706f2543Smrg 92706f2543Smrg#if 0 93706f2543Smrg DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen); 94706f2543Smrg if (pScreen->CreatePixmap) 95706f2543Smrg ret = pScreen->CreatePixmap(pPixmap); 96706f2543Smrg#endif 97706f2543Smrg 98706f2543Smrg /* Create pixmap on back-end server */ 99706f2543Smrg if (depth == 24) bpp = 32; 100706f2543Smrg else bpp = depth; 101706f2543Smrg 102706f2543Smrg pPixmap = AllocatePixmap(pScreen, 0); 103706f2543Smrg if (!pPixmap) 104706f2543Smrg return NullPixmap; 105706f2543Smrg 106706f2543Smrg pPixmap->drawable.type = DRAWABLE_PIXMAP; 107706f2543Smrg pPixmap->drawable.class = 0; 108706f2543Smrg pPixmap->drawable.pScreen = pScreen; 109706f2543Smrg pPixmap->drawable.depth = depth; 110706f2543Smrg pPixmap->drawable.bitsPerPixel = bpp; 111706f2543Smrg pPixmap->drawable.id = 0; 112706f2543Smrg pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 113706f2543Smrg pPixmap->drawable.x = 0; 114706f2543Smrg pPixmap->drawable.y = 0; 115706f2543Smrg pPixmap->drawable.width = width; 116706f2543Smrg pPixmap->drawable.height = height; 117706f2543Smrg pPixmap->devKind = PixmapBytePad(width, bpp); 118706f2543Smrg pPixmap->refcnt = 1; 119706f2543Smrg pPixmap->usage_hint = usage_hint; 120706f2543Smrg 121706f2543Smrg pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); 122706f2543Smrg pPixPriv->pixmap = (Pixmap)0; 123706f2543Smrg pPixPriv->detachedImage = NULL; 124706f2543Smrg 125706f2543Smrg /* Create the pixmap on the back-end server */ 126706f2543Smrg if (dmxScreen->beDisplay) { 127706f2543Smrg dmxBECreatePixmap(pPixmap); 128706f2543Smrg } 129706f2543Smrg 130706f2543Smrg#if 0 131706f2543Smrg DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen); 132706f2543Smrg#endif 133706f2543Smrg 134706f2543Smrg return pPixmap; 135706f2543Smrg} 136706f2543Smrg 137706f2543Smrg/** Destroy the pixmap on the back-end server. */ 138706f2543SmrgBool dmxBEFreePixmap(PixmapPtr pPixmap) 139706f2543Smrg{ 140706f2543Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 141706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 142706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); 143706f2543Smrg 144706f2543Smrg if (pPixPriv->pixmap) { 145706f2543Smrg XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap); 146706f2543Smrg pPixPriv->pixmap = (Pixmap)0; 147706f2543Smrg return TRUE; 148706f2543Smrg } 149706f2543Smrg 150706f2543Smrg return FALSE; 151706f2543Smrg} 152706f2543Smrg 153706f2543Smrg/** Destroy the pixmap pointed to by \a pPixmap. */ 154706f2543SmrgBool dmxDestroyPixmap(PixmapPtr pPixmap) 155706f2543Smrg{ 156706f2543Smrg ScreenPtr pScreen = pPixmap->drawable.pScreen; 157706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; 158706f2543Smrg Bool ret = TRUE; 159706f2543Smrg 160706f2543Smrg#if 0 161706f2543Smrg DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen); 162706f2543Smrg#endif 163706f2543Smrg 164706f2543Smrg if (--pPixmap->refcnt) 165706f2543Smrg return TRUE; 166706f2543Smrg 167706f2543Smrg /* Destroy pixmap on back-end server */ 168706f2543Smrg if (dmxScreen->beDisplay) { 169706f2543Smrg if (dmxBEFreePixmap(pPixmap)) { 170706f2543Smrg /* Also make sure that we destroy any detached image */ 171706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); 172706f2543Smrg if (pPixPriv->detachedImage) 173706f2543Smrg XDestroyImage(pPixPriv->detachedImage); 174706f2543Smrg dmxSync(dmxScreen, FALSE); 175706f2543Smrg } 176706f2543Smrg } 177706f2543Smrg FreePixmap(pPixmap); 178706f2543Smrg 179706f2543Smrg#if 0 180706f2543Smrg if (pScreen->DestroyPixmap) 181706f2543Smrg ret = pScreen->DestroyPixmap(pPixmap); 182706f2543Smrg DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen); 183706f2543Smrg#endif 184706f2543Smrg 185706f2543Smrg return ret; 186706f2543Smrg} 187706f2543Smrg 188706f2543Smrg/** Create and return a region based on the pixmap pointed to by \a 189706f2543Smrg * pPixmap. */ 190706f2543SmrgRegionPtr dmxBitmapToRegion(PixmapPtr pPixmap) 191706f2543Smrg{ 192706f2543Smrg DMXScreenInfo *dmxScreen = &dmxScreens[pPixmap->drawable.pScreen->myNum]; 193706f2543Smrg dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); 194706f2543Smrg XImage *ximage; 195706f2543Smrg RegionPtr pReg, pTmpReg; 196706f2543Smrg int x, y; 197706f2543Smrg unsigned long previousPixel, currentPixel; 198706f2543Smrg BoxRec Box; 199706f2543Smrg Bool overlap; 200706f2543Smrg 201706f2543Smrg if (!dmxScreen->beDisplay) { 202706f2543Smrg pReg = RegionCreate(NullBox, 1); 203706f2543Smrg return pReg; 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0, 207706f2543Smrg pPixmap->drawable.width, pPixmap->drawable.height, 208706f2543Smrg 1, XYPixmap); 209706f2543Smrg 210706f2543Smrg pReg = RegionCreate(NullBox, 1); 211706f2543Smrg pTmpReg = RegionCreate(NullBox, 1); 212706f2543Smrg if(!pReg || !pTmpReg) { 213706f2543Smrg XDestroyImage(ximage); 214706f2543Smrg return NullRegion; 215706f2543Smrg } 216706f2543Smrg 217706f2543Smrg for (y = 0; y < pPixmap->drawable.height; y++) { 218706f2543Smrg Box.y1 = y; 219706f2543Smrg Box.y2 = y + 1; 220706f2543Smrg previousPixel = 0L; 221706f2543Smrg for (x = 0; x < pPixmap->drawable.width; x++) { 222706f2543Smrg currentPixel = XGetPixel(ximage, x, y); 223706f2543Smrg if (previousPixel != currentPixel) { 224706f2543Smrg if (previousPixel == 0L) { 225706f2543Smrg /* left edge */ 226706f2543Smrg Box.x1 = x; 227706f2543Smrg } else if (currentPixel == 0L) { 228706f2543Smrg /* right edge */ 229706f2543Smrg Box.x2 = x; 230706f2543Smrg RegionReset(pTmpReg, &Box); 231706f2543Smrg RegionAppend(pReg, pTmpReg); 232706f2543Smrg } 233706f2543Smrg previousPixel = currentPixel; 234706f2543Smrg } 235706f2543Smrg } 236706f2543Smrg if (previousPixel != 0L) { 237706f2543Smrg /* right edge because of the end of pixmap */ 238706f2543Smrg Box.x2 = pPixmap->drawable.width; 239706f2543Smrg RegionReset(pTmpReg, &Box); 240706f2543Smrg RegionAppend(pReg, pTmpReg); 241706f2543Smrg } 242706f2543Smrg } 243706f2543Smrg 244706f2543Smrg RegionDestroy(pTmpReg); 245706f2543Smrg XDestroyImage(ximage); 246706f2543Smrg 247706f2543Smrg RegionValidate(pReg, &overlap); 248706f2543Smrg 249706f2543Smrg dmxSync(dmxScreen, FALSE); 250706f2543Smrg return pReg; 251706f2543Smrg} 252