| 1 | /* |
| 2 | *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. |
| 3 | * |
| 4 | *Permission is hereby granted, free of charge, to any person obtaining |
| 5 | * a copy of this software and associated documentation files (the |
| 6 | *"Software"), to deal in the Software without restriction, including |
| 7 | *without limitation the rights to use, copy, modify, merge, publish, |
| 8 | *distribute, sublicense, and/or sell copies of the Software, and to |
| 9 | *permit persons to whom the Software is furnished to do so, subject to |
| 10 | *the following conditions: |
| 11 | * |
| 12 | *The above copyright notice and this permission notice shall be |
| 13 | *included in all copies or substantial portions of the Software. |
| 14 | * |
| 15 | *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| 16 | *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| 17 | *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| 18 | *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR |
| 19 | *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF |
| 20 | *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
| 21 | *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 22 | * |
| 23 | *Except as contained in this notice, the name of the XFree86 Project |
| 24 | *shall not be used in advertising or otherwise to promote the sale, use |
| 25 | *or other dealings in this Software without prior written authorization |
| 26 | *from the XFree86 Project. |
| 27 | * |
| 28 | * Authors: Dakshinamurthy Karra |
| 29 | * Suhaib M Siddiqi |
| 30 | * Peter Busch |
| 31 | * Harold L Hunt II |
| 32 | * Kensuke Matsuzaki |
| 33 | */ |
| 34 | |
| 35 | #ifdef HAVE_XWIN_CONFIG_H |
| 36 | #include <xwin-config.h> |
| 37 | #endif |
| 38 | #include "win.h" |
| 39 | #include "winmsg.h" |
| 40 | |
| 41 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 42 | static RootlessFrameProcsRec winMWExtWMProcs = { |
| 43 | winMWExtWMCreateFrame, |
| 44 | winMWExtWMDestroyFrame, |
| 45 | |
| 46 | winMWExtWMMoveFrame, |
| 47 | winMWExtWMResizeFrame, |
| 48 | winMWExtWMRestackFrame, |
| 49 | winMWExtWMReshapeFrame, |
| 50 | winMWExtWMUnmapFrame, |
| 51 | |
| 52 | winMWExtWMStartDrawing, |
| 53 | winMWExtWMStopDrawing, |
| 54 | winMWExtWMUpdateRegion, |
| 55 | winMWExtWMDamageRects, |
| 56 | winMWExtWMRootlessSwitchWindow, |
| 57 | NULL, //winMWExtWMDoReorderWindow, |
| 58 | NULL, //winMWExtWMHideWindow, |
| 59 | NULL, //winMWExtWMUpdateColorMap, |
| 60 | |
| 61 | NULL, //winMWExtWMCopyBytes, |
| 62 | winMWExtWMCopyWindow |
| 63 | }; |
| 64 | #endif |
| 65 | |
| 66 | /* |
| 67 | * Prototypes |
| 68 | */ |
| 69 | |
| 70 | /* |
| 71 | * Local functions |
| 72 | */ |
| 73 | |
| 74 | static Bool |
| 75 | winSaveScreen(ScreenPtr pScreen, int on); |
| 76 | |
| 77 | /* |
| 78 | * Determine what type of screen we are initializing |
| 79 | * and call the appropriate procedure to intiailize |
| 80 | * that type of screen. |
| 81 | */ |
| 82 | |
| 83 | Bool |
| 84 | winScreenInit(ScreenPtr pScreen, int argc, char **argv) |
| 85 | { |
| 86 | winScreenInfoPtr pScreenInfo = &g_ScreenInfo[pScreen->myNum]; |
| 87 | winPrivScreenPtr pScreenPriv; |
| 88 | HDC hdc; |
| 89 | DWORD dwInitialBPP; |
| 90 | |
| 91 | #if CYGDEBUG || YES |
| 92 | winDebug("winScreenInit - dwWidth: %ld dwHeight: %ld\n", |
| 93 | pScreenInfo->dwWidth, pScreenInfo->dwHeight); |
| 94 | #endif |
| 95 | |
| 96 | /* Allocate privates for this screen */ |
| 97 | if (!winAllocatePrivates(pScreen)) { |
| 98 | ErrorF("winScreenInit - Couldn't allocate screen privates\n"); |
| 99 | return FALSE; |
| 100 | } |
| 101 | |
| 102 | /* Get a pointer to the privates structure that was allocated */ |
| 103 | pScreenPriv = winGetScreenPriv(pScreen); |
| 104 | |
| 105 | /* Save a pointer to this screen in the screen info structure */ |
| 106 | pScreenInfo->pScreen = pScreen; |
| 107 | |
| 108 | /* Save a pointer to the screen info in the screen privates structure */ |
| 109 | /* This allows us to get back to the screen info from a screen pointer */ |
| 110 | pScreenPriv->pScreenInfo = pScreenInfo; |
| 111 | |
| 112 | /* |
| 113 | * Determine which engine to use. |
| 114 | * |
| 115 | * NOTE: This is done once per screen because each screen possibly has |
| 116 | * a preferred engine specified on the command line. |
| 117 | */ |
| 118 | if (!winSetEngine(pScreen)) { |
| 119 | ErrorF("winScreenInit - winSetEngine () failed\n"); |
| 120 | return FALSE; |
| 121 | } |
| 122 | |
| 123 | /* Horribly misnamed function: Allow engine to adjust BPP for screen */ |
| 124 | dwInitialBPP = pScreenInfo->dwBPP; |
| 125 | |
| 126 | if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) { |
| 127 | ErrorF("winScreenInit - winAdjustVideoMode () failed\n"); |
| 128 | return FALSE; |
| 129 | } |
| 130 | |
| 131 | if (dwInitialBPP == WIN_DEFAULT_BPP) { |
| 132 | /* No -depth parameter was passed, let the user know the depth being used */ |
| 133 | ErrorF |
| 134 | ("winScreenInit - Using Windows display depth of %d bits per pixel\n", |
| 135 | (int) pScreenInfo->dwBPP); |
| 136 | } |
| 137 | else if (dwInitialBPP != pScreenInfo->dwBPP) { |
| 138 | /* Warn user if engine forced a depth different to -depth parameter */ |
| 139 | ErrorF |
| 140 | ("winScreenInit - Command line depth of %d bpp overidden by engine, using %d bpp\n", |
| 141 | (int) dwInitialBPP, (int) pScreenInfo->dwBPP); |
| 142 | } |
| 143 | else { |
| 144 | ErrorF("winScreenInit - Using command line depth of %d bpp\n", |
| 145 | (int) pScreenInfo->dwBPP); |
| 146 | } |
| 147 | |
| 148 | /* Check for supported display depth */ |
| 149 | if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) { |
| 150 | ErrorF("winScreenInit - Unsupported display depth: %d\n" |
| 151 | "Change your Windows display depth to 15, 16, 24, or 32 bits " |
| 152 | "per pixel.\n", (int) pScreenInfo->dwBPP); |
| 153 | ErrorF("winScreenInit - Supported depths: %08x\n", WIN_SUPPORTED_BPPS); |
| 154 | #if WIN_CHECK_DEPTH |
| 155 | return FALSE; |
| 156 | #endif |
| 157 | } |
| 158 | |
| 159 | /* |
| 160 | * Check that all monitors have the same display depth if we are using |
| 161 | * multiple monitors |
| 162 | */ |
| 163 | if (pScreenInfo->fMultipleMonitors |
| 164 | && !GetSystemMetrics(SM_SAMEDISPLAYFORMAT)) { |
| 165 | ErrorF("winScreenInit - Monitors do not all have same pixel format / " |
| 166 | "display depth.\n"); |
| 167 | if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) { |
| 168 | ErrorF |
| 169 | ("winScreenInit - Performance may suffer off primary display.\n"); |
| 170 | } |
| 171 | else { |
| 172 | ErrorF("winScreenInit - Using primary display only.\n"); |
| 173 | pScreenInfo->fMultipleMonitors = FALSE; |
| 174 | } |
| 175 | } |
| 176 | |
| 177 | /* Create display window */ |
| 178 | if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) { |
| 179 | ErrorF("winScreenInit - pwinCreateBoundingWindow () " "failed\n"); |
| 180 | return FALSE; |
| 181 | } |
| 182 | |
| 183 | /* Get a device context */ |
| 184 | hdc = GetDC(pScreenPriv->hwndScreen); |
| 185 | |
| 186 | /* Are we using multiple monitors? */ |
| 187 | if (pScreenInfo->fMultipleMonitors) { |
| 188 | /* |
| 189 | * In this case, some of the defaults set in |
| 190 | * winInitializeScreenDefaults() are not correct ... |
| 191 | */ |
| 192 | if (!pScreenInfo->fUserGaveHeightAndWidth) { |
| 193 | pScreenInfo->dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); |
| 194 | pScreenInfo->dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | /* Release the device context */ |
| 199 | ReleaseDC(pScreenPriv->hwndScreen, hdc); |
| 200 | |
| 201 | /* Clear the visuals list */ |
| 202 | miClearVisualTypes(); |
| 203 | |
| 204 | /* Call the engine dependent screen initialization procedure */ |
| 205 | if (!((*pScreenPriv->pwinFinishScreenInit) (pScreen->myNum, pScreen, argc, argv))) { |
| 206 | ErrorF("winScreenInit - winFinishScreenInit () failed\n"); |
| 207 | |
| 208 | /* call the engine dependent screen close procedure to clean up from a failure */ |
| 209 | pScreenPriv->pwinCloseScreen(pScreen); |
| 210 | |
| 211 | return FALSE; |
| 212 | } |
| 213 | |
| 214 | if (!g_fSoftwareCursor) |
| 215 | winInitCursor(pScreen); |
| 216 | else |
| 217 | winErrorFVerb(2, "winScreenInit - Using software cursor\n"); |
| 218 | |
| 219 | /* |
| 220 | Note the screen origin in a normalized coordinate space where (0,0) is at the top left |
| 221 | of the native virtual desktop area |
| 222 | */ |
| 223 | pScreen->x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN); |
| 224 | pScreen->y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN); |
| 225 | |
| 226 | ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n", |
| 227 | pScreen->myNum, pScreen->x, pScreen->y); |
| 228 | |
| 229 | #if CYGDEBUG || YES |
| 230 | winDebug("winScreenInit - returning\n"); |
| 231 | #endif |
| 232 | |
| 233 | return TRUE; |
| 234 | } |
| 235 | |
| 236 | static Bool |
| 237 | winCreateScreenResources(ScreenPtr pScreen) |
| 238 | { |
| 239 | winScreenPriv(pScreen); |
| 240 | Bool result; |
| 241 | |
| 242 | result = pScreenPriv->pwinCreateScreenResources(pScreen); |
| 243 | |
| 244 | /* Now the screen bitmap has been wrapped in a pixmap, |
| 245 | add that to the Shadow framebuffer */ |
| 246 | if (!shadowAdd(pScreen, pScreen->devPrivate, |
| 247 | pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) { |
| 248 | ErrorF("winCreateScreenResources - shadowAdd () failed\n"); |
| 249 | return FALSE; |
| 250 | } |
| 251 | |
| 252 | return result; |
| 253 | } |
| 254 | |
| 255 | /* See Porting Layer Definition - p. 20 */ |
| 256 | Bool |
| 257 | winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv) |
| 258 | { |
| 259 | winScreenPriv(pScreen); |
| 260 | winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; |
| 261 | VisualPtr pVisual = NULL; |
| 262 | |
| 263 | #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) |
| 264 | int iReturn; |
| 265 | #endif |
| 266 | |
| 267 | /* Create framebuffer */ |
| 268 | if (!(*pScreenPriv->pwinInitScreen) (pScreen)) { |
| 269 | ErrorF("winFinishScreenInitFB - Could not allocate framebuffer\n"); |
| 270 | return FALSE; |
| 271 | } |
| 272 | |
| 273 | /* |
| 274 | * Calculate the number of bits that are used to represent color in each pixel, |
| 275 | * the color depth for the screen |
| 276 | */ |
| 277 | if (pScreenInfo->dwBPP == 8) |
| 278 | pScreenInfo->dwDepth = 8; |
| 279 | else |
| 280 | pScreenInfo->dwDepth = winCountBits(pScreenPriv->dwRedMask) |
| 281 | + winCountBits(pScreenPriv->dwGreenMask) |
| 282 | + winCountBits(pScreenPriv->dwBlueMask); |
| 283 | |
| 284 | winErrorFVerb(2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n", |
| 285 | (unsigned int) pScreenPriv->dwRedMask, |
| 286 | (unsigned int) pScreenPriv->dwGreenMask, |
| 287 | (unsigned int) pScreenPriv->dwBlueMask); |
| 288 | |
| 289 | /* Init visuals */ |
| 290 | if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) { |
| 291 | ErrorF("winFinishScreenInitFB - winInitVisuals failed\n"); |
| 292 | return FALSE; |
| 293 | } |
| 294 | |
| 295 | /* Apparently we need this for the render extension */ |
| 296 | miSetPixmapDepths(); |
| 297 | |
| 298 | /* Start fb initialization */ |
| 299 | if (!fbSetupScreen(pScreen, |
| 300 | pScreenInfo->pfb, |
| 301 | pScreenInfo->dwWidth, pScreenInfo->dwHeight, |
| 302 | monitorResolution, monitorResolution, |
| 303 | pScreenInfo->dwStride, pScreenInfo->dwBPP)) { |
| 304 | ErrorF("winFinishScreenInitFB - fbSetupScreen failed\n"); |
| 305 | return FALSE; |
| 306 | } |
| 307 | |
| 308 | /* Override default colormap routines if visual class is dynamic */ |
| 309 | if (pScreenInfo->dwDepth == 8 |
| 310 | && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI |
| 311 | || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL |
| 312 | && pScreenInfo->fFullScreen) |
| 313 | || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD |
| 314 | && pScreenInfo->fFullScreen))) { |
| 315 | winSetColormapFunctions(pScreen); |
| 316 | |
| 317 | /* |
| 318 | * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its |
| 319 | * own colormap, as it cannot allocate 7 planes in the default |
| 320 | * colormap. Setting whitePixel to 1 allows Magic to get 7 |
| 321 | * planes in the default colormap, so it doesn't create its |
| 322 | * own colormap. This latter situation is highly desireable, |
| 323 | * as it keeps the Magic window viewable when switching to |
| 324 | * other X clients that use the default colormap. |
| 325 | */ |
| 326 | pScreen->blackPixel = 0; |
| 327 | pScreen->whitePixel = 1; |
| 328 | } |
| 329 | |
| 330 | /* Place our save screen function */ |
| 331 | pScreen->SaveScreen = winSaveScreen; |
| 332 | |
| 333 | /* Finish fb initialization */ |
| 334 | if (!fbFinishScreenInit(pScreen, |
| 335 | pScreenInfo->pfb, |
| 336 | pScreenInfo->dwWidth, pScreenInfo->dwHeight, |
| 337 | monitorResolution, monitorResolution, |
| 338 | pScreenInfo->dwStride, pScreenInfo->dwBPP)) { |
| 339 | ErrorF("winFinishScreenInitFB - fbFinishScreenInit failed\n"); |
| 340 | return FALSE; |
| 341 | } |
| 342 | |
| 343 | /* Save a pointer to the root visual */ |
| 344 | for (pVisual = pScreen->visuals; |
| 345 | pVisual->vid != pScreen->rootVisual; pVisual++); |
| 346 | pScreenPriv->pRootVisual = pVisual; |
| 347 | |
| 348 | /* |
| 349 | * Setup points to the block and wakeup handlers. Pass a pointer |
| 350 | * to the current screen as pWakeupdata. |
| 351 | */ |
| 352 | pScreen->BlockHandler = winBlockHandler; |
| 353 | pScreen->WakeupHandler = winWakeupHandler; |
| 354 | |
| 355 | /* Render extension initialization, calls miPictureInit */ |
| 356 | if (!fbPictureInit(pScreen, NULL, 0)) { |
| 357 | ErrorF("winFinishScreenInitFB - fbPictureInit () failed\n"); |
| 358 | return FALSE; |
| 359 | } |
| 360 | |
| 361 | #ifdef RANDR |
| 362 | /* Initialize resize and rotate support */ |
| 363 | if (!winRandRInit(pScreen)) { |
| 364 | ErrorF("winFinishScreenInitFB - winRandRInit () failed\n"); |
| 365 | return FALSE; |
| 366 | } |
| 367 | #endif |
| 368 | |
| 369 | /* Setup the cursor routines */ |
| 370 | #if CYGDEBUG |
| 371 | winDebug("winFinishScreenInitFB - Calling miDCInitialize ()\n"); |
| 372 | #endif |
| 373 | miDCInitialize(pScreen, &g_winPointerCursorFuncs); |
| 374 | |
| 375 | /* KDrive does winCreateDefColormap right after miDCInitialize */ |
| 376 | /* Create a default colormap */ |
| 377 | #if CYGDEBUG |
| 378 | winDebug("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); |
| 379 | #endif |
| 380 | if (!winCreateDefColormap(pScreen)) { |
| 381 | ErrorF("winFinishScreenInitFB - Could not create colormap\n"); |
| 382 | return FALSE; |
| 383 | } |
| 384 | |
| 385 | /* Initialize the shadow framebuffer layer */ |
| 386 | if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI |
| 387 | || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD |
| 388 | || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) |
| 389 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 390 | && !pScreenInfo->fMWExtWM |
| 391 | #endif |
| 392 | ) { |
| 393 | #if CYGDEBUG |
| 394 | winDebug("winFinishScreenInitFB - Calling shadowSetup ()\n"); |
| 395 | #endif |
| 396 | if (!shadowSetup(pScreen)) { |
| 397 | ErrorF("winFinishScreenInitFB - shadowSetup () failed\n"); |
| 398 | return FALSE; |
| 399 | } |
| 400 | |
| 401 | /* Wrap CreateScreenResources so we can add the screen pixmap |
| 402 | to the Shadow framebuffer after it's been created */ |
| 403 | pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources; |
| 404 | pScreen->CreateScreenResources = winCreateScreenResources; |
| 405 | } |
| 406 | |
| 407 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 408 | /* Handle multi-window external window manager mode */ |
| 409 | if (pScreenInfo->fMWExtWM) { |
| 410 | winDebug("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n"); |
| 411 | |
| 412 | RootlessInit(pScreen, &winMWExtWMProcs); |
| 413 | |
| 414 | winDebug("winScreenInit - MultiWindowExtWM - RootlessInit returned\n"); |
| 415 | |
| 416 | rootless_CopyBytes_threshold = 0; |
| 417 | /* FIXME: How many? Profiling needed? */ |
| 418 | rootless_CopyWindow_threshold = 1; |
| 419 | |
| 420 | winWindowsWMExtensionInit(); |
| 421 | } |
| 422 | #endif |
| 423 | |
| 424 | /* Handle rootless mode */ |
| 425 | if (pScreenInfo->fRootless) { |
| 426 | /* Define the WRAP macro temporarily for local use */ |
| 427 | #define WRAP(a) \ |
| 428 | if (pScreen->a) { \ |
| 429 | pScreenPriv->a = pScreen->a; \ |
| 430 | } else { \ |
| 431 | winDebug("winScreenInit - null screen fn " #a "\n"); \ |
| 432 | pScreenPriv->a = NULL; \ |
| 433 | } |
| 434 | |
| 435 | /* Save a pointer to each lower-level window procedure */ |
| 436 | WRAP(CreateWindow); |
| 437 | WRAP(DestroyWindow); |
| 438 | WRAP(RealizeWindow); |
| 439 | WRAP(UnrealizeWindow); |
| 440 | WRAP(PositionWindow); |
| 441 | WRAP(ChangeWindowAttributes); |
| 442 | WRAP(SetShape); |
| 443 | |
| 444 | /* Assign rootless window procedures to be top level procedures */ |
| 445 | pScreen->CreateWindow = winCreateWindowRootless; |
| 446 | pScreen->DestroyWindow = winDestroyWindowRootless; |
| 447 | pScreen->PositionWindow = winPositionWindowRootless; |
| 448 | /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless; */ |
| 449 | pScreen->RealizeWindow = winMapWindowRootless; |
| 450 | pScreen->UnrealizeWindow = winUnmapWindowRootless; |
| 451 | pScreen->SetShape = winSetShapeRootless; |
| 452 | |
| 453 | /* Undefine the WRAP macro, as it is not needed elsewhere */ |
| 454 | #undef WRAP |
| 455 | } |
| 456 | |
| 457 | #ifdef XWIN_MULTIWINDOW |
| 458 | /* Handle multi window mode */ |
| 459 | else if (pScreenInfo->fMultiWindow) { |
| 460 | /* Define the WRAP macro temporarily for local use */ |
| 461 | #define WRAP(a) \ |
| 462 | if (pScreen->a) { \ |
| 463 | pScreenPriv->a = pScreen->a; \ |
| 464 | } else { \ |
| 465 | winDebug("null screen fn " #a "\n"); \ |
| 466 | pScreenPriv->a = NULL; \ |
| 467 | } |
| 468 | |
| 469 | /* Save a pointer to each lower-level window procedure */ |
| 470 | WRAP(CreateWindow); |
| 471 | WRAP(DestroyWindow); |
| 472 | WRAP(RealizeWindow); |
| 473 | WRAP(UnrealizeWindow); |
| 474 | WRAP(PositionWindow); |
| 475 | WRAP(ChangeWindowAttributes); |
| 476 | WRAP(ReparentWindow); |
| 477 | WRAP(RestackWindow); |
| 478 | WRAP(ResizeWindow); |
| 479 | WRAP(MoveWindow); |
| 480 | WRAP(CopyWindow); |
| 481 | WRAP(SetShape); |
| 482 | |
| 483 | /* Assign multi-window window procedures to be top level procedures */ |
| 484 | pScreen->CreateWindow = winCreateWindowMultiWindow; |
| 485 | pScreen->DestroyWindow = winDestroyWindowMultiWindow; |
| 486 | pScreen->PositionWindow = winPositionWindowMultiWindow; |
| 487 | /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow; */ |
| 488 | pScreen->RealizeWindow = winMapWindowMultiWindow; |
| 489 | pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; |
| 490 | pScreen->ReparentWindow = winReparentWindowMultiWindow; |
| 491 | pScreen->RestackWindow = winRestackWindowMultiWindow; |
| 492 | pScreen->ResizeWindow = winResizeWindowMultiWindow; |
| 493 | pScreen->MoveWindow = winMoveWindowMultiWindow; |
| 494 | pScreen->CopyWindow = winCopyWindowMultiWindow; |
| 495 | pScreen->SetShape = winSetShapeMultiWindow; |
| 496 | |
| 497 | /* Undefine the WRAP macro, as it is not needed elsewhere */ |
| 498 | #undef WRAP |
| 499 | } |
| 500 | #endif |
| 501 | |
| 502 | /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ |
| 503 | pScreenPriv->CloseScreen = pScreen->CloseScreen; |
| 504 | pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; |
| 505 | |
| 506 | #if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) |
| 507 | /* Create a mutex for modules in separate threads to wait for */ |
| 508 | iReturn = pthread_mutex_init(&pScreenPriv->pmServerStarted, NULL); |
| 509 | if (iReturn != 0) { |
| 510 | ErrorF("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", |
| 511 | iReturn); |
| 512 | return FALSE; |
| 513 | } |
| 514 | |
| 515 | /* Own the mutex for modules in separate threads */ |
| 516 | iReturn = pthread_mutex_lock(&pScreenPriv->pmServerStarted); |
| 517 | if (iReturn != 0) { |
| 518 | ErrorF("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", |
| 519 | iReturn); |
| 520 | return FALSE; |
| 521 | } |
| 522 | |
| 523 | /* Set the ServerStarted flag to false */ |
| 524 | pScreenPriv->fServerStarted = FALSE; |
| 525 | #endif |
| 526 | |
| 527 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 528 | pScreenPriv->fRestacking = FALSE; |
| 529 | #endif |
| 530 | |
| 531 | #if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) |
| 532 | if (FALSE |
| 533 | #ifdef XWIN_MULTIWINDOW |
| 534 | || pScreenInfo->fMultiWindow |
| 535 | #endif |
| 536 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 537 | || pScreenInfo->fInternalWM |
| 538 | #endif |
| 539 | ) { |
| 540 | #if CYGDEBUG || YES |
| 541 | winDebug("winFinishScreenInitFB - Calling winInitWM.\n"); |
| 542 | #endif |
| 543 | |
| 544 | /* Initialize multi window mode */ |
| 545 | if (!winInitWM(&pScreenPriv->pWMInfo, |
| 546 | &pScreenPriv->ptWMProc, |
| 547 | &pScreenPriv->ptXMsgProc, |
| 548 | &pScreenPriv->pmServerStarted, |
| 549 | pScreenInfo->dwScreen, (HWND) &pScreenPriv->hwndScreen, |
| 550 | #ifdef XWIN_MULTIWINDOWEXTWM |
| 551 | pScreenInfo->fInternalWM || |
| 552 | #endif |
| 553 | FALSE)) { |
| 554 | ErrorF("winFinishScreenInitFB - winInitWM () failed.\n"); |
| 555 | return FALSE; |
| 556 | } |
| 557 | } |
| 558 | #endif |
| 559 | |
| 560 | /* Tell the server that we are enabled */ |
| 561 | pScreenPriv->fEnabled = TRUE; |
| 562 | |
| 563 | /* Tell the server that we have a valid depth */ |
| 564 | pScreenPriv->fBadDepth = FALSE; |
| 565 | |
| 566 | #if CYGDEBUG || YES |
| 567 | winDebug("winFinishScreenInitFB - returning\n"); |
| 568 | #endif |
| 569 | |
| 570 | return TRUE; |
| 571 | } |
| 572 | |
| 573 | #ifdef XWIN_NATIVEGDI |
| 574 | /* See Porting Layer Definition - p. 20 */ |
| 575 | |
| 576 | Bool |
| 577 | winFinishScreenInitNativeGDI(int i, |
| 578 | ScreenPtr pScreen, int argc, char **argv) |
| 579 | { |
| 580 | winScreenPriv(pScreen); |
| 581 | winScreenInfoPtr pScreenInfo = &g_ScreenInfo[i]; |
| 582 | VisualPtr pVisuals = NULL; |
| 583 | DepthPtr pDepths = NULL; |
| 584 | VisualID rootVisual = 0; |
| 585 | int nVisuals = 0, nDepths = 0, nRootDepth = 0; |
| 586 | |
| 587 | /* Ignore user input (mouse, keyboard) */ |
| 588 | pScreenInfo->fIgnoreInput = FALSE; |
| 589 | |
| 590 | /* Get device contexts for the screen and shadow bitmap */ |
| 591 | pScreenPriv->hdcScreen = GetDC(pScreenPriv->hwndScreen); |
| 592 | if (pScreenPriv->hdcScreen == NULL) |
| 593 | FatalError("winFinishScreenInitNativeGDI - Couldn't get a DC\n"); |
| 594 | |
| 595 | /* Init visuals */ |
| 596 | if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) { |
| 597 | ErrorF("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n"); |
| 598 | return FALSE; |
| 599 | } |
| 600 | |
| 601 | /* Initialize the mi visuals */ |
| 602 | if (!miInitVisuals(&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth, |
| 603 | &rootVisual, |
| 604 | ((unsigned long) 1 << (pScreenInfo->dwDepth - 1)), 8, |
| 605 | TrueColor)) { |
| 606 | ErrorF("winFinishScreenInitNativeGDI - miInitVisuals () failed\n"); |
| 607 | return FALSE; |
| 608 | } |
| 609 | |
| 610 | /* Initialize the CloseScreen procedure pointer */ |
| 611 | pScreen->CloseScreen = NULL; |
| 612 | |
| 613 | /* Initialize the mi code */ |
| 614 | if (!miScreenInit(pScreen, NULL, /* No framebuffer */ |
| 615 | pScreenInfo->dwWidth, pScreenInfo->dwHeight, |
| 616 | monitorResolution, monitorResolution, |
| 617 | pScreenInfo->dwStride, |
| 618 | nRootDepth, nDepths, pDepths, rootVisual, |
| 619 | nVisuals, pVisuals)) { |
| 620 | ErrorF("winFinishScreenInitNativeGDI - miScreenInit failed\n"); |
| 621 | return FALSE; |
| 622 | } |
| 623 | |
| 624 | pScreen->defColormap = FakeClientID(0); |
| 625 | |
| 626 | /* |
| 627 | * Register our block and wakeup handlers; these procedures |
| 628 | * process messages in our Windows message queue; specifically, |
| 629 | * they process mouse and keyboard input. |
| 630 | */ |
| 631 | pScreen->BlockHandler = winBlockHandler; |
| 632 | pScreen->WakeupHandler = winWakeupHandler; |
| 633 | |
| 634 | /* Place our save screen function */ |
| 635 | pScreen->SaveScreen = winSaveScreen; |
| 636 | |
| 637 | /* Pixmaps */ |
| 638 | pScreen->CreatePixmap = winCreatePixmapNativeGDI; |
| 639 | pScreen->DestroyPixmap = winDestroyPixmapNativeGDI; |
| 640 | |
| 641 | /* Other Screen Routines */ |
| 642 | pScreen->QueryBestSize = winQueryBestSizeNativeGDI; |
| 643 | pScreen->SaveScreen = winSaveScreen; |
| 644 | pScreen->GetImage = miGetImage; |
| 645 | pScreen->GetSpans = winGetSpansNativeGDI; |
| 646 | |
| 647 | /* Window Procedures */ |
| 648 | pScreen->CreateWindow = winCreateWindowNativeGDI; |
| 649 | pScreen->DestroyWindow = winDestroyWindowNativeGDI; |
| 650 | pScreen->PositionWindow = winPositionWindowNativeGDI; |
| 651 | /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI; */ |
| 652 | pScreen->RealizeWindow = winMapWindowNativeGDI; |
| 653 | pScreen->UnrealizeWindow = winUnmapWindowNativeGDI; |
| 654 | |
| 655 | /* Paint window */ |
| 656 | pScreen->CopyWindow = winCopyWindowNativeGDI; |
| 657 | |
| 658 | /* Fonts */ |
| 659 | pScreen->RealizeFont = winRealizeFontNativeGDI; |
| 660 | pScreen->UnrealizeFont = winUnrealizeFontNativeGDI; |
| 661 | |
| 662 | /* GC */ |
| 663 | pScreen->CreateGC = winCreateGCNativeGDI; |
| 664 | |
| 665 | /* Colormap Routines */ |
| 666 | pScreen->CreateColormap = miInitializeColormap; |
| 667 | pScreen->DestroyColormap = |
| 668 | (DestroyColormapProcPtr) (void (*)(void)) NoopDDA; |
| 669 | pScreen->InstallColormap = miInstallColormap; |
| 670 | pScreen->UninstallColormap = miUninstallColormap; |
| 671 | pScreen->ListInstalledColormaps = miListInstalledColormaps; |
| 672 | pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA; |
| 673 | pScreen->ResolveColor = miResolveColor; |
| 674 | |
| 675 | /* Bitmap */ |
| 676 | pScreen->BitmapToRegion = winPixmapToRegionNativeGDI; |
| 677 | |
| 678 | ErrorF("winFinishScreenInitNativeGDI - calling miDCInitialize\n"); |
| 679 | |
| 680 | /* Set the default white and black pixel positions */ |
| 681 | pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0; |
| 682 | |
| 683 | /* Initialize the cursor */ |
| 684 | if (!miDCInitialize(pScreen, &g_winPointerCursorFuncs)) { |
| 685 | ErrorF("winFinishScreenInitNativeGDI - miDCInitialize failed\n"); |
| 686 | return FALSE; |
| 687 | } |
| 688 | |
| 689 | /* Create a default colormap */ |
| 690 | if (!miCreateDefColormap(pScreen)) { |
| 691 | ErrorF("winFinishScreenInitNativeGDI - miCreateDefColormap () " |
| 692 | "failed\n"); |
| 693 | return FALSE; |
| 694 | } |
| 695 | |
| 696 | ErrorF("winFinishScreenInitNativeGDI - miCreateDefColormap () " |
| 697 | "returned\n"); |
| 698 | |
| 699 | /* mi doesn't use a CloseScreen procedure, so no need to wrap */ |
| 700 | pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; |
| 701 | |
| 702 | /* Tell the server that we are enabled */ |
| 703 | pScreenPriv->fEnabled = TRUE; |
| 704 | |
| 705 | ErrorF("winFinishScreenInitNativeGDI - Successful addition of " |
| 706 | "screen %p\n", pScreen); |
| 707 | |
| 708 | return TRUE; |
| 709 | } |
| 710 | #endif |
| 711 | |
| 712 | /* See Porting Layer Definition - p. 33 */ |
| 713 | static Bool |
| 714 | winSaveScreen(ScreenPtr pScreen, int on) |
| 715 | { |
| 716 | return TRUE; |
| 717 | } |