From 58d4323eceafa5a6f5b156b0f15e962c8aea3c7c Mon Sep 17 00:00:00 2001 From: Marcel Metz Date: Sun, 2 Oct 2011 16:13:47 -0400 Subject: [PATCH] Implemented display aware glfwVideoModes function for X11 XRandR and win32. --- src/fullscreen.c | 8 ++++++- src/internal.h | 5 ++++- src/win32_display.c | 2 ++ src/win32_fullscreen.c | 4 ++-- src/win32_platform.h | 8 +++++++ src/x11_display.c | 7 ++++-- src/x11_fullscreen.c | 51 ++++++++++++++++++++++++++++++++++-------- src/x11_platform.h | 10 +++++++++ 8 files changed, 80 insertions(+), 15 deletions(-) diff --git a/src/fullscreen.c b/src/fullscreen.c index 6814bcac..ec8c6bfd 100644 --- a/src/fullscreen.c +++ b/src/fullscreen.c @@ -110,13 +110,19 @@ GLFWAPI int glfwGetVideoModes(GLFWdisplay display, GLFWvidmode* list, int maxcou return 0; } + if (display == GLFW_DISPLAY_INVALID_HANDLE) + { + _glfwSetError(GLFW_INVALID_VALUE, "Display handle is invalid."); + return 0; + } + if (maxcount <= 0 || list == NULL) { // TODO: Figure out if this is an error return 0; } - count = _glfwPlatformGetVideoModes(list, maxcount); + count = _glfwPlatformGetVideoModes(display, list, maxcount); if (count > 0) qsort(list, count, sizeof(GLFWvidmode), _glfwCompareVideoModes); diff --git a/src/internal.h b/src/internal.h index e757aaee..1ecccc5f 100644 --- a/src/internal.h +++ b/src/internal.h @@ -232,6 +232,9 @@ struct _GLFWdisplay // logical orientation of the screen on the desktop int screenXPosition; int screenYPosition; + + // These are defined in the current port's platform.h + _GLFW_PLATFORM_DISPLAY_STATE; }; //------------------------------------------------------------------------ @@ -298,7 +301,7 @@ void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); // Fullscreen -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount); +int _glfwPlatformGetVideoModes(GLFWdisplay display, GLFWvidmode* list, int maxcount); void _glfwPlatformGetDesktopMode(GLFWvidmode* mode); // Gamma ramp diff --git a/src/win32_display.c b/src/win32_display.c index 31b48cef..e489b9d7 100644 --- a/src/win32_display.c +++ b/src/win32_display.c @@ -57,6 +57,8 @@ _GLFWdisplay** _glfwCreateDisplay(_GLFWdisplay** current, DISPLAY_DEVICE* adapte (*current)->screenXPosition = setting->dmPosition.x; (*current)->screenYPosition = setting->dmPosition.y; + + memcpy((*current)->Win32.DeviceName, adapter->DeviceName, 32); return &((*current)->next); } diff --git a/src/win32_fullscreen.c b/src/win32_fullscreen.c index f8cc0dbc..5aed5bf1 100644 --- a/src/win32_fullscreen.c +++ b/src/win32_fullscreen.c @@ -182,7 +182,7 @@ void _glfwRestoreVideoMode(void) // Get a list of available video modes //======================================================================== -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) +int _glfwPlatformGetVideoModes(GLFWdisplay display, GLFWvidmode* list, int maxcount) { DEVMODE deviceMode; DWORD deviceModeNum; @@ -197,7 +197,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) vidModes = NULL; vidModesCount = 0; - while (EnumDisplaySettings(NULL, deviceModeNum, &deviceMode) && (!list || (vidModesCount < maxcount))) + while (EnumDisplaySettings(display->Win32.DeviceName, deviceModeNum, &deviceMode) && (!list || (vidModesCount < maxcount))) { deviceModeNum++; diff --git a/src/win32_platform.h b/src/win32_platform.h index d1ee889a..4b99805c 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -202,6 +202,7 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void); #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32 #define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryWin32 Win32 #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL +#define _GLFW_PLATFORM_DISPLAY_STATE _GLFWdisplayWin32 Win32 //======================================================================== @@ -310,6 +311,13 @@ typedef struct _GLFWlibraryWin32 } _GLFWlibraryWin32; +//------------------------------------------------------------------------ +// Platform-specific display structure +//------------------------------------------------------------------------ +typedef struct _GLFWdisplayWin32 +{ + char DeviceName[32]; +} _GLFWdisplayWin32; //======================================================================== // Prototypes for platform specific internal functions diff --git a/src/x11_display.c b/src/x11_display.c index bd4a90a4..ec882ded 100644 --- a/src/x11_display.c +++ b/src/x11_display.c @@ -51,6 +51,8 @@ _GLFWdisplay** _glfwCreateDisplay(_GLFWdisplay** current, XRROutputInfo* outputI (*current)->screenXPosition = crtcInfo->x; (*current)->screenYPosition = crtcInfo->y; + + (*current)->X11.output = outputInfo; return &((*current)->next); } @@ -60,6 +62,8 @@ _GLFWdisplay* _glfwDestroyDisplay(_GLFWdisplay* display) result = display->next; + XRRFreeOutputInfo(display->X11.output); + _glfwFree(display); return result; @@ -105,10 +109,9 @@ void _glfwInitDisplays(void) curDisplay = _glfwCreateDisplay(curDisplay, outputInfo, crtcInfo); + // Freeing of the outputInfo is done in _glfwDestroyDisplay XRRFreeCrtcInfo(crtcInfo); } - - XRRFreeOutputInfo(outputInfo); } } } diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index c154fe3d..d7f98859 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -325,11 +325,26 @@ struct _glfwResolution int height; }; +int _glfwCompareResolution(const void* left, const void* right) +{ + int result = 0; + const struct _glfwResolution* leftResolution = left; + const struct _glfwResolution* rightResolution = right; + + result = leftResolution->height - rightResolution->height; + if (result == 0) + { + result = leftResolution->width - rightResolution->width; + } + + return result; +} + //======================================================================== // List available video modes //======================================================================== -int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) +int _glfwPlatformGetVideoModes(GLFWdisplay display, GLFWvidmode* list, int maxcount) { int count, k, l, r, g, b, rgba, gl; int depth, screen; @@ -397,19 +412,37 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) if (_glfwLibrary.X11.RandR.available) { #if defined(_GLFW_HAS_XRANDR) - sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - sizelist = XRRConfigSizes(sc, &sizecount); + XRRScreenResources* resource; + unsigned int a; + resource = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root); - resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * sizecount); + resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * display->X11.output->nmode); - for (k = 0; k < sizecount; k++) + for (k = 0; k < display->X11.output->nmode; k++) { - resarray[rescount].width = sizelist[k].width; - resarray[rescount].height = sizelist[k].height; - rescount++; + for (a = 0; a < resource->nmode; a++) + { + if (resource->modes[a].id != display->X11.output->modes[k]) + { + continue; + } + + struct _glfwResolution res = { + resource->modes[a].width, + resource->modes[a].height + }; + + if (!bsearch(&res, resarray, rescount, sizeof(struct _glfwResolution), _glfwCompareResolution)) + { + resarray[rescount].width = resource->modes[a].width; + resarray[rescount].height = resource->modes[a].height; + rescount++; + qsort(resarray, rescount, sizeof(struct _glfwResolution), _glfwCompareResolution); + } + } } - XRRFreeScreenConfigInfo(sc); + XRRFreeScreenResources(resource); #endif /*_GLFW_HAS_XRANDR*/ } else if (_glfwLibrary.X11.VidMode.available) diff --git a/src/x11_platform.h b/src/x11_platform.h index ed730566..7a3199a7 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -88,6 +88,7 @@ #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11 #define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11 #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX +#define _GLFW_PLATFORM_DISPLAY_STATE _GLFWdisplayX11 X11 //======================================================================== @@ -244,6 +245,15 @@ GLFWGLOBAL struct { } _glfwJoy[GLFW_JOYSTICK_LAST + 1]; +//------------------------------------------------------------------------ +// Platform-specific window structure +//------------------------------------------------------------------------ +typedef struct _GLFWdisplayX11 +{ + XRROutputInfo* output; +} _GLFWdisplayX11; + + //======================================================================== // Prototypes for platform specific internal functions //========================================================================