1/* 2 3Copyright 1990, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29#ifdef HAVE_DIX_CONFIG_H 30#include <dix-config.h> 31#endif 32 33#include <X11/X.h> 34#include "servermd.h" 35#include "misc.h" 36#include "mi.h" 37#include "scrnintstr.h" 38#include "pixmapstr.h" 39#include "dix.h" 40#include "miline.h" 41#ifdef MITSHM 42#include <X11/extensions/shm.h> 43#include "shmint.h" 44#endif 45 46/* We use this structure to propogate some information from miScreenInit to 47 * miCreateScreenResources. miScreenInit allocates the structure, fills it 48 * in, and puts it into pScreen->devPrivate. miCreateScreenResources 49 * extracts the info and frees the structure. We could've accomplished the 50 * same thing by adding fields to the screen structure, but they would have 51 * ended up being redundant, and would have exposed this mi implementation 52 * detail to the whole server. 53 */ 54 55typedef struct 56{ 57 pointer pbits; /* pointer to framebuffer */ 58 int width; /* delta to add to a framebuffer addr to move one row down */ 59} miScreenInitParmsRec, *miScreenInitParmsPtr; 60 61 62/* this plugs into pScreen->ModifyPixmapHeader */ 63Bool 64miModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth, 65 int bitsPerPixel, int devKind, pointer pPixData) 66{ 67 if (!pPixmap) 68 return FALSE; 69 70 /* 71 * If all arguments are specified, reinitialize everything (including 72 * validated state). 73 */ 74 if ((width > 0) && (height > 0) && (depth > 0) && (bitsPerPixel > 0) && 75 (devKind > 0) && pPixData) { 76 pPixmap->drawable.depth = depth; 77 pPixmap->drawable.bitsPerPixel = bitsPerPixel; 78 pPixmap->drawable.id = 0; 79 pPixmap->drawable.x = 0; 80 pPixmap->drawable.y = 0; 81 pPixmap->drawable.width = width; 82 pPixmap->drawable.height = height; 83 pPixmap->devKind = devKind; 84 pPixmap->refcnt = 1; 85 pPixmap->devPrivate.ptr = pPixData; 86 } else { 87 /* 88 * Only modify specified fields, keeping all others intact. 89 */ 90 91 if (width > 0) 92 pPixmap->drawable.width = width; 93 94 if (height > 0) 95 pPixmap->drawable.height = height; 96 97 if (depth > 0) 98 pPixmap->drawable.depth = depth; 99 100 if (bitsPerPixel > 0) 101 pPixmap->drawable.bitsPerPixel = bitsPerPixel; 102 else if ((bitsPerPixel < 0) && (depth > 0)) 103 pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth); 104 105 /* 106 * CAVEAT: Non-SI DDXen may use devKind and devPrivate fields for 107 * other purposes. 108 */ 109 if (devKind > 0) 110 pPixmap->devKind = devKind; 111 else if ((devKind < 0) && ((width > 0) || (depth > 0))) 112 pPixmap->devKind = PixmapBytePad(pPixmap->drawable.width, 113 pPixmap->drawable.depth); 114 115 if (pPixData) 116 pPixmap->devPrivate.ptr = pPixData; 117 } 118 pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 119 return TRUE; 120} 121 122static Bool 123miCloseScreen (int iScreen, ScreenPtr pScreen) 124{ 125 return ((*pScreen->DestroyPixmap)((PixmapPtr)pScreen->devPrivate)); 126} 127 128/* With the introduction of pixmap privates, the "screen pixmap" can no 129 * longer be created in miScreenInit, since all the modules that could 130 * possibly ask for pixmap private space have not been initialized at 131 * that time. pScreen->CreateScreenResources is called after all 132 * possible private-requesting modules have been inited; we create the 133 * screen pixmap here. 134 */ 135Bool 136miCreateScreenResources(ScreenPtr pScreen) 137{ 138 miScreenInitParmsPtr pScrInitParms; 139 pointer value; 140 141 pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; 142 143 /* if width is non-zero, pScreen->devPrivate will be a pixmap 144 * else it will just take the value pbits 145 */ 146 if (pScrInitParms->width) 147 { 148 PixmapPtr pPixmap; 149 150 /* create a pixmap with no data, then redirect it to point to 151 * the screen 152 */ 153 pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); 154 if (!pPixmap) 155 return FALSE; 156 157 if (!(*pScreen->ModifyPixmapHeader)(pPixmap, pScreen->width, 158 pScreen->height, pScreen->rootDepth, 159 BitsPerPixel(pScreen->rootDepth), 160 PixmapBytePad(pScrInitParms->width, pScreen->rootDepth), 161 pScrInitParms->pbits)) 162 return FALSE; 163 value = (pointer)pPixmap; 164 } 165 else 166 { 167 value = pScrInitParms->pbits; 168 } 169 free(pScreen->devPrivate); /* freeing miScreenInitParmsRec */ 170 pScreen->devPrivate = value; /* pPixmap or pbits */ 171 return TRUE; 172} 173 174Bool 175miScreenDevPrivateInit(ScreenPtr pScreen, int width, pointer pbits) 176{ 177 miScreenInitParmsPtr pScrInitParms; 178 179 /* Stash pbits and width in a short-lived miScreenInitParmsRec attached 180 * to the screen, until CreateScreenResources can put them in the 181 * screen pixmap. 182 */ 183 pScrInitParms = malloc(sizeof(miScreenInitParmsRec)); 184 if (!pScrInitParms) 185 return FALSE; 186 pScrInitParms->pbits = pbits; 187 pScrInitParms->width = width; 188 pScreen->devPrivate = (pointer)pScrInitParms; 189 return TRUE; 190} 191 192static PixmapPtr 193miGetScreenPixmap(ScreenPtr pScreen) 194{ 195 return (PixmapPtr)(pScreen->devPrivate); 196} 197 198static void 199miSetScreenPixmap(PixmapPtr pPix) 200{ 201 if (pPix) 202 pPix->drawable.pScreen->devPrivate = (pointer)pPix; 203} 204 205Bool 206miScreenInit( 207 ScreenPtr pScreen, 208 pointer pbits, /* pointer to screen bits */ 209 int xsize, int ysize, /* in pixels */ 210 int dpix, int dpiy, /* dots per inch */ 211 int width, /* pixel width of frame buffer */ 212 int rootDepth, /* depth of root window */ 213 int numDepths, /* number of depths supported */ 214 DepthRec *depths, /* supported depths */ 215 VisualID rootVisual, /* root visual */ 216 int numVisuals, /* number of visuals supported */ 217 VisualRec *visuals /* supported visuals */ 218 ) 219{ 220 pScreen->width = xsize; 221 pScreen->height = ysize; 222 pScreen->mmWidth = (xsize * 254 + dpix * 5) / (dpix * 10); 223 pScreen->mmHeight = (ysize * 254 + dpiy * 5) / (dpiy * 10); 224 pScreen->numDepths = numDepths; 225 pScreen->rootDepth = rootDepth; 226 pScreen->allowedDepths = depths; 227 pScreen->rootVisual = rootVisual; 228 /* defColormap */ 229 pScreen->minInstalledCmaps = 1; 230 pScreen->maxInstalledCmaps = 1; 231 pScreen->backingStoreSupport = NotUseful; 232 pScreen->saveUnderSupport = NotUseful; 233 /* whitePixel, blackPixel */ 234 pScreen->ModifyPixmapHeader = miModifyPixmapHeader; 235 pScreen->CreateScreenResources = miCreateScreenResources; 236 pScreen->GetScreenPixmap = miGetScreenPixmap; 237 pScreen->SetScreenPixmap = miSetScreenPixmap; 238 pScreen->numVisuals = numVisuals; 239 pScreen->visuals = visuals; 240 if (width) 241 { 242#ifdef MITSHM 243 ShmRegisterFbFuncs(pScreen); 244#endif 245 pScreen->CloseScreen = miCloseScreen; 246 } 247 /* else CloseScreen */ 248 /* QueryBestSize, SaveScreen, GetImage, GetSpans */ 249 pScreen->SourceValidate = (SourceValidateProcPtr) 0; 250 /* CreateWindow, DestroyWindow, PositionWindow, ChangeWindowAttributes */ 251 /* RealizeWindow, UnrealizeWindow */ 252 pScreen->ValidateTree = miValidateTree; 253 pScreen->PostValidateTree = (PostValidateTreeProcPtr) 0; 254 pScreen->WindowExposures = miWindowExposures; 255 /* CopyWindow */ 256 pScreen->ClearToBackground = miClearToBackground; 257 pScreen->ClipNotify = (ClipNotifyProcPtr) 0; 258 pScreen->RestackWindow = (RestackWindowProcPtr) 0; 259 /* CreatePixmap, DestroyPixmap */ 260 /* RealizeFont, UnrealizeFont */ 261 /* CreateGC */ 262 /* CreateColormap, DestroyColormap, InstallColormap, UninstallColormap */ 263 /* ListInstalledColormaps, StoreColors, ResolveColor */ 264 /* BitmapToRegion */ 265 pScreen->SendGraphicsExpose = miSendGraphicsExpose; 266 pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA; 267 pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA; 268 pScreen->blockData = (pointer)0; 269 pScreen->wakeupData = (pointer)0; 270 pScreen->MarkWindow = miMarkWindow; 271 pScreen->MarkOverlappedWindows = miMarkOverlappedWindows; 272 pScreen->MoveWindow = miMoveWindow; 273 pScreen->ResizeWindow = miSlideAndSizeWindow; 274 pScreen->GetLayerWindow = miGetLayerWindow; 275 pScreen->HandleExposures = miHandleValidateExposures; 276 pScreen->ReparentWindow = (ReparentWindowProcPtr) 0; 277 pScreen->ChangeBorderWidth = miChangeBorderWidth; 278 pScreen->SetShape = miSetShape; 279 pScreen->MarkUnrealizedWindow = miMarkUnrealizedWindow; 280 281 miSetZeroLineBias(pScreen, DEFAULTZEROLINEBIAS); 282 283 return miScreenDevPrivateInit(pScreen, width, pbits); 284} 285 286DevPrivateKeyRec miZeroLineScreenKeyRec; 287 288void 289miSetZeroLineBias(ScreenPtr pScreen, unsigned int bias) 290{ 291 if (!dixRegisterPrivateKey(&miZeroLineScreenKeyRec, PRIVATE_SCREEN, 0)) 292 return; 293 294 dixSetPrivate(&pScreen->devPrivates, miZeroLineScreenKey, 295 (unsigned long *)(unsigned long)bias); 296} 297