winscrinit.c revision ed6184df
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/* 42 * Determine what type of screen we are initializing 43 * and call the appropriate procedure to initialize 44 * that type of screen. 45 */ 46 47Bool 48winScreenInit(ScreenPtr pScreen, int argc, char **argv) 49{ 50 winScreenInfoPtr pScreenInfo = &g_ScreenInfo[pScreen->myNum]; 51 winPrivScreenPtr pScreenPriv; 52 HDC hdc; 53 DWORD dwInitialBPP; 54 55#if CYGDEBUG || YES 56 winDebug("winScreenInit - dwWidth: %u dwHeight: %u\n", 57 (unsigned int)pScreenInfo->dwWidth, (unsigned int)pScreenInfo->dwHeight); 58#endif 59 60 /* Allocate privates for this screen */ 61 if (!winAllocatePrivates(pScreen)) { 62 ErrorF("winScreenInit - Couldn't allocate screen privates\n"); 63 return FALSE; 64 } 65 66 /* Get a pointer to the privates structure that was allocated */ 67 pScreenPriv = winGetScreenPriv(pScreen); 68 69 /* Save a pointer to this screen in the screen info structure */ 70 pScreenInfo->pScreen = pScreen; 71 72 /* Save a pointer to the screen info in the screen privates structure */ 73 /* This allows us to get back to the screen info from a screen pointer */ 74 pScreenPriv->pScreenInfo = pScreenInfo; 75 76 /* 77 * Determine which engine to use. 78 * 79 * NOTE: This is done once per screen because each screen possibly has 80 * a preferred engine specified on the command line. 81 */ 82 if (!winSetEngine(pScreen)) { 83 ErrorF("winScreenInit - winSetEngine () failed\n"); 84 return FALSE; 85 } 86 87 /* Horribly misnamed function: Allow engine to adjust BPP for screen */ 88 dwInitialBPP = pScreenInfo->dwBPP; 89 90 if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) { 91 ErrorF("winScreenInit - winAdjustVideoMode () failed\n"); 92 return FALSE; 93 } 94 95 if (dwInitialBPP == WIN_DEFAULT_BPP) { 96 /* No -depth parameter was passed, let the user know the depth being used */ 97 ErrorF 98 ("winScreenInit - Using Windows display depth of %d bits per pixel\n", 99 (int) pScreenInfo->dwBPP); 100 } 101 else if (dwInitialBPP != pScreenInfo->dwBPP) { 102 /* Warn user if engine forced a depth different to -depth parameter */ 103 ErrorF 104 ("winScreenInit - Command line depth of %d bpp overridden by engine, using %d bpp\n", 105 (int) dwInitialBPP, (int) pScreenInfo->dwBPP); 106 } 107 else { 108 ErrorF("winScreenInit - Using command line depth of %d bpp\n", 109 (int) pScreenInfo->dwBPP); 110 } 111 112 /* Check for supported display depth */ 113 if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) { 114 ErrorF("winScreenInit - Unsupported display depth: %d\n" 115 "Change your Windows display depth to 15, 16, 24, or 32 bits " 116 "per pixel.\n", (int) pScreenInfo->dwBPP); 117 ErrorF("winScreenInit - Supported depths: %08x\n", WIN_SUPPORTED_BPPS); 118#if WIN_CHECK_DEPTH 119 return FALSE; 120#endif 121 } 122 123 /* 124 * Check that all monitors have the same display depth if we are using 125 * multiple monitors 126 */ 127 if (pScreenInfo->fMultipleMonitors 128 && !GetSystemMetrics(SM_SAMEDISPLAYFORMAT)) { 129 ErrorF("winScreenInit - Monitors do not all have same pixel format / " 130 "display depth.\n"); 131 if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) { 132 ErrorF 133 ("winScreenInit - Performance may suffer off primary display.\n"); 134 } 135 else { 136 ErrorF("winScreenInit - Using primary display only.\n"); 137 pScreenInfo->fMultipleMonitors = FALSE; 138 } 139 } 140 141 /* Create display window */ 142 if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) { 143 ErrorF("winScreenInit - pwinCreateBoundingWindow () " "failed\n"); 144 return FALSE; 145 } 146 147 /* Get a device context */ 148 hdc = GetDC(pScreenPriv->hwndScreen); 149 150 /* Are we using multiple monitors? */ 151 if (pScreenInfo->fMultipleMonitors) { 152 /* 153 * In this case, some of the defaults set in 154 * winInitializeScreenDefaults() are not correct ... 155 */ 156 if (!pScreenInfo->fUserGaveHeightAndWidth) { 157 pScreenInfo->dwWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN); 158 pScreenInfo->dwHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN); 159 } 160 } 161 162 /* Release the device context */ 163 ReleaseDC(pScreenPriv->hwndScreen, hdc); 164 165 /* Clear the visuals list */ 166 miClearVisualTypes(); 167 168 /* Call the engine dependent screen initialization procedure */ 169 if (!((*pScreenPriv->pwinFinishScreenInit) (pScreen->myNum, pScreen, argc, argv))) { 170 ErrorF("winScreenInit - winFinishScreenInit () failed\n"); 171 172 /* call the engine dependent screen close procedure to clean up from a failure */ 173 pScreenPriv->pwinCloseScreen(pScreen); 174 175 return FALSE; 176 } 177 178 if (!g_fSoftwareCursor) 179 winInitCursor(pScreen); 180 else 181 winErrorFVerb(2, "winScreenInit - Using software cursor\n"); 182 183 if (!noPanoramiXExtension) { 184 /* 185 Note the screen origin in a normalized coordinate space where (0,0) is at the top left 186 of the native virtual desktop area 187 */ 188 pScreen->x = 189 pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN); 190 pScreen->y = 191 pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN); 192 193 ErrorF("Screen %d added at virtual desktop coordinate (%d,%d).\n", 194 pScreen->myNum, pScreen->x, pScreen->y); 195 } 196 197#if CYGDEBUG || YES 198 winDebug("winScreenInit - returning\n"); 199#endif 200 201 return TRUE; 202} 203 204static Bool 205winCreateScreenResources(ScreenPtr pScreen) 206{ 207 winScreenPriv(pScreen); 208 Bool result; 209 210 result = pScreenPriv->pwinCreateScreenResources(pScreen); 211 212 /* Now the screen bitmap has been wrapped in a pixmap, 213 add that to the Shadow framebuffer */ 214 if (!shadowAdd(pScreen, pScreen->devPrivate, 215 pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) { 216 ErrorF("winCreateScreenResources - shadowAdd () failed\n"); 217 return FALSE; 218 } 219 220 return result; 221} 222 223/* See Porting Layer Definition - p. 20 */ 224Bool 225winFinishScreenInitFB(int i, ScreenPtr pScreen, int argc, char **argv) 226{ 227 winScreenPriv(pScreen); 228 winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; 229 VisualPtr pVisual = NULL; 230 231 int iReturn; 232 233 /* Create framebuffer */ 234 if (!(*pScreenPriv->pwinInitScreen) (pScreen)) { 235 ErrorF("winFinishScreenInitFB - Could not allocate framebuffer\n"); 236 return FALSE; 237 } 238 239 /* 240 * Calculate the number of bits that are used to represent color in each pixel, 241 * the color depth for the screen 242 */ 243 if (pScreenInfo->dwBPP == 8) 244 pScreenInfo->dwDepth = 8; 245 else 246 pScreenInfo->dwDepth = winCountBits(pScreenPriv->dwRedMask) 247 + winCountBits(pScreenPriv->dwGreenMask) 248 + winCountBits(pScreenPriv->dwBlueMask); 249 250 winErrorFVerb(2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n", 251 (unsigned int) pScreenPriv->dwRedMask, 252 (unsigned int) pScreenPriv->dwGreenMask, 253 (unsigned int) pScreenPriv->dwBlueMask); 254 255 /* Init visuals */ 256 if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) { 257 ErrorF("winFinishScreenInitFB - winInitVisuals failed\n"); 258 return FALSE; 259 } 260 261 if ((pScreenInfo->dwBPP == 8) && (pScreenInfo->fCompositeWM)) { 262 ErrorF("-compositewm disabled due to 8bpp depth\n"); 263 pScreenInfo->fCompositeWM = FALSE; 264 } 265 266 /* Apparently we need this for the render extension */ 267 miSetPixmapDepths(); 268 269 /* Start fb initialization */ 270 if (!fbSetupScreen(pScreen, 271 pScreenInfo->pfb, 272 pScreenInfo->dwWidth, pScreenInfo->dwHeight, 273 monitorResolution, monitorResolution, 274 pScreenInfo->dwStride, pScreenInfo->dwBPP)) { 275 ErrorF("winFinishScreenInitFB - fbSetupScreen failed\n"); 276 return FALSE; 277 } 278 279 /* Override default colormap routines if visual class is dynamic */ 280 if (pScreenInfo->dwDepth == 8 281 && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI 282 || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL 283 && pScreenInfo->fFullScreen))) { 284 winSetColormapFunctions(pScreen); 285 286 /* 287 * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its 288 * own colormap, as it cannot allocate 7 planes in the default 289 * colormap. Setting whitePixel to 1 allows Magic to get 7 290 * planes in the default colormap, so it doesn't create its 291 * own colormap. This latter situation is highly desirable, 292 * as it keeps the Magic window viewable when switching to 293 * other X clients that use the default colormap. 294 */ 295 pScreen->blackPixel = 0; 296 pScreen->whitePixel = 1; 297 } 298 299 /* Finish fb initialization */ 300 if (!fbFinishScreenInit(pScreen, 301 pScreenInfo->pfb, 302 pScreenInfo->dwWidth, pScreenInfo->dwHeight, 303 monitorResolution, monitorResolution, 304 pScreenInfo->dwStride, pScreenInfo->dwBPP)) { 305 ErrorF("winFinishScreenInitFB - fbFinishScreenInit failed\n"); 306 return FALSE; 307 } 308 309 /* Save a pointer to the root visual */ 310 for (pVisual = pScreen->visuals; 311 pVisual->vid != pScreen->rootVisual; pVisual++); 312 pScreenPriv->pRootVisual = pVisual; 313 314 /* 315 * Setup points to the block and wakeup handlers. Pass a pointer 316 * to the current screen as pWakeupdata. 317 */ 318 pScreen->BlockHandler = winBlockHandler; 319 pScreen->WakeupHandler = winWakeupHandler; 320 321 /* Render extension initialization, calls miPictureInit */ 322 if (!fbPictureInit(pScreen, NULL, 0)) { 323 ErrorF("winFinishScreenInitFB - fbPictureInit () failed\n"); 324 return FALSE; 325 } 326 327#ifdef RANDR 328 /* Initialize resize and rotate support */ 329 if (!winRandRInit(pScreen)) { 330 ErrorF("winFinishScreenInitFB - winRandRInit () failed\n"); 331 return FALSE; 332 } 333#endif 334 335 /* Setup the cursor routines */ 336#if CYGDEBUG 337 winDebug("winFinishScreenInitFB - Calling miDCInitialize ()\n"); 338#endif 339 miDCInitialize(pScreen, &g_winPointerCursorFuncs); 340 341 /* KDrive does winCreateDefColormap right after miDCInitialize */ 342 /* Create a default colormap */ 343#if CYGDEBUG 344 winDebug("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); 345#endif 346 if (!winCreateDefColormap(pScreen)) { 347 ErrorF("winFinishScreenInitFB - Could not create colormap\n"); 348 return FALSE; 349 } 350 351 /* Initialize the shadow framebuffer layer */ 352 if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI 353 || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)) { 354#if CYGDEBUG 355 winDebug("winFinishScreenInitFB - Calling shadowSetup ()\n"); 356#endif 357 if (!shadowSetup(pScreen)) { 358 ErrorF("winFinishScreenInitFB - shadowSetup () failed\n"); 359 return FALSE; 360 } 361 362 /* Wrap CreateScreenResources so we can add the screen pixmap 363 to the Shadow framebuffer after it's been created */ 364 pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources; 365 pScreen->CreateScreenResources = winCreateScreenResources; 366 } 367 368 /* Handle rootless mode */ 369 if (pScreenInfo->fRootless) { 370 /* Define the WRAP macro temporarily for local use */ 371#define WRAP(a) \ 372 if (pScreen->a) { \ 373 pScreenPriv->a = pScreen->a; \ 374 } else { \ 375 winDebug("winScreenInit - null screen fn " #a "\n"); \ 376 pScreenPriv->a = NULL; \ 377 } 378 379 /* Save a pointer to each lower-level window procedure */ 380 WRAP(CreateWindow); 381 WRAP(DestroyWindow); 382 WRAP(RealizeWindow); 383 WRAP(UnrealizeWindow); 384 WRAP(PositionWindow); 385 WRAP(ChangeWindowAttributes); 386 WRAP(SetShape); 387 388 /* Assign rootless window procedures to be top level procedures */ 389 pScreen->CreateWindow = winCreateWindowRootless; 390 pScreen->DestroyWindow = winDestroyWindowRootless; 391 pScreen->PositionWindow = winPositionWindowRootless; 392 /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless; */ 393 pScreen->RealizeWindow = winMapWindowRootless; 394 pScreen->UnrealizeWindow = winUnmapWindowRootless; 395 pScreen->SetShape = winSetShapeRootless; 396 397 /* Undefine the WRAP macro, as it is not needed elsewhere */ 398#undef WRAP 399 } 400 401 /* Handle multi window mode */ 402 else if (pScreenInfo->fMultiWindow) { 403 /* Define the WRAP macro temporarily for local use */ 404#define WRAP(a) \ 405 if (pScreen->a) { \ 406 pScreenPriv->a = pScreen->a; \ 407 } else { \ 408 winDebug("null screen fn " #a "\n"); \ 409 pScreenPriv->a = NULL; \ 410 } 411 412 /* Save a pointer to each lower-level window procedure */ 413 WRAP(CreateWindow); 414 WRAP(DestroyWindow); 415 WRAP(RealizeWindow); 416 WRAP(UnrealizeWindow); 417 WRAP(PositionWindow); 418 WRAP(ChangeWindowAttributes); 419 WRAP(ReparentWindow); 420 WRAP(RestackWindow); 421 WRAP(ResizeWindow); 422 WRAP(MoveWindow); 423 WRAP(CopyWindow); 424 WRAP(SetShape); 425 WRAP(ModifyPixmapHeader); 426 427 /* Assign multi-window window procedures to be top level procedures */ 428 pScreen->CreateWindow = winCreateWindowMultiWindow; 429 pScreen->DestroyWindow = winDestroyWindowMultiWindow; 430 pScreen->PositionWindow = winPositionWindowMultiWindow; 431 /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow; */ 432 pScreen->RealizeWindow = winMapWindowMultiWindow; 433 pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; 434 pScreen->ReparentWindow = winReparentWindowMultiWindow; 435 pScreen->RestackWindow = winRestackWindowMultiWindow; 436 pScreen->ResizeWindow = winResizeWindowMultiWindow; 437 pScreen->MoveWindow = winMoveWindowMultiWindow; 438 pScreen->CopyWindow = winCopyWindowMultiWindow; 439 pScreen->SetShape = winSetShapeMultiWindow; 440 441 if (pScreenInfo->fCompositeWM) { 442 pScreen->CreatePixmap = winCreatePixmapMultiwindow; 443 pScreen->DestroyPixmap = winDestroyPixmapMultiwindow; 444 pScreen->ModifyPixmapHeader = winModifyPixmapHeaderMultiwindow; 445 } 446 447 /* Undefine the WRAP macro, as it is not needed elsewhere */ 448#undef WRAP 449 } 450 451 /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ 452 pScreenPriv->CloseScreen = pScreen->CloseScreen; 453 pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; 454 455 /* Create a mutex for modules in separate threads to wait for */ 456 iReturn = pthread_mutex_init(&pScreenPriv->pmServerStarted, NULL); 457 if (iReturn != 0) { 458 ErrorF("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", 459 iReturn); 460 return FALSE; 461 } 462 463 /* Own the mutex for modules in separate threads */ 464 iReturn = pthread_mutex_lock(&pScreenPriv->pmServerStarted); 465 if (iReturn != 0) { 466 ErrorF("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", 467 iReturn); 468 return FALSE; 469 } 470 471 /* Set the ServerStarted flag to false */ 472 pScreenPriv->fServerStarted = FALSE; 473 474 475 if (pScreenInfo->fMultiWindow) { 476#if CYGDEBUG || YES 477 winDebug("winFinishScreenInitFB - Calling winInitWM.\n"); 478#endif 479 480 /* Initialize multi window mode */ 481 if (!winInitWM(&pScreenPriv->pWMInfo, 482 &pScreenPriv->ptWMProc, 483 &pScreenPriv->ptXMsgProc, 484 &pScreenPriv->pmServerStarted, 485 pScreenInfo->dwScreen, 486 (HWND) &pScreenPriv->hwndScreen, 487 pScreenInfo->fCompositeWM)) { 488 ErrorF("winFinishScreenInitFB - winInitWM () failed.\n"); 489 return FALSE; 490 } 491 } 492 493 /* Tell the server that we are enabled */ 494 pScreenPriv->fEnabled = TRUE; 495 496 /* Tell the server that we have a valid depth */ 497 pScreenPriv->fBadDepth = FALSE; 498 499#if CYGDEBUG || YES 500 winDebug("winFinishScreenInitFB - returning\n"); 501#endif 502 503 return TRUE; 504} 505