Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented display mode enumeration for Mac OS X. Modes are automatically sorted by size and their width/height ratio is calculated.
- Loading branch information
Showing
6 changed files
with
321 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
/** | ||
* @file displaymode_macx.h | ||
* Changing and enumerating available display modes for Mac OS X. @ingroup gl | ||
* | ||
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#ifndef LIBDENG_DISPLAYMODE_MACX_H | ||
#define LIBDENG_DISPLAYMODE_MACX_H | ||
|
||
#include "displaymode.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
void DisplayMode_Native_Init(void); | ||
|
||
int DisplayMode_Native_Count(void); | ||
|
||
void DisplayMode_Native_GetMode(int index, DisplayMode* mode); | ||
|
||
void DisplayMode_Native_Shutdown(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // LIBDENG_DISPLAYMODE_MACX_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/** | ||
* @file displaymode.mm | ||
* Mac OS X implementation of the DisplayMode class. @ingroup gl | ||
* | ||
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#include "displaymode_macx.h" | ||
#include "dd_types.h" | ||
|
||
#include <assert.h> | ||
#include <CoreFoundation/CoreFoundation.h> | ||
#include <ApplicationServices/ApplicationServices.h> | ||
#include <vector> | ||
#include <qDebug> | ||
|
||
/// Returns -1 on error. | ||
static int intFromDict(CFDictionaryRef dict, CFStringRef key) | ||
{ | ||
CFNumberRef ref = (CFNumberRef) CFDictionaryGetValue(dict, key); | ||
if(!ref) return -1; | ||
int value; | ||
if(!CFNumberGetValue(ref, kCFNumberIntType, &value)) return -1; | ||
return value; | ||
} | ||
|
||
/// Returns -1 on error. | ||
static float floatFromDict(CFDictionaryRef dict, CFStringRef key) | ||
{ | ||
CFNumberRef ref = (CFNumberRef) CFDictionaryGetValue(dict, key); | ||
if(!ref) return -1; | ||
float value; | ||
if(!CFNumberGetValue(ref, kCFNumberFloatType, &value)) return -1; | ||
return value; | ||
} | ||
|
||
static DisplayMode modeFromDict(CFDictionaryRef dict) | ||
{ | ||
DisplayMode m; | ||
m.width = intFromDict(dict, kCGDisplayWidth); | ||
m.height = intFromDict(dict, kCGDisplayHeight); | ||
m.refreshRate = floatFromDict(dict, kCGDisplayRefreshRate); | ||
m.depth = intFromDict(dict, kCGDisplayBitsPerPixel); | ||
return m; | ||
} | ||
|
||
static std::vector<DisplayMode> displayModes; | ||
|
||
void DisplayMode_Native_Init(void) | ||
{ | ||
// Let's see which modes are available. | ||
CFArrayRef modes = CGDisplayAvailableModes(kCGDirectMainDisplay); | ||
CFIndex count = CFArrayGetCount(modes); | ||
for(CFIndex i = 0; i < count; ++i) | ||
{ | ||
displayModes.push_back(modeFromDict((CFDictionaryRef)CFArrayGetValueAtIndex(modes, i))); | ||
} | ||
} | ||
|
||
int DisplayMode_Native_Count(void) | ||
{ | ||
return displayModes.size(); | ||
} | ||
|
||
void DisplayMode_Native_GetMode(int index, DisplayMode* mode) | ||
{ | ||
assert(index >= 0 && index < (int)displayModes.size()); | ||
*mode = displayModes[index]; | ||
} | ||
|
||
void DisplayMode_Native_Shutdown(void) | ||
{ | ||
displayModes.clear(); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/** | ||
* @file displaymode.h | ||
* Changing and enumerating available display modes. @ingroup gl | ||
* | ||
* @authors Copyright © 2012 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#ifndef LIBDENG_DISPLAYMODE_H | ||
#define LIBDENG_DISPLAYMODE_H | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct displaymode_s { | ||
int width; | ||
int height; | ||
float refreshRate; // might be zero | ||
int depth; | ||
|
||
// Calculated automatically: | ||
int ratioX; | ||
int ratioY; | ||
} DisplayMode; | ||
|
||
/** | ||
* Initializes the DisplayMode class. Enumerates all available display modes and | ||
* saves the current display mode. | ||
*/ | ||
int DisplayMode_Init(void); | ||
|
||
/** | ||
* Shuts down the DisplayMode class. The current display mode is restored to what | ||
* it was at initialization time. | ||
*/ | ||
void DisplayMode_Shutdown(void); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
#endif // LIBDENG_DISPLAYMODE_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
/** | ||
* @file displaymode.cpp | ||
* Platform-independent display mode management. @ingroup gl | ||
* | ||
* @authors Copyright (c) 2012 Jaakko Keränen <jaakko.keranen@iki.fi> | ||
* | ||
* @par License | ||
* GPL: http://www.gnu.org/licenses/gpl.html | ||
* | ||
* <small>This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by the | ||
* Free Software Foundation; either version 2 of the License, or (at your | ||
* option) any later version. This program is distributed in the hope that it | ||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty | ||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General | ||
* Public License for more details. You should have received a copy of the GNU | ||
* General Public License along with this program; if not, write to the Free | ||
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
* 02110-1301 USA</small> | ||
*/ | ||
|
||
#include "displaymode.h" | ||
|
||
#ifdef MACOSX | ||
# include "displaymode_macx.h" | ||
#endif | ||
|
||
#include <vector> | ||
#include <set> | ||
#include <algorithm> | ||
|
||
#include <qDebug> | ||
|
||
static bool inited = false; | ||
|
||
typedef std::set<DisplayMode> DisplayModes; | ||
static DisplayModes displayModes; | ||
|
||
static bool operator < (const DisplayMode& a, const DisplayMode& b) | ||
{ | ||
if(a.height == b.height) | ||
{ | ||
if(a.width == b.width) | ||
{ | ||
if(a.depth == b.depth) | ||
{ | ||
return a.refreshRate < b.refreshRate; | ||
} | ||
return a.depth < b.depth; | ||
} | ||
return a.width < b.width; | ||
} | ||
return a.height < b.height; | ||
} | ||
|
||
static void calculateRatio(int width, int height, int* x, int* y) | ||
{ | ||
Q_ASSERT(x && y); | ||
|
||
*x = width; | ||
*y = height; | ||
|
||
// Reduce until we must resort to fractions. | ||
forever | ||
{ | ||
bool divved = false; | ||
for(int div = 2; div <= qMin(*x/2, *y/2); div++) | ||
{ | ||
int dx = *x / div; | ||
if(dx * div != *x) continue; | ||
int dy = *y / div; | ||
if(dy * div != *y) continue; | ||
divved = true; | ||
*x = dx; | ||
*y = dy; | ||
break; | ||
} | ||
if(!divved) break; | ||
} | ||
|
||
if(*x == 8 && *y == 5) | ||
{ | ||
// This is commonly referred to as 16:10. | ||
*x *= 2; | ||
*y *= 2; | ||
} | ||
} | ||
|
||
int DisplayMode_Init(void) | ||
{ | ||
if(inited) return true; | ||
|
||
DisplayMode_Native_Init(); | ||
|
||
for(int i = 0; i < DisplayMode_Native_Count(); ++i) | ||
{ | ||
DisplayMode m; | ||
DisplayMode_Native_GetMode(i, &m); | ||
calculateRatio(m.width, m.height, &m.ratioX, &m.ratioY); | ||
displayModes.insert(m); | ||
} | ||
|
||
for(DisplayModes::iterator i = displayModes.begin(); i != displayModes.end(); ++i) | ||
{ | ||
qDebug() << "size" << i->width << "x" << i->height << "depth" << i->depth << "rate" | ||
<< i->refreshRate << "ratio" << i->ratioX << ":" << i->ratioY; | ||
} | ||
|
||
inited = true; | ||
return true; | ||
} | ||
|
||
void DisplayMode_Shutdown(void) | ||
{ | ||
displayModes.clear(); | ||
|
||
DisplayMode_Native_Shutdown(); | ||
} |