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