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