1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mac/carbon/display.cpp 3// Purpose: Mac implementation of wxDisplay class 4// Author: Ryan Norton & Brian Victor 5// Modified by: Royce Mitchell III, Vadim Zeitlin 6// Created: 06/21/02 7// RCS-ID: $Id: display.cpp 62911 2009-12-17 13:39:54Z SC $ 8// Copyright: (c) wxWidgets team 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// ============================================================================ 13// declarations 14// ============================================================================ 15 16// ---------------------------------------------------------------------------- 17// headers 18// ---------------------------------------------------------------------------- 19 20#include "wx/wxprec.h" 21 22#ifdef __BORLANDC__ 23 #pragma hdrstop 24#endif 25 26#if wxUSE_DISPLAY 27 28#include "wx/display.h" 29 30#ifndef WX_PRECOMP 31 #include "wx/dynarray.h" 32 #include "wx/log.h" 33 #include "wx/string.h" 34 #include "wx/gdicmn.h" 35#endif 36 37#ifdef __DARWIN__ 38 #include <Carbon/Carbon.h> 39#else 40 #include <Gestalt.h> 41 #include <Displays.h> 42 #include <Quickdraw.h> 43 #include <Video.h> // for VDSwitchInfoRec 44 #include <FixMath.h> 45 #include <Debugging.h> 46#endif 47 48#include "wx/display_impl.h" 49 50// ---------------------------------------------------------------------------- 51// display classes implementation 52// ---------------------------------------------------------------------------- 53 54#ifdef __WXMAC_OSX__ 55 56class wxDisplayImplMacOSX : public wxDisplayImpl 57{ 58public: 59 wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id) 60 : wxDisplayImpl(n), 61 m_id(id) 62 { 63 } 64 65 virtual wxRect GetGeometry() const; 66 virtual wxRect GetClientArea() const; 67 virtual wxString GetName() const { return wxString(); } 68 69 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; 70 virtual wxVideoMode GetCurrentMode() const; 71 virtual bool ChangeMode(const wxVideoMode& mode); 72 73 virtual bool IsPrimary() const; 74 75private: 76 CGDirectDisplayID m_id; 77 78 DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX) 79}; 80 81class wxDisplayFactoryMacOSX : public wxDisplayFactory 82{ 83public: 84 wxDisplayFactoryMacOSX() {} 85 86 virtual wxDisplayImpl *CreateDisplay(unsigned n); 87 virtual unsigned GetCount(); 88 virtual int GetFromPoint(const wxPoint& pt); 89 90protected: 91 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX) 92}; 93 94// ============================================================================ 95// wxDisplayFactoryMacOSX implementation 96// ============================================================================ 97 98// gets all displays that are not mirror displays 99 100static CGDisplayErr wxOSXGetDisplayList(CGDisplayCount maxDisplays, 101 CGDirectDisplayID *displays, 102 CGDisplayCount *displayCount) 103{ 104 CGDisplayErr error = kCGErrorSuccess; 105 CGDisplayCount onlineCount; 106 107 error = CGGetOnlineDisplayList(0,NULL,&onlineCount); 108 if ( error == kCGErrorSuccess ) 109 { 110 *displayCount = 0; 111 if ( onlineCount > 0 ) 112 { 113 CGDirectDisplayID *onlineDisplays = new CGDirectDisplayID[onlineCount]; 114 error = CGGetOnlineDisplayList(onlineCount,onlineDisplays,&onlineCount); 115 if ( error == kCGErrorSuccess ) 116 { 117 for ( CGDisplayCount i = 0; i < onlineCount; ++i ) 118 { 119 if ( CGDisplayMirrorsDisplay(onlineDisplays[i]) != kCGNullDirectDisplay ) 120 continue; 121 122 if ( displays == NULL ) 123 *displayCount += 1; 124 else 125 { 126 if ( *displayCount < maxDisplays ) 127 { 128 displays[*displayCount] = onlineDisplays[i]; 129 *displayCount += 1; 130 } 131 } 132 } 133 } 134 delete[] onlineDisplays; 135 } 136 137 } 138 return error; 139} 140 141unsigned wxDisplayFactoryMacOSX::GetCount() 142{ 143 CGDisplayCount count; 144 CGDisplayErr err = wxOSXGetDisplayList(0, NULL, &count); 145 146 wxCHECK_MSG( err == CGDisplayNoErr, 0, wxT("wxOSXGetDisplayList() failed") ); 147 148 return count; 149} 150 151int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) 152{ 153 CGPoint thePoint = {(float)p.x, (float)p.y}; 154 CGDirectDisplayID theID; 155 CGDisplayCount theCount; 156 CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); 157 wxASSERT(err == CGDisplayNoErr); 158 159 int nWhich = wxNOT_FOUND; 160 161 if (theCount) 162 { 163 theCount = GetCount(); 164 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; 165 err = wxOSXGetDisplayList(theCount, theIDs, &theCount); 166 wxASSERT(err == CGDisplayNoErr); 167 168 for (nWhich = 0; nWhich < (int) theCount; ++nWhich) 169 { 170 if (theIDs[nWhich] == theID) 171 break; 172 } 173 174 delete [] theIDs; 175 176 if (nWhich == (int) theCount) 177 { 178 wxFAIL_MSG(wxT("Failed to find display in display list")); 179 nWhich = wxNOT_FOUND; 180 } 181 } 182 183 return nWhich; 184} 185 186wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n) 187{ 188 CGDisplayCount theCount = GetCount(); 189 CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; 190 191 CGDisplayErr err = wxOSXGetDisplayList(theCount, theIDs, &theCount); 192 wxCHECK_MSG( err == CGDisplayNoErr, NULL, wxT("wxOSXGetDisplayList() failed") ); 193 194 wxASSERT( n < theCount ); 195 196 wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]); 197 198 delete [] theIDs; 199 200 return display; 201} 202 203// ============================================================================ 204// wxDisplayImplMacOSX implementation 205// ============================================================================ 206 207bool wxDisplayImplMacOSX::IsPrimary() const 208{ 209 return CGDisplayIsMain(m_id); 210} 211 212wxRect wxDisplayImplMacOSX::GetGeometry() const 213{ 214 CGRect theRect = CGDisplayBounds(m_id); 215 return wxRect( (int)theRect.origin.x, 216 (int)theRect.origin.y, 217 (int)theRect.size.width, 218 (int)theRect.size.height ); //floats 219} 220 221wxRect wxDisplayImplMacOSX::GetClientArea() const 222{ 223 // VZ: I don't know how to get client area for arbitrary display but 224 // wxGetClientDisplayRect() does work correctly for at least the main 225 // one (TODO: do it correctly for the other displays too) 226 if ( IsPrimary() ) 227 return wxGetClientDisplayRect(); 228 229 return wxDisplayImpl::GetClientArea(); 230} 231 232static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) 233{ 234 CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key ); 235 if (value == NULL) 236 return 0; 237 238 int num = 0; 239 CFNumberGetValue( value, kCFNumberIntType, &num ); 240 241 return num; 242} 243 244wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const 245{ 246 wxArrayVideoModes resultModes; 247 248 CFArrayRef theArray = CGDisplayAvailableModes( m_id ); 249 250 for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i) 251 { 252 CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex( theArray, i ); 253 254 wxVideoMode theMode( 255 wxCFDictKeyToInt( theValue, kCGDisplayWidth ), 256 wxCFDictKeyToInt( theValue, kCGDisplayHeight ), 257 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ), 258 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate )); 259 260 if (theMode.Matches( mode )) 261 resultModes.Add( theMode ); 262 } 263 264 return resultModes; 265} 266 267wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const 268{ 269 CFDictionaryRef theValue = CGDisplayCurrentMode( m_id ); 270 271 return wxVideoMode( 272 wxCFDictKeyToInt( theValue, kCGDisplayWidth ), 273 wxCFDictKeyToInt( theValue, kCGDisplayHeight ), 274 wxCFDictKeyToInt( theValue, kCGDisplayBitsPerPixel ), 275 wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate )); 276} 277 278bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode ) 279{ 280 // Changing to default mode (wxDefaultVideoMode) doesn't 281 // work because we don't have access to the system's 'scrn' 282 // resource which holds the user's mode which the system 283 // will return to after this app is done 284 boolean_t bExactMatch; 285 CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate( 286 m_id, 287 (size_t)mode.bpp, 288 (size_t)mode.w, 289 (size_t)mode.h, 290 (double)mode.refresh, 291 &bExactMatch ); 292 293 bool bOK = bExactMatch; 294 295 if (bOK) 296 bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr; 297 298 return bOK; 299} 300 301// ============================================================================ 302// wxDisplay::CreateFactory() 303// ============================================================================ 304 305/* static */ wxDisplayFactory *wxDisplay::CreateFactory() 306{ 307 return new wxDisplayFactoryMacOSX; 308} 309 310#else // !__WXMAC_OSX__ 311 312class wxDisplayImplMac : public wxDisplayImpl 313{ 314public: 315 wxDisplayImplMac(unsigned n, GDHandle hndl) 316 : wxDisplayImpl(n), 317 m_hndl(hndl) 318 { 319 } 320 321 virtual wxRect GetGeometry() const; 322 virtual wxString GetName() const { return wxString(); } 323 324 virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; 325 virtual wxVideoMode GetCurrentMode() const; 326 virtual bool ChangeMode(const wxVideoMode& mode); 327 328private: 329 GDHandle m_hndl; 330 331 DECLARE_NO_COPY_CLASS(wxDisplayImplMac) 332}; 333 334class wxDisplayFactoryMac : public wxDisplayFactory 335{ 336public: 337 wxDisplayFactoryMac(); 338 339 virtual wxDisplayImpl *CreateDisplay(unsigned n); 340 virtual unsigned GetCount(); 341 virtual int GetFromPoint(const wxPoint& pt); 342 343protected: 344 DECLARE_NO_COPY_CLASS(wxDisplayFactoryMac) 345}; 346 347// ============================================================================ 348// wxDisplayFactoryMac implementation 349// ============================================================================ 350 351unsigned wxDisplayFactoryMac::GetCount() 352{ 353 unsigned num = 0; 354 GDHandle hndl = DMGetFirstScreenDevice(true); 355 while(hndl) 356 { 357 num++; 358 hndl = DMGetNextScreenDevice(hndl, true); 359 } 360 return num; 361} 362 363int wxDisplayFactoryMac::GetFromPoint(const wxPoint &p) 364{ 365 unsigned num = 0; 366 GDHandle hndl = DMGetFirstScreenDevice(true); 367 while(hndl) 368 { 369 Rect screenrect = (*hndl)->gdRect; 370 if (p.x >= screenrect.left && 371 p.x <= screenrect.right && 372 p.y >= screenrect.top && 373 p.y <= screenrect.bottom) 374 { 375 return num; 376 } 377 num++; 378 hndl = DMGetNextScreenDevice(hndl, true); 379 } 380 381 return wxNOT_FOUND; 382} 383 384wxDisplayImpl *wxDisplayFactoryMac::CreateDisplay(unsigned n) 385{ 386 unsigned nOrig = n; 387 388 GDHandle hndl = DMGetFirstScreenDevice(true); 389 while(hndl) 390 { 391 if (n == 0) 392 { 393 return new wxDisplayImplMac(nOrig, hndl); 394 } 395 n--; 396 hndl = DMGetNextScreenDevice(hndl, true); 397 } 398 399 return NULL; 400} 401 402// ============================================================================ 403// wxDisplayImplMac implementation 404// ============================================================================ 405 406wxRect wxDisplayImplMac::GetGeometry() const 407{ 408 Rect screenrect = (*m_hndl)->gdRect; 409 return wxRect(screenrect.left, screenrect.top, 410 screenrect.right - screenrect.left, 411 screenrect.bottom - screenrect.top); 412} 413 414struct DMModeIteratorRec 415{ 416 wxArrayVideoModes* pModes; 417 const wxVideoMode* pMatchMode; 418}; 419 420pascal void DMModeListIteratorProc( 421 void* pData, 422 DMListIndexType nIndex, 423 DMDisplayModeListEntryPtr pInfo) 424{ 425 DMModeIteratorRec* pInfoData = (DMModeIteratorRec*) pData; 426 427 // Note that in testing the refresh rate is always 0 on my ibook - RN 428 int refresh = (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate); 429 430#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock 431 432 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) 433 { 434 if (wxVideoMode( (int) pInfo->displayModeResolutionInfo->csHorizontalPixels, 435 (int) pInfo->displayModeResolutionInfo->csVerticalLines, 436 (int) pDBI->vpPixelSize, 437 refresh).Matches(*pInfoData->pMatchMode) ) 438 { 439 pInfoData->pModes->Add( 440 wxVideoMode( 441 (int) pInfo->displayModeResolutionInfo->csHorizontalPixels, 442 (int) pInfo->displayModeResolutionInfo->csVerticalLines, 443 (int) pDBI->vpPixelSize, 444 refresh ) ); 445 } 446 } 447 448#undef pDBI 449} 450 451struct DMModeInfoRec 452{ 453 const wxVideoMode* pMode; 454 VDSwitchInfoRec sMode; 455 bool bMatched; 456}; 457 458pascal void DMModeInfoProc( 459 void* pData, 460 DMListIndexType nIndex, 461 DMDisplayModeListEntryPtr pInfo ) 462{ 463 DMModeInfoRec* pInfoData = (DMModeInfoRec*) pData; 464 Fixed refresh = Long2Fix(pInfoData->pMode->refresh); 465 466#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock 467 468 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) 469 { 470 if (pInfoData->pMode->w == (int&) pInfo->displayModeResolutionInfo->csHorizontalPixels && 471 pInfoData->pMode->h == (int&) pInfo->displayModeResolutionInfo->csVerticalLines && 472 pInfoData->pMode->bpp == (int) pDBI->vpPixelSize && 473 refresh == pInfo->displayModeResolutionInfo->csRefreshRate) 474 { 475 memcpy( 476 &pInfoData->sMode, 477 pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo, 478 sizeof(VDSwitchInfoRec)); 479 pInfoData->sMode.csMode = pDBI->vpPixelSize; 480 pInfoData->bMatched = true; 481 break; 482 } 483 } 484 485#undef pDBI 486} 487 488struct DMModeTransRec 489{ 490 wxVideoMode Mode; 491 const VDSwitchInfoRec* psMode; 492 bool bMatched; 493}; 494 495pascal void DMModeTransProc( 496 void* pData, 497 DMListIndexType nIndex, 498 DMDisplayModeListEntryPtr pInfo) 499{ 500 DMModeTransRec* pInfoData = (DMModeTransRec*) pData; 501 502#define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock 503 504 for (unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) 505 { 506 if (pInfoData->psMode->csData == pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo->csData) 507 { 508 pInfoData->Mode = wxVideoMode( 509 (int) pInfo->displayModeResolutionInfo->csHorizontalPixels, 510 (int) pInfo->displayModeResolutionInfo->csVerticalLines, 511 (int) pDBI->vpPixelSize, 512 (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate) ); 513 pInfoData->bMatched = true; 514 break; 515 } 516 } 517 518#undef pDBI 519} 520 521wxArrayVideoModes wxDisplayImplMac::GetModes(const wxVideoMode& mode) const 522{ 523 wxArrayVideoModes Modes; 524 unsigned long dwDMVer; 525 526 // Check DM version == 2 527 // (for backward compatibility only - 7.5.3+ use 2.0) 528 Gestalt( gestaltDisplayMgrVers, (long*) &dwDMVer ); 529 if (dwDMVer >= 0x020000) 530 { 531 DMListIndexType nNumModes; 532 DMListType pModes; 533 DMDisplayModeListIteratorUPP uppMLI; 534 DisplayIDType nDisplayID; 535 OSErr err; 536 537 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); 538 verify_noerr( err ); 539 540 // Create a new list... 541 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes); 542 wxASSERT_MSG( err == noErr, wxT("Could not create a new display mode list") ); 543 544 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeListIteratorProc); 545 wxASSERT( uppMLI ); 546 547 DMModeIteratorRec sModeInfo; 548 sModeInfo.pModes = &Modes; 549 sModeInfo.pMatchMode = &mode; 550 551 for (DMListIndexType i = 0; i < nNumModes; ++i) 552 { 553 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo); 554 verify_noerr( err ); 555 } 556 557 DisposeDMDisplayModeListIteratorUPP(uppMLI); 558 err = DMDisposeList(pModes); 559 verify_noerr( err ); 560 } 561 else // DM 1.0, 1.2, 1.x 562 { 563 wxLogSysError( 564 wxString::Format( 565 wxT("Display Manager Version %u Not Supported! Present? %s"), 566 (unsigned int) dwDMVer / 0x10000, 567 (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) ); 568 } 569 570 return Modes; 571} 572 573wxVideoMode wxDisplayImplMac::GetCurrentMode() const 574{ 575 unsigned long dwDMVer; 576 wxVideoMode RetMode; 577 578 // Check DM version == 2 579 // (for backward compatibility only - 7.5.3+ use 2.0) 580 Gestalt( gestaltDisplayMgrVers, (long*) &dwDMVer ); 581 if (dwDMVer >= 0x020000) 582 { 583 VDSwitchInfoRec sMode; // Note: csMode member also contains the bit depth 584 OSErr err; 585 586 err = DMGetDisplayMode( m_hndl, &sMode ); 587 if (err == noErr) 588 { 589 DMListIndexType nNumModes; 590 DMListType pModes; 591 DMDisplayModeListIteratorUPP uppMLI; 592 DisplayIDType nDisplayID; 593 594 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); 595 verify_noerr( err ); 596 597 // Create a new list... 598 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes); 599 wxASSERT_MSG( err == noErr, wxT("Could not create a new display mode list") ); 600 601 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeTransProc); 602 wxASSERT( uppMLI ); 603 604 DMModeTransRec sModeInfo; 605 sModeInfo.bMatched = false; 606 sModeInfo.psMode = &sMode; 607 for (DMListIndexType i = 0; i < nNumModes; ++i) 608 { 609 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo); 610 verify_noerr( err ); 611 612 if ( sModeInfo.bMatched ) 613 { 614 RetMode = sModeInfo.Mode; 615 break; 616 } 617 } 618 619 DisposeDMDisplayModeListIteratorUPP(uppMLI); 620 err = DMDisposeList(pModes); 621 verify_noerr( err ); 622 } 623 else // Can't get current mode? 624 { 625 wxLogSysError( 626 wxString::Format( 627 wxT("Couldn't obtain current display mode!!!\ndwDMVer:%u"), 628 (unsigned int) dwDMVer)); 629 } 630 } 631 else // DM ver 1 632 { 633 wxLogSysError( 634 wxString::Format( 635 wxT("Display Manager Version %u Not Supported! Present? %s"), 636 (unsigned int) dwDMVer / 0x10000, 637 (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) ); 638 } 639 640 return RetMode; 641} 642 643bool wxDisplayImplMac::ChangeMode(const wxVideoMode& mode) 644{ 645 unsigned long dwDMVer; 646 647 Gestalt( gestaltDisplayMgrVers, (long*)&dwDMVer ); 648 if (GetCount() == 1 || dwDMVer >= 0x020000) 649 { 650 if (mode == wxDefaultVideoMode) 651 { 652 return true; 653 654#if 0 655//#ifndef __DARWIN__ 656// Handle hDisplayState; 657// if (DMBeginConfigureDisplays(&hDisplayState) != noErr) 658// { 659// wxLogSysError(wxT("Could not lock display for display mode changing!")); 660// return false; 661// } 662// 663// wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr); 664// DMEndConfigureDisplays(hDisplayState); 665// return true; 666//#else 667 // hmmmmm.... 668// return true; 669//#endif 670#endif 671 } 672 673 //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode) 674 //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode 675 //so we have to use this icky structure 676 VDSwitchInfoRec sMode; 677 memset( &sMode, 0, sizeof(VDSwitchInfoRec) ); 678 679 DMListIndexType nNumModes; 680 DMListType pModes; 681 DMDisplayModeListIteratorUPP uppMLI; 682 DisplayIDType nDisplayID; 683 OSErr err; 684 685 err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); 686 verify_noerr( err ); 687 688 // Create a new list... 689 err = DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes); 690 wxASSERT_MSG(err == noErr, wxT("Could not create a new display mode list") ); 691 692 uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc); 693 wxASSERT(uppMLI); 694 695 DMModeInfoRec sModeInfo; 696 sModeInfo.bMatched = false; 697 sModeInfo.pMode = &mode; 698 unsigned int i; 699 700 for (i = 0; i < nNumModes; ++i) 701 { 702 err = DMGetIndexedDisplayModeFromList(pModes, i, NULL, uppMLI, &sModeInfo); 703 verify_noerr( err ); 704 705 if (sModeInfo.bMatched) 706 { 707 sMode = sModeInfo.sMode; 708 break; 709 } 710 } 711 712 if (i == nNumModes) 713 return false; 714 715 DisposeDMDisplayModeListIteratorUPP(uppMLI); 716 717 err = DMDisposeList(pModes); 718 verify_noerr( err ); 719 720 // For the really paranoid - 721 // unsigned long flags; 722 // Boolean bok; 723 // wxASSERT(noErr == DMCheckDisplayMode(m_hndl, sMode.csData, 724 // sMode.csMode, &flags, NULL, &bok)); 725 // wxASSERT(bok); 726 727 Handle hDisplayState; 728 if (DMBeginConfigureDisplays(&hDisplayState) != noErr) 729 { 730 wxLogSysError(wxT("Could not lock display for display mode changing!")); 731 732 return false; 733 } 734 735 unsigned long dwBPP = (unsigned long) mode.bpp; 736 err = DMSetDisplayMode( 737 m_hndl, sMode.csData, 738 (unsigned long*) &(dwBPP), 739 NULL, //(unsigned long) &sMode 740 hDisplayState ); 741 742 if (err != noErr) 743 { 744 DMEndConfigureDisplays(hDisplayState); 745 wxLogError(wxT("Could not set the display mode")); 746 747 return false; 748 } 749 750 DMEndConfigureDisplays(hDisplayState); 751 } 752 else // DM 1.0, 1.2, 1.x 753 { 754 wxLogSysError( 755 wxString::Format( 756 wxT("Monitor gravitation not supported yet. dwDMVer:%u"), 757 (unsigned int) dwDMVer)); 758 759 return false; 760 } 761 762 return true; 763} 764 765// ============================================================================ 766// wxDisplay::CreateFactory() 767// ============================================================================ 768 769/* static */ wxDisplayFactory *wxDisplay::CreateFactory() 770{ 771 return new wxDisplayFactoryMac; 772} 773 774#endif // !OSX 775 776#endif // wxUSE_DISPLAY 777