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 "scrnintstr.h" 22706f2543Smrg#include "dix.h" 23706f2543Smrg#include "mi.h" 24706f2543Smrg#include "mibstore.h" 25706f2543Smrg#include "micmap.h" 26706f2543Smrg#include "colormapst.h" 27706f2543Smrg#include "resource.h" 28706f2543Smrg 29706f2543Smrg#include "Xnest.h" 30706f2543Smrg 31706f2543Smrg#include "Display.h" 32706f2543Smrg#include "Screen.h" 33706f2543Smrg#include "XNGC.h" 34706f2543Smrg#include "GCOps.h" 35706f2543Smrg#include "Drawable.h" 36706f2543Smrg#include "XNFont.h" 37706f2543Smrg#include "Color.h" 38706f2543Smrg#include "XNCursor.h" 39706f2543Smrg#include "Visual.h" 40706f2543Smrg#include "Events.h" 41706f2543Smrg#include "Init.h" 42706f2543Smrg#include "mipointer.h" 43706f2543Smrg#include "Args.h" 44706f2543Smrg#include "mipointrst.h" 45706f2543Smrg 46706f2543SmrgWindow xnestDefaultWindows[MAXSCREENS]; 47706f2543SmrgWindow xnestScreenSaverWindows[MAXSCREENS]; 48706f2543SmrgDevPrivateKeyRec xnestCursorScreenKeyRec; 49706f2543Smrg 50706f2543SmrgScreenPtr 51706f2543SmrgxnestScreen(Window window) 52706f2543Smrg{ 53706f2543Smrg int i; 54706f2543Smrg 55706f2543Smrg for (i = 0; i < xnestNumScreens; i++) 56706f2543Smrg if (xnestDefaultWindows[i] == window) 57706f2543Smrg return screenInfo.screens[i]; 58706f2543Smrg 59706f2543Smrg return NULL; 60706f2543Smrg} 61706f2543Smrg 62706f2543Smrgstatic int 63706f2543Smrgoffset(unsigned long mask) 64706f2543Smrg{ 65706f2543Smrg int count; 66706f2543Smrg 67706f2543Smrg for (count = 0; !(mask & 1) && count < 32; count++) 68706f2543Smrg mask >>= 1; 69706f2543Smrg 70706f2543Smrg return count; 71706f2543Smrg} 72706f2543Smrg 73706f2543Smrgstatic Bool 74706f2543SmrgxnestSaveScreen(ScreenPtr pScreen, int what) 75706f2543Smrg{ 76706f2543Smrg if (xnestSoftwareScreenSaver) 77706f2543Smrg return False; 78706f2543Smrg else { 79706f2543Smrg switch (what) { 80706f2543Smrg case SCREEN_SAVER_ON: 81706f2543Smrg XMapRaised(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 82706f2543Smrg xnestSetScreenSaverColormapWindow(pScreen); 83706f2543Smrg break; 84706f2543Smrg 85706f2543Smrg case SCREEN_SAVER_OFF: 86706f2543Smrg XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 87706f2543Smrg xnestSetInstalledColormapWindows(pScreen); 88706f2543Smrg break; 89706f2543Smrg 90706f2543Smrg case SCREEN_SAVER_FORCER: 91706f2543Smrg lastEventTime = GetTimeInMillis(); 92706f2543Smrg XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 93706f2543Smrg xnestSetInstalledColormapWindows(pScreen); 94706f2543Smrg break; 95706f2543Smrg 96706f2543Smrg case SCREEN_SAVER_CYCLE: 97706f2543Smrg XUnmapWindow(xnestDisplay, xnestScreenSaverWindows[pScreen->myNum]); 98706f2543Smrg xnestSetInstalledColormapWindows(pScreen); 99706f2543Smrg break; 100706f2543Smrg } 101706f2543Smrg return True; 102706f2543Smrg } 103706f2543Smrg} 104706f2543Smrg 105706f2543Smrgstatic Bool 106706f2543SmrgxnestCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) 107706f2543Smrg{ 108706f2543Smrg return FALSE; 109706f2543Smrg} 110706f2543Smrg 111706f2543Smrgstatic void 112706f2543SmrgxnestCrossScreen(ScreenPtr pScreen, Bool entering) 113706f2543Smrg{ 114706f2543Smrg} 115706f2543Smrg 116706f2543Smrgstatic miPointerScreenFuncRec xnestPointerCursorFuncs = 117706f2543Smrg{ 118706f2543Smrg xnestCursorOffScreen, 119706f2543Smrg xnestCrossScreen, 120706f2543Smrg miPointerWarpCursor 121706f2543Smrg}; 122706f2543Smrg 123706f2543Smrgstatic miPointerSpriteFuncRec xnestPointerSpriteFuncs = 124706f2543Smrg{ 125706f2543Smrg xnestRealizeCursor, 126706f2543Smrg xnestUnrealizeCursor, 127706f2543Smrg xnestSetCursor, 128706f2543Smrg xnestMoveCursor, 129706f2543Smrg xnestDeviceCursorInitialize, 130706f2543Smrg xnestDeviceCursorCleanup 131706f2543Smrg}; 132706f2543Smrg 133706f2543SmrgBool 134706f2543SmrgxnestOpenScreen(int index, ScreenPtr pScreen, int argc, char *argv[]) 135706f2543Smrg{ 136706f2543Smrg VisualPtr visuals; 137706f2543Smrg DepthPtr depths; 138706f2543Smrg int numVisuals, numDepths; 139706f2543Smrg int i, j, depthIndex; 140706f2543Smrg unsigned long valuemask; 141706f2543Smrg XSetWindowAttributes attributes; 142706f2543Smrg XWindowAttributes gattributes; 143706f2543Smrg XSizeHints sizeHints; 144706f2543Smrg VisualID defaultVisual; 145706f2543Smrg int rootDepth; 146706f2543Smrg miPointerScreenPtr PointPriv; 147706f2543Smrg 148706f2543Smrg if (!dixRegisterPrivateKey(&xnestWindowPrivateKeyRec, PRIVATE_WINDOW, sizeof(xnestPrivWin))) 149706f2543Smrg return FALSE; 150706f2543Smrg if (!dixRegisterPrivateKey(&xnestGCPrivateKeyRec, PRIVATE_GC, sizeof(xnestPrivGC))) 151706f2543Smrg return FALSE; 152706f2543Smrg if (!dixRegisterPrivateKey(&xnestPixmapPrivateKeyRec, PRIVATE_PIXMAP, sizeof (xnestPrivPixmap))) 153706f2543Smrg return FALSE; 154706f2543Smrg if (!dixRegisterPrivateKey(&xnestColormapPrivateKeyRec, PRIVATE_COLORMAP, sizeof (xnestPrivColormap))) 155706f2543Smrg return FALSE; 156706f2543Smrg if (!dixRegisterPrivateKey(&xnestCursorScreenKeyRec, PRIVATE_SCREEN, 0)) 157706f2543Smrg return FALSE; 158706f2543Smrg 159706f2543Smrg visuals = (VisualPtr)malloc(xnestNumVisuals * sizeof(VisualRec)); 160706f2543Smrg numVisuals = 0; 161706f2543Smrg 162706f2543Smrg depths = (DepthPtr)malloc(MAXDEPTH * sizeof(DepthRec)); 163706f2543Smrg depths[0].depth = 1; 164706f2543Smrg depths[0].numVids = 0; 165706f2543Smrg depths[0].vids = (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 166706f2543Smrg numDepths = 1; 167706f2543Smrg 168706f2543Smrg for (i = 0; i < xnestNumVisuals; i++) { 169706f2543Smrg visuals[numVisuals].class = xnestVisuals[i].class; 170706f2543Smrg visuals[numVisuals].bitsPerRGBValue = xnestVisuals[i].bits_per_rgb; 171706f2543Smrg visuals[numVisuals].ColormapEntries = xnestVisuals[i].colormap_size; 172706f2543Smrg visuals[numVisuals].nplanes = xnestVisuals[i].depth; 173706f2543Smrg visuals[numVisuals].redMask = xnestVisuals[i].red_mask; 174706f2543Smrg visuals[numVisuals].greenMask = xnestVisuals[i].green_mask; 175706f2543Smrg visuals[numVisuals].blueMask = xnestVisuals[i].blue_mask; 176706f2543Smrg visuals[numVisuals].offsetRed = offset(xnestVisuals[i].red_mask); 177706f2543Smrg visuals[numVisuals].offsetGreen = offset(xnestVisuals[i].green_mask); 178706f2543Smrg visuals[numVisuals].offsetBlue = offset(xnestVisuals[i].blue_mask); 179706f2543Smrg 180706f2543Smrg /* Check for and remove duplicates. */ 181706f2543Smrg for (j = 0; j < numVisuals; j++) { 182706f2543Smrg if (visuals[numVisuals].class == visuals[j].class && 183706f2543Smrg visuals[numVisuals].bitsPerRGBValue == visuals[j].bitsPerRGBValue && 184706f2543Smrg visuals[numVisuals].ColormapEntries == visuals[j].ColormapEntries && 185706f2543Smrg visuals[numVisuals].nplanes == visuals[j].nplanes && 186706f2543Smrg visuals[numVisuals].redMask == visuals[j].redMask && 187706f2543Smrg visuals[numVisuals].greenMask == visuals[j].greenMask && 188706f2543Smrg visuals[numVisuals].blueMask == visuals[j].blueMask && 189706f2543Smrg visuals[numVisuals].offsetRed == visuals[j].offsetRed && 190706f2543Smrg visuals[numVisuals].offsetGreen == visuals[j].offsetGreen && 191706f2543Smrg visuals[numVisuals].offsetBlue == visuals[j].offsetBlue) 192706f2543Smrg break; 193706f2543Smrg } 194706f2543Smrg if (j < numVisuals) 195706f2543Smrg break; 196706f2543Smrg 197706f2543Smrg visuals[numVisuals].vid = FakeClientID(0); 198706f2543Smrg 199706f2543Smrg depthIndex = UNDEFINED; 200706f2543Smrg for (j = 0; j < numDepths; j++) 201706f2543Smrg if (depths[j].depth == xnestVisuals[i].depth) { 202706f2543Smrg depthIndex = j; 203706f2543Smrg break; 204706f2543Smrg } 205706f2543Smrg 206706f2543Smrg if (depthIndex == UNDEFINED) { 207706f2543Smrg depthIndex = numDepths; 208706f2543Smrg depths[depthIndex].depth = xnestVisuals[i].depth; 209706f2543Smrg depths[depthIndex].numVids = 0; 210706f2543Smrg depths[depthIndex].vids = 211706f2543Smrg (VisualID *)malloc(MAXVISUALSPERDEPTH * sizeof(VisualID)); 212706f2543Smrg numDepths++; 213706f2543Smrg } 214706f2543Smrg if (depths[depthIndex].numVids >= MAXVISUALSPERDEPTH) { 215706f2543Smrg FatalError("Visual table overflow"); 216706f2543Smrg } 217706f2543Smrg depths[depthIndex].vids[depths[depthIndex].numVids] = 218706f2543Smrg visuals[numVisuals].vid; 219706f2543Smrg depths[depthIndex].numVids++; 220706f2543Smrg 221706f2543Smrg numVisuals++; 222706f2543Smrg } 223706f2543Smrg visuals = (VisualPtr)realloc(visuals, numVisuals * sizeof(VisualRec)); 224706f2543Smrg 225706f2543Smrg defaultVisual = visuals[xnestDefaultVisualIndex].vid; 226706f2543Smrg rootDepth = visuals[xnestDefaultVisualIndex].nplanes; 227706f2543Smrg 228706f2543Smrg if (xnestParentWindow != 0) { 229706f2543Smrg XGetWindowAttributes(xnestDisplay, xnestParentWindow, &gattributes); 230706f2543Smrg xnestWidth = gattributes.width; 231706f2543Smrg xnestHeight = gattributes.height; 232706f2543Smrg } 233706f2543Smrg 234706f2543Smrg /* myNum */ 235706f2543Smrg /* id */ 236706f2543Smrg miScreenInit(pScreen, NULL, xnestWidth, xnestHeight, 1, 1, xnestWidth, 237706f2543Smrg rootDepth, 238706f2543Smrg numDepths, depths, 239706f2543Smrg defaultVisual, /* root visual */ 240706f2543Smrg numVisuals, visuals); 241706f2543Smrg 242706f2543Smrg pScreen->defColormap = (Colormap) FakeClientID(0); 243706f2543Smrg pScreen->minInstalledCmaps = MINCMAPS; 244706f2543Smrg pScreen->maxInstalledCmaps = MAXCMAPS; 245706f2543Smrg pScreen->backingStoreSupport = NotUseful; 246706f2543Smrg pScreen->saveUnderSupport = NotUseful; 247706f2543Smrg pScreen->whitePixel = xnestWhitePixel; 248706f2543Smrg pScreen->blackPixel = xnestBlackPixel; 249706f2543Smrg /* GCperDepth */ 250706f2543Smrg /* PixmapPerDepth */ 251706f2543Smrg pScreen->devPrivate = NULL; 252706f2543Smrg /* WindowPrivateLen */ 253706f2543Smrg /* WindowPrivateSizes */ 254706f2543Smrg /* totalWindowSize */ 255706f2543Smrg /* GCPrivateLen */ 256706f2543Smrg /* GCPrivateSizes */ 257706f2543Smrg /* totalGCSize */ 258706f2543Smrg 259706f2543Smrg /* Random screen procedures */ 260706f2543Smrg 261706f2543Smrg pScreen->QueryBestSize = xnestQueryBestSize; 262706f2543Smrg pScreen->SaveScreen = xnestSaveScreen; 263706f2543Smrg pScreen->GetImage = xnestGetImage; 264706f2543Smrg pScreen->GetSpans = xnestGetSpans; 265706f2543Smrg pScreen->SourceValidate = NULL; 266706f2543Smrg 267706f2543Smrg /* Window Procedures */ 268706f2543Smrg 269706f2543Smrg pScreen->CreateWindow = xnestCreateWindow; 270706f2543Smrg pScreen->DestroyWindow = xnestDestroyWindow; 271706f2543Smrg pScreen->PositionWindow = xnestPositionWindow; 272706f2543Smrg pScreen->ChangeWindowAttributes = xnestChangeWindowAttributes; 273706f2543Smrg pScreen->RealizeWindow = xnestRealizeWindow; 274706f2543Smrg pScreen->UnrealizeWindow = xnestUnrealizeWindow; 275706f2543Smrg pScreen->PostValidateTree = NULL; 276706f2543Smrg pScreen->WindowExposures = xnestWindowExposures; 277706f2543Smrg pScreen->CopyWindow = xnestCopyWindow; 278706f2543Smrg pScreen->ClipNotify = xnestClipNotify; 279706f2543Smrg 280706f2543Smrg /* Pixmap procedures */ 281706f2543Smrg 282706f2543Smrg pScreen->CreatePixmap = xnestCreatePixmap; 283706f2543Smrg pScreen->DestroyPixmap = xnestDestroyPixmap; 284706f2543Smrg 285706f2543Smrg /* Font procedures */ 286706f2543Smrg 287706f2543Smrg pScreen->RealizeFont = xnestRealizeFont; 288706f2543Smrg pScreen->UnrealizeFont = xnestUnrealizeFont; 289706f2543Smrg 290706f2543Smrg /* GC procedures */ 291706f2543Smrg 292706f2543Smrg pScreen->CreateGC = xnestCreateGC; 293706f2543Smrg 294706f2543Smrg /* Colormap procedures */ 295706f2543Smrg 296706f2543Smrg pScreen->CreateColormap = xnestCreateColormap; 297706f2543Smrg pScreen->DestroyColormap = xnestDestroyColormap; 298706f2543Smrg pScreen->InstallColormap = xnestInstallColormap; 299706f2543Smrg pScreen->UninstallColormap = xnestUninstallColormap; 300706f2543Smrg pScreen->ListInstalledColormaps = xnestListInstalledColormaps; 301706f2543Smrg pScreen->StoreColors = xnestStoreColors; 302706f2543Smrg pScreen->ResolveColor = xnestResolveColor; 303706f2543Smrg 304706f2543Smrg pScreen->BitmapToRegion = xnestPixmapToRegion; 305706f2543Smrg 306706f2543Smrg /* OS layer procedures */ 307706f2543Smrg 308706f2543Smrg pScreen->BlockHandler = (ScreenBlockHandlerProcPtr)NoopDDA; 309706f2543Smrg pScreen->WakeupHandler = (ScreenWakeupHandlerProcPtr)NoopDDA; 310706f2543Smrg pScreen->blockData = NULL; 311706f2543Smrg pScreen->wakeupData = NULL; 312706f2543Smrg 313706f2543Smrg miDCInitialize(pScreen, &xnestPointerCursorFuncs); /* init SW rendering */ 314706f2543Smrg PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); 315706f2543Smrg xnestCursorFuncs.spriteFuncs = PointPriv->spriteFuncs; 316706f2543Smrg dixSetPrivate(&pScreen->devPrivates, xnestCursorScreenKey, &xnestCursorFuncs); 317706f2543Smrg PointPriv->spriteFuncs = &xnestPointerSpriteFuncs; 318706f2543Smrg 319706f2543Smrg pScreen->mmWidth = xnestWidth * DisplayWidthMM(xnestDisplay, 320706f2543Smrg DefaultScreen(xnestDisplay)) / 321706f2543Smrg DisplayWidth(xnestDisplay, 322706f2543Smrg DefaultScreen(xnestDisplay)); 323706f2543Smrg pScreen->mmHeight = xnestHeight * DisplayHeightMM(xnestDisplay, 324706f2543Smrg DefaultScreen(xnestDisplay)) / 325706f2543Smrg DisplayHeight(xnestDisplay, 326706f2543Smrg DefaultScreen(xnestDisplay)); 327706f2543Smrg 328706f2543Smrg /* overwrite miCloseScreen with our own */ 329706f2543Smrg pScreen->CloseScreen = xnestCloseScreen; 330706f2543Smrg 331706f2543Smrg if (!miScreenDevPrivateInit(pScreen, xnestWidth, NULL)) 332706f2543Smrg return FALSE; 333706f2543Smrg 334706f2543Smrg /* overwrite miSetShape with our own */ 335706f2543Smrg pScreen->SetShape = xnestSetShape; 336706f2543Smrg 337706f2543Smrg /* devPrivates */ 338706f2543Smrg 339706f2543Smrg#define POSITION_OFFSET (pScreen->myNum * (xnestWidth + xnestHeight) / 32) 340706f2543Smrg 341706f2543Smrg if (xnestDoFullGeneration) { 342706f2543Smrg 343706f2543Smrg valuemask = CWBackPixel | CWEventMask | CWColormap; 344706f2543Smrg attributes.background_pixel = xnestWhitePixel; 345706f2543Smrg attributes.event_mask = xnestEventMask; 346706f2543Smrg attributes.colormap = xnestDefaultVisualColormap(xnestDefaultVisual(pScreen)); 347706f2543Smrg 348706f2543Smrg if (xnestParentWindow != 0) { 349706f2543Smrg xnestDefaultWindows[pScreen->myNum] = xnestParentWindow; 350706f2543Smrg XSelectInput (xnestDisplay, xnestDefaultWindows[pScreen->myNum], 351706f2543Smrg xnestEventMask); 352706f2543Smrg } else 353706f2543Smrg xnestDefaultWindows[pScreen->myNum] = 354706f2543Smrg XCreateWindow(xnestDisplay, 355706f2543Smrg DefaultRootWindow(xnestDisplay), 356706f2543Smrg xnestX + POSITION_OFFSET, 357706f2543Smrg xnestY + POSITION_OFFSET, 358706f2543Smrg xnestWidth, xnestHeight, 359706f2543Smrg xnestBorderWidth, 360706f2543Smrg pScreen->rootDepth, 361706f2543Smrg InputOutput, 362706f2543Smrg xnestDefaultVisual(pScreen), 363706f2543Smrg valuemask, &attributes); 364706f2543Smrg 365706f2543Smrg if (!xnestWindowName) 366706f2543Smrg xnestWindowName = argv[0]; 367706f2543Smrg 368706f2543Smrg sizeHints.flags = PPosition | PSize | PMaxSize; 369706f2543Smrg sizeHints.x = xnestX + POSITION_OFFSET; 370706f2543Smrg sizeHints.y = xnestY + POSITION_OFFSET; 371706f2543Smrg sizeHints.width = sizeHints.max_width = xnestWidth; 372706f2543Smrg sizeHints.height = sizeHints.max_height = xnestHeight; 373706f2543Smrg if (xnestUserGeometry & XValue || xnestUserGeometry & YValue) 374706f2543Smrg sizeHints.flags |= USPosition; 375706f2543Smrg if (xnestUserGeometry & WidthValue || xnestUserGeometry & HeightValue) 376706f2543Smrg sizeHints.flags |= USSize; 377706f2543Smrg XSetStandardProperties(xnestDisplay, 378706f2543Smrg xnestDefaultWindows[pScreen->myNum], 379706f2543Smrg xnestWindowName, 380706f2543Smrg xnestWindowName, 381706f2543Smrg xnestIconBitmap, 382706f2543Smrg argv, argc, &sizeHints); 383706f2543Smrg 384706f2543Smrg XMapWindow(xnestDisplay, xnestDefaultWindows[pScreen->myNum]); 385706f2543Smrg 386706f2543Smrg valuemask = CWBackPixmap | CWColormap; 387706f2543Smrg attributes.background_pixmap = xnestScreenSaverPixmap; 388706f2543Smrg attributes.colormap = 389706f2543Smrg DefaultColormap(xnestDisplay, DefaultScreen(xnestDisplay)); 390706f2543Smrg xnestScreenSaverWindows[pScreen->myNum] = 391706f2543Smrg XCreateWindow(xnestDisplay, 392706f2543Smrg xnestDefaultWindows[pScreen->myNum], 393706f2543Smrg 0, 0, xnestWidth, xnestHeight, 0, 394706f2543Smrg DefaultDepth(xnestDisplay, DefaultScreen(xnestDisplay)), 395706f2543Smrg InputOutput, 396706f2543Smrg DefaultVisual(xnestDisplay, DefaultScreen(xnestDisplay)), 397706f2543Smrg valuemask, &attributes); 398706f2543Smrg } 399706f2543Smrg 400706f2543Smrg if (!xnestCreateDefaultColormap(pScreen)) return False; 401706f2543Smrg 402706f2543Smrg return True; 403706f2543Smrg} 404706f2543Smrg 405706f2543SmrgBool 406706f2543SmrgxnestCloseScreen(int index, ScreenPtr pScreen) 407706f2543Smrg{ 408706f2543Smrg int i; 409706f2543Smrg 410706f2543Smrg for (i = 0; i < pScreen->numDepths; i++) 411706f2543Smrg free(pScreen->allowedDepths[i].vids); 412706f2543Smrg free(pScreen->allowedDepths); 413706f2543Smrg free(pScreen->visuals); 414706f2543Smrg free(pScreen->devPrivate); 415706f2543Smrg 416706f2543Smrg /* 417706f2543Smrg If xnestDoFullGeneration all x resources will be destroyed upon closing 418706f2543Smrg the display connection. There is no need to generate extra protocol. 419706f2543Smrg */ 420706f2543Smrg 421706f2543Smrg return True; 422706f2543Smrg} 423