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