Changeset 128

Show
Ignore:
Timestamp:
08/24/10 14:06:10 (18 months ago)
Author:
Carsten
Message:

Applied  http://trac.wxwidgets.org/changeset/65398 that closes  http://trac.wxwidgets.org/ticket/12387
also to our local copy of wxWidgets (2.9.1), anticipating the next (future) vendor update (to 2.9.2).

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • cafu/branches/cafu_to_wx/ExtLibs/wxWidgets/src/msw/display.cpp

    r107 r128  
    4444#include "wx/msw/private.h" 
    4545 
    46 // define this to use DirectDraw for display mode switching: this is disabled 
    47 // by default because ddraw.h is now always available and also it's not really 
    48 // clear what are the benefits of using DirectDraw compared to the standard API 
    49  
    50 #if !defined(wxUSE_DIRECTDRAW) 
    51     #define wxUSE_DIRECTDRAW 0 
    52 #endif 
    53  
    5446#ifndef __WXWINCE__ 
    5547    // Older versions of windef.h don't define HMONITOR.  Unfortunately, we 
     
    7971#endif // !__WXWINCE__ 
    8072 
    81 #if wxUSE_DIRECTDRAW 
    82     #include <ddraw.h> 
    83  
    84     // we don't want to link with ddraw.lib which contains the real 
    85     // IID_IDirectDraw2 definition 
    86     const GUID wxIID_IDirectDraw2 = 
    87      { 0xB3A6F3E0, 0x2B43, 0x11CF, { 0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 } }; 
    88 #endif // wxUSE_DIRECTDRAW 
    89  
    9073// display functions are found in different DLLs under WinCE and normal Win32 
    9174#ifdef __WXWINCE__ 
     
    10487                                                 DWORD dwFlags, 
    10588                                                 LPVOID lParam); 
    106  
    107 #if wxUSE_DIRECTDRAW 
    108 typedef BOOL (PASCAL *DDEnumExCallback_t)(GUID *pGuid, 
    109                                           LPTSTR driverDescription, 
    110                                           LPTSTR driverName, 
    111                                           LPVOID lpContext, 
    112                                           HMONITOR hmon); 
    113  
    114 typedef HRESULT (WINAPI *DirectDrawEnumerateEx_t)(DDEnumExCallback_t lpCallback, 
    115                                                   LPVOID lpContext, 
    116                                                   DWORD dwFlags); 
    117  
    118 typedef HRESULT (WINAPI *DirectDrawCreate_t)(GUID *lpGUID, 
    119                                              LPDIRECTDRAW *lplpDD, 
    120                                              IUnknown *pUnkOuter); 
    121 #endif // wxUSE_DIRECTDRAW 
    12289 
    12390typedef BOOL (WINAPI *EnumDisplayMonitors_t)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); 
     
    241208 
    242209    // delete all m_displays elements: can be called from the derived class 
    243     // dtor if it is important to do this before destroying it (as in 
    244     // wxDisplayFactoryDirectDraw case), otherwise will be done by our dtor 
     210    // dtor if it is important to do this before destroying it, 
     211    // otherwise will be done by our dtor 
    245212    void Clear(); 
    246213 
     
    294261                                          LPARAM dwData); 
    295262 
    296  
    297263    // add a monitor description to m_displays array 
    298264    void AddDisplay(HMONITOR hMonitor, LPRECT lprcMonitor); 
    299265}; 
    300266 
    301 // ---------------------------------------------------------------------------- 
    302 // wxDisplay implementation using DirectDraw 
    303 // ---------------------------------------------------------------------------- 
    304  
    305 #if wxUSE_DIRECTDRAW 
    306  
    307 struct wxDisplayInfoDirectDraw : wxDisplayInfo 
    308 { 
    309     wxDisplayInfoDirectDraw(const GUID& guid, HMONITOR hmon, LPTSTR name) 
    310         : wxDisplayInfo(hmon), 
    311           m_guid(guid) 
    312     { 
    313         m_pDD2 = NULL; 
    314         m_devName = name; 
    315     } 
    316  
    317     virtual ~wxDisplayInfoDirectDraw() 
    318     { 
    319         if ( m_pDD2 ) 
    320             m_pDD2->Release(); 
    321     } 
    322  
    323  
    324     // IDirectDraw object used to control this display, may be NULL 
    325     IDirectDraw2 *m_pDD2; 
    326  
    327     // DirectDraw GUID for this display, only valid when using DirectDraw 
    328     const GUID m_guid; 
    329  
    330  
    331     wxDECLARE_NO_COPY_CLASS(wxDisplayInfoDirectDraw); 
    332 }; 
    333  
    334 class wxDisplayImplDirectDraw : public wxDisplayImplWin32Base 
    335 { 
    336 public: 
    337     wxDisplayImplDirectDraw(unsigned n, wxDisplayInfo& info, IDirectDraw2 *pDD2) 
    338         : wxDisplayImplWin32Base(n, info), 
    339           m_pDD2(pDD2) 
    340     { 
    341         m_pDD2->AddRef(); 
    342     } 
    343  
    344     virtual ~wxDisplayImplDirectDraw() 
    345     { 
    346         m_pDD2->Release(); 
    347     } 
    348  
    349     virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; 
    350     virtual bool ChangeMode(const wxVideoMode& mode); 
    351  
    352 private: 
    353     IDirectDraw2 *m_pDD2; 
    354  
    355     wxDECLARE_NO_COPY_CLASS(wxDisplayImplDirectDraw); 
    356 }; 
    357  
    358 class wxDisplayFactoryDirectDraw : public wxDisplayFactoryWin32Base 
    359 { 
    360 public: 
    361     wxDisplayFactoryDirectDraw(); 
    362     virtual ~wxDisplayFactoryDirectDraw(); 
    363  
    364     virtual wxDisplayImpl *CreateDisplay(unsigned n); 
    365  
    366 private: 
    367     // callback used with DirectDrawEnumerateEx() 
    368     static BOOL WINAPI DDEnumExCallback(GUID *pGuid, 
    369                                         LPTSTR driverDescription, 
    370                                         LPTSTR driverName, 
    371                                         LPVOID lpContext, 
    372                                         HMONITOR hmon); 
    373  
    374     // add a monitor description to m_displays array 
    375     void AddDisplay(const GUID& guid, HMONITOR hmon, LPTSTR name); 
    376  
    377  
    378     // ddraw.dll 
    379     wxDynamicLibrary m_dllDDraw; 
    380  
    381     // dynamically resolved DirectDrawCreate() 
    382     DirectDrawCreate_t m_pfnDirectDrawCreate; 
    383  
    384     wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryDirectDraw); 
    385 }; 
    386  
    387 #endif // wxUSE_DIRECTDRAW 
    388  
    389267 
    390268// ============================================================================ 
     
    398276/* static */ wxDisplayFactory *wxDisplay::CreateFactory() 
    399277{ 
    400     // we have 2 implementations for modern Windows: one using standard Win32 
    401     // and another using DirectDraw, the choice between them is done using a 
    402     // system option 
    403  
    404 #if wxUSE_DIRECTDRAW 
    405     if ( wxSystemOptions::GetOptionInt(wxT("msw.display.directdraw")) ) 
    406     { 
    407         wxDisplayFactoryDirectDraw *factoryDD = new wxDisplayFactoryDirectDraw; 
    408         if ( factoryDD->IsOk() ) 
    409             return factoryDD; 
    410  
    411         delete factoryDD; 
    412     } 
    413 #endif // wxUSE_DIRECTDRAW 
    414  
    415278    wxDisplayFactoryMultimon *factoryMM = new wxDisplayFactoryMultimon; 
     279 
    416280    if ( factoryMM->IsOk() ) 
    417281        return factoryMM; 
     
    419283    delete factoryMM; 
    420284 
    421  
    422285    // finally fall back to a stub implementation if all else failed (Win95?) 
    423286    return new wxDisplayFactorySingle; 
    424287} 
     288 
    425289 
    426290// ---------------------------------------------------------------------------- 
     
    591455        return; 
    592456 
    593     // look up EnumDisplayMonitors() which we don't need with DirectDraw 
    594     // implementation 
     457    // look up EnumDisplayMonitors() 
    595458    EnumDisplayMonitors_t pfnEnumDisplayMonitors; 
    596459    { 
     
    794657} 
    795658 
    796  
    797 // ============================================================================ 
    798 // DirectDraw-based wxDisplay implementation 
    799 // ============================================================================ 
    800  
    801 #if wxUSE_DIRECTDRAW 
    802  
    803 // ---------------------------------------------------------------------------- 
    804 // wxDisplayFactoryDirectDraw initialization 
    805 // ---------------------------------------------------------------------------- 
    806  
    807 wxDisplayFactoryDirectDraw::wxDisplayFactoryDirectDraw() 
    808 { 
    809     if ( !ms_supportsMultimon ) 
    810         return; 
    811  
    812     m_dllDDraw.Load(wxT("ddraw.dll"), wxDL_VERBATIM | wxDL_QUIET); 
    813  
    814     if ( !m_dllDDraw.IsLoaded() ) 
    815         return; 
    816  
    817     DirectDrawEnumerateEx_t 
    818         wxDL_INIT_FUNC_AW(pfn, DirectDrawEnumerateEx, m_dllDDraw); 
    819     if ( !pfnDirectDrawEnumerateEx ) 
    820         return; 
    821  
    822     // we can't continue without DirectDrawCreate() later, so resolve it right 
    823     // now and fail the initialization if it's not available 
    824     if ( !wxDL_INIT_FUNC(m_pfn, DirectDrawCreate, m_dllDDraw) ) 
    825         return; 
    826  
    827     if ( (*pfnDirectDrawEnumerateEx)(DDEnumExCallback, 
    828                                      this, 
    829                                      DDENUM_ATTACHEDSECONDARYDEVICES) != DD_OK ) 
    830     { 
    831         wxLogLastError(wxT("DirectDrawEnumerateEx")); 
    832     } 
    833 } 
    834  
    835 wxDisplayFactoryDirectDraw::~wxDisplayFactoryDirectDraw() 
    836 { 
    837     // we must clear m_displays now, before m_dllDDraw is unloaded as otherwise 
    838     // calling m_pDD2->Release() later would crash 
    839     Clear(); 
    840 } 
    841  
    842 // ---------------------------------------------------------------------------- 
    843 // callbacks for monitor/modes enumeration stuff 
    844 // ---------------------------------------------------------------------------- 
    845  
    846 BOOL WINAPI 
    847 wxDisplayFactoryDirectDraw::DDEnumExCallback(GUID *pGuid, 
    848                                              LPTSTR WXUNUSED(driverDescription), 
    849                                              LPTSTR driverName, 
    850                                              LPVOID lpContext, 
    851                                              HMONITOR hmon) 
    852 { 
    853     if ( pGuid ) 
    854     { 
    855         wxDisplayFactoryDirectDraw * self = 
    856             static_cast<wxDisplayFactoryDirectDraw *>(lpContext); 
    857         self->AddDisplay(*pGuid, hmon, driverName); 
    858     } 
    859     //else: we're called for the primary monitor, skip it 
    860  
    861     // continue the enumeration 
    862     return TRUE; 
    863 } 
    864  
    865 // ---------------------------------------------------------------------------- 
    866 // wxDisplayFactoryDirectDraw helpers 
    867 // ---------------------------------------------------------------------------- 
    868  
    869 void wxDisplayFactoryDirectDraw::AddDisplay(const GUID& guid, 
    870                                             HMONITOR hmon, 
    871                                             LPTSTR name) 
    872 { 
    873     m_displays.Add(new wxDisplayInfoDirectDraw(guid, hmon, name)); 
    874 } 
    875  
    876 // ---------------------------------------------------------------------------- 
    877 // wxDisplayFactoryDirectDraw inherited pure virtuals implementation 
    878 // ---------------------------------------------------------------------------- 
    879  
    880 wxDisplayImpl *wxDisplayFactoryDirectDraw::CreateDisplay(unsigned n) 
    881 { 
    882     wxCHECK_MSG( n < m_displays.size(), NULL, wxT("invalid display index") ); 
    883  
    884     wxDisplayInfoDirectDraw * 
    885         info = static_cast<wxDisplayInfoDirectDraw *>(m_displays[n]); 
    886  
    887     if ( !info->m_pDD2 ) 
    888     { 
    889         IDirectDraw *pDD; 
    890         GUID guid(info->m_guid); 
    891         HRESULT hr = (*m_pfnDirectDrawCreate)(&guid, &pDD, NULL); 
    892  
    893         if ( FAILED(hr) || !pDD ) 
    894         { 
    895             // what to do?? 
    896             wxLogApiError(wxT("DirectDrawCreate"), hr); 
    897             return NULL; 
    898         } 
    899  
    900         // we got IDirectDraw, but we need IDirectDraw2 
    901         hr = pDD->QueryInterface(wxIID_IDirectDraw2, (void **)&info->m_pDD2); 
    902         pDD->Release(); 
    903  
    904         if ( FAILED(hr) || !info->m_pDD2 ) 
    905         { 
    906             wxLogApiError(wxT("IDirectDraw::QueryInterface(IDD2)"), hr); 
    907             return NULL; 
    908         } 
    909  
    910         // NB: m_pDD2 will now be only destroyed when m_displays is destroyed 
    911         //     which is ok as we don't want to recreate DD objects all the time 
    912     } 
    913     //else: DirectDraw object corresponding to our display already exists 
    914  
    915     return new wxDisplayImplDirectDraw(n, *info, info->m_pDD2); 
    916 } 
    917  
    918 // ============================================================================ 
    919 // wxDisplayImplDirectDraw 
    920 // ============================================================================ 
    921  
    922 // ---------------------------------------------------------------------------- 
    923 // video modes enumeration 
    924 // ---------------------------------------------------------------------------- 
    925  
    926 // tiny helper class used to pass information from GetModes() to 
    927 // wxDDEnumModesCallback 
    928 class wxDDVideoModesAdder 
    929 { 
    930 public: 
    931     // our Add() method will add modes matching modeMatch to modes array 
    932     wxDDVideoModesAdder(wxArrayVideoModes& modes, const wxVideoMode& modeMatch) 
    933         : m_modes(modes), 
    934           m_modeMatch(modeMatch) 
    935     { 
    936     } 
    937  
    938     void Add(const wxVideoMode& mode) 
    939     { 
    940         if ( mode.Matches(m_modeMatch) ) 
    941             m_modes.Add(mode); 
    942     } 
    943  
    944 private: 
    945     wxArrayVideoModes& m_modes; 
    946     const wxVideoMode& m_modeMatch; 
    947  
    948     wxDECLARE_NO_COPY_CLASS(wxDDVideoModesAdder); 
    949 }; 
    950  
    951 HRESULT WINAPI wxDDEnumModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc, 
    952                                      LPVOID lpContext) 
    953 { 
    954     // we need at least the mode size 
    955     static const DWORD FLAGS_REQUIRED = DDSD_HEIGHT | DDSD_WIDTH; 
    956     if ( (lpDDSurfaceDesc->dwFlags & FLAGS_REQUIRED) == FLAGS_REQUIRED ) 
    957     { 
    958         wxDDVideoModesAdder * const vmodes = 
    959             static_cast<wxDDVideoModesAdder *>(lpContext); 
    960  
    961         vmodes->Add(wxVideoMode(lpDDSurfaceDesc->dwWidth, 
    962                                 lpDDSurfaceDesc->dwHeight, 
    963                                 lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, 
    964                                 lpDDSurfaceDesc->dwRefreshRate)); 
    965     } 
    966  
    967     // continue the enumeration 
    968     return DDENUMRET_OK; 
    969 } 
    970  
    971 wxArrayVideoModes 
    972 wxDisplayImplDirectDraw::GetModes(const wxVideoMode& modeMatch) const 
    973 { 
    974     wxArrayVideoModes modes; 
    975     wxDDVideoModesAdder modesAdder(modes, modeMatch); 
    976  
    977     HRESULT hr = m_pDD2->EnumDisplayModes 
    978                          ( 
    979                             DDEDM_REFRESHRATES, 
    980                             NULL,                   // all modes 
    981                             &modesAdder,            // callback parameter 
    982                             wxDDEnumModesCallback 
    983                          ); 
    984  
    985     if ( FAILED(hr) ) 
    986     { 
    987         wxLogApiError(wxT("IDirectDraw::EnumDisplayModes"), hr); 
    988     } 
    989  
    990     return modes; 
    991 } 
    992  
    993 // ---------------------------------------------------------------------------- 
    994 // video mode switching 
    995 // ---------------------------------------------------------------------------- 
    996  
    997 bool wxDisplayImplDirectDraw::ChangeMode(const wxVideoMode& mode) 
    998 { 
    999     wxWindow *winTop = wxTheApp->GetTopWindow(); 
    1000     wxCHECK_MSG( winTop, false, wxT("top level window required for DirectX") ); 
    1001  
    1002     HRESULT hr = m_pDD2->SetCooperativeLevel 
    1003                          ( 
    1004                             GetHwndOf(winTop), 
    1005                             DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN 
    1006                          ); 
    1007     if ( FAILED(hr) ) 
    1008     { 
    1009         wxLogApiError(wxT("IDirectDraw2::SetCooperativeLevel"), hr); 
    1010  
    1011         return false; 
    1012     } 
    1013  
    1014     hr = m_pDD2->SetDisplayMode(mode.w, mode.h, mode.bpp, mode.refresh, 0); 
    1015     if ( FAILED(hr) ) 
    1016     { 
    1017         wxLogApiError(wxT("IDirectDraw2::SetDisplayMode"), hr); 
    1018  
    1019         return false; 
    1020     } 
    1021  
    1022     return true; 
    1023 } 
    1024  
    1025 #endif // wxUSE_DIRECTDRAW 
    1026  
    1027659#endif // wxUSE_DISPLAY