Mercurial > vba-linux
diff src/win32/VideoMode.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/win32/VideoMode.cpp Sat Mar 03 10:31:27 2012 -0600 1.3 @@ -0,0 +1,347 @@ 1.4 +// VideoMode.cpp : implementation file 1.5 +// 1.6 + 1.7 +#include "stdafx.h" 1.8 +#include "resource.h" 1.9 + 1.10 +/// #define _AFXDLL /// EVIL 1.11 +/// #include "afxwin.h" /// EVIL 1.12 +/// #include "afxdll_.h" /// EVIL 1.13 + 1.14 +#define DIRECTDRAW_VERSION 0x0700 1.15 +#include "ddraw.h" 1.16 + 1.17 +#include "VideoMode.h" 1.18 + 1.19 +#include "../common/System.h" // for system messages 1.20 + 1.21 +#define MAX_DRIVERS 32 // 32 drivers maximum 1.22 + 1.23 +//----------------------------------------------------------------------------- 1.24 +// Local structures 1.25 +//----------------------------------------------------------------------------- 1.26 +// Keeps data on the available DDraw drivers 1.27 +struct 1.28 +{ 1.29 + char szDescription[128]; 1.30 + char szName[128]; 1.31 + GUID * pGUID; 1.32 + GUID GUIDcopy; 1.33 + HMONITOR hm; 1.34 +} Drivers[MAX_DRIVERS]; 1.35 + 1.36 +//----------------------------------------------------------------------------- 1.37 +// Local data 1.38 +//----------------------------------------------------------------------------- 1.39 +static int gDriverCnt = 0; // Total number of drivers 1.40 +static GUID *gpSelectedDriverGUID; 1.41 + 1.42 +//----------------------------------------------------------------------------- 1.43 +// Name: DDEnumCallbackEx() 1.44 +// Desc: This call back is used to determine the existing available DDraw 1.45 +// devices, so the user can pick which one to run on. 1.46 +//----------------------------------------------------------------------------- 1.47 +BOOL WINAPI 1.48 +DDEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm) 1.49 +{ 1.50 + if (pGUID) 1.51 + { 1.52 + Drivers[gDriverCnt].GUIDcopy = *pGUID; 1.53 + Drivers[gDriverCnt].pGUID = &Drivers[gDriverCnt].GUIDcopy; 1.54 + } 1.55 + else 1.56 + Drivers[gDriverCnt].pGUID = NULL; 1.57 + Drivers[gDriverCnt].szDescription[127] = '\0'; 1.58 + Drivers[gDriverCnt].szName[127] = '\0'; 1.59 + strncpy(Drivers[gDriverCnt].szDescription, pDescription, 127); 1.60 + strncpy(Drivers[gDriverCnt].szName, pName, 127); 1.61 + Drivers[gDriverCnt].hm = hm; 1.62 + if (gDriverCnt < MAX_DRIVERS) 1.63 + gDriverCnt++; 1.64 + else 1.65 + return DDENUMRET_CANCEL; 1.66 + return DDENUMRET_OK; 1.67 +} 1.68 + 1.69 +//----------------------------------------------------------------------------- 1.70 +// Name: DDEnumCallback() 1.71 +// Desc: This callback is used only with old versions of DDraw. 1.72 +//----------------------------------------------------------------------------- 1.73 +BOOL WINAPI 1.74 +DDEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context) 1.75 +{ 1.76 + return (DDEnumCallbackEx(pGUID, pDescription, pName, context, NULL)); 1.77 +} 1.78 + 1.79 +static HRESULT WINAPI addVideoMode(LPDDSURFACEDESC2 surf, LPVOID lpContext) 1.80 +{ 1.81 + HWND h = (HWND)lpContext; 1.82 + char buffer[50]; 1.83 + 1.84 + switch (surf->ddpfPixelFormat.dwRGBBitCount) 1.85 + { 1.86 + case 16: 1.87 + case 24: 1.88 + case 32: 1.89 + if (surf->dwWidth >= 640 && surf->dwHeight >= 480) 1.90 + { 1.91 + sprintf(buffer, "%4dx%4dx%2d", surf->dwWidth, surf->dwHeight, 1.92 + surf->ddpfPixelFormat.dwRGBBitCount); 1.93 + int pos = ::SendMessage(h, LB_ADDSTRING, 0, (LPARAM)buffer); 1.94 + ::SendMessage(h, LB_SETITEMDATA, pos, 1.95 + (surf->ddpfPixelFormat.dwRGBBitCount << 24) | 1.96 + ((surf->dwWidth & 4095) << 12) | 1.97 + (surf->dwHeight & 4095)); 1.98 + } 1.99 + } 1.100 + 1.101 + return DDENUMRET_OK; 1.102 +} 1.103 + 1.104 +int winVideoModeSelect(CWnd *pWnd, GUID **guid) 1.105 +{ 1.106 + HINSTANCE h = /**/ ::LoadLibrary("ddraw.dll"); 1.107 + 1.108 + // If ddraw.dll doesn't exist in the search path, 1.109 + // then DirectX probably isn't installed, so fail. 1.110 + if (!h) 1.111 + return -1; 1.112 + 1.113 + gDriverCnt = 0; 1.114 + 1.115 + // Note that you must know which version of the 1.116 + // function to retrieve (see the following text). 1.117 + // For this example, we use the ANSI version. 1.118 + LPDIRECTDRAWENUMERATEEX lpDDEnumEx; 1.119 + lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX) 1.120 + GetProcAddress(h, "DirectDrawEnumerateExA"); 1.121 + 1.122 + // If the function is there, call it to enumerate all display 1.123 + // devices attached to the desktop, and any non-display DirectDraw 1.124 + // devices. 1.125 + if (lpDDEnumEx) 1.126 + lpDDEnumEx(DDEnumCallbackEx, NULL, 1.127 + DDENUM_ATTACHEDSECONDARYDEVICES | 1.128 + DDENUM_NONDISPLAYDEVICES 1.129 + ); 1.130 + else 1.131 + { 1.132 + /* 1.133 + * We must be running on an old version of DirectDraw. 1.134 + * Therefore MultiMon isn't supported. Fall back on 1.135 + * DirectDrawEnumerate to enumerate standard devices on a 1.136 + * single-monitor system. 1.137 + */ 1.138 + BOOL (WINAPI *lpDDEnum)(LPDDENUMCALLBACK, LPVOID); 1.139 + 1.140 + lpDDEnum = (BOOL (WINAPI *)(LPDDENUMCALLBACK, LPVOID)) 1.141 + GetProcAddress(h, "DirectDrawEnumerateA"); 1.142 + if (lpDDEnum) 1.143 + lpDDEnum(DDEnumCallback, NULL); 1.144 + 1.145 + /* Note that it could be handy to let the OldCallback function 1.146 + * be a wrapper for a DDEnumCallbackEx. 1.147 + * 1.148 + * Such a function would look like: 1.149 + * BOOL FAR PASCAL OldCallback(GUID FAR *lpGUID, 1.150 + * LPSTR pDesc, 1.151 + * LPSTR pName, 1.152 + * LPVOID pContext) 1.153 + * { 1.154 + * return Callback(lpGUID,pDesc,pName,pContext,NULL); 1.155 + * } 1.156 + */ 1.157 + } 1.158 + 1.159 + int selected = 0; 1.160 + 1.161 + if (gDriverCnt > 1) 1.162 + { 1.163 + VideoDriverSelect d(pWnd); 1.164 + 1.165 + selected = d.DoModal(); 1.166 + 1.167 + if (selected == -1) 1.168 + { 1.169 + // If the library was loaded by calling LoadLibrary(), 1.170 + // then you must use FreeLibrary() to let go of it. 1.171 + /**/ ::FreeLibrary(h); 1.172 + 1.173 + return -1; 1.174 + } 1.175 + } 1.176 + 1.177 + HRESULT (WINAPI *DDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown *); 1.178 + DDrawCreateEx = (HRESULT (WINAPI *)(GUID *, LPVOID *, REFIID, IUnknown *)) 1.179 + GetProcAddress(h, "DirectDrawCreateEx"); 1.180 + 1.181 + LPDIRECTDRAW7 ddraw = NULL; 1.182 + if (DDrawCreateEx) 1.183 + { 1.184 + HRESULT hret = DDrawCreateEx(Drivers[selected].pGUID, 1.185 + (void * *)&ddraw, 1.186 + IID_IDirectDraw7, 1.187 + NULL); 1.188 + if (hret != DD_OK) 1.189 + { 1.190 + systemMessage(0, "Error during DirectDrawCreateEx: %08x", hret); 1.191 + /**/ ::FreeLibrary(h); 1.192 + return -1; 1.193 + } 1.194 + } 1.195 + else 1.196 + { 1.197 + // should not happen.... 1.198 + systemMessage(0, "Error getting DirectDrawCreateEx"); 1.199 + /**/ ::FreeLibrary(h); 1.200 + return -1; 1.201 + } 1.202 + 1.203 + VideoMode dlg(ddraw, pWnd); 1.204 + 1.205 + int res = dlg.DoModal(); 1.206 + 1.207 + if (res != -1) 1.208 + { 1.209 + *guid = Drivers[selected].pGUID; 1.210 + } 1.211 + ddraw->Release(); 1.212 + ddraw = NULL; 1.213 + 1.214 + // If the library was loaded by calling LoadLibrary(), 1.215 + // then you must use FreeLibrary() to let go of it. 1.216 + /**/ ::FreeLibrary(h); 1.217 + 1.218 + return res; 1.219 +} 1.220 + 1.221 +///////////////////////////////////////////////////////////////////////////// 1.222 +// VideoMode dialog 1.223 + 1.224 +VideoMode::VideoMode(LPDIRECTDRAW7 pDraw, CWnd*pParent /*=NULL*/) 1.225 + : CDialog(VideoMode::IDD, pParent) 1.226 +{ 1.227 + //{{AFX_DATA_INIT(VideoMode) 1.228 + // NOTE: the ClassWizard will add member initialization here 1.229 + //}}AFX_DATA_INIT 1.230 + pDirectDraw = pDraw; 1.231 +} 1.232 + 1.233 +void VideoMode::DoDataExchange(CDataExchange*pDX) 1.234 +{ 1.235 + CDialog::DoDataExchange(pDX); 1.236 + //{{AFX_DATA_MAP(VideoMode) 1.237 + DDX_Control(pDX, IDC_MODES, m_modes); 1.238 + //}}AFX_DATA_MAP 1.239 +} 1.240 + 1.241 +BEGIN_MESSAGE_MAP(VideoMode, CDialog) 1.242 +//{{AFX_MSG_MAP(VideoMode) 1.243 +ON_LBN_SELCHANGE(IDC_MODES, OnSelchangeModes) 1.244 +ON_BN_CLICKED(ID_CANCEL, OnCancel) 1.245 +ON_BN_CLICKED(ID_OK, OnOk) 1.246 +//}}AFX_MSG_MAP 1.247 +END_MESSAGE_MAP() 1.248 + 1.249 +///////////////////////////////////////////////////////////////////////////// 1.250 +// VideoMode message handlers 1.251 + 1.252 +void VideoMode::OnSelchangeModes() 1.253 +{ 1.254 + int item = m_modes.GetCurSel(); 1.255 + 1.256 + GetDlgItem(ID_OK)->EnableWindow(item != -1); 1.257 +} 1.258 + 1.259 +void VideoMode::OnCancel() 1.260 +{ 1.261 + EndDialog(-1); 1.262 +} 1.263 + 1.264 +void VideoMode::OnOk() 1.265 +{ 1.266 + int cur = m_modes.GetCurSel(); 1.267 + 1.268 + if (cur != -1) 1.269 + { 1.270 + cur = m_modes.GetItemData(cur); 1.271 + } 1.272 + EndDialog(cur); 1.273 +} 1.274 + 1.275 +BOOL VideoMode::OnInitDialog() 1.276 +{ 1.277 + CDialog::OnInitDialog(); 1.278 + 1.279 + // check for available fullscreen modes 1.280 + pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, m_modes.m_hWnd, 1.281 + addVideoMode); 1.282 + 1.283 + GetDlgItem(ID_OK)->EnableWindow(FALSE); 1.284 + CenterWindow(); 1.285 + 1.286 + return TRUE; // return TRUE unless you set the focus to a control 1.287 + // EXCEPTION: OCX Property Pages should return FALSE 1.288 +} 1.289 + 1.290 +///////////////////////////////////////////////////////////////////////////// 1.291 +// VideoDriverSelect dialog 1.292 + 1.293 +VideoDriverSelect::VideoDriverSelect(CWnd*pParent /*=NULL*/) 1.294 + : CDialog(VideoDriverSelect::IDD, pParent) 1.295 +{ 1.296 + //{{AFX_DATA_INIT(VideoDriverSelect) 1.297 + // NOTE: the ClassWizard will add member initialization here 1.298 + //}}AFX_DATA_INIT 1.299 +} 1.300 + 1.301 +void VideoDriverSelect::DoDataExchange(CDataExchange*pDX) 1.302 +{ 1.303 + CDialog::DoDataExchange(pDX); 1.304 + //{{AFX_DATA_MAP(VideoDriverSelect) 1.305 + DDX_Control(pDX, IDC_DRIVERS, m_drivers); 1.306 + //}}AFX_DATA_MAP 1.307 +} 1.308 + 1.309 +BEGIN_MESSAGE_MAP(VideoDriverSelect, CDialog) 1.310 +//{{AFX_MSG_MAP(VideoDriverSelect) 1.311 +ON_BN_CLICKED(ID_OK, OnOk) 1.312 +ON_BN_CLICKED(ID_CANCEL, OnCancel) 1.313 +ON_LBN_SELCHANGE(IDC_DRIVERS, OnSelchangeDrivers) 1.314 +//}}AFX_MSG_MAP 1.315 +END_MESSAGE_MAP() 1.316 + 1.317 +///////////////////////////////////////////////////////////////////////////// 1.318 +// VideoDriverSelect message handlers 1.319 + 1.320 +void VideoDriverSelect::OnCancel() 1.321 +{ 1.322 + EndDialog(-1); 1.323 +} 1.324 + 1.325 +void VideoDriverSelect::OnOk() 1.326 +{ 1.327 + EndDialog(m_drivers.GetCurSel()); 1.328 +} 1.329 + 1.330 +BOOL VideoDriverSelect::OnInitDialog() 1.331 +{ 1.332 + CDialog::OnInitDialog(); 1.333 + 1.334 + for (int i = 0; i < gDriverCnt; i++) 1.335 + { 1.336 + m_drivers.AddString(Drivers[i].szDescription); 1.337 + } 1.338 + 1.339 + GetDlgItem(ID_OK)->EnableWindow(FALSE); 1.340 + CenterWindow(); 1.341 + 1.342 + return TRUE; // return TRUE unless you set the focus to a control 1.343 + // EXCEPTION: OCX Property Pages should return FALSE 1.344 +} 1.345 + 1.346 +void VideoDriverSelect::OnSelchangeDrivers() 1.347 +{ 1.348 + GetDlgItem(ID_OK)->EnableWindow(m_drivers.GetCurSel() != -1); 1.349 +} 1.350 +