00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <windows.h>
00021 #include <stdio.h>
00022
00023 #include "Win32.h"
00024 #include "OglDrv.h"
00025
00026
00027 HWND originalWnd = NULL;
00028 WNDPROC originalWndProc = NULL;
00029 HDC hDC = NULL;
00030 HGLRC hRC = NULL;
00031 GLboolean fullscreen = GE_FALSE;
00032
00033
00034 static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
00035 {
00036 switch(iMessage)
00037 {
00038 case WM_DESTROY:
00039 break;
00040
00041 default:
00042 if(originalWndProc != NULL)
00043 {
00044 return originalWndProc(hWnd, iMessage, wParam, lParam);
00045 }
00046 }
00047
00048 return 0;
00049 }
00050
00051
00052 void WindowSetup(DRV_DriverHook *Hook)
00053 {
00054 HINSTANCE hInstance;
00055 WNDCLASS wc;
00056 RECT wndRect;
00057 DWORD style = 0;
00058 char className[256];
00059
00060
00061 hInstance = (HINSTANCE)GetWindowLong(Hook->hWnd, GWL_HINSTANCE);
00062 memset(className, 0, sizeof(className));
00063 GetClassName(Hook->hWnd, className, 256);
00064 GetClassInfo(hInstance, className, &wc);
00065 GetWindowRect(Hook->hWnd, &wndRect);
00066
00067 originalWnd = Hook->hWnd;
00068
00069 strcat(className, "_r");
00070
00071 wc.lpszClassName = className;
00072 wc.style |= CS_OWNDC;
00073
00074 originalWndProc = wc.lpfnWndProc;
00075 wc.lpfnWndProc = WndProc;
00076
00077 if(Hook->Width != -1 && Hook->Height != -1)
00078 {
00079 style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
00080 }
00081
00082 RegisterClass(&wc);
00083
00084 Hook->hWnd = CreateWindowEx(
00085 0,
00086 wc.lpszClassName,
00087 wc.lpszClassName,
00088 style,
00089 wndRect.left,
00090 wndRect.top,
00091 wndRect.right - wndRect.left,
00092 wndRect.bottom - wndRect.top,
00093 NULL,
00094 NULL,
00095 hInstance,
00096 NULL);
00097
00098 if(Hook->Width != -1 && Hook->Height != -1)
00099 {
00100 SetWindowPos(originalWnd, HWND_BOTTOM, 0, 0, Hook->Width, Hook->Height, 0);
00101 SetWindowPos(Hook->hWnd, HWND_TOP, 0, 0, Hook->Width, Hook->Height, 0);
00102 }
00103
00104 ShowWindow(originalWnd, SW_HIDE);
00105 ShowWindow(Hook->hWnd, SW_SHOW);
00106 }
00107
00108
00109 void WindowCleanup()
00110 {
00111 HINSTANCE hInstance;
00112 char className[256];
00113
00114 if(ClientWindow.hWnd != NULL)
00115 {
00116 if(hDC != NULL && hRC != NULL)
00117 {
00118 wglMakeCurrent(hDC, NULL);
00119 wglDeleteContext(hRC);
00120 }
00121
00122 ReleaseDC(ClientWindow.hWnd, hDC);
00123 }
00124
00125 if(fullscreen)
00126 {
00127 ChangeDisplaySettings(NULL, 0);
00128 fullscreen = GE_FALSE;
00129 }
00130
00131 if(ClientWindow.hWnd != NULL)
00132 {
00133 hInstance = (HINSTANCE)GetWindowLong(ClientWindow.hWnd, GWL_HINSTANCE);
00134 memset(className, 0, sizeof(className));
00135 GetClassName(ClientWindow.hWnd, className, 256);
00136
00137 UnregisterClass(className, hInstance);
00138 DestroyWindow(ClientWindow.hWnd);
00139
00140 if(originalWnd != NULL)
00141 {
00142 ShowWindow(originalWnd, SW_SHOW);
00143 }
00144 }
00145 }
00146
00147
00148 void FlipGLBuffers()
00149 {
00150 SwapBuffers(hDC);
00151 }
00152
00153
00154 geBoolean SetFullscreen(DRV_DriverHook *Hook)
00155 {
00156 GLuint modeCount, refresh = 0;
00157 GLboolean foundMatch = GE_FALSE;
00158 DEVMODE devMode, bestMode;
00159
00160 devMode.dmSize = sizeof(DEVMODE);
00161 devMode.dmPelsWidth = Hook->Width;
00162 devMode.dmPelsHeight = Hook->Height;
00163
00164 modeCount = 0;
00165
00166 while(EnumDisplaySettings(NULL, modeCount++, &devMode))
00167 {
00168 if(devMode.dmBitsPerPel != COLOR_DEPTH)
00169 {
00170 continue;
00171 }
00172
00173 if((GLint)devMode.dmPelsWidth == Hook->Width &&
00174 (GLint)devMode.dmPelsHeight == Hook->Height)
00175 {
00176 if(devMode.dmDisplayFrequency >= refresh)
00177 {
00178 bestMode = devMode;
00179 foundMatch = GE_TRUE;
00180 }
00181 }
00182 }
00183
00184
00185 if(foundMatch)
00186 {
00187 if(ChangeDisplaySettings(&bestMode, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL)
00188 {
00189 fullscreen = GE_TRUE;
00190 return GE_TRUE;
00191 }
00192 }
00193
00194
00195 return GE_FALSE;
00196 }
00197
00198
00199 void SetGLPixelFormat(DRV_DriverHook *Hook)
00200 {
00201 GLint nPixelFormat;
00202 static PIXELFORMATDESCRIPTOR pfd;
00203
00204 memset(&pfd, 0x00, sizeof(pfd));
00205
00206 pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);
00207 pfd.nVersion = 1;
00208 pfd.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
00209 pfd.dwLayerMask = PFD_MAIN_PLANE;
00210 pfd.iPixelType = PFD_TYPE_RGBA;
00211 pfd.cColorBits = COLOR_DEPTH;
00212 pfd.cDepthBits = ZBUFFER_DEPTH;
00213 pfd.cAccumBits = 0;
00214 pfd.cStencilBits = 0;
00215
00216 hDC = GetDC(Hook->hWnd);
00217
00218 if(hDC != NULL)
00219 {
00220 if(GetPixelFormat(hDC) <= 0)
00221 {
00222 nPixelFormat = ChoosePixelFormat(hDC, &pfd);
00223 SetPixelFormat(hDC, nPixelFormat, &pfd);
00224 }
00225
00226 hRC = wglCreateContext(hDC);
00227 wglMakeCurrent(hDC, hRC);
00228 }
00229 }
00230
00231
00232 GLint EnumNativeModes(DRV_ENUM_MODES_CB *Cb, void *Context)
00233 {
00234 DEVMODE devMode;
00235 GLint modeCount, modeListCount;
00236 char resolution[16];
00237 GLint idx = 0;
00238 MODELIST *modeList = NULL;
00239
00240 modeCount = 0;
00241
00242 memset(&devMode, 0x00, sizeof(DEVMODE));
00243 devMode.dmSize = sizeof(DEVMODE);
00244
00245 while(EnumDisplaySettings(NULL, modeCount, &devMode))
00246 {
00247 modeCount++;
00248
00249 if(devMode.dmBitsPerPel != COLOR_DEPTH)
00250 {
00251 continue;
00252 }
00253
00254 if(ChangeDisplaySettings(&devMode, CDS_TEST) != DISP_CHANGE_SUCCESSFUL)
00255 {
00256 continue;
00257 }
00258 }
00259
00260 modeList = (MODELIST *)malloc(modeCount * sizeof(MODELIST));
00261 memset(modeList, 0x00, modeCount * sizeof(MODELIST));
00262 modeListCount = modeCount;
00263 modeCount = 0;
00264
00265 memset(&devMode, 0x00, sizeof(DEVMODE));
00266 devMode.dmSize = sizeof(DEVMODE);
00267
00268 while(EnumDisplaySettings(NULL, modeCount, &devMode))
00269 {
00270 GLboolean found = GE_FALSE;
00271 GLint count;
00272
00273 modeCount++;
00274
00275 if(devMode.dmBitsPerPel != COLOR_DEPTH)
00276 {
00277 continue;
00278 }
00279
00280 if(ChangeDisplaySettings(&devMode, CDS_TEST) == DISP_CHANGE_SUCCESSFUL)
00281 {
00282 for(count = 0; count < modeListCount; count++)
00283 {
00284 if(modeList[count].width == devMode.dmPelsWidth &&
00285 modeList[count].height == devMode.dmPelsHeight)
00286 {
00287 found = GE_TRUE;
00288 break;
00289 }
00290 }
00291
00292 if(!found)
00293 {
00294 sprintf(resolution, "%dx%d", devMode.dmPelsWidth, devMode.dmPelsHeight);
00295
00296 if(!Cb(modeCount + 1, resolution, devMode.dmPelsWidth, devMode.dmPelsHeight, Context))
00297 {
00298 free(modeList);
00299 return modeCount;
00300 }
00301
00302 for(count = 0; count < modeListCount; count++)
00303 {
00304 if(modeList[count].width == 0 && modeList[count].height == 0)
00305 {
00306 modeList[count].width = devMode.dmPelsWidth;
00307 modeList[count].height = devMode.dmPelsHeight;
00308 break;
00309 }
00310 }
00311 }
00312 }
00313
00314 modeCount++;
00315 }
00316
00317 free(modeList);
00318
00319 Cb(modeCount + 1, "WindowMode", -1, -1, Context);
00320
00321 return modeCount;
00322 }
00323