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