mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-02 01:44:06 -04:00
patch from gerakinis and yaio to detect available desktop sizes
This commit is contained in:
parent
cdea7d12b5
commit
9a3d16b1c5
@ -17,6 +17,145 @@
|
|||||||
#include "pnmImage.h"
|
#include "pnmImage.h"
|
||||||
#include "subprocessWindow.h"
|
#include "subprocessWindow.h"
|
||||||
#include "nativeWindowHandle.h"
|
#include "nativeWindowHandle.h"
|
||||||
|
#import <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
// some macros to make code more readable.
|
||||||
|
#define GetModeWidth(mode) GetDictionaryLong((mode), kCGDisplayWidth)
|
||||||
|
#define GetModeHeight(mode) GetDictionaryLong((mode), kCGDisplayHeight)
|
||||||
|
#define GetModeRefreshRate(mode) GetDictionaryLong((mode), kCGDisplayRefreshRate)
|
||||||
|
#define GetModeBitsPerPixel(mode) GetDictionaryLong((mode), kCGDisplayBitsPerPixel)
|
||||||
|
#define GetModeSafeForHardware(mode) GetDictionaryBoolean((mode), kCGDisplayModeIsSafeForHardware)
|
||||||
|
#define GetModeStretched(mode) GetDictionaryBoolean((mode), kCGDisplayModeIsStretched)
|
||||||
|
#define MAX_DISPLAYS 32
|
||||||
|
|
||||||
|
Boolean GetDictionaryBoolean(CFDictionaryRef theDict, const void* key) {
|
||||||
|
// get a boolean from the dictionary
|
||||||
|
Boolean value = false;
|
||||||
|
CFBooleanRef boolRef;
|
||||||
|
boolRef = (CFBooleanRef)CFDictionaryGetValue(theDict, key);
|
||||||
|
if (boolRef != NULL)
|
||||||
|
value = CFBooleanGetValue(boolRef);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
long GetDictionaryLong(CFDictionaryRef theDict, const void* key) {
|
||||||
|
// get a long from the dictionary
|
||||||
|
long value = 0;
|
||||||
|
CFNumberRef numRef;
|
||||||
|
numRef = (CFNumberRef)CFDictionaryGetValue(theDict, key);
|
||||||
|
if (numRef != NULL)
|
||||||
|
CFNumberGetValue(numRef, kCFNumberLongType, &value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static CFComparisonResult CompareModes (const void *val1,const void *val2,void *context) {
|
||||||
|
// CFArray comparison callback for sorting display modes.
|
||||||
|
#pragma unused(context)
|
||||||
|
CFDictionaryRef thisMode = (CFDictionaryRef)val1;
|
||||||
|
CFDictionaryRef otherMode = (CFDictionaryRef)val2;
|
||||||
|
|
||||||
|
long width = GetModeWidth(thisMode);
|
||||||
|
long otherWidth = GetModeWidth(otherMode);
|
||||||
|
long height = GetModeHeight(thisMode);
|
||||||
|
long otherHeight = GetModeHeight(otherMode);
|
||||||
|
|
||||||
|
// sort modes in screen size order
|
||||||
|
if (width * height < otherWidth * otherHeight) {
|
||||||
|
return kCFCompareLessThan;
|
||||||
|
} else if (width * height > otherWidth * otherHeight) {
|
||||||
|
return kCFCompareGreaterThan;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort modes by bits per pixel
|
||||||
|
long bitsPerPixel = GetModeBitsPerPixel(thisMode);
|
||||||
|
long otherBitsPerPixel = GetModeBitsPerPixel(otherMode);
|
||||||
|
if (bitsPerPixel < otherBitsPerPixel) {
|
||||||
|
return kCFCompareLessThan;
|
||||||
|
} else if (bitsPerPixel > otherBitsPerPixel) {
|
||||||
|
return kCFCompareGreaterThan;
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort modes by refresh rate.
|
||||||
|
long refreshRate = GetModeRefreshRate(thisMode);
|
||||||
|
long otherRefreshRate = GetModeRefreshRate(otherMode);
|
||||||
|
if (refreshRate < otherRefreshRate) {
|
||||||
|
return kCFCompareLessThan;
|
||||||
|
} else if (refreshRate > otherRefreshRate) {
|
||||||
|
return kCFCompareGreaterThan;
|
||||||
|
}
|
||||||
|
|
||||||
|
return kCFCompareEqualTo;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFArrayRef GSCGDisplayAvailableModesUsefulForOpenGL(CGDirectDisplayID display) {
|
||||||
|
// get a list of all possible display modes for this system.
|
||||||
|
CFArrayRef availableModes = CGDisplayAvailableModes(display);
|
||||||
|
unsigned int numberOfAvailableModes = CFArrayGetCount(availableModes);
|
||||||
|
|
||||||
|
// creat mutable array to hold the display modes we are interested int.
|
||||||
|
CFMutableArrayRef usefulModes = CFArrayCreateMutable(kCFAllocatorDefault, numberOfAvailableModes, NULL);
|
||||||
|
|
||||||
|
// get the current bits per pixel.
|
||||||
|
long currentModeBitsPerPixel = GetModeBitsPerPixel(CGDisplayCurrentMode(display));
|
||||||
|
|
||||||
|
unsigned int i;
|
||||||
|
for (i= 0; i<numberOfAvailableModes; ++i) {
|
||||||
|
// look at each mode in the available list
|
||||||
|
CFDictionaryRef mode = (CFDictionaryRef)CFArrayGetValueAtIndex(availableModes, i);
|
||||||
|
|
||||||
|
// we are only interested in modes with the same bits per pixel as current.
|
||||||
|
// to allow for switching from fullscreen to windowed modes.
|
||||||
|
// that are safe for this hardward
|
||||||
|
// that are not stretched.
|
||||||
|
long bitsPerPixel = GetModeBitsPerPixel(mode);
|
||||||
|
Boolean safeForHardware = GetModeSafeForHardware(mode);
|
||||||
|
Boolean stretched = GetModeStretched(mode);
|
||||||
|
|
||||||
|
if ((bitsPerPixel != currentModeBitsPerPixel) || (!safeForHardware) || (stretched)) {
|
||||||
|
continue; // skip this mode
|
||||||
|
}
|
||||||
|
|
||||||
|
long width = GetModeWidth(mode);
|
||||||
|
long height = GetModeHeight(mode);
|
||||||
|
long refreshRate = GetModeRefreshRate(mode);
|
||||||
|
Boolean replaced = false;
|
||||||
|
Boolean skipped = false;
|
||||||
|
|
||||||
|
// now check to see if we already added a mode like this one.
|
||||||
|
// we want the highest refresh rate for this width/height
|
||||||
|
unsigned int j;
|
||||||
|
unsigned int currentNumberOfUsefulModes = CFArrayGetCount(usefulModes);
|
||||||
|
for (j = 0; j < currentNumberOfUsefulModes; ++j) {
|
||||||
|
CFDictionaryRef otherMode = (CFDictionaryRef)CFArrayGetValueAtIndex(usefulModes, j);
|
||||||
|
long otherWidth = GetModeWidth(otherMode);
|
||||||
|
long otherHeight = GetModeHeight(otherMode);
|
||||||
|
if ((otherWidth == width) && (otherHeight == height)) {
|
||||||
|
long otherRefreshRate = GetModeRefreshRate(otherMode);
|
||||||
|
if (otherRefreshRate < refreshRate) {
|
||||||
|
// replace lower refresh rate.
|
||||||
|
const void* value = mode;
|
||||||
|
CFArrayReplaceValues(usefulModes, CFRangeMake(j ,1), &value, 1);
|
||||||
|
replaced = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (otherRefreshRate > refreshRate) {
|
||||||
|
skipped = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// this is a useful mode so add it to the array.
|
||||||
|
if (!replaced && !skipped) {
|
||||||
|
CFArrayAppendValue(usefulModes, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// now sort the useful mode array, using the comparison callback.
|
||||||
|
CFArraySortValues( usefulModes,
|
||||||
|
CFRangeMake(0, CFArrayGetCount(usefulModes)),
|
||||||
|
(CFComparatorFunction) CompareModes, NULL);
|
||||||
|
// return the CFArray of the useful display modes.
|
||||||
|
return usefulModes;
|
||||||
|
}
|
||||||
|
|
||||||
TypeHandle osxGraphicsPipe::_type_handle;
|
TypeHandle osxGraphicsPipe::_type_handle;
|
||||||
|
|
||||||
@ -30,6 +169,26 @@ osxGraphicsPipe() {
|
|||||||
CGRect display_bounds = CGDisplayBounds(kCGDirectMainDisplay);
|
CGRect display_bounds = CGDisplayBounds(kCGDirectMainDisplay);
|
||||||
_display_width = CGRectGetWidth(display_bounds);
|
_display_width = CGRectGetWidth(display_bounds);
|
||||||
_display_height = CGRectGetHeight(display_bounds);
|
_display_height = CGRectGetHeight(display_bounds);
|
||||||
|
|
||||||
|
CGDirectDisplayID display, displayArray[MAX_DISPLAYS] ;
|
||||||
|
CGDisplayCount numDisplays;
|
||||||
|
CFDictionaryRef displayMode;
|
||||||
|
CFArrayRef displayModeArray;
|
||||||
|
int number, i;
|
||||||
|
CGGetActiveDisplayList (MAX_DISPLAYS, displayArray, &numDisplays);
|
||||||
|
display = displayArray [numDisplays - 1];
|
||||||
|
displayModeArray = GSCGDisplayAvailableModesUsefulForOpenGL( display );
|
||||||
|
number = CFArrayGetCount( displayModeArray );
|
||||||
|
DisplayMode *displays = new DisplayMode[ number ];
|
||||||
|
for(i = 0; i < number; i++) {
|
||||||
|
displayMode = (CFDictionaryRef) CFArrayGetValueAtIndex (displayModeArray, i);
|
||||||
|
_display_information -> _total_display_modes++;
|
||||||
|
displays[i].width = (signed int)GetModeWidth (displayMode);
|
||||||
|
displays[i].height = (signed int)GetModeHeight (displayMode);
|
||||||
|
displays[i].bits_per_pixel = (signed int)GetModeBitsPerPixel (displayMode);
|
||||||
|
displays[i].refresh_rate = (signed int)GetModeRefreshRate (displayMode);
|
||||||
|
}
|
||||||
|
_display_information -> _display_mode_array = displays;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Loading…
x
Reference in New Issue
Block a user