00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <windows.h>
00029
00030 #include "pipe/p_compiler.h"
00031 #include "util/u_memory.h"
00032 #include "stw_pixelformat.h"
00033 #include "stw_wgl_arbmultisample.h"
00034 #include "stw_wgl_arbpixelformat.h"
00035
00036 #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
00037 #define WGL_DRAW_TO_WINDOW_ARB 0x2001
00038 #define WGL_DRAW_TO_BITMAP_ARB 0x2002
00039 #define WGL_ACCELERATION_ARB 0x2003
00040 #define WGL_NEED_PALETTE_ARB 0x2004
00041 #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
00042 #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
00043 #define WGL_SWAP_METHOD_ARB 0x2007
00044 #define WGL_NUMBER_OVERLAYS_ARB 0x2008
00045 #define WGL_NUMBER_UNDERLAYS_ARB 0x2009
00046 #define WGL_TRANSPARENT_ARB 0x200A
00047 #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
00048 #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
00049 #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
00050 #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
00051 #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
00052 #define WGL_SHARE_DEPTH_ARB 0x200C
00053 #define WGL_SHARE_STENCIL_ARB 0x200D
00054 #define WGL_SHARE_ACCUM_ARB 0x200E
00055 #define WGL_SUPPORT_GDI_ARB 0x200F
00056 #define WGL_SUPPORT_OPENGL_ARB 0x2010
00057 #define WGL_DOUBLE_BUFFER_ARB 0x2011
00058 #define WGL_STEREO_ARB 0x2012
00059 #define WGL_PIXEL_TYPE_ARB 0x2013
00060 #define WGL_COLOR_BITS_ARB 0x2014
00061 #define WGL_RED_BITS_ARB 0x2015
00062 #define WGL_RED_SHIFT_ARB 0x2016
00063 #define WGL_GREEN_BITS_ARB 0x2017
00064 #define WGL_GREEN_SHIFT_ARB 0x2018
00065 #define WGL_BLUE_BITS_ARB 0x2019
00066 #define WGL_BLUE_SHIFT_ARB 0x201A
00067 #define WGL_ALPHA_BITS_ARB 0x201B
00068 #define WGL_ALPHA_SHIFT_ARB 0x201C
00069 #define WGL_ACCUM_BITS_ARB 0x201D
00070 #define WGL_ACCUM_RED_BITS_ARB 0x201E
00071 #define WGL_ACCUM_GREEN_BITS_ARB 0x201F
00072 #define WGL_ACCUM_BLUE_BITS_ARB 0x2020
00073 #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
00074 #define WGL_DEPTH_BITS_ARB 0x2022
00075 #define WGL_STENCIL_BITS_ARB 0x2023
00076 #define WGL_AUX_BUFFERS_ARB 0x2024
00077
00078 #define WGL_NO_ACCELERATION_ARB 0x2025
00079 #define WGL_GENERIC_ACCELERATION_ARB 0x2026
00080 #define WGL_FULL_ACCELERATION_ARB 0x2027
00081
00082 #define WGL_SWAP_EXCHANGE_ARB 0x2028
00083 #define WGL_SWAP_COPY_ARB 0x2029
00084 #define WGL_SWAP_UNDEFINED_ARB 0x202A
00085
00086 #define WGL_TYPE_RGBA_ARB 0x202B
00087 #define WGL_TYPE_COLORINDEX_ARB 0x202C
00088
00089 static boolean
00090 query_attrib(
00091 int iPixelFormat,
00092 int iLayerPlane,
00093 int attrib,
00094 int *pvalue )
00095 {
00096 uint count;
00097 uint index;
00098 const struct pixelformat_info *pf;
00099
00100 count = pixelformat_get_extended_count();
00101
00102 if (attrib == WGL_NUMBER_PIXEL_FORMATS_ARB) {
00103 *pvalue = (int) count;
00104 return TRUE;
00105 }
00106
00107 index = (uint) iPixelFormat - 1;
00108 if (index >= count)
00109 return FALSE;
00110
00111 pf = pixelformat_get_info( index );
00112
00113 switch (attrib) {
00114 case WGL_DRAW_TO_WINDOW_ARB:
00115 *pvalue = TRUE;
00116 return TRUE;
00117
00118 case WGL_DRAW_TO_BITMAP_ARB:
00119 *pvalue = FALSE;
00120 return TRUE;
00121
00122 case WGL_NEED_PALETTE_ARB:
00123 *pvalue = FALSE;
00124 return TRUE;
00125
00126 case WGL_NEED_SYSTEM_PALETTE_ARB:
00127 *pvalue = FALSE;
00128 return TRUE;
00129
00130 case WGL_SWAP_METHOD_ARB:
00131 if (pf->flags & PF_FLAG_DOUBLEBUFFER)
00132 *pvalue = WGL_SWAP_COPY_ARB;
00133 else
00134 *pvalue = WGL_SWAP_UNDEFINED_ARB;
00135 return TRUE;
00136
00137 case WGL_SWAP_LAYER_BUFFERS_ARB:
00138 *pvalue = FALSE;
00139 return TRUE;
00140
00141 case WGL_NUMBER_OVERLAYS_ARB:
00142 *pvalue = 0;
00143 return TRUE;
00144
00145 case WGL_NUMBER_UNDERLAYS_ARB:
00146 *pvalue = 0;
00147 return TRUE;
00148 }
00149
00150 if (iLayerPlane != 0)
00151 return FALSE;
00152
00153 switch (attrib) {
00154 case WGL_ACCELERATION_ARB:
00155 *pvalue = WGL_FULL_ACCELERATION_ARB;
00156 break;
00157
00158 case WGL_TRANSPARENT_ARB:
00159 *pvalue = FALSE;
00160 break;
00161
00162 case WGL_TRANSPARENT_RED_VALUE_ARB:
00163 case WGL_TRANSPARENT_GREEN_VALUE_ARB:
00164 case WGL_TRANSPARENT_BLUE_VALUE_ARB:
00165 case WGL_TRANSPARENT_ALPHA_VALUE_ARB:
00166 case WGL_TRANSPARENT_INDEX_VALUE_ARB:
00167 break;
00168
00169 case WGL_SHARE_DEPTH_ARB:
00170 case WGL_SHARE_STENCIL_ARB:
00171 case WGL_SHARE_ACCUM_ARB:
00172 *pvalue = TRUE;
00173 break;
00174
00175 case WGL_SUPPORT_GDI_ARB:
00176 *pvalue = FALSE;
00177 break;
00178
00179 case WGL_SUPPORT_OPENGL_ARB:
00180 *pvalue = TRUE;
00181 break;
00182
00183 case WGL_DOUBLE_BUFFER_ARB:
00184 if (pf->flags & PF_FLAG_DOUBLEBUFFER)
00185 *pvalue = TRUE;
00186 else
00187 *pvalue = FALSE;
00188 break;
00189
00190 case WGL_STEREO_ARB:
00191 *pvalue = FALSE;
00192 break;
00193
00194 case WGL_PIXEL_TYPE_ARB:
00195 *pvalue = WGL_TYPE_RGBA_ARB;
00196 break;
00197
00198 case WGL_COLOR_BITS_ARB:
00199 *pvalue = (int) (pf->color.redbits + pf->color.greenbits + pf->color.bluebits);
00200 break;
00201
00202 case WGL_RED_BITS_ARB:
00203 *pvalue = (int) pf->color.redbits;
00204 break;
00205
00206 case WGL_RED_SHIFT_ARB:
00207 *pvalue = (int) pf->color.redshift;
00208 break;
00209
00210 case WGL_GREEN_BITS_ARB:
00211 *pvalue = (int) pf->color.greenbits;
00212 break;
00213
00214 case WGL_GREEN_SHIFT_ARB:
00215 *pvalue = (int) pf->color.greenshift;
00216 break;
00217
00218 case WGL_BLUE_BITS_ARB:
00219 *pvalue = (int) pf->color.bluebits;
00220 break;
00221
00222 case WGL_BLUE_SHIFT_ARB:
00223 *pvalue = (int) pf->color.blueshift;
00224 break;
00225
00226 case WGL_ALPHA_BITS_ARB:
00227 *pvalue = (int) pf->alpha.alphabits;
00228 break;
00229
00230 case WGL_ALPHA_SHIFT_ARB:
00231 *pvalue = (int) pf->alpha.alphashift;
00232 break;
00233
00234 case WGL_ACCUM_BITS_ARB:
00235 case WGL_ACCUM_RED_BITS_ARB:
00236 case WGL_ACCUM_GREEN_BITS_ARB:
00237 case WGL_ACCUM_BLUE_BITS_ARB:
00238 case WGL_ACCUM_ALPHA_BITS_ARB:
00239 *pvalue = 0;
00240 break;
00241
00242 case WGL_DEPTH_BITS_ARB:
00243 *pvalue = (int) pf->depth.depthbits;
00244 break;
00245
00246 case WGL_STENCIL_BITS_ARB:
00247 *pvalue = (int) pf->depth.stencilbits;
00248 break;
00249
00250 case WGL_AUX_BUFFERS_ARB:
00251 *pvalue = 0;
00252 break;
00253
00254 case WGL_SAMPLE_BUFFERS_ARB:
00255 if (pf->flags & PF_FLAG_MULTISAMPLED)
00256 *pvalue = wgl_query_sample_buffers();
00257 else
00258 *pvalue = 0;
00259 break;
00260
00261 case WGL_SAMPLES_ARB:
00262 if (pf->flags & PF_FLAG_MULTISAMPLED)
00263 *pvalue = wgl_query_samples();
00264 else
00265 *pvalue = 0;
00266 break;
00267
00268 default:
00269 return FALSE;
00270 }
00271
00272 return TRUE;
00273 }
00274
00275 struct attrib_match_info
00276 {
00277 int attribute;
00278 int weight;
00279 BOOL exact;
00280 };
00281
00282 static struct attrib_match_info attrib_match[] = {
00283
00284
00285 { WGL_DRAW_TO_WINDOW_ARB, 0, TRUE },
00286 { WGL_DRAW_TO_BITMAP_ARB, 0, TRUE },
00287 { WGL_ACCELERATION_ARB, 0, TRUE },
00288 { WGL_NEED_PALETTE_ARB, 0, TRUE },
00289 { WGL_NEED_SYSTEM_PALETTE_ARB, 0, TRUE },
00290 { WGL_SWAP_LAYER_BUFFERS_ARB, 0, TRUE },
00291 { WGL_SWAP_METHOD_ARB, 0, TRUE },
00292 { WGL_NUMBER_OVERLAYS_ARB, 4, FALSE },
00293 { WGL_NUMBER_UNDERLAYS_ARB, 4, FALSE },
00294
00295
00296
00297 { WGL_SUPPORT_GDI_ARB, 0, TRUE },
00298 { WGL_SUPPORT_OPENGL_ARB, 0, TRUE },
00299 { WGL_DOUBLE_BUFFER_ARB, 0, TRUE },
00300 { WGL_STEREO_ARB, 0, TRUE },
00301 { WGL_PIXEL_TYPE_ARB, 0, TRUE },
00302 { WGL_COLOR_BITS_ARB, 1, FALSE },
00303 { WGL_RED_BITS_ARB, 1, FALSE },
00304 { WGL_GREEN_BITS_ARB, 1, FALSE },
00305 { WGL_BLUE_BITS_ARB, 1, FALSE },
00306 { WGL_ALPHA_BITS_ARB, 1, FALSE },
00307 { WGL_ACCUM_BITS_ARB, 1, FALSE },
00308 { WGL_ACCUM_RED_BITS_ARB, 1, FALSE },
00309 { WGL_ACCUM_GREEN_BITS_ARB, 1, FALSE },
00310 { WGL_ACCUM_BLUE_BITS_ARB, 1, FALSE },
00311 { WGL_ACCUM_ALPHA_BITS_ARB, 1, FALSE },
00312 { WGL_DEPTH_BITS_ARB, 1, FALSE },
00313 { WGL_STENCIL_BITS_ARB, 1, FALSE },
00314 { WGL_AUX_BUFFERS_ARB, 2, FALSE },
00315
00316
00317 { WGL_SAMPLE_BUFFERS_ARB, 2, FALSE },
00318 { WGL_SAMPLES_ARB, 2, FALSE }
00319 };
00320
00321 struct pixelformat_score
00322 {
00323 int points;
00324 uint index;
00325 };
00326
00327 static BOOL
00328 score_pixelformats(
00329 struct pixelformat_score *scores,
00330 uint count,
00331 int attribute,
00332 int expected_value )
00333 {
00334 uint i;
00335 struct attrib_match_info *ami = NULL;
00336 uint index;
00337
00338
00339
00340 for (i = 0; i < sizeof( attrib_match ) / sizeof( attrib_match[0] ); i++) {
00341 if (attrib_match[i].attribute == attribute) {
00342 ami = &attrib_match[i];
00343 break;
00344 }
00345 }
00346 if (ami == NULL)
00347 return TRUE;
00348
00349
00350
00351
00352 for (index = 0; index < count; index++) {
00353 int actual_value;
00354
00355 if (!query_attrib( index + 1, 0, attribute, &actual_value ))
00356 return FALSE;
00357
00358 if (ami->exact) {
00359
00360
00361
00362
00363 if (actual_value != expected_value)
00364 scores[index].points = 0;
00365 }
00366 else {
00367
00368
00369
00370
00371
00372 if (actual_value < expected_value)
00373 scores[index].points = 0;
00374 else if (actual_value > expected_value)
00375 scores[index].points -= (actual_value - expected_value) * ami->weight;
00376 }
00377 }
00378
00379 return TRUE;
00380 }
00381
00382 WINGDIAPI BOOL APIENTRY
00383 wglChoosePixelFormatARB(
00384 HDC hdc,
00385 const int *piAttribIList,
00386 const FLOAT *pfAttribFList,
00387 UINT nMaxFormats,
00388 int *piFormats,
00389 UINT *nNumFormats )
00390 {
00391 uint count;
00392 struct pixelformat_score *scores;
00393 uint i;
00394
00395 *nNumFormats = 0;
00396
00397
00398
00399
00400
00401
00402 count = pixelformat_get_extended_count();
00403 scores = (struct pixelformat_score *) MALLOC( count * sizeof( struct pixelformat_score ) );
00404 if (scores == NULL)
00405 return FALSE;
00406 for (i = 0; i < count; i++) {
00407 scores[i].points = 0x7fffffff;
00408 scores[i].index = i;
00409 }
00410
00411
00412
00413 if (piAttribIList != NULL) {
00414 while (*piAttribIList != 0) {
00415 if (!score_pixelformats( scores, count, piAttribIList[0], piAttribIList[1] )) {
00416 FREE( scores );
00417 return FALSE;
00418 }
00419 piAttribIList += 2;
00420 }
00421 }
00422 if (pfAttribFList != NULL) {
00423 while (*pfAttribFList != 0) {
00424 if (!score_pixelformats( scores, count, (int) pfAttribFList[0], (int) pfAttribFList[1] )) {
00425 FREE( scores );
00426 return FALSE;
00427 }
00428 pfAttribFList += 2;
00429 }
00430 }
00431
00432
00433
00434
00435 if (count > 1) {
00436 uint n = count;
00437 boolean swapped;
00438
00439 do {
00440 swapped = FALSE;
00441 for (i = 1; i < n; i++) {
00442 if (scores[i - 1].points < scores[i].points) {
00443 struct pixelformat_score score = scores[i - 1];
00444
00445 scores[i - 1] = scores[i];
00446 scores[i] = score;
00447 swapped = TRUE;
00448 }
00449 }
00450 n--;
00451 }
00452 while (swapped);
00453 }
00454
00455
00456
00457
00458 for (i = 0; i < count; i++) {
00459 if (scores[i].points > 0) {
00460 if (*nNumFormats < nMaxFormats)
00461 piFormats[*nNumFormats] = scores[i].index + 1;
00462 (*nNumFormats)++;
00463 }
00464 }
00465
00466 FREE( scores );
00467 return TRUE;
00468 }
00469
00470 WINGDIAPI BOOL APIENTRY
00471 wglGetPixelFormatAttribfvARB(
00472 HDC hdc,
00473 int iPixelFormat,
00474 int iLayerPlane,
00475 UINT nAttributes,
00476 const int *piAttributes,
00477 FLOAT *pfValues )
00478 {
00479 UINT i;
00480
00481 (void) hdc;
00482
00483 for (i = 0; i < nAttributes; i++) {
00484 int value;
00485
00486 if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &value ))
00487 return FALSE;
00488 pfValues[i] = (FLOAT) value;
00489 }
00490
00491 return TRUE;
00492 }
00493
00494 WINGDIAPI BOOL APIENTRY
00495 wglGetPixelFormatAttribivARB(
00496 HDC hdc,
00497 int iPixelFormat,
00498 int iLayerPlane,
00499 UINT nAttributes,
00500 const int *piAttributes,
00501 int *piValues )
00502 {
00503 UINT i;
00504
00505 (void) hdc;
00506
00507 for (i = 0; i < nAttributes; i++) {
00508 if (!query_attrib( iPixelFormat, iLayerPlane, piAttributes[i], &piValues[i] ))
00509 return FALSE;
00510 }
00511
00512 return TRUE;
00513 }