Mercurial > vba-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // VideoMode.cpp : implementation file | |
2 // | |
3 | |
4 #include "stdafx.h" | |
5 #include "resource.h" | |
6 | |
7 /// #define _AFXDLL /// EVIL | |
8 /// #include "afxwin.h" /// EVIL | |
9 /// #include "afxdll_.h" /// EVIL | |
10 | |
11 #define DIRECTDRAW_VERSION 0x0700 | |
12 #include "ddraw.h" | |
13 | |
14 #include "VideoMode.h" | |
15 | |
16 #include "../common/System.h" // for system messages | |
17 | |
18 #define MAX_DRIVERS 32 // 32 drivers maximum | |
19 | |
20 //----------------------------------------------------------------------------- | |
21 // Local structures | |
22 //----------------------------------------------------------------------------- | |
23 // Keeps data on the available DDraw drivers | |
24 struct | |
25 { | |
26 char szDescription[128]; | |
27 char szName[128]; | |
28 GUID * pGUID; | |
29 GUID GUIDcopy; | |
30 HMONITOR hm; | |
31 } Drivers[MAX_DRIVERS]; | |
32 | |
33 //----------------------------------------------------------------------------- | |
34 // Local data | |
35 //----------------------------------------------------------------------------- | |
36 static int gDriverCnt = 0; // Total number of drivers | |
37 static GUID *gpSelectedDriverGUID; | |
38 | |
39 //----------------------------------------------------------------------------- | |
40 // Name: DDEnumCallbackEx() | |
41 // Desc: This call back is used to determine the existing available DDraw | |
42 // devices, so the user can pick which one to run on. | |
43 //----------------------------------------------------------------------------- | |
44 BOOL WINAPI | |
45 DDEnumCallbackEx(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID pContext, HMONITOR hm) | |
46 { | |
47 if (pGUID) | |
48 { | |
49 Drivers[gDriverCnt].GUIDcopy = *pGUID; | |
50 Drivers[gDriverCnt].pGUID = &Drivers[gDriverCnt].GUIDcopy; | |
51 } | |
52 else | |
53 Drivers[gDriverCnt].pGUID = NULL; | |
54 Drivers[gDriverCnt].szDescription[127] = '\0'; | |
55 Drivers[gDriverCnt].szName[127] = '\0'; | |
56 strncpy(Drivers[gDriverCnt].szDescription, pDescription, 127); | |
57 strncpy(Drivers[gDriverCnt].szName, pName, 127); | |
58 Drivers[gDriverCnt].hm = hm; | |
59 if (gDriverCnt < MAX_DRIVERS) | |
60 gDriverCnt++; | |
61 else | |
62 return DDENUMRET_CANCEL; | |
63 return DDENUMRET_OK; | |
64 } | |
65 | |
66 //----------------------------------------------------------------------------- | |
67 // Name: DDEnumCallback() | |
68 // Desc: This callback is used only with old versions of DDraw. | |
69 //----------------------------------------------------------------------------- | |
70 BOOL WINAPI | |
71 DDEnumCallback(GUID *pGUID, LPSTR pDescription, LPSTR pName, LPVOID context) | |
72 { | |
73 return (DDEnumCallbackEx(pGUID, pDescription, pName, context, NULL)); | |
74 } | |
75 | |
76 static HRESULT WINAPI addVideoMode(LPDDSURFACEDESC2 surf, LPVOID lpContext) | |
77 { | |
78 HWND h = (HWND)lpContext; | |
79 char buffer[50]; | |
80 | |
81 switch (surf->ddpfPixelFormat.dwRGBBitCount) | |
82 { | |
83 case 16: | |
84 case 24: | |
85 case 32: | |
86 if (surf->dwWidth >= 640 && surf->dwHeight >= 480) | |
87 { | |
88 sprintf(buffer, "%4dx%4dx%2d", surf->dwWidth, surf->dwHeight, | |
89 surf->ddpfPixelFormat.dwRGBBitCount); | |
90 int pos = ::SendMessage(h, LB_ADDSTRING, 0, (LPARAM)buffer); | |
91 ::SendMessage(h, LB_SETITEMDATA, pos, | |
92 (surf->ddpfPixelFormat.dwRGBBitCount << 24) | | |
93 ((surf->dwWidth & 4095) << 12) | | |
94 (surf->dwHeight & 4095)); | |
95 } | |
96 } | |
97 | |
98 return DDENUMRET_OK; | |
99 } | |
100 | |
101 int winVideoModeSelect(CWnd *pWnd, GUID **guid) | |
102 { | |
103 HINSTANCE h = /**/ ::LoadLibrary("ddraw.dll"); | |
104 | |
105 // If ddraw.dll doesn't exist in the search path, | |
106 // then DirectX probably isn't installed, so fail. | |
107 if (!h) | |
108 return -1; | |
109 | |
110 gDriverCnt = 0; | |
111 | |
112 // Note that you must know which version of the | |
113 // function to retrieve (see the following text). | |
114 // For this example, we use the ANSI version. | |
115 LPDIRECTDRAWENUMERATEEX lpDDEnumEx; | |
116 lpDDEnumEx = (LPDIRECTDRAWENUMERATEEX) | |
117 GetProcAddress(h, "DirectDrawEnumerateExA"); | |
118 | |
119 // If the function is there, call it to enumerate all display | |
120 // devices attached to the desktop, and any non-display DirectDraw | |
121 // devices. | |
122 if (lpDDEnumEx) | |
123 lpDDEnumEx(DDEnumCallbackEx, NULL, | |
124 DDENUM_ATTACHEDSECONDARYDEVICES | | |
125 DDENUM_NONDISPLAYDEVICES | |
126 ); | |
127 else | |
128 { | |
129 /* | |
130 * We must be running on an old version of DirectDraw. | |
131 * Therefore MultiMon isn't supported. Fall back on | |
132 * DirectDrawEnumerate to enumerate standard devices on a | |
133 * single-monitor system. | |
134 */ | |
135 BOOL (WINAPI *lpDDEnum)(LPDDENUMCALLBACK, LPVOID); | |
136 | |
137 lpDDEnum = (BOOL (WINAPI *)(LPDDENUMCALLBACK, LPVOID)) | |
138 GetProcAddress(h, "DirectDrawEnumerateA"); | |
139 if (lpDDEnum) | |
140 lpDDEnum(DDEnumCallback, NULL); | |
141 | |
142 /* Note that it could be handy to let the OldCallback function | |
143 * be a wrapper for a DDEnumCallbackEx. | |
144 * | |
145 * Such a function would look like: | |
146 * BOOL FAR PASCAL OldCallback(GUID FAR *lpGUID, | |
147 * LPSTR pDesc, | |
148 * LPSTR pName, | |
149 * LPVOID pContext) | |
150 * { | |
151 * return Callback(lpGUID,pDesc,pName,pContext,NULL); | |
152 * } | |
153 */ | |
154 } | |
155 | |
156 int selected = 0; | |
157 | |
158 if (gDriverCnt > 1) | |
159 { | |
160 VideoDriverSelect d(pWnd); | |
161 | |
162 selected = d.DoModal(); | |
163 | |
164 if (selected == -1) | |
165 { | |
166 // If the library was loaded by calling LoadLibrary(), | |
167 // then you must use FreeLibrary() to let go of it. | |
168 /**/ ::FreeLibrary(h); | |
169 | |
170 return -1; | |
171 } | |
172 } | |
173 | |
174 HRESULT (WINAPI *DDrawCreateEx)(GUID *, LPVOID *, REFIID, IUnknown *); | |
175 DDrawCreateEx = (HRESULT (WINAPI *)(GUID *, LPVOID *, REFIID, IUnknown *)) | |
176 GetProcAddress(h, "DirectDrawCreateEx"); | |
177 | |
178 LPDIRECTDRAW7 ddraw = NULL; | |
179 if (DDrawCreateEx) | |
180 { | |
181 HRESULT hret = DDrawCreateEx(Drivers[selected].pGUID, | |
182 (void * *)&ddraw, | |
183 IID_IDirectDraw7, | |
184 NULL); | |
185 if (hret != DD_OK) | |
186 { | |
187 systemMessage(0, "Error during DirectDrawCreateEx: %08x", hret); | |
188 /**/ ::FreeLibrary(h); | |
189 return -1; | |
190 } | |
191 } | |
192 else | |
193 { | |
194 // should not happen.... | |
195 systemMessage(0, "Error getting DirectDrawCreateEx"); | |
196 /**/ ::FreeLibrary(h); | |
197 return -1; | |
198 } | |
199 | |
200 VideoMode dlg(ddraw, pWnd); | |
201 | |
202 int res = dlg.DoModal(); | |
203 | |
204 if (res != -1) | |
205 { | |
206 *guid = Drivers[selected].pGUID; | |
207 } | |
208 ddraw->Release(); | |
209 ddraw = NULL; | |
210 | |
211 // If the library was loaded by calling LoadLibrary(), | |
212 // then you must use FreeLibrary() to let go of it. | |
213 /**/ ::FreeLibrary(h); | |
214 | |
215 return res; | |
216 } | |
217 | |
218 ///////////////////////////////////////////////////////////////////////////// | |
219 // VideoMode dialog | |
220 | |
221 VideoMode::VideoMode(LPDIRECTDRAW7 pDraw, CWnd*pParent /*=NULL*/) | |
222 : CDialog(VideoMode::IDD, pParent) | |
223 { | |
224 //{{AFX_DATA_INIT(VideoMode) | |
225 // NOTE: the ClassWizard will add member initialization here | |
226 //}}AFX_DATA_INIT | |
227 pDirectDraw = pDraw; | |
228 } | |
229 | |
230 void VideoMode::DoDataExchange(CDataExchange*pDX) | |
231 { | |
232 CDialog::DoDataExchange(pDX); | |
233 //{{AFX_DATA_MAP(VideoMode) | |
234 DDX_Control(pDX, IDC_MODES, m_modes); | |
235 //}}AFX_DATA_MAP | |
236 } | |
237 | |
238 BEGIN_MESSAGE_MAP(VideoMode, CDialog) | |
239 //{{AFX_MSG_MAP(VideoMode) | |
240 ON_LBN_SELCHANGE(IDC_MODES, OnSelchangeModes) | |
241 ON_BN_CLICKED(ID_CANCEL, OnCancel) | |
242 ON_BN_CLICKED(ID_OK, OnOk) | |
243 //}}AFX_MSG_MAP | |
244 END_MESSAGE_MAP() | |
245 | |
246 ///////////////////////////////////////////////////////////////////////////// | |
247 // VideoMode message handlers | |
248 | |
249 void VideoMode::OnSelchangeModes() | |
250 { | |
251 int item = m_modes.GetCurSel(); | |
252 | |
253 GetDlgItem(ID_OK)->EnableWindow(item != -1); | |
254 } | |
255 | |
256 void VideoMode::OnCancel() | |
257 { | |
258 EndDialog(-1); | |
259 } | |
260 | |
261 void VideoMode::OnOk() | |
262 { | |
263 int cur = m_modes.GetCurSel(); | |
264 | |
265 if (cur != -1) | |
266 { | |
267 cur = m_modes.GetItemData(cur); | |
268 } | |
269 EndDialog(cur); | |
270 } | |
271 | |
272 BOOL VideoMode::OnInitDialog() | |
273 { | |
274 CDialog::OnInitDialog(); | |
275 | |
276 // check for available fullscreen modes | |
277 pDirectDraw->EnumDisplayModes(DDEDM_STANDARDVGAMODES, NULL, m_modes.m_hWnd, | |
278 addVideoMode); | |
279 | |
280 GetDlgItem(ID_OK)->EnableWindow(FALSE); | |
281 CenterWindow(); | |
282 | |
283 return TRUE; // return TRUE unless you set the focus to a control | |
284 // EXCEPTION: OCX Property Pages should return FALSE | |
285 } | |
286 | |
287 ///////////////////////////////////////////////////////////////////////////// | |
288 // VideoDriverSelect dialog | |
289 | |
290 VideoDriverSelect::VideoDriverSelect(CWnd*pParent /*=NULL*/) | |
291 : CDialog(VideoDriverSelect::IDD, pParent) | |
292 { | |
293 //{{AFX_DATA_INIT(VideoDriverSelect) | |
294 // NOTE: the ClassWizard will add member initialization here | |
295 //}}AFX_DATA_INIT | |
296 } | |
297 | |
298 void VideoDriverSelect::DoDataExchange(CDataExchange*pDX) | |
299 { | |
300 CDialog::DoDataExchange(pDX); | |
301 //{{AFX_DATA_MAP(VideoDriverSelect) | |
302 DDX_Control(pDX, IDC_DRIVERS, m_drivers); | |
303 //}}AFX_DATA_MAP | |
304 } | |
305 | |
306 BEGIN_MESSAGE_MAP(VideoDriverSelect, CDialog) | |
307 //{{AFX_MSG_MAP(VideoDriverSelect) | |
308 ON_BN_CLICKED(ID_OK, OnOk) | |
309 ON_BN_CLICKED(ID_CANCEL, OnCancel) | |
310 ON_LBN_SELCHANGE(IDC_DRIVERS, OnSelchangeDrivers) | |
311 //}}AFX_MSG_MAP | |
312 END_MESSAGE_MAP() | |
313 | |
314 ///////////////////////////////////////////////////////////////////////////// | |
315 // VideoDriverSelect message handlers | |
316 | |
317 void VideoDriverSelect::OnCancel() | |
318 { | |
319 EndDialog(-1); | |
320 } | |
321 | |
322 void VideoDriverSelect::OnOk() | |
323 { | |
324 EndDialog(m_drivers.GetCurSel()); | |
325 } | |
326 | |
327 BOOL VideoDriverSelect::OnInitDialog() | |
328 { | |
329 CDialog::OnInitDialog(); | |
330 | |
331 for (int i = 0; i < gDriverCnt; i++) | |
332 { | |
333 m_drivers.AddString(Drivers[i].szDescription); | |
334 } | |
335 | |
336 GetDlgItem(ID_OK)->EnableWindow(FALSE); | |
337 CenterWindow(); | |
338 | |
339 return TRUE; // return TRUE unless you set the focus to a control | |
340 // EXCEPTION: OCX Property Pages should return FALSE | |
341 } | |
342 | |
343 void VideoDriverSelect::OnSelchangeDrivers() | |
344 { | |
345 GetDlgItem(ID_OK)->EnableWindow(m_drivers.GetCurSel() != -1); | |
346 } | |
347 |