|
|
|
@ -31,77 +31,102 @@ |
|
|
|
|
#include "internal.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//************************************************************************
|
|
|
|
|
//**** GLFW internal functions ****
|
|
|
|
|
//************************************************************************
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Convert BPP to RGB bits based on "best guess"
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static void bpp2rgb( int bpp, int *r, int *g, int *b ) |
|
|
|
|
static void bpp2rgb(int bpp, int* r, int* g, int* b) |
|
|
|
|
{ |
|
|
|
|
int delta; |
|
|
|
|
|
|
|
|
|
// We assume that by 32 they really meant 24
|
|
|
|
|
if( bpp == 32 ) |
|
|
|
|
{ |
|
|
|
|
if (bpp == 32) |
|
|
|
|
bpp = 24; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Convert "bits per pixel" to red, green & blue sizes
|
|
|
|
|
|
|
|
|
|
*r = *g = *b = bpp / 3; |
|
|
|
|
delta = bpp - (*r * 3); |
|
|
|
|
if( delta >= 1 ) |
|
|
|
|
{ |
|
|
|
|
if (delta >= 1) |
|
|
|
|
*g = *g + 1; |
|
|
|
|
} |
|
|
|
|
if( delta == 2 ) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
if (delta == 2) |
|
|
|
|
*r = *r + 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Return closest video mode by dimensions, refresh rate and channel sizes
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static int getClosestVideoMode(int* w, int* h, |
|
|
|
|
int* r, int* g, int* b, |
|
|
|
|
int* refresh) |
|
|
|
|
{ |
|
|
|
|
int bpp, bestmode; |
|
|
|
|
|
|
|
|
|
// Colorbits = sum of red/green/blue bits
|
|
|
|
|
bpp = *r + *g + *b; |
|
|
|
|
|
|
|
|
|
// If colorbits < 15 (e.g. 0) or >= 24, default to 32 bpp
|
|
|
|
|
if (bpp < 15 || bpp >= 24) |
|
|
|
|
bpp = 32; |
|
|
|
|
|
|
|
|
|
// Find best match
|
|
|
|
|
bestmode = _glfwGetClosestVideoModeBPP(w, h, &bpp, refresh); |
|
|
|
|
|
|
|
|
|
// Convert "bits per pixel" to red, green & blue sizes
|
|
|
|
|
bpp2rgb(bpp, r, g, b); |
|
|
|
|
|
|
|
|
|
return bestmode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW internal API //////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Return closest video mode by dimensions, refresh rate and bits per pixel
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh ) |
|
|
|
|
int _glfwGetClosestVideoModeBPP(int* w, int* h, int* bpp, int* refresh) |
|
|
|
|
{ |
|
|
|
|
int mode, bestmode, match, bestmatch, rr, bestrr, success; |
|
|
|
|
int mode, bestmode, match, bestmatch, rr, bestrr, success; |
|
|
|
|
DEVMODE dm; |
|
|
|
|
|
|
|
|
|
// Find best match
|
|
|
|
|
bestmatch = 0x7fffffff; |
|
|
|
|
bestrr = 0x7fffffff; |
|
|
|
|
mode = bestmode = 0; |
|
|
|
|
|
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
success = EnumDisplaySettings( NULL, mode, &dm ); |
|
|
|
|
if( success ) |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
success = EnumDisplaySettings(NULL, mode, &dm); |
|
|
|
|
if (success) |
|
|
|
|
{ |
|
|
|
|
match = dm.dmBitsPerPel - *bpp; |
|
|
|
|
if( match < 0 ) match = -match; |
|
|
|
|
match = ( match << 25 ) | |
|
|
|
|
( (dm.dmPelsWidth - *w) * |
|
|
|
|
(dm.dmPelsWidth - *w) + |
|
|
|
|
(dm.dmPelsHeight - *h) * |
|
|
|
|
(dm.dmPelsHeight - *h) ); |
|
|
|
|
if( match < bestmatch ) |
|
|
|
|
if (match < 0) |
|
|
|
|
match = -match; |
|
|
|
|
|
|
|
|
|
match = (match << 25) | |
|
|
|
|
((dm.dmPelsWidth - *w) * |
|
|
|
|
(dm.dmPelsWidth - *w) + |
|
|
|
|
(dm.dmPelsHeight - *h) * |
|
|
|
|
(dm.dmPelsHeight - *h)); |
|
|
|
|
if (match < bestmatch) |
|
|
|
|
{ |
|
|
|
|
bestmatch = match; |
|
|
|
|
bestmode = mode; |
|
|
|
|
bestrr = (dm.dmDisplayFrequency - *refresh) * |
|
|
|
|
(dm.dmDisplayFrequency - *refresh); |
|
|
|
|
} |
|
|
|
|
else if( match == bestmatch && *refresh > 0 ) |
|
|
|
|
else if (match == bestmatch && *refresh > 0) |
|
|
|
|
{ |
|
|
|
|
rr = (dm.dmDisplayFrequency - *refresh) * |
|
|
|
|
(dm.dmDisplayFrequency - *refresh); |
|
|
|
|
if( rr < bestrr ) |
|
|
|
|
if (rr < bestrr) |
|
|
|
|
{ |
|
|
|
|
bestmatch = match; |
|
|
|
|
bestmode = mode; |
|
|
|
@ -109,13 +134,13 @@ int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh ) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
mode ++; |
|
|
|
|
mode++; |
|
|
|
|
} |
|
|
|
|
while( success ); |
|
|
|
|
while (success); |
|
|
|
|
|
|
|
|
|
// Get the parameters for the best matching display mode
|
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
(void) EnumDisplaySettings( NULL, bestmode, &dm ); |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
EnumDisplaySettings(NULL, bestmode, &dm); |
|
|
|
|
|
|
|
|
|
// Fill out actual width and height
|
|
|
|
|
*w = dm.dmPelsWidth; |
|
|
|
@ -131,72 +156,41 @@ int _glfwGetClosestVideoModeBPP( int *w, int *h, int *bpp, int *refresh ) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Return closest video mode by dimensions, refresh rate and channel sizes
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
static int getClosestVideoMode( int *w, int *h, |
|
|
|
|
int *r, int *g, int *b, |
|
|
|
|
int *refresh ) |
|
|
|
|
{ |
|
|
|
|
int bpp, bestmode; |
|
|
|
|
|
|
|
|
|
// Colorbits = sum of red/green/blue bits
|
|
|
|
|
bpp = *r + *g + *b; |
|
|
|
|
|
|
|
|
|
// If colorbits < 15 (e.g. 0) or >= 24, default to 32 bpp
|
|
|
|
|
if( bpp < 15 || bpp >= 24 ) |
|
|
|
|
{ |
|
|
|
|
bpp = 32; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Find best match
|
|
|
|
|
bestmode = _glfwGetClosestVideoModeBPP( w, h, &bpp, refresh ); |
|
|
|
|
|
|
|
|
|
// Convert "bits per pixel" to red, green & blue sizes
|
|
|
|
|
bpp2rgb( bpp, r, g, b ); |
|
|
|
|
|
|
|
|
|
return bestmode; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Change the current video mode
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
void _glfwSetVideoModeMODE( int mode ) |
|
|
|
|
void _glfwSetVideoModeMODE(int mode) |
|
|
|
|
{ |
|
|
|
|
DEVMODE dm; |
|
|
|
|
int success; |
|
|
|
|
|
|
|
|
|
// Get the parameters for the best matching display mode
|
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
(void) EnumDisplaySettings( NULL, mode, &dm ); |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
EnumDisplaySettings(NULL, mode, &dm); |
|
|
|
|
|
|
|
|
|
// Set which fields we want to specify
|
|
|
|
|
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL; |
|
|
|
|
|
|
|
|
|
// Do we have a prefered refresh rate?
|
|
|
|
|
if( _glfwWin.desiredRefreshRate > 0 ) |
|
|
|
|
if (_glfwWin.desiredRefreshRate > 0) |
|
|
|
|
{ |
|
|
|
|
dm.dmFields = dm.dmFields | DM_DISPLAYFREQUENCY; |
|
|
|
|
dm.dmDisplayFrequency = _glfwWin.desiredRefreshRate; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Change display setting
|
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
success = ChangeDisplaySettings( &dm, CDS_FULLSCREEN ); |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
success = ChangeDisplaySettings(&dm, CDS_FULLSCREEN); |
|
|
|
|
|
|
|
|
|
// If the mode change was not possible, query the current display
|
|
|
|
|
// settings (we'll use the desktop resolution for fullscreen mode)
|
|
|
|
|
if( success == DISP_CHANGE_SUCCESSFUL ) |
|
|
|
|
{ |
|
|
|
|
if (success == DISP_CHANGE_SUCCESSFUL) |
|
|
|
|
_glfwWin.modeID = mode; |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
_glfwWin.modeID = ENUM_REGISTRY_SETTINGS; |
|
|
|
|
EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm ); |
|
|
|
|
EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &dm); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Set the window size to that of the display mode
|
|
|
|
@ -209,27 +203,27 @@ void _glfwSetVideoModeMODE( int mode ) |
|
|
|
|
// Change the current video mode
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
void _glfwSetVideoMode( int *w, int *h, int r, int g, int b, int refresh ) |
|
|
|
|
void _glfwSetVideoMode(int* w, int* h, int r, int g, int b, int refresh) |
|
|
|
|
{ |
|
|
|
|
int bestmode; |
|
|
|
|
int bestmode; |
|
|
|
|
|
|
|
|
|
// Find a best match mode
|
|
|
|
|
bestmode = getClosestVideoMode( w, h, &r, &g, &b, &refresh ); |
|
|
|
|
bestmode = getClosestVideoMode(w, h, &r, &g, &b, &refresh); |
|
|
|
|
|
|
|
|
|
// Change mode
|
|
|
|
|
_glfwSetVideoModeMODE( bestmode ); |
|
|
|
|
_glfwSetVideoModeMODE(bestmode); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//************************************************************************
|
|
|
|
|
//**** GLFW user functions ****
|
|
|
|
|
//************************************************************************
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
////// GLFW platform API //////
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
//========================================================================
|
|
|
|
|
// Get a list of available video modes
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) |
|
|
|
|
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) |
|
|
|
|
{ |
|
|
|
|
int count, success, mode, i, j; |
|
|
|
|
int m1, m2, bpp, r, g, b; |
|
|
|
@ -238,37 +232,35 @@ int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) |
|
|
|
|
// Loop through all video modes and extract all the UNIQUE modes
|
|
|
|
|
count = 0; |
|
|
|
|
mode = 0; |
|
|
|
|
|
|
|
|
|
do |
|
|
|
|
{ |
|
|
|
|
// Get video mode properties
|
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
success = EnumDisplaySettings( NULL, mode, &dm ); |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
success = EnumDisplaySettings(NULL, mode, &dm); |
|
|
|
|
|
|
|
|
|
// Is it a valid mode? (only list depths >= 15 bpp)
|
|
|
|
|
if( success && dm.dmBitsPerPel >= 15 ) |
|
|
|
|
if (success && dm.dmBitsPerPel >= 15) |
|
|
|
|
{ |
|
|
|
|
// Convert to RGB, and back to bpp ("mask out" alpha bits etc)
|
|
|
|
|
bpp2rgb( dm.dmBitsPerPel, &r, &g, &b ); |
|
|
|
|
bpp2rgb(dm.dmBitsPerPel, &r, &g, &b); |
|
|
|
|
bpp = r + g + b; |
|
|
|
|
|
|
|
|
|
// Mode "code" for this mode
|
|
|
|
|
m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight); |
|
|
|
|
|
|
|
|
|
// Insert mode in list (sorted), and avoid duplicates
|
|
|
|
|
for( i = 0; i < count; i ++ ) |
|
|
|
|
for (i = 0; i < count; i++) |
|
|
|
|
{ |
|
|
|
|
// Mode "code" for already listed mode
|
|
|
|
|
bpp = list[i].redBits + list[i].greenBits + |
|
|
|
|
list[i].blueBits; |
|
|
|
|
bpp = list[i].redBits + list[i].greenBits + list[i].blueBits; |
|
|
|
|
m2 = (bpp << 25) | (list[i].width * list[i].height); |
|
|
|
|
if( m1 <= m2 ) |
|
|
|
|
{ |
|
|
|
|
if (m1 <= m2) |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// New entry at the end of the list?
|
|
|
|
|
if( i >= count ) |
|
|
|
|
if (i >= count) |
|
|
|
|
{ |
|
|
|
|
list[count].width = dm.dmPelsWidth; |
|
|
|
|
list[count].height = dm.dmPelsHeight; |
|
|
|
@ -278,23 +270,22 @@ int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) |
|
|
|
|
count ++; |
|
|
|
|
} |
|
|
|
|
// Insert new entry in the list?
|
|
|
|
|
else if( m1 < m2 ) |
|
|
|
|
else if (m1 < m2) |
|
|
|
|
{ |
|
|
|
|
for( j = count; j > i; j -- ) |
|
|
|
|
{ |
|
|
|
|
list[j] = list[j-1]; |
|
|
|
|
} |
|
|
|
|
for (j = count; j > i; j--) |
|
|
|
|
list[j] = list[j - 1]; |
|
|
|
|
|
|
|
|
|
list[i].width = dm.dmPelsWidth; |
|
|
|
|
list[i].height = dm.dmPelsHeight; |
|
|
|
|
list[i].redBits = r; |
|
|
|
|
list[i].greenBits = g; |
|
|
|
|
list[i].blueBits = b; |
|
|
|
|
count ++; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
mode ++; |
|
|
|
|
mode++; |
|
|
|
|
} |
|
|
|
|
while( success && (count < maxcount) ); |
|
|
|
|
while (success && (count < maxcount)); |
|
|
|
|
|
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
@ -304,17 +295,17 @@ int _glfwPlatformGetVideoModes( GLFWvidmode *list, int maxcount ) |
|
|
|
|
// Get the desktop video mode
|
|
|
|
|
//========================================================================
|
|
|
|
|
|
|
|
|
|
void _glfwPlatformGetDesktopMode( GLFWvidmode *mode ) |
|
|
|
|
void _glfwPlatformGetDesktopMode(GLFWvidmode* mode) |
|
|
|
|
{ |
|
|
|
|
DEVMODE dm; |
|
|
|
|
|
|
|
|
|
// Get desktop display mode
|
|
|
|
|
dm.dmSize = sizeof( DEVMODE ); |
|
|
|
|
(void) EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm ); |
|
|
|
|
dm.dmSize = sizeof(DEVMODE); |
|
|
|
|
EnumDisplaySettings(NULL, ENUM_REGISTRY_SETTINGS, &dm); |
|
|
|
|
|
|
|
|
|
// Return desktop mode parameters
|
|
|
|
|
mode->width = dm.dmPelsWidth; |
|
|
|
|
mode->height = dm.dmPelsHeight; |
|
|
|
|
bpp2rgb( dm.dmBitsPerPel, &mode->redBits, &mode->greenBits, &mode->blueBits ); |
|
|
|
|
bpp2rgb(dm.dmBitsPerPel, &mode->redBits, &mode->greenBits, &mode->blueBits); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|