00001
00002
00003
00004 #include <string.h>
00005 #include <allegro.h>
00006 #include <allegro/internal/aintern.h>
00007
00008
00009 #include "alleggl.h"
00010 #include "glvtable.h"
00011 #include "allglint.h"
00012
00013
00014 static BITMAP *allegro_gl_win_init_windowed(int w, int h, int v_w, int v_h,
00015 int color_depth);
00016 static BITMAP *allegro_gl_win_init_fullscreen(int w, int h, int v_w, int v_h,
00017 int color_depth);
00018 static void allegro_gl_win_exit(struct BITMAP *b);
00019 static GFX_MODE_LIST* allegro_gl_win_fetch_mode_list(void);
00020
00021 static struct allegro_gl_driver allegro_gl_win;
00022
00023 #define PREFIX_I "agl-win INFO: "
00024 #define PREFIX_W "agl-win WARNING: "
00025 #define PREFIX_E "agl-win ERROR: "
00026
00027
00028 static BITMAP *allegro_gl_screen = NULL;
00029
00030
00031
00032 GFX_DRIVER gfx_allegro_gl_windowed = {
00033 GFX_OPENGL_WINDOWED,
00034 EMPTY_STRING,
00035 EMPTY_STRING,
00036 "AllegroGL Windowed (Win32)",
00037 allegro_gl_win_init_windowed,
00038 allegro_gl_win_exit,
00039 NULL,
00040 NULL,
00041 NULL,
00042 NULL, NULL,
00043 NULL,
00044 allegro_gl_create_video_bitmap,
00045 allegro_gl_destroy_video_bitmap,
00046 NULL, NULL,
00047 NULL, NULL,
00048 allegro_gl_set_mouse_sprite,
00049 allegro_gl_show_mouse,
00050 allegro_gl_hide_mouse,
00051 allegro_gl_move_mouse,
00052 NULL, NULL, NULL,
00053 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 18)
00054 NULL,
00055 #endif
00056 NULL,
00057 0,0,
00058 0,
00059 0,
00060 0,
00061 0,
00062 0,
00063 TRUE
00064 };
00065
00066
00067
00068 GFX_DRIVER gfx_allegro_gl_fullscreen = {
00069 GFX_OPENGL_FULLSCREEN,
00070 EMPTY_STRING,
00071 EMPTY_STRING,
00072 "AllegroGL Fullscreen (Win32)",
00073 allegro_gl_win_init_fullscreen,
00074 allegro_gl_win_exit,
00075 NULL,
00076 NULL,
00077 NULL,
00078 NULL, NULL,
00079 NULL,
00080 allegro_gl_create_video_bitmap,
00081 allegro_gl_destroy_video_bitmap,
00082 NULL, NULL,
00083 NULL, NULL,
00084 allegro_gl_set_mouse_sprite,
00085 allegro_gl_show_mouse,
00086 allegro_gl_hide_mouse,
00087 allegro_gl_move_mouse,
00088 NULL, NULL, NULL,
00089 #if GET_ALLEGRO_VERSION() >= MAKE_VER(4, 1, 18)
00090 NULL,
00091 #endif
00092 allegro_gl_win_fetch_mode_list,
00093 0,0,
00094 0,
00095 0,
00096 0,
00097 0,
00098 0,
00099 FALSE
00100 };
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 HDC __allegro_gl_hdc = NULL;
00112
00113
00114
00115
00116 static HGLRC allegro_glrc = NULL;
00117
00118
00119 static int fullscreen = 0;
00120
00121
00122 static HWND wnd = NULL;
00123
00124
00125 static int initialized = 0;
00126
00127
00128
00129
00130 static DWORD style_saved, exstyle_saved;
00131 static DEVMODE dm_saved;
00132 static int test_windows_created = 0;
00133 static int new_w = 0, new_h = 0;
00134
00135 static PIXELFORMATDESCRIPTOR pfd = {
00136 sizeof(PIXELFORMATDESCRIPTOR),
00137 1,
00138 PFD_DRAW_TO_WINDOW
00139 | PFD_SUPPORT_OPENGL
00140 | PFD_DOUBLEBUFFER,
00141 PFD_TYPE_RGBA,
00142 24,
00143 0, 0, 0, 0, 0, 0,
00144 0,
00145 0,
00146 0,
00147 0, 0, 0, 0,
00148 0,
00149 0,
00150 0,
00151 PFD_MAIN_PLANE,
00152 0,
00153 0, 0, 0
00154 };
00155
00156
00157
00158
00159
00160 static void log_win32_msg(const char *prefix, const char *func,
00161 const char *error_msg, DWORD err) {
00162
00163 char *err_msg = NULL;
00164 BOOL free_msg = TRUE;
00165
00166
00167
00168
00169
00170 if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER
00171 | FORMAT_MESSAGE_FROM_SYSTEM
00172 | FORMAT_MESSAGE_IGNORE_INSERTS,
00173 NULL, err & 0x3FFF,
00174 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00175 (LPTSTR) &err_msg, 0, NULL)) {
00176 err_msg = "(Unable to decode error code) ";
00177 free_msg = FALSE;
00178 }
00179
00180
00181 if (err_msg && strlen(err_msg) > 1)
00182 *(err_msg + strlen(err_msg) - 2) = '\0';
00183
00184 TRACE("%s%s(): %s %s (0x%08lx)\n", prefix, func,
00185 error_msg ? error_msg : "",
00186 err_msg ? err_msg : "(null)",
00187 (unsigned long)err);
00188
00189 if (free_msg) {
00190 LocalFree(err_msg);
00191 }
00192
00193 return;
00194 }
00195
00196
00197
00198
00199 static void log_win32_error(const char *func, const char *error_msg,
00200 DWORD err) {
00201 log_win32_msg(PREFIX_E, func, error_msg, err);
00202 }
00203
00204
00205
00206
00207 static void log_win32_warning(const char *func, const char *error_msg,
00208 DWORD err) {
00209 log_win32_msg(PREFIX_W, func, error_msg, err);
00210 }
00211
00212
00213
00214
00215 static void log_win32_note(const char *func, const char *error_msg, DWORD err) {
00216 log_win32_msg(PREFIX_I, func, error_msg, err);
00217 }
00218
00219
00220
00221
00222 #define ALLEGROGL_TEST_WINDOW_CLASS "AllegroGLTestWindow"
00223
00224
00225
00226
00227
00228 static int register_test_window()
00229 {
00230 WNDCLASS wc;
00231
00232 memset(&wc, 0, sizeof(wc));
00233 wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
00234 wc.lpfnWndProc = DefWindowProc;
00235 wc.hInstance = GetModuleHandle(NULL);
00236 wc.hIcon = LoadIcon(GetModuleHandle(NULL), IDI_APPLICATION);
00237 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
00238 wc.lpszClassName = ALLEGROGL_TEST_WINDOW_CLASS;
00239
00240 if (!RegisterClass(&wc)) {
00241 DWORD err = GetLastError();
00242
00243 if (err != ERROR_CLASS_ALREADY_EXISTS) {
00244 log_win32_error("register_test_window",
00245 "Unable to register the window class!", err);
00246 return -1;
00247 }
00248 }
00249
00250 return 0;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260 static HWND create_test_window()
00261 {
00262 HWND wnd = CreateWindow(ALLEGROGL_TEST_WINDOW_CLASS,
00263 "AllegroGL Test Window",
00264 WS_POPUP | WS_CLIPCHILDREN,
00265 0, 0, new_w, new_h,
00266 NULL, NULL,
00267 GetModuleHandle(NULL),
00268 NULL);
00269
00270 if (!wnd) {
00271 log_win32_error("create_test_window",
00272 "Unable to create a test window!", GetLastError());
00273 return NULL;
00274 }
00275
00276 test_windows_created++;
00277 return wnd;
00278 }
00279
00280
00281
00282
00283 static void print_pixel_format(struct allegro_gl_display_info *dinfo) {
00284
00285 if (!dinfo) {
00286 return;
00287 }
00288
00289 TRACE(PREFIX_I "Acceleration: %s\n", ((dinfo->rmethod == 0) ? "No"
00290 : ((dinfo->rmethod == 1) ? "Yes" : "Unknown")));
00291 TRACE(PREFIX_I "RGBA: %i.%i.%i.%i\n", dinfo->pixel_size.rgba.r,
00292 dinfo->pixel_size.rgba.g, dinfo->pixel_size.rgba.b,
00293 dinfo->pixel_size.rgba.a);
00294
00295 TRACE(PREFIX_I "Accum: %i.%i.%i.%i\n", dinfo->accum_size.rgba.r,
00296 dinfo->accum_size.rgba.g, dinfo->accum_size.rgba.b,
00297 dinfo->accum_size.rgba.a);
00298
00299 TRACE(PREFIX_I "DblBuf: %i Zbuf: %i Stereo: %i Aux: %i Stencil: %i\n",
00300 dinfo->doublebuffered, dinfo->depth_size, dinfo->stereo,
00301 dinfo->aux_buffers, dinfo->stencil_size);
00302
00303 TRACE(PREFIX_I "Shift: %i.%i.%i.%i\n", dinfo->r_shift, dinfo->g_shift,
00304 dinfo->b_shift, dinfo->a_shift);
00305
00306 TRACE(PREFIX_I "Sample Buffers: %i Samples: %i\n",
00307 dinfo->sample_buffers, dinfo->samples);
00308
00309 TRACE(PREFIX_I "Decoded bpp: %i\n", dinfo->colour_depth);
00310 }
00311
00312
00313
00314
00315
00316
00317 static int decode_pixel_format(PIXELFORMATDESCRIPTOR * pfd, HDC hdc, int format,
00318 struct allegro_gl_display_info *dinfo,
00319 int desktop_depth)
00320 {
00321 TRACE(PREFIX_I "Decoding: \n");
00322
00323 if (!(pfd->dwFlags & PFD_SUPPORT_OPENGL)) {
00324 TRACE(PREFIX_I "OpenGL Unsupported\n");
00325 return -1;
00326 }
00327 if (pfd->iPixelType != PFD_TYPE_RGBA) {
00328 TRACE(PREFIX_I "Not RGBA mode\n");
00329 return -1;
00330 }
00331
00332 if ((pfd->cColorBits != desktop_depth)
00333 && (pfd->cColorBits != 32 || desktop_depth < 24)) {
00334 TRACE(PREFIX_I "Current color depth != "
00335 "pixel format color depth\n");
00336
00337 }
00338
00339
00340
00341 if (((pfd->dwFlags & PFD_GENERIC_ACCELERATED)
00342 && (pfd->dwFlags & PFD_GENERIC_FORMAT))
00343 || (!(pfd->dwFlags & PFD_GENERIC_ACCELERATED)
00344 && !(pfd->dwFlags & PFD_GENERIC_FORMAT)))
00345 dinfo->rmethod = 1;
00346 else
00347 dinfo->rmethod = 0;
00348
00349
00350
00351 dinfo->pixel_size.rgba.r = pfd->cRedBits;
00352 dinfo->pixel_size.rgba.g = pfd->cGreenBits;
00353 dinfo->pixel_size.rgba.b = pfd->cBlueBits;
00354 dinfo->pixel_size.rgba.a = pfd->cAlphaBits;
00355
00356
00357 dinfo->accum_size.rgba.r = pfd->cAccumRedBits;
00358 dinfo->accum_size.rgba.g = pfd->cAccumGreenBits;
00359 dinfo->accum_size.rgba.b = pfd->cAccumBlueBits;
00360 dinfo->accum_size.rgba.a = pfd->cAccumAlphaBits;
00361
00362
00363 dinfo->doublebuffered = pfd->dwFlags & PFD_DOUBLEBUFFER;
00364 dinfo->stereo = pfd->dwFlags & PFD_STEREO;
00365 dinfo->aux_buffers = pfd->cAuxBuffers;
00366 dinfo->depth_size = pfd->cDepthBits;
00367 dinfo->stencil_size = pfd->cStencilBits;
00368
00369
00370 dinfo->r_shift = pfd->cRedShift;
00371 dinfo->g_shift = pfd->cGreenShift;
00372 dinfo->b_shift = pfd->cBlueShift;
00373 dinfo->a_shift = pfd->cAlphaShift;
00374
00375
00376
00377
00378 dinfo->sample_buffers = 0;
00379 dinfo->samples = 0;
00380
00381
00382
00383
00384 dinfo->float_color = 0;
00385 dinfo->float_depth = 0;
00386
00387
00388
00389 dinfo->colour_depth = 0;
00390 if (dinfo->pixel_size.rgba.r == 5 && dinfo->pixel_size.rgba.b == 5) {
00391 if (dinfo->pixel_size.rgba.g == 5)
00392 dinfo->colour_depth = 15;
00393 if (dinfo->pixel_size.rgba.g == 6)
00394 dinfo->colour_depth = 16;
00395 }
00396 if (dinfo->pixel_size.rgba.r == 8
00397 && dinfo->pixel_size.rgba.g == 8 && dinfo->pixel_size.rgba.b == 8) {
00398 if (dinfo->pixel_size.rgba.a == 8)
00399 dinfo->colour_depth = 32;
00400 else
00401 dinfo->colour_depth = 24;
00402 }
00403
00404
00405 dinfo->allegro_format = (dinfo->colour_depth != 0)
00406 && (dinfo->g_shift == dinfo->pixel_size.rgba.b)
00407 && (dinfo->r_shift * dinfo->b_shift == 0)
00408 && (dinfo->r_shift + dinfo->b_shift ==
00409 dinfo->pixel_size.rgba.b + dinfo->pixel_size.rgba.g);
00410
00411 return 0;
00412 }
00413
00414
00415
00416
00417
00418
00419 static int decode_pixel_format_attrib(struct allegro_gl_display_info *dinfo,
00420 int num_attribs, const int *attrib, const int *value,
00421 int desktop_depth) {
00422 int i;
00423
00424 TRACE(PREFIX_I "Decoding: \n");
00425
00426 dinfo->samples = 0;
00427 dinfo->sample_buffers = 0;
00428 dinfo->float_depth = 0;
00429 dinfo->float_color = 0;
00430
00431 for (i = 0; i < num_attribs; i++) {
00432
00433
00434
00435
00436 if (attrib[i] == WGL_SUPPORT_OPENGL_ARB && value[i] == 0) {
00437 TRACE(PREFIX_I "OpenGL Unsupported\n");
00438 return -1;
00439 }
00440 else if (attrib[i] == WGL_DRAW_TO_WINDOW_ARB && value[i] == 0) {
00441 TRACE(PREFIX_I "Can't draw to window\n");
00442 return -1;
00443 }
00444 else if (attrib[i] == WGL_PIXEL_TYPE_ARB &&
00445 (value[i] != WGL_TYPE_RGBA_ARB
00446 && value[i] != WGL_TYPE_RGBA_FLOAT_ARB)) {
00447 TRACE(PREFIX_I "Not RGBA mode\n");
00448 return -1;
00449 }
00450
00451 else if (attrib[i] == WGL_COLOR_BITS_ARB) {
00452 if ((value[i] != desktop_depth)
00453 && (value[i] != 32 || desktop_depth < 24)) {
00454 TRACE(PREFIX_I "Current color depth != "
00455 "pixel format color depth\n");
00456
00457 }
00458 }
00459
00460 else if (attrib[i] == WGL_ACCELERATION_ARB) {
00461 dinfo->rmethod = (value[i] == WGL_NO_ACCELERATION_ARB) ? 0 : 1;
00462 }
00463
00464 else if (attrib[i] == WGL_RED_BITS_ARB) {
00465 dinfo->pixel_size.rgba.r = value[i];
00466 }
00467 else if (attrib[i] == WGL_GREEN_BITS_ARB) {
00468 dinfo->pixel_size.rgba.g = value[i];
00469 }
00470 else if (attrib[i] == WGL_BLUE_BITS_ARB) {
00471 dinfo->pixel_size.rgba.b = value[i];
00472 }
00473 else if (attrib[i] == WGL_ALPHA_BITS_ARB) {
00474 dinfo->pixel_size.rgba.a = value[i];
00475 }
00476
00477 else if (attrib[i] == WGL_RED_SHIFT_ARB) {
00478 dinfo->r_shift = value[i];
00479 }
00480 else if (attrib[i] == WGL_GREEN_SHIFT_ARB) {
00481 dinfo->g_shift = value[i];
00482 }
00483 else if (attrib[i] == WGL_BLUE_SHIFT_ARB) {
00484 dinfo->b_shift = value[i];
00485 }
00486 else if (attrib[i] == WGL_ALPHA_SHIFT_ARB) {
00487 dinfo->a_shift = value[i];
00488 }
00489
00490
00491 else if (attrib[i] == WGL_ACCUM_RED_BITS_ARB) {
00492 dinfo->accum_size.rgba.r = value[i];
00493 }
00494 else if (attrib[i] == WGL_ACCUM_GREEN_BITS_ARB) {
00495 dinfo->accum_size.rgba.g = value[i];
00496 }
00497 else if (attrib[i] == WGL_ACCUM_BLUE_BITS_ARB) {
00498 dinfo->accum_size.rgba.b = value[i];
00499 }
00500 else if (attrib[i] == WGL_ACCUM_ALPHA_BITS_ARB) {
00501 dinfo->accum_size.rgba.a = value[i];
00502 }
00503
00504 else if (attrib[i] == WGL_DOUBLE_BUFFER_ARB) {
00505 dinfo->doublebuffered = value[i];
00506 }
00507 else if (attrib[i] == WGL_STEREO_ARB) {
00508 dinfo->stereo = value[i];
00509 }
00510 else if (attrib[i] == WGL_AUX_BUFFERS_ARB) {
00511 dinfo->aux_buffers = value[i];
00512 }
00513 else if (attrib[i] == WGL_DEPTH_BITS_ARB) {
00514 dinfo->depth_size = value[i];
00515 }
00516 else if (attrib[i] == WGL_STENCIL_BITS_ARB) {
00517 dinfo->stencil_size = value[i];
00518 }
00519
00520 else if (attrib[i] == WGL_SAMPLE_BUFFERS_ARB) {
00521 dinfo->sample_buffers = value[i];
00522 }
00523 else if (attrib[i] == WGL_SAMPLES_ARB) {
00524 dinfo->samples = value[i];
00525 }
00526
00527 if (attrib[i] == WGL_PIXEL_TYPE_ARB
00528 && value[i] == WGL_TYPE_RGBA_FLOAT_ARB) {
00529 dinfo->float_color = TRUE;
00530 }
00531
00532 else if (attrib[i] == WGL_DEPTH_FLOAT_EXT) {
00533 dinfo->float_depth = value[i];
00534 }
00535 }
00536
00537
00538
00539 dinfo->colour_depth = 0;
00540 if (dinfo->pixel_size.rgba.r == 5 && dinfo->pixel_size.rgba.b == 5) {
00541 if (dinfo->pixel_size.rgba.g == 5)
00542 dinfo->colour_depth = 15;
00543 if (dinfo->pixel_size.rgba.g == 6)
00544 dinfo->colour_depth = 16;
00545 }
00546 if (dinfo->pixel_size.rgba.r == 8
00547 && dinfo->pixel_size.rgba.g == 8 && dinfo->pixel_size.rgba.b == 8) {
00548 if (dinfo->pixel_size.rgba.a == 8)
00549 dinfo->colour_depth = 32;
00550 else
00551 dinfo->colour_depth = 24;
00552 }
00553
00554 dinfo->allegro_format = (dinfo->colour_depth != 0)
00555 && (dinfo->g_shift == dinfo->pixel_size.rgba.b)
00556 && (dinfo->r_shift * dinfo->b_shift == 0)
00557 && (dinfo->r_shift + dinfo->b_shift ==
00558 dinfo->pixel_size.rgba.b + dinfo->pixel_size.rgba.g);
00559
00560 return 0;
00561 }
00562
00563
00564
00565 typedef struct format_t {
00566 int score;
00567 int format;
00568 } format_t;
00569
00570
00571
00572
00573 static int select_pixel_format_sorter(const void *p0, const void *p1) {
00574 format_t *f0 = (format_t*)p0;
00575 format_t *f1 = (format_t*)p1;
00576
00577 if (f0->score == f1->score) {
00578 return 0;
00579 }
00580 else if (f0->score > f1->score) {
00581 return -1;
00582 }
00583 else {
00584 return 1;
00585 }
00586 }
00587
00588
00589
00590
00591 int describe_pixel_format_old(HDC dc, int fmt, int desktop_depth,
00592 format_t *formats, int *num_formats,
00593 struct allegro_gl_display_info *pdinfo) {
00594
00595 struct allegro_gl_display_info dinfo;
00596 PIXELFORMATDESCRIPTOR pfd;
00597 int score = -1;
00598
00599 int result = DescribePixelFormat(dc, fmt, sizeof(pfd), &pfd);
00600
00601
00602 if (pdinfo) {
00603 dinfo = *pdinfo;
00604 }
00605
00606 if (!result) {
00607 log_win32_warning("describe_pixel_format_old",
00608 "DescribePixelFormat() failed!", GetLastError());
00609 return -1;
00610 }
00611
00612 result = !decode_pixel_format(&pfd, dc, fmt, &dinfo, desktop_depth);
00613
00614 if (result) {
00615 print_pixel_format(&dinfo);
00616 score = __allegro_gl_score_config(fmt, &dinfo);
00617 }
00618
00619 if (score < 0) {
00620 return -1;
00621 }
00622
00623 if (formats && num_formats) {
00624 formats[*num_formats].score = score;
00625 formats[*num_formats].format = fmt;
00626 (*num_formats)++;
00627 }
00628
00629 if (pdinfo) {
00630 *pdinfo = dinfo;
00631 }
00632
00633 return 0;
00634 }
00635
00636
00637
00638 static AGL_GetPixelFormatAttribivARB_t __wglGetPixelFormatAttribivARB = NULL;
00639 static AGL_GetPixelFormatAttribivEXT_t __wglGetPixelFormatAttribivEXT = NULL;
00640
00641
00642
00643
00644 int describe_pixel_format_new(HDC dc, int fmt, int desktop_depth,
00645 format_t *formats, int *num_formats,
00646 struct allegro_gl_display_info *pdinfo) {
00647
00648 struct allegro_gl_display_info dinfo;
00649 int score = -1;
00650
00651
00652
00653
00654 int attrib[] = {
00655 WGL_SUPPORT_OPENGL_ARB,
00656 WGL_DRAW_TO_WINDOW_ARB,
00657 WGL_PIXEL_TYPE_ARB,
00658 WGL_ACCELERATION_ARB,
00659 WGL_DOUBLE_BUFFER_ARB,
00660 WGL_DEPTH_BITS_ARB,
00661 WGL_COLOR_BITS_ARB,
00662 WGL_RED_BITS_ARB,
00663 WGL_GREEN_BITS_ARB,
00664 WGL_BLUE_BITS_ARB,
00665 WGL_ALPHA_BITS_ARB,
00666 WGL_RED_SHIFT_ARB,
00667 WGL_GREEN_SHIFT_ARB,
00668 WGL_BLUE_SHIFT_ARB,
00669 WGL_ALPHA_SHIFT_ARB,
00670 WGL_STENCIL_BITS_ARB,
00671 WGL_STEREO_ARB,
00672 WGL_ACCUM_BITS_ARB,
00673 WGL_ACCUM_RED_BITS_ARB,
00674 WGL_ACCUM_GREEN_BITS_ARB,
00675 WGL_ACCUM_BLUE_BITS_ARB,
00676 WGL_ACCUM_ALPHA_BITS_ARB,
00677 WGL_AUX_BUFFERS_ARB,
00678
00679
00680
00681
00682
00683
00684
00685 WGL_AUX_BUFFERS_ARB,
00686 WGL_AUX_BUFFERS_ARB,
00687 WGL_AUX_BUFFERS_ARB,
00688 };
00689
00690 const int num_attribs = sizeof(attrib) / sizeof(attrib[0]);
00691 int *value = (int*)malloc(sizeof(int) * num_attribs);
00692 int result;
00693 BOOL ret;
00694 int old_valid = __allegro_gl_valid_context;
00695
00696
00697 if (!value) {
00698 TRACE(PREFIX_E "describe_pixel_format_new(): Unable to allocate "
00699 "memory for pixel format descriptor!\n");
00700 return -1;
00701 }
00702
00703
00704 if (pdinfo) {
00705 dinfo = *pdinfo;
00706 }
00707
00708
00709
00710
00711
00712
00713 __allegro_gl_valid_context = 1;
00714 if (allegro_gl_is_extension_supported("WGL_ARB_multisample")) {
00715 attrib[num_attribs - 3] = WGL_SAMPLE_BUFFERS_ARB;
00716 attrib[num_attribs - 2] = WGL_SAMPLES_ARB;
00717 }
00718 if (allegro_gl_is_extension_supported("WGL_EXT_depth_float")) {
00719 attrib[num_attribs - 1] = WGL_DEPTH_FLOAT_EXT;
00720 }
00721 __allegro_gl_valid_context = old_valid;
00722
00723
00724
00725 if (__wglGetPixelFormatAttribivARB) {
00726 ret = __wglGetPixelFormatAttribivARB(dc, fmt, 0, num_attribs,
00727 attrib, value);
00728 }
00729 else if (__wglGetPixelFormatAttribivEXT) {
00730 ret = __wglGetPixelFormatAttribivEXT(dc, fmt, 0, num_attribs,
00731 attrib, value);
00732 }
00733 else {
00734 ret = 0;
00735 }
00736
00737
00738 if (!ret) {
00739 log_win32_error("describe_pixel_format_new",
00740 "wglGetPixelFormatAttrib failed!", GetLastError());
00741 free(value);
00742 return -1;
00743 }
00744
00745
00746 result = !decode_pixel_format_attrib(&dinfo, num_attribs, attrib, value,
00747 desktop_depth);
00748 free(value);
00749
00750 if (result) {
00751 print_pixel_format(&dinfo);
00752 score = __allegro_gl_score_config(fmt, &dinfo);
00753 }
00754
00755 if (score < 0) {
00756 return 0;
00757 }
00758
00759 if (formats && num_formats) {
00760 formats[*num_formats].score = score;
00761 formats[*num_formats].format = fmt;
00762 (*num_formats)++;
00763 }
00764
00765 if (pdinfo) {
00766 *pdinfo = dinfo;
00767 }
00768
00769 return 0;
00770 }
00771
00772
00773
00774
00775 int get_num_pixel_formats(HDC dc, int *new_pf_code) {
00776
00777
00778
00779
00780 if (new_pf_code && *new_pf_code) {
00781 int attrib[1];
00782 int value[1];
00783
00784 TRACE(PREFIX_I "get_num_pixel_formats(): Attempting to use WGL_pf.\n");
00785 attrib[0] = WGL_NUMBER_PIXEL_FORMATS_ARB;
00786 if ((__wglGetPixelFormatAttribivARB
00787 && __wglGetPixelFormatAttribivARB(dc, 0, 0, 1, attrib, value)
00788 == GL_FALSE)
00789 || (__wglGetPixelFormatAttribivEXT
00790 && __wglGetPixelFormatAttribivEXT(dc, 0, 0, 1, attrib, value)
00791 == GL_FALSE)) {
00792 log_win32_note("get_num_pixel_formats",
00793 "WGL_ARB/EXT_pixel_format use failed!", GetLastError());
00794 *new_pf_code = 0;
00795 }
00796 else {
00797 return value[0];
00798 }
00799 }
00800
00801 if (!new_pf_code || !*new_pf_code) {
00802 PIXELFORMATDESCRIPTOR pfd;
00803 int ret;
00804
00805 TRACE(PREFIX_I "get_num_pixel_formats(): Using DescribePixelFormat.\n");
00806 ret = DescribePixelFormat(dc, 1, sizeof(pfd), &pfd);
00807
00808 if (!ret) {
00809 log_win32_error("get_num_pixel_formats",
00810 "DescribePixelFormat failed!", GetLastError());
00811 }
00812
00813 return ret;
00814 }
00815
00816 return 0;
00817 }
00818
00819
00820
00821
00822 static int select_pixel_format(PIXELFORMATDESCRIPTOR * pfd)
00823 {
00824 int i;
00825 int result, maxindex;
00826 int desktop_depth;
00827
00828 HWND testwnd = NULL;
00829 HDC testdc = NULL;
00830 HGLRC testrc = NULL;
00831
00832 format_t *format = NULL;
00833 int num_formats = 0;
00834 int new_pf_code = 0;
00835
00836
00837 __allegro_gl_reset_scorer();
00838
00839
00840 desktop_depth = desktop_color_depth();
00841
00842 if (register_test_window() < 0) {
00843 return 0;
00844 }
00845
00846 testwnd = create_test_window();
00847
00848 if (!testwnd) {
00849 return 0;
00850 }
00851
00852 testdc = GetDC(testwnd);
00853
00854
00855 TRACE(PREFIX_I "select_pixel_format(): Trying to set up temporary RC\n");
00856 {
00857 HDC old_dc = __allegro_gl_hdc;
00858 int old_valid = __allegro_gl_valid_context;
00859 PIXELFORMATDESCRIPTOR pfd;
00860 int pf;
00861
00862 new_pf_code = 0;
00863
00864
00865
00866
00867 memset(&pfd, 0, sizeof(pfd));
00868 pfd.nSize = sizeof(pfd);
00869 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
00870 | PFD_DOUBLEBUFFER_DONTCARE | PFD_STEREO_DONTCARE;
00871 pfd.iPixelType = PFD_TYPE_RGBA;
00872 pfd.iLayerType = PFD_MAIN_PLANE;
00873 pfd.cColorBits = 32;
00874
00875 TRACE(PREFIX_I "select_pixel_format(): ChoosePixelFormat()\n");
00876 pf = ChoosePixelFormat(testdc, &pfd);
00877
00878 if (!pf) {
00879 log_win32_warning("select_pixel_format",
00880 "Unable to chose a temporary pixel format!",
00881 GetLastError());
00882 goto fail_pf;
00883 }
00884
00885
00886 TRACE(PREFIX_I "select_pixel_format(): SetPixelFormat()\n");
00887 memset(&pfd, 0, sizeof(pfd));
00888 if (!SetPixelFormat(testdc, pf, &pfd)) {
00889 log_win32_warning("select_pixel_format",
00890 "Unable to set a temporary pixel format!",
00891 GetLastError());
00892 goto fail_pf;
00893 }
00894
00895 TRACE(PREFIX_I "select_pixel_format(): CreateContext()\n");
00896 testrc = wglCreateContext(testdc);
00897
00898 if (!testrc) {
00899 log_win32_warning("select_pixel_format",
00900 "Unable to create a render context!",
00901 GetLastError());
00902 goto fail_pf;
00903 }
00904
00905 TRACE(PREFIX_I "select_pixel_format(): MakeCurrent()\n");
00906 if (!wglMakeCurrent(testdc, testrc)) {
00907 log_win32_warning("select_pixel_format",
00908 "Unable to set the render context as current!",
00909 GetLastError());
00910 goto fail_pf;
00911 }
00912
00913 __allegro_gl_hdc = testdc;
00914 __allegro_gl_valid_context = TRUE;
00915
00916
00917
00918
00919
00920 TRACE(PREFIX_I "select_pixel_format(): GetExtensionsStringARB()\n");
00921 if (strstr(glGetString(GL_VENDOR), "NVIDIA")) {
00922 AGL_GetExtensionsStringARB_t __wglGetExtensionsStringARB = NULL;
00923
00924 __wglGetExtensionsStringARB = (AGL_GetExtensionsStringARB_t)
00925 wglGetProcAddress("wglGetExtensionsStringARB");
00926
00927 TRACE(PREFIX_I "select_pixel_format(): Querying for "
00928 "WGL_ARB_extension_string\n");
00929
00930 if (__wglGetExtensionsStringARB) {
00931 TRACE(PREFIX_I "select_pixel_format(): Calling "
00932 "__wglGetExtensionsStringARB\n");
00933 __wglGetExtensionsStringARB(testdc);
00934 }
00935 }
00936
00937
00938
00939 if (!allegro_gl_is_extension_supported("WGL_ARB_pixel_format")
00940 && !allegro_gl_is_extension_supported("WGL_EXT_pixel_format")) {
00941 TRACE(PREFIX_I "select_pixel_format(): WGL_ARB/EXT_pf unsupported.\n");
00942 goto fail_pf;
00943 }
00944
00945
00946
00947
00948 TRACE(PREFIX_I "select_pixel_format(): GetProcAddress()\n");
00949 __wglGetPixelFormatAttribivARB = (AGL_GetPixelFormatAttribivARB_t)
00950 wglGetProcAddress("wglGetPixelFormatAttribivARB");
00951 __wglGetPixelFormatAttribivEXT = (AGL_GetPixelFormatAttribivEXT_t)
00952 wglGetProcAddress("wglGetPixelFormatAttribivEXT");
00953
00954 if (!__wglGetPixelFormatAttribivARB
00955 && !__wglGetPixelFormatAttribivEXT) {
00956 TRACE(PREFIX_E "select_pixel_format(): WGL_ARB/EXT_pf not "
00957 "correctly supported!\n");
00958 goto fail_pf;
00959 }
00960
00961 new_pf_code = 1;
00962 goto exit_pf;
00963
00964 fail_pf:
00965 wglMakeCurrent(NULL, NULL);
00966 if (testrc) {
00967 wglDeleteContext(testrc);
00968 }
00969 testrc = NULL;
00970
00971 __wglGetPixelFormatAttribivARB = NULL;
00972 __wglGetPixelFormatAttribivEXT = NULL;
00973 exit_pf:
00974 __allegro_gl_hdc = old_dc;
00975 __allegro_gl_valid_context = old_valid;
00976 }
00977
00978 maxindex = get_num_pixel_formats(testdc, &new_pf_code);
00979
00980
00981
00982
00983 if (!new_pf_code && testrc) {
00984 TRACE(PREFIX_W "select_pixel_format(): WGL_ARB_pf call failed - "
00985 "reverted to plain old WGL.\n");
00986 wglMakeCurrent(NULL, NULL);
00987 wglDeleteContext(testrc);
00988 testrc = NULL;
00989 __wglGetPixelFormatAttribivARB = NULL;
00990 __wglGetPixelFormatAttribivEXT = NULL;
00991 }
00992
00993 TRACE(PREFIX_I "select_pixel_format(): %i formats.\n", maxindex);
00994
00995 if (maxindex < 1) {
00996 TRACE(PREFIX_E "select_pixel_format(): Didn't find any pixel "
00997 "formats at all!\n");
00998 goto bail;
00999 }
01000
01001 format = malloc((maxindex + 1) * sizeof(format_t));
01002
01003 if (!format) {
01004 TRACE(PREFIX_E "select_pixel_format(): Unable to allocate memory for "
01005 "pixel format scores!\n");
01006 goto bail;
01007 }
01008
01009
01010 TRACE(PREFIX_I "select_pixel_format(): Testing pixel formats:\n");
01011 for (i = 1; i <= maxindex; i++) {
01012
01013 int use_old = !new_pf_code;
01014
01015 TRACE(PREFIX_I "Format %i:\n", i);
01016
01017 if (new_pf_code) {
01018 if (describe_pixel_format_new(testdc, i, desktop_depth,
01019 format, &num_formats, NULL) < 0) {
01020 TRACE(PREFIX_W "select_pixel_format(): Wasn't able to use "
01021 "WGL_PixelFormat - reverting to old WGL code.\n");
01022 use_old = 1;
01023 }
01024 }
01025
01026 if (use_old) {
01027 if (describe_pixel_format_old(testdc, i, desktop_depth,
01028 format, &num_formats, NULL) < 0) {
01029 TRACE(PREFIX_W "select_pixel_format(): Unable to rely on "
01030 "unextended WGL to describe this pixelformat.\n");
01031 }
01032 }
01033 }
01034
01035 if (new_pf_code) {
01036 wglMakeCurrent(NULL, NULL);
01037 wglDeleteContext(testrc);
01038 testrc = NULL;
01039 }
01040 if (testwnd) {
01041 ReleaseDC(testwnd, testdc);
01042 testdc = NULL;
01043 DestroyWindow(testwnd);
01044 testwnd = NULL;
01045 }
01046
01047 if (num_formats < 1) {
01048 TRACE(PREFIX_E "select_pixel_format(): Didn't find any available "
01049 "pixel formats!\n");
01050 goto bail;
01051 }
01052
01053 qsort(format, num_formats, sizeof(format_t), select_pixel_format_sorter);
01054
01055
01056
01057
01058 for (i = 0; i < num_formats ; i++) {
01059 HGLRC rc;
01060
01061
01062 testwnd = create_test_window();
01063 testdc = GetDC(testwnd);
01064
01065 if (SetPixelFormat(testdc, format[i].format, pfd)) {
01066 rc = wglCreateContext(testdc);
01067 if (!rc) {
01068 TRACE(PREFIX_I "select_pixel_format(): Unable to create RC!\n");
01069 }
01070 else {
01071 if (wglMakeCurrent(testdc, rc)) {
01072 wglMakeCurrent(NULL, NULL);
01073 wglDeleteContext(rc);
01074 rc = NULL;
01075
01076 TRACE(PREFIX_I "select_pixel_format(): Best config is: %i"
01077 "\n", format[i].format);
01078
01079
01080
01081
01082 if (!DescribePixelFormat(testdc, format[i].format,
01083 sizeof *pfd, pfd)) {
01084 TRACE(PREFIX_E "Cannot describe this pixel format\n");
01085 ReleaseDC(testwnd, testdc);
01086 DestroyWindow(testwnd);
01087 testdc = NULL;
01088 testwnd = NULL;
01089 continue;
01090 }
01091
01092 ReleaseDC(testwnd, testdc);
01093 DestroyWindow(testwnd);
01094
01095 result = format[i].format;
01096
01097 free(format);
01098 return result;
01099 }
01100 else {
01101 wglMakeCurrent(NULL, NULL);
01102 wglDeleteContext(rc);
01103 rc = NULL;
01104 log_win32_warning("select_pixel_format",
01105 "Couldn't make the temporary render context "
01106 "current for the this pixel format.",
01107 GetLastError());
01108 }
01109 }
01110 }
01111 else {
01112 log_win32_note("select_pixel_format",
01113 "Unable to set pixel format!", GetLastError());
01114 }
01115
01116 ReleaseDC(testwnd, testdc);
01117 DestroyWindow(testwnd);
01118 testdc = NULL;
01119 testwnd = NULL;
01120 }
01121
01122 TRACE(PREFIX_E "select_pixel_format(): All modes have failed...\n");
01123 bail:
01124 if (format) {
01125 free(format);
01126 }
01127 if (new_pf_code) {
01128 wglMakeCurrent(NULL, NULL);
01129 if (testrc) {
01130 wglDeleteContext(testrc);
01131 }
01132 }
01133 if (testwnd) {
01134 ReleaseDC(testwnd, testdc);
01135 DestroyWindow(testwnd);
01136 }
01137
01138 return 0;
01139 }
01140
01141
01142
01143 static void allegrogl_init_window(int w, int h, DWORD style, DWORD exstyle)
01144 {
01145 RECT rect;
01146
01147 #define req __allegro_gl_required_settings
01148 #define sug __allegro_gl_suggested_settings
01149
01150 int x = 32, y = 32;
01151
01152 if (req & AGL_WINDOW_X || sug & AGL_WINDOW_X)
01153 x = allegro_gl_display_info.x;
01154 if (req & AGL_WINDOW_Y || sug & AGL_WINDOW_Y)
01155 y = allegro_gl_display_info.y;
01156
01157 #undef req
01158 #undef sug
01159
01160 if (!fullscreen) {
01161 rect.left = x;
01162 rect.right = x + w;
01163 rect.top = y;
01164 rect.bottom = y + h;
01165 }
01166 else {
01167 rect.left = 0;
01168 rect.right = w;
01169 rect.top = 0;
01170 rect.bottom = h;
01171 }
01172
01173
01174 style_saved = GetWindowLong(wnd, GWL_STYLE);
01175 exstyle_saved = GetWindowLong(wnd, GWL_EXSTYLE);
01176
01177
01178 SetWindowLong(wnd, GWL_STYLE, style);
01179 SetWindowLong(wnd, GWL_EXSTYLE, exstyle);
01180
01181 if (!fullscreen) {
01182 AdjustWindowRectEx(&rect, style, FALSE, exstyle);
01183 }
01184
01185
01186 SetWindowPos(wnd, 0, rect.left, rect.top,
01187 rect.right - rect.left, rect.bottom - rect.top,
01188 SWP_NOZORDER | SWP_FRAMECHANGED);
01189
01190 return;
01191 }
01192
01193
01194
01195 static BITMAP *allegro_gl_create_screen (GFX_DRIVER *drv, int w, int h,
01196 int depth)
01197 {
01198 BITMAP *bmp;
01199 int is_linear = drv->linear;
01200
01201 drv->linear = 1;
01202 bmp = _make_bitmap (w, h, 0, drv, depth, 0);
01203
01204 if (!bmp) {
01205 return NULL;
01206 }
01207
01208 bmp->id = BMP_ID_VIDEO | 1000;
01209 drv->linear = is_linear;
01210
01211 drv->w = w;
01212 drv->h = h;
01213
01214 return bmp;
01215 }
01216
01217
01218 static LRESULT CALLBACK dummy_wnd_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
01219 {
01220 return DefWindowProc(wnd, message, wparam, lparam);
01221 }
01222
01223 static HWND dummy_wnd;
01224
01225 static void dummy_window(void)
01226 {
01227 WNDCLASS wnd_class;
01228
01229 wnd_class.style = CS_HREDRAW | CS_VREDRAW;
01230 wnd_class.lpfnWndProc = dummy_wnd_proc;
01231 wnd_class.cbClsExtra = 0;
01232 wnd_class.cbWndExtra = 0;
01233 wnd_class.hInstance = GetModuleHandle(NULL);
01234 wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
01235 wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
01236 wnd_class.hbrBackground = NULL;
01237 wnd_class.lpszMenuName = NULL;
01238 wnd_class.lpszClassName = "allegro focus";
01239
01240 RegisterClass(&wnd_class);
01241
01242 dummy_wnd = CreateWindow("allegro focus", "Allegro", WS_POPUP | WS_VISIBLE,
01243 0, 0, 200, 200,
01244 NULL, NULL, GetModuleHandle(NULL), NULL);
01245
01246 ShowWindow(dummy_wnd, SW_SHOWNORMAL);
01247 SetForegroundWindow(dummy_wnd);
01248 }
01249
01250 static void remove_dummy_window(void)
01251 {
01252 DestroyWindow(dummy_wnd);
01253 UnregisterClass("allegro focus", GetModuleHandle(NULL));
01254 }
01255
01256
01257 static BITMAP *allegro_gl_win_init(int w, int h, int v_w, int v_h)
01258 {
01259 static int first_time = 1;
01260
01261 DWORD style=0, exstyle=0;
01262 int refresh_rate = _refresh_rate_request;
01263 int desktop_depth;
01264 int pf=0;
01265
01266 new_w = w;
01267 new_h = h;
01268
01269
01270 if ((v_w != 0 && v_w != w) || (v_h != 0 && v_h != h)) {
01271 TRACE(PREFIX_E "win_init(): Virtual screens are not supported in "
01272 "AllegroGL!\n");
01273 return NULL;
01274 }
01275
01276
01277 __allegro_gl_fill_in_info();
01278
01279
01280
01281
01282 desktop_depth = desktop_color_depth();
01283
01284 if (desktop_depth < 15)
01285 return NULL;
01286
01287 TRACE(PREFIX_I "win_init(): Requested color depth: %i "
01288 "Desktop color depth: %i\n", allegro_gl_display_info.colour_depth,
01289 desktop_depth);
01290
01291
01292
01293
01294
01295
01296 if (fullscreen) dummy_window();
01297
01298
01299
01300
01301 if (fullscreen) {
01302 gfx_allegro_gl_fullscreen.w = w;
01303 gfx_allegro_gl_fullscreen.h = h;
01304 }
01305 else {
01306 gfx_allegro_gl_windowed.w = w;
01307 gfx_allegro_gl_windowed.h = h;
01308 }
01309
01310
01311
01312
01313
01314
01315 if (!first_time) {
01316 win_set_window(NULL);
01317 }
01318 first_time = 0;
01319
01320
01321 wnd = win_get_window();
01322 if (!wnd)
01323 return NULL;
01324
01325
01326 if (fullscreen) {
01327 style = WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
01328 exstyle = WS_EX_APPWINDOW | WS_EX_TOPMOST;
01329 }
01330 else {
01331 style = WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX | WS_CLIPCHILDREN
01332 | WS_CLIPSIBLINGS;
01333 exstyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
01334 }
01335
01336 TRACE(PREFIX_I "win_init(): Setting up window.\n");
01337 allegrogl_init_window(w, h, style, exstyle);
01338
01339 __allegro_gl_hdc = GetDC(wnd);
01340 if (!__allegro_gl_hdc) {
01341 goto Error;
01342 }
01343
01344 TRACE(PREFIX_I "win_init(): Driver selected fullscreen: %s\n",
01345 fullscreen ? "Yes" : "No");
01346
01347 if (fullscreen)
01348 {
01349 DEVMODE dm;
01350 DEVMODE fallback_dm;
01351 int fallback_dm_valid = 0;
01352
01353 int bpp_to_check[] = {16, 32, 24, 15, 0};
01354 int bpp_checked[] = {0, 0, 0, 0, 0};
01355 int bpp_index = 0;
01356 int i, j, result, modeswitch, done = 0;
01357
01358 for (j = 0; j < 4; j++)
01359 {
01360 if (bpp_to_check[j] == allegro_gl_get(AGL_COLOR_DEPTH))
01361 {
01362 bpp_index = j;
01363 break;
01364 }
01365 }
01366
01367 dm.dmSize = sizeof(DEVMODE);
01368 dm_saved.dmSize = sizeof(DEVMODE);
01369
01370
01371 EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm_saved);
01372 dm.dmBitsPerPel = desktop_depth;
01373
01374 do
01375 {
01376 if (!bpp_to_check[bpp_index])
01377 {
01378 TRACE(PREFIX_E "win_init(): No more color depths to test.\n"
01379 "\tUnable to find appropriate full screen mode and pixel "
01380 "format.\n");
01381 goto Error;
01382 }
01383
01384 TRACE(PREFIX_I "win_init(): Testing color depth: %i\n",
01385 bpp_to_check[bpp_index]);
01386
01387 memset(&dm, 0, sizeof(DEVMODE));
01388 dm.dmSize = sizeof(DEVMODE);
01389
01390 i = 0;
01391 do
01392 {
01393 modeswitch = EnumDisplaySettings(NULL, i, &dm);
01394 if (!modeswitch)
01395 break;
01396
01397 if ((dm.dmPelsWidth == (unsigned) w)
01398 && (dm.dmPelsHeight == (unsigned) h)
01399 && (dm.dmBitsPerPel == (unsigned) bpp_to_check[bpp_index])
01400 && (dm.dmDisplayFrequency != (unsigned) refresh_rate)) {
01401
01402
01403
01404
01405
01406 if (!fallback_dm_valid) {
01407 fallback_dm = dm;
01408 fallback_dm_valid = 1;
01409 }
01410 else if (dm.dmDisplayFrequency >= 60) {
01411 if (dm.dmDisplayFrequency < fallback_dm.dmDisplayFrequency) {
01412 fallback_dm = dm;
01413 }
01414 }
01415 }
01416
01417 i++;
01418 }
01419 while ((dm.dmPelsWidth != (unsigned) w)
01420 || (dm.dmPelsHeight != (unsigned) h)
01421 || (dm.dmBitsPerPel != (unsigned) bpp_to_check[bpp_index])
01422 || (dm.dmDisplayFrequency != (unsigned) refresh_rate));
01423
01424 if (!modeswitch && !fallback_dm_valid) {
01425 TRACE(PREFIX_I "win_init(): Unable to set mode, continuing "
01426 "with next color depth\n");
01427 }
01428 else {
01429 if (!modeswitch && fallback_dm_valid)
01430 dm = fallback_dm;
01431
01432 TRACE(PREFIX_I "win_init(): bpp_to_check[bpp_index] = %i\n",
01433 bpp_to_check[bpp_index]);
01434 TRACE(PREFIX_I "win_init(): dm.dmBitsPerPel = %i\n",
01435 (int)dm.dmBitsPerPel);
01436
01437 dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL
01438 | DM_DISPLAYFREQUENCY;
01439
01440 result = ChangeDisplaySettings(&dm, CDS_FULLSCREEN);
01441
01442 if (result == DISP_CHANGE_SUCCESSFUL)
01443 {
01444 TRACE(PREFIX_I "win_init(): Setting pixel format.\n");
01445 pf = select_pixel_format(&pfd);
01446 if (pf) {
01447 TRACE(PREFIX_I "mode found\n");
01448 _set_current_refresh_rate(dm.dmDisplayFrequency);
01449 done = 1;
01450 }
01451 else {
01452 TRACE(PREFIX_I "win_init(): Couldn't find compatible "
01453 "GL context. Trying another screen mode.\n");
01454 }
01455 }
01456 }
01457
01458 fallback_dm_valid = 0;
01459 bpp_checked[bpp_index] = 1;
01460
01461 bpp_index = 0;
01462 while (bpp_checked[bpp_index]) {
01463 bpp_index++;
01464 }
01465 } while (!done);
01466 }
01467 else {
01468 DEVMODE dm;
01469
01470 memset(&dm, 0, sizeof(DEVMODE));
01471 dm.dmSize = sizeof(DEVMODE);
01472 if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) != 0) {
01473 _set_current_refresh_rate(dm.dmDisplayFrequency);
01474 }
01475 }
01476
01477 if (!fullscreen) {
01478 TRACE(PREFIX_I "win_init(): Setting pixel format.\n");
01479 pf = select_pixel_format(&pfd);
01480 if (pf == 0)
01481 goto Error;
01482 }
01483
01484
01485 if (!SetPixelFormat(__allegro_gl_hdc, pf, &pfd)) {
01486 log_win32_error("win_init",
01487 "Unable to set pixel format.",
01488 GetLastError());
01489 goto Error;
01490 }
01491
01492
01493 allegro_glrc = wglCreateContext(__allegro_gl_hdc);
01494
01495 if (!allegro_glrc) {
01496 log_win32_error("win_init",
01497 "Unable to create a render context!",
01498 GetLastError());
01499 goto Error;
01500 }
01501 if (!wglMakeCurrent(__allegro_gl_hdc, allegro_glrc)) {
01502 log_win32_error("win_init",
01503 "Unable to make the context current!",
01504 GetLastError());
01505 goto Error;
01506 }
01507
01508
01509 if (__wglGetPixelFormatAttribivARB || __wglGetPixelFormatAttribivEXT) {
01510 describe_pixel_format_new(__allegro_gl_hdc, pf, desktop_depth,
01511 NULL, NULL, &allegro_gl_display_info);
01512 }
01513 else {
01514 describe_pixel_format_old(__allegro_gl_hdc, pf, desktop_depth,
01515 NULL, NULL, &allegro_gl_display_info);
01516 }
01517
01518
01519 __allegro_gl_set_allegro_image_format(FALSE);
01520 set_color_depth(allegro_gl_display_info.colour_depth);
01521 allegro_gl_display_info.w = w;
01522 allegro_gl_display_info.h = h;
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535 {
01536 DWORD lock_time;
01537
01538 #define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000
01539 #define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001
01540 if (fullscreen) {
01541 SystemParametersInfo(SPI_GETFOREGROUNDLOCKTIMEOUT,
01542 0, (LPVOID)&lock_time, 0);
01543 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,
01544 0, (LPVOID)0,
01545 SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
01546 }
01547
01548 ShowWindow(wnd, SW_SHOWNORMAL);
01549 SetForegroundWindow(wnd);
01550
01551
01552
01553
01554 while (GetForegroundWindow() != wnd) {
01555 rest(100);
01556 SetForegroundWindow(wnd);
01557 }
01558 UpdateWindow(wnd);
01559
01560 if (fullscreen) {
01561 SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT,
01562 0, (LPVOID)lock_time,
01563 SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE);
01564 }
01565 #undef SPI_GETFOREGROUNDLOCKTIMEOUT
01566 #undef SPI_SETFOREGROUNDLOCKTIMEOUT
01567 }
01568
01569 win_grab_input();
01570
01571 if (fullscreen) {
01572 allegro_gl_screen= allegro_gl_create_screen(&gfx_allegro_gl_fullscreen,
01573 w, h, allegro_gl_get(AGL_COLOR_DEPTH));
01574 }
01575 else {
01576 allegro_gl_screen= allegro_gl_create_screen(&gfx_allegro_gl_windowed,
01577 w, h, allegro_gl_get(AGL_COLOR_DEPTH));
01578 }
01579
01580 if (!allegro_gl_screen) {
01581 ChangeDisplaySettings(NULL, 0);
01582 goto Error;
01583 }
01584
01585
01586 TRACE(PREFIX_I "win_init(): GLScreen: %ix%ix%i\n",
01587 w, h, allegro_gl_get(AGL_COLOR_DEPTH));
01588
01589 allegro_gl_screen->id |= BMP_ID_VIDEO | BMP_ID_MASK;
01590
01591 __allegro_gl_valid_context = TRUE;
01592 __allegro_gl_driver = &allegro_gl_win;
01593 initialized = 1;
01594
01595
01596 TRACE(PREFIX_I "OpenGL Version: %s\n", (AL_CONST char*)glGetString(GL_VERSION));
01597 TRACE(PREFIX_I "Vendor: %s\n", (AL_CONST char*)glGetString(GL_VENDOR));
01598 TRACE(PREFIX_I "Renderer: %s\n\n", (AL_CONST char*)glGetString(GL_RENDERER));
01599
01600
01601 allegro_gl_info.is_mesa_driver = FALSE;
01602 if (strstr((AL_CONST char*)glGetString(GL_VERSION),"Mesa")) {
01603 AGL_LOG(1, "OpenGL driver based on Mesa\n");
01604 allegro_gl_info.is_mesa_driver = TRUE;
01605 }
01606
01607
01608 __allegro_gl_manage_extensions();
01609
01610
01611 __allegro_gl__glvtable_update_vtable(&allegro_gl_screen->vtable);
01612 memcpy(&_screen_vtable, allegro_gl_screen->vtable, sizeof(GFX_VTABLE));
01613 allegro_gl_screen->vtable = &_screen_vtable;
01614
01615
01616 if (wglGetExtensionsStringARB) {
01617 AGL_LOG(1, "WGL Extensions :\n");
01618 #if LOGLEVEL >= 1
01619 __allegro_gl_print_extensions((AL_CONST char*)wglGetExtensionsStringARB(wglGetCurrentDC()));
01620 #endif
01621 }
01622 else {
01623 TRACE(PREFIX_I "win_init(): No WGL Extensions available\n");
01624 }
01625
01626 gfx_capabilities |= GFX_HW_CURSOR;
01627
01628
01629
01630
01631 glViewport(0, 0, SCREEN_W, SCREEN_H);
01632 glMatrixMode(GL_PROJECTION);
01633 glLoadIdentity();
01634 glMatrixMode(GL_MODELVIEW);
01635 glLoadIdentity();
01636
01637 if (allegro_gl_extensions_GL.ARB_multisample) {
01638
01639
01640 if (allegro_gl_opengl_version() >= 1.3)
01641 glSampleCoverage(1.0, GL_FALSE);
01642 else
01643 glSampleCoverageARB(1.0, GL_FALSE);
01644 }
01645
01646
01647 glBindTexture(GL_TEXTURE_2D, 0);
01648
01649 screen = allegro_gl_screen;
01650
01651 if (fullscreen)
01652 remove_dummy_window();
01653
01654 return allegro_gl_screen;
01655
01656 Error:
01657 if (allegro_glrc) {
01658 wglDeleteContext(allegro_glrc);
01659 }
01660 if (__allegro_gl_hdc) {
01661 ReleaseDC(wnd, __allegro_gl_hdc);
01662 }
01663 __allegro_gl_hdc = NULL;
01664 ChangeDisplaySettings(NULL, 0);
01665 allegro_gl_win_exit(NULL);
01666
01667 return NULL;
01668 }
01669
01670
01671
01672 static BITMAP *allegro_gl_win_init_windowed(int w, int h, int v_w, int v_h,
01673 int color_depth)
01674 {
01675 fullscreen = 0;
01676 return allegro_gl_win_init(w, h, v_w, v_h);
01677 }
01678
01679
01680
01681 static BITMAP *allegro_gl_win_init_fullscreen(int w, int h, int v_w, int v_h,
01682 int color_depth)
01683 {
01684 fullscreen = 1;
01685 return allegro_gl_win_init(w, h, v_w, v_h);
01686 }
01687
01688
01689
01690 static void allegro_gl_win_exit(struct BITMAP *b)
01691 {
01692
01693
01694
01695
01696 __allegro_gl_unmanage_extensions();
01697
01698 if (allegro_glrc) {
01699 wglDeleteContext(allegro_glrc);
01700 allegro_glrc = NULL;
01701 }
01702
01703 if (__allegro_gl_hdc) {
01704 ReleaseDC(wnd, __allegro_gl_hdc);
01705 __allegro_gl_hdc = NULL;
01706 }
01707
01708 if (fullscreen && initialized) {
01709
01710 ChangeDisplaySettings(NULL, 0);
01711 _set_current_refresh_rate(0);
01712 }
01713 initialized = 0;
01714
01715
01716
01717
01718
01719 allegro_gl_screen = NULL;
01720
01721
01722 system_driver->restore_console_state();
01723
01724
01725 SetWindowLong(wnd, GWL_STYLE, style_saved);
01726 SetWindowLong(wnd, GWL_EXSTYLE, exstyle_saved);
01727 SetWindowPos(wnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER
01728 | SWP_FRAMECHANGED);
01729
01730 __allegro_gl_valid_context = FALSE;
01731
01732 return;
01733 }
01734
01735
01736
01737
01738
01739 static int is_mode_entry_unique(GFX_MODE_LIST *mode_list, DEVMODE *dm) {
01740 int i;
01741
01742 for (i = 0; i < mode_list->num_modes; ++i) {
01743 if (mode_list->mode[i].width == (int)dm->dmPelsWidth
01744 && mode_list->mode[i].height == (int)dm->dmPelsHeight
01745 && mode_list->mode[i].bpp == (int)dm->dmBitsPerPel)
01746 return FALSE;
01747 }
01748
01749 return TRUE;
01750 }
01751
01752
01753
01754
01755 static GFX_MODE_LIST* allegro_gl_win_fetch_mode_list(void)
01756 {
01757 int c, modes_count;
01758 GFX_MODE_LIST *mode_list;
01759 DEVMODE dm;
01760
01761 dm.dmSize = sizeof(DEVMODE);
01762
01763
01764 mode_list = malloc(sizeof(GFX_MODE_LIST));
01765 if (!mode_list) {
01766 return NULL;
01767 }
01768
01769
01770
01771
01772 mode_list->mode = malloc(sizeof(GFX_MODE));
01773 if (!mode_list->mode) {
01774 free(mode_list);
01775 return NULL;
01776 }
01777 mode_list->mode[0].width = 0;
01778 mode_list->mode[0].height = 0;
01779 mode_list->mode[0].bpp = 0;
01780 mode_list->num_modes = 0;
01781
01782 modes_count = 0;
01783 c = 0;
01784 while (EnumDisplaySettings(NULL, c, &dm)) {
01785 mode_list->mode = realloc(mode_list->mode,
01786 sizeof(GFX_MODE) * (modes_count + 2));
01787 if (!mode_list->mode) {
01788 free(mode_list);
01789 return NULL;
01790 }
01791
01792
01793
01794
01795 if (dm.dmBitsPerPel > 8 && is_mode_entry_unique(mode_list, &dm)) {
01796 mode_list->mode[modes_count].width = dm.dmPelsWidth;
01797 mode_list->mode[modes_count].height = dm.dmPelsHeight;
01798 mode_list->mode[modes_count].bpp = dm.dmBitsPerPel;
01799 ++modes_count;
01800 mode_list->mode[modes_count].width = 0;
01801 mode_list->mode[modes_count].height = 0;
01802 mode_list->mode[modes_count].bpp = 0;
01803 mode_list->num_modes = modes_count;
01804 }
01805 ++c;
01806 };
01807
01808 return mode_list;
01809 }
01810
01811
01812
01813
01814
01815
01816 static void flip(void)
01817 {
01818 SwapBuffers(__allegro_gl_hdc);
01819 }
01820
01821
01822
01823 static void gl_on(void)
01824 {
01825 return;
01826 }
01827
01828
01829
01830 static void gl_off(void)
01831 {
01832 return;
01833 }
01834
01835
01836
01837
01838
01839 static struct allegro_gl_driver allegro_gl_win = {
01840 flip, gl_on, gl_off, NULL
01841 };
01842