mirror of
https://github.com/glfw/glfw.git
synced 2024-11-22 10:05:10 +00:00
Merge remote-tracking branch 'adrian/multi-display-support' into multi-monitor
Conflicts: .gitignore
This commit is contained in:
commit
26c95559d2
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,7 +1,7 @@
|
|||||||
|
*.a
|
||||||
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
cmake_install.cmake
|
cmake_install.cmake
|
||||||
CMakeCache.txt
|
|
||||||
Makefile
|
|
||||||
cmake_uninstall.cmake
|
cmake_uninstall.cmake
|
||||||
.DS_Store
|
.DS_Store
|
||||||
src/config.h
|
src/config.h
|
||||||
@ -9,6 +9,9 @@ src/libglfw.pc
|
|||||||
src/libglfw.so
|
src/libglfw.so
|
||||||
src/libglfw.a
|
src/libglfw.a
|
||||||
src/libglfw.dylib
|
src/libglfw.dylib
|
||||||
|
src/libglfw.lib
|
||||||
|
src/libglfwdll.lib
|
||||||
|
src/libglfw.dll
|
||||||
examples/boing
|
examples/boing
|
||||||
examples/gears
|
examples/gears
|
||||||
examples/heightmap
|
examples/heightmap
|
||||||
@ -32,6 +35,7 @@ tests/peter
|
|||||||
tests/reopen
|
tests/reopen
|
||||||
tests/sharing
|
tests/sharing
|
||||||
tests/tearing
|
tests/tearing
|
||||||
|
tests/version
|
||||||
tests/windows
|
tests/windows
|
||||||
tests/*.app
|
tests/*.app
|
||||||
tests/*.exe
|
tests/*.exe
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
# This line is used to link with static libraries
|
# This line is used to link with static libraries
|
||||||
# Note that the library list should be updated to be obtained from
|
# Note that the library list should be updated to be obtained from
|
||||||
# the main CMakeLists.txt
|
# the main CMakeLists.txt
|
||||||
link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||||
|
|
||||||
|
if (UNIX AND NOT APPLE AND NOT CYGWIN)
|
||||||
|
find_library(MATH_LIBRARY m)
|
||||||
|
find_library(REALTIME_LIBRARY rt)
|
||||||
|
link_libraries(${MATH_LIBRARY} ${REALTIME_LIBRARY})
|
||||||
|
endif (UNIX AND NOT APPLE AND NOT CYGWIN)
|
||||||
|
|
||||||
include_directories(${GLFW_SOURCE_DIR}/include
|
include_directories(${GLFW_SOURCE_DIR}/include
|
||||||
${GLFW_SOURCE_DIR}/support
|
${GLFW_SOURCE_DIR}/support
|
||||||
${OPENGL_INCLUDE_DIR})
|
${OPENGL_INCLUDE_DIR})
|
||||||
|
@ -458,10 +458,22 @@ extern "C" {
|
|||||||
/* Gamma ramps */
|
/* Gamma ramps */
|
||||||
#define GLFW_GAMMA_RAMP_SIZE 256
|
#define GLFW_GAMMA_RAMP_SIZE 256
|
||||||
|
|
||||||
|
/* Monitor constants */
|
||||||
|
#define GLFW_MONITOR_NAME 0x00060000
|
||||||
|
#define GLFW_MONITOR_PHYSICAL_WIDTH 0x00060001
|
||||||
|
#define GLFW_MONITOR_PHYSICAL_HEIGHT 0x00060002
|
||||||
|
#define GLFW_MONITOR_SCREEN_POS_X 0x00060003
|
||||||
|
#define GLFW_MONITOR_SCREEN_POS_Y 0x00060004
|
||||||
|
#define GLFW_MONITOR_CONNECTED 0x00061000
|
||||||
|
#define GLFW_MONITOR_DISCONNECTED 0x00061001
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Typedefs
|
* Typedefs
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
|
/* Monitor handle type */
|
||||||
|
typedef void* GLFWmonitor;
|
||||||
|
|
||||||
/* Window handle type */
|
/* Window handle type */
|
||||||
typedef void* GLFWwindow;
|
typedef void* GLFWwindow;
|
||||||
|
|
||||||
@ -479,6 +491,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow,int,int);
|
|||||||
typedef void (* GLFWcharfun)(GLFWwindow,int);
|
typedef void (* GLFWcharfun)(GLFWwindow,int);
|
||||||
typedef void* (* GLFWmallocfun)(size_t);
|
typedef void* (* GLFWmallocfun)(size_t);
|
||||||
typedef void (* GLFWfreefun)(void*);
|
typedef void (* GLFWfreefun)(void*);
|
||||||
|
typedef void (* GLFWmonitordevicefun)(GLFWmonitor,int);
|
||||||
|
|
||||||
/* The video mode structure used by glfwGetVideoModes */
|
/* The video mode structure used by glfwGetVideoModes */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -528,8 +541,20 @@ GLFWAPI int glfwGetError(void);
|
|||||||
GLFWAPI const char* glfwErrorString(int error);
|
GLFWAPI const char* glfwErrorString(int error);
|
||||||
GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun);
|
GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun);
|
||||||
|
|
||||||
|
/* Monitor callback registration */
|
||||||
|
GLFWAPI void glfwSetMonitorDeviceCallback(GLFWmonitordevicefun cbfun);
|
||||||
|
|
||||||
|
/* Monitor attributes */
|
||||||
|
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor monitor, void* pointer);
|
||||||
|
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor monitor);
|
||||||
|
GLFWAPI int glfwGetMonitorParam(GLFWmonitor monitor, int param);
|
||||||
|
GLFWAPI const char* glfwGetMonitorString(GLFWmonitor monitor, int param);
|
||||||
|
|
||||||
|
/* Monitor discovery */
|
||||||
|
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor iterator);
|
||||||
|
|
||||||
/* Video mode functions */
|
/* Video mode functions */
|
||||||
GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount);
|
GLFWAPI int glfwGetVideoModes(GLFWmonitor monitor, GLFWvidmode* list, int maxcount);
|
||||||
GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode);
|
GLFWAPI void glfwGetDesktopMode(GLFWvidmode* mode);
|
||||||
|
|
||||||
/* Gamma ramp functions */
|
/* Gamma ramp functions */
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_definitions(-DWINVER=0x0501)
|
||||||
|
endif(WIN32)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
if(_GLFW_HAS_XRANDR)
|
if(_GLFW_HAS_XRANDR)
|
||||||
set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xrandr")
|
set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xrandr")
|
||||||
@ -15,7 +19,7 @@ include_directories(${GLFW_SOURCE_DIR}/src
|
|||||||
${GLFW_BINARY_DIR}/src
|
${GLFW_BINARY_DIR}/src
|
||||||
${GLFW_INCLUDE_DIR})
|
${GLFW_INCLUDE_DIR})
|
||||||
|
|
||||||
set(common_SOURCES enable.c error.c fullscreen.c gamma.c init.c input.c
|
set(common_SOURCES monitor.c enable.c error.c fullscreen.c gamma.c init.c input.c
|
||||||
joystick.c opengl.c time.c window.c)
|
joystick.c opengl.c time.c window.c)
|
||||||
|
|
||||||
if(_GLFW_COCOA_NSGL)
|
if(_GLFW_COCOA_NSGL)
|
||||||
@ -29,10 +33,10 @@ elseif(_GLFW_WIN32_WGL)
|
|||||||
set(libglfw_SOURCES ${common_SOURCES} win32_enable.c win32_fullscreen.c
|
set(libglfw_SOURCES ${common_SOURCES} win32_enable.c win32_fullscreen.c
|
||||||
win32_gamma.c win32_init.c win32_joystick.c
|
win32_gamma.c win32_init.c win32_joystick.c
|
||||||
win32_opengl.c win32_time.c win32_window.c
|
win32_opengl.c win32_time.c win32_window.c
|
||||||
win32_dllmain.c)
|
win32_dllmain.c win32_monitor.c)
|
||||||
elseif(_GLFW_X11_GLX)
|
elseif(_GLFW_X11_GLX)
|
||||||
set(libglfw_SOURCES ${common_SOURCES} x11_enable.c x11_fullscreen.c
|
set(libglfw_SOURCES ${common_SOURCES} x11_monitor.c x11_enable.c
|
||||||
x11_gamma.c x11_init.c x11_joystick.c
|
x11_fullscreen.c x11_gamma.c x11_init.c x11_joystick.c
|
||||||
x11_keysym2unicode.c x11_opengl.c x11_time.c
|
x11_keysym2unicode.c x11_opengl.c x11_time.c
|
||||||
x11_window.c)
|
x11_window.c)
|
||||||
else()
|
else()
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
// Lexical comparison function for GLFW video modes, used by qsort
|
// Lexical comparison function for GLFW video modes, used by qsort
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
static int compareVideoModes(const void* firstPtr, const void* secondPtr)
|
int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr)
|
||||||
{
|
{
|
||||||
int firstBPP, secondBPP, firstSize, secondSize;
|
int firstBPP, secondBPP, firstSize, secondSize;
|
||||||
GLFWvidmode* first = (GLFWvidmode*) firstPtr;
|
GLFWvidmode* first = (GLFWvidmode*) firstPtr;
|
||||||
@ -100,9 +100,10 @@ void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
|
|||||||
// Get a list of available video modes
|
// Get a list of available video modes
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
|
GLFWAPI int glfwGetVideoModes(GLFWmonitor handle, GLFWvidmode* list, int maxcount)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
|
||||||
if (!_glfwInitialized)
|
if (!_glfwInitialized)
|
||||||
{
|
{
|
||||||
@ -110,6 +111,13 @@ GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (monitor == NULL)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_INVALID_VALUE,
|
||||||
|
"glfwGetVideoModes: Invalid monitor handle");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (maxcount <= 0)
|
if (maxcount <= 0)
|
||||||
{
|
{
|
||||||
_glfwSetError(GLFW_INVALID_VALUE,
|
_glfwSetError(GLFW_INVALID_VALUE,
|
||||||
@ -125,9 +133,9 @@ GLFWAPI int glfwGetVideoModes(GLFWvidmode* list, int maxcount)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
count = _glfwPlatformGetVideoModes(list, maxcount);
|
count = _glfwPlatformGetVideoModes(monitor, list, maxcount);
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
qsort(list, count, sizeof(GLFWvidmode), compareVideoModes);
|
qsort(list, count, sizeof(GLFWvidmode), _glfwCompareVideoModes);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,7 @@ typedef struct _GLFWwndconfig _GLFWwndconfig;
|
|||||||
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
typedef struct _GLFWfbconfig _GLFWfbconfig;
|
||||||
typedef struct _GLFWwindow _GLFWwindow;
|
typedef struct _GLFWwindow _GLFWwindow;
|
||||||
typedef struct _GLFWlibrary _GLFWlibrary;
|
typedef struct _GLFWlibrary _GLFWlibrary;
|
||||||
|
typedef struct _GLFWmonitor _GLFWmonitor;
|
||||||
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
@ -219,6 +220,27 @@ struct _GLFWwindow
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Display structure
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
struct _GLFWmonitor
|
||||||
|
{
|
||||||
|
struct _GLFWmonitor* next;
|
||||||
|
|
||||||
|
void* userPointer;
|
||||||
|
|
||||||
|
char* name;
|
||||||
|
// physical dimensions in millimeters.
|
||||||
|
int physicalWidth;
|
||||||
|
int physicalHeight;
|
||||||
|
// logical orientation of the screen on the desktop
|
||||||
|
int screenX;
|
||||||
|
int screenY;
|
||||||
|
|
||||||
|
// These are defined in the current port's platform.h
|
||||||
|
_GLFW_PLATFORM_MONITOR_STATE;
|
||||||
|
};
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Library global data
|
// Library global data
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
@ -229,6 +251,8 @@ struct _GLFWlibrary
|
|||||||
_GLFWwindow* windowListHead;
|
_GLFWwindow* windowListHead;
|
||||||
_GLFWwindow* currentWindow;
|
_GLFWwindow* currentWindow;
|
||||||
_GLFWwindow* activeWindow;
|
_GLFWwindow* activeWindow;
|
||||||
|
_GLFWwindow* cursorLockWindow;
|
||||||
|
_GLFWmonitor* monitorListHead;
|
||||||
|
|
||||||
GLFWwindowsizefun windowSizeCallback;
|
GLFWwindowsizefun windowSizeCallback;
|
||||||
GLFWwindowclosefun windowCloseCallback;
|
GLFWwindowclosefun windowCloseCallback;
|
||||||
@ -240,6 +264,7 @@ struct _GLFWlibrary
|
|||||||
GLFWscrollfun scrollCallback;
|
GLFWscrollfun scrollCallback;
|
||||||
GLFWkeyfun keyCallback;
|
GLFWkeyfun keyCallback;
|
||||||
GLFWcharfun charCallback;
|
GLFWcharfun charCallback;
|
||||||
|
GLFWmonitordevicefun monitorCallback;
|
||||||
|
|
||||||
GLFWthreadmodel threading;
|
GLFWthreadmodel threading;
|
||||||
GLFWallocator allocator;
|
GLFWallocator allocator;
|
||||||
@ -281,7 +306,7 @@ void _glfwPlatformEnableSystemKeys(_GLFWwindow* window);
|
|||||||
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
|
void _glfwPlatformDisableSystemKeys(_GLFWwindow* window);
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount);
|
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount);
|
||||||
void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
|
void _glfwPlatformGetDesktopMode(GLFWvidmode* mode);
|
||||||
|
|
||||||
// Gamma ramp
|
// Gamma ramp
|
||||||
@ -332,6 +357,7 @@ void _glfwFree(void* ptr);
|
|||||||
|
|
||||||
// Fullscren management (fullscreen.c)
|
// Fullscren management (fullscreen.c)
|
||||||
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue);
|
||||||
|
int _glfwCompareVideoModes(const void* firstPtr, const void* secondPtr);
|
||||||
|
|
||||||
// Error handling (error.c)
|
// Error handling (error.c)
|
||||||
void _glfwSetError(int error, const char* description);
|
void _glfwSetError(int error, const char* description);
|
||||||
|
147
src/monitor.c
Normal file
147
src/monitor.c
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW - An OpenGL framework
|
||||||
|
// Platform: Any
|
||||||
|
// API version: 3.0
|
||||||
|
// WWW: http://www.glfw.org/
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW public API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Iterate through connected monitors
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLFWAPI GLFWmonitor glfwGetNextMonitor(GLFWmonitor handle)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* iterator = (_GLFWmonitor*) handle;
|
||||||
|
_GLFWmonitor* result = NULL;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterator == NULL)
|
||||||
|
result = _glfwLibrary.monitorListHead;
|
||||||
|
else
|
||||||
|
result = iterator->next;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Get monitor parameter
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLFWAPI int glfwGetMonitorParam(GLFWmonitor handle, int param)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor == NULL)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_INVALID_VALUE,
|
||||||
|
"glfwGetMonitorParam: Invalid monitor handle");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case GLFW_MONITOR_PHYSICAL_WIDTH:
|
||||||
|
return monitor->physicalWidth;
|
||||||
|
case GLFW_MONITOR_PHYSICAL_HEIGHT:
|
||||||
|
return monitor->physicalHeight;
|
||||||
|
case GLFW_MONITOR_SCREEN_POS_X:
|
||||||
|
return monitor->screenX;
|
||||||
|
case GLFW_MONITOR_SCREEN_POS_Y:
|
||||||
|
return monitor->screenY;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwSetError(GLFW_INVALID_ENUM,
|
||||||
|
"glfwGetMonitorParam: Invalid enum value for 'param' parameter");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Get monitor string
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLFWAPI const char* glfwGetMonitorString(GLFWmonitor handle, int param)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
|
||||||
|
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (monitor == NULL)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_INVALID_VALUE,
|
||||||
|
"glfwGetMonitorString: Invalid monitor handle");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (param)
|
||||||
|
{
|
||||||
|
case GLFW_MONITOR_NAME:
|
||||||
|
return monitor->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwSetError(GLFW_INVALID_ENUM,
|
||||||
|
"glfwGetMonitorString: Invalid enum value for 'param' parameter");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
//========================================================================
|
||||||
|
// Set a callback function for monitor events
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
GLFWAPI void glfwSetMonitorDeviceCallback(GLFWmonitordevicefun cbfun)
|
||||||
|
{
|
||||||
|
if (!_glfwInitialized)
|
||||||
|
{
|
||||||
|
_glfwSetError(GLFW_NOT_INITIALIZED, NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwLibrary.monitorCallback= cbfun;
|
||||||
|
}
|
||||||
|
|
@ -182,71 +182,58 @@ void _glfwRestoreVideoMode(void)
|
|||||||
// Get a list of available video modes
|
// Get a list of available video modes
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount)
|
||||||
{
|
{
|
||||||
int count, success, mode, i, j;
|
DEVMODE deviceMode;
|
||||||
int m1, m2, bpp, r, g, b;
|
DWORD deviceModeNum;
|
||||||
DEVMODE dm;
|
|
||||||
|
|
||||||
// Loop through all video modes and extract all the UNIQUE modes
|
GLFWvidmode* vidModes;
|
||||||
count = 0;
|
int vidModesCount;
|
||||||
mode = 0;
|
GLFWvidmode vidMode;
|
||||||
|
|
||||||
do
|
deviceMode.dmSize = sizeof(DEVMODE);
|
||||||
|
deviceModeNum = 0;
|
||||||
|
|
||||||
|
vidModes = NULL;
|
||||||
|
vidModesCount = 0;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
{
|
{
|
||||||
// Get video mode properties
|
if (!EnumDisplaySettings(monitor->Win32.name, deviceModeNum, &deviceMode))
|
||||||
dm.dmSize = sizeof(DEVMODE);
|
break;
|
||||||
success = EnumDisplaySettings(NULL, mode, &dm);
|
|
||||||
|
|
||||||
// Is it a valid mode? (only list depths >= 15 bpp)
|
if (vidModesCount >= maxcount)
|
||||||
if (success && dm.dmBitsPerPel >= 15)
|
break;
|
||||||
{
|
|
||||||
// Convert to RGB, and back to bpp ("mask out" alpha bits etc)
|
|
||||||
_glfwSplitBPP(dm.dmBitsPerPel, &r, &g, &b);
|
|
||||||
bpp = r + g + b;
|
|
||||||
|
|
||||||
// Mode "code" for this mode
|
deviceModeNum++;
|
||||||
m1 = (bpp << 25) | (dm.dmPelsWidth * dm.dmPelsHeight);
|
|
||||||
|
|
||||||
// Insert mode in list (sorted), and avoid duplicates
|
if (deviceMode.dmBitsPerPel < 15)
|
||||||
for (i = 0; i < count; i++)
|
continue;
|
||||||
{
|
|
||||||
// Mode "code" for already listed mode
|
|
||||||
bpp = list[i].redBits + list[i].greenBits + list[i].blueBits;
|
|
||||||
m2 = (bpp << 25) | (list[i].width * list[i].height);
|
|
||||||
if (m1 <= m2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New entry at the end of the list?
|
vidMode.height = deviceMode.dmPelsHeight;
|
||||||
if (i >= count)
|
vidMode.width = deviceMode.dmPelsWidth;
|
||||||
{
|
// Convert to RGB, and back to bpp ("mask out" alpha bits etc)
|
||||||
list[count].width = dm.dmPelsWidth;
|
_glfwSplitBPP(deviceMode.dmBitsPerPel,
|
||||||
list[count].height = dm.dmPelsHeight;
|
&vidMode.redBits,
|
||||||
list[count].redBits = r;
|
&vidMode.greenBits,
|
||||||
list[count].greenBits = g;
|
&vidMode.blueBits);
|
||||||
list[count].blueBits = b;
|
|
||||||
count ++;
|
|
||||||
}
|
|
||||||
// Insert new entry in the list?
|
|
||||||
else if (m1 < m2)
|
|
||||||
{
|
|
||||||
for (j = count; j > i; j--)
|
|
||||||
list[j] = list[j - 1];
|
|
||||||
|
|
||||||
list[i].width = dm.dmPelsWidth;
|
// skip duplicates.
|
||||||
list[i].height = dm.dmPelsHeight;
|
if (vidModes && bsearch(&vidMode, vidModes, vidModesCount, sizeof(GLFWvidmode), _glfwCompareVideoModes))
|
||||||
list[i].redBits = r;
|
continue;
|
||||||
list[i].greenBits = g;
|
|
||||||
list[i].blueBits = b;
|
vidModes = realloc(vidModes, sizeof(GLFWvidmode) * ++vidModesCount);
|
||||||
count++;
|
memcpy(vidModes + (vidModesCount - 1), &vidMode, sizeof(GLFWvidmode));
|
||||||
}
|
|
||||||
}
|
qsort(vidModes, vidModesCount, sizeof(GLFWvidmode), _glfwCompareVideoModes);
|
||||||
mode++;
|
|
||||||
}
|
}
|
||||||
while (success && (count < maxcount));
|
|
||||||
|
|
||||||
return count;
|
if (list && maxcount)
|
||||||
|
memcpy(list, vidModes, sizeof(GLFWvidmode) * min(vidModesCount, maxcount));
|
||||||
|
|
||||||
|
free(vidModes);
|
||||||
|
|
||||||
|
return vidModesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,6 +165,8 @@ int _glfwPlatformInit(void)
|
|||||||
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
|
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
|
||||||
_glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
|
_glfwLibrary.currentRamp = _glfwLibrary.originalRamp;
|
||||||
|
|
||||||
|
_glfwInitMonitors();
|
||||||
|
|
||||||
_glfwInitTimer();
|
_glfwInitTimer();
|
||||||
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
@ -180,6 +182,8 @@ int _glfwPlatformTerminate(void)
|
|||||||
// Restore the original gamma ramp
|
// Restore the original gamma ramp
|
||||||
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
|
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
|
||||||
|
|
||||||
|
_glfwTerminateMonitors();
|
||||||
|
|
||||||
if (_glfwLibrary.Win32.classAtom)
|
if (_glfwLibrary.Win32.classAtom)
|
||||||
{
|
{
|
||||||
UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.Win32.instance);
|
UnregisterClass(_GLFW_WNDCLASSNAME, _glfwLibrary.Win32.instance);
|
||||||
|
231
src/win32_monitor.c
Normal file
231
src/win32_monitor.c
Normal file
@ -0,0 +1,231 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW - An OpenGL library
|
||||||
|
// Platform: X11 (Unix)
|
||||||
|
// API version: 3.0
|
||||||
|
// WWW: http://www.glfw.org/
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
// The MinGW package for Debian lacks this
|
||||||
|
#ifndef EDS_ROTATEDMODE
|
||||||
|
#define EDS_ROTATEDMODE 0x00000004
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
_GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current,
|
||||||
|
DISPLAY_DEVICE* adapter,
|
||||||
|
DISPLAY_DEVICE* monitor,
|
||||||
|
DEVMODE* setting)
|
||||||
|
{
|
||||||
|
HDC dc = NULL;
|
||||||
|
|
||||||
|
*current = _glfwMalloc(sizeof(_GLFWmonitor));
|
||||||
|
memset(*current, 0, sizeof(_GLFWmonitor));
|
||||||
|
|
||||||
|
dc = CreateDC("DISPLAY", monitor->DeviceString, NULL, NULL);
|
||||||
|
|
||||||
|
(*current)->physicalWidth = GetDeviceCaps(dc, HORZSIZE);
|
||||||
|
(*current)->physicalHeight = GetDeviceCaps(dc, VERTSIZE);
|
||||||
|
|
||||||
|
DeleteDC(dc);
|
||||||
|
|
||||||
|
(*current)->name = _glfwMalloc(strlen(monitor->DeviceName) + 1);
|
||||||
|
memcpy((*current)->name, monitor->DeviceName, strlen(monitor->DeviceName) + 1);
|
||||||
|
(*current)->name[strlen(monitor->DeviceName)] = '\0';
|
||||||
|
|
||||||
|
(*current)->screenX = setting->dmPosition.x;
|
||||||
|
(*current)->screenY = setting->dmPosition.y;
|
||||||
|
|
||||||
|
memcpy((*current)->Win32.name, adapter->DeviceName, 32);
|
||||||
|
return &((*current)->next);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* result;
|
||||||
|
|
||||||
|
result = monitor->next;
|
||||||
|
|
||||||
|
_glfwFree(monitor->name);
|
||||||
|
_glfwFree(monitor);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo: This is ugly. The platform should only allocate a list of the current devices.
|
||||||
|
// The platform independent code should be in charge of the handling for the initial
|
||||||
|
// setup, refreshing and freeing the list.
|
||||||
|
void _glfwInitMonitors(void)
|
||||||
|
{
|
||||||
|
_GLFWmonitor** curMonitor;
|
||||||
|
|
||||||
|
DISPLAY_DEVICE adapter;
|
||||||
|
DWORD adapterNum;
|
||||||
|
|
||||||
|
DISPLAY_DEVICE monitor;
|
||||||
|
|
||||||
|
DEVMODE setting;
|
||||||
|
DWORD settingNum;
|
||||||
|
|
||||||
|
curMonitor = &_glfwLibrary.monitorListHead;
|
||||||
|
|
||||||
|
adapter.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
adapterNum = 0;
|
||||||
|
|
||||||
|
monitor.cb = sizeof(DISPLAY_DEVICE);
|
||||||
|
setting.dmSize = sizeof(DEVMODE);
|
||||||
|
settingNum = 0;
|
||||||
|
|
||||||
|
while (EnumDisplayDevices(NULL, adapterNum++, &adapter, 0))
|
||||||
|
{
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER || !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
EnumDisplaySettingsEx(adapter.DeviceName,
|
||||||
|
ENUM_CURRENT_SETTINGS,
|
||||||
|
&setting,
|
||||||
|
EDS_ROTATEDMODE);
|
||||||
|
|
||||||
|
EnumDisplayDevices(adapter.DeviceName, 0, &monitor, 0);
|
||||||
|
|
||||||
|
curMonitor = _glfwCreateMonitor(curMonitor, &adapter, &monitor, &setting);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwRefreshMonitors(void)
|
||||||
|
{
|
||||||
|
DISPLAY_DEVICE adapter;
|
||||||
|
DWORD adapterNum = 0;
|
||||||
|
|
||||||
|
DISPLAY_DEVICE monitor;
|
||||||
|
|
||||||
|
DEVMODE setting;
|
||||||
|
|
||||||
|
_GLFWmonitor* newMonitorList = NULL;
|
||||||
|
_GLFWmonitor** curMonitor = &newMonitorList;
|
||||||
|
|
||||||
|
_GLFWmonitor* curNewMonitor;
|
||||||
|
_GLFWmonitor* curOldMonitor;
|
||||||
|
|
||||||
|
while (EnumDisplayDevices(NULL, adapterNum++, &adapter, 0))
|
||||||
|
{
|
||||||
|
if (adapter.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER || !(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
EnumDisplaySettingsEx(adapter.DeviceName, ENUM_CURRENT_SETTINGS, &setting, EDS_ROTATEDMODE);
|
||||||
|
|
||||||
|
EnumDisplayDevices(adapter.DeviceName, 0, &monitor, 0);
|
||||||
|
|
||||||
|
curMonitor = _glfwCreateMonitor(curMonitor, &adapter, &monitor, &setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
curNewMonitor = newMonitorList;
|
||||||
|
curOldMonitor = _glfwLibrary.monitorListHead;
|
||||||
|
|
||||||
|
while (_glfwLibrary.monitorCallback && (curNewMonitor || curOldMonitor))
|
||||||
|
{
|
||||||
|
_GLFWmonitor* lookAheadOldMonitor;
|
||||||
|
_GLFWmonitor* lookAheadNewMonitor;
|
||||||
|
|
||||||
|
if (curOldMonitor && curNewMonitor && !strcmp(curOldMonitor->name, curOldMonitor->name))
|
||||||
|
{
|
||||||
|
curNewMonitor = curNewMonitor->next;
|
||||||
|
curOldMonitor = curOldMonitor->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (curNewMonitor && !curOldMonitor)
|
||||||
|
{
|
||||||
|
_glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED);
|
||||||
|
curNewMonitor = curNewMonitor->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!curNewMonitor && curOldMonitor)
|
||||||
|
{
|
||||||
|
_glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED);
|
||||||
|
curOldMonitor = curOldMonitor->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
lookAheadOldMonitor = curOldMonitor->next;
|
||||||
|
lookAheadNewMonitor = curNewMonitor->next;
|
||||||
|
|
||||||
|
while (lookAheadOldMonitor && !strcmp(curNewMonitor->name, lookAheadOldMonitor->name))
|
||||||
|
lookAheadOldMonitor = lookAheadOldMonitor->next;
|
||||||
|
|
||||||
|
while (lookAheadNewMonitor && !strcmp(curOldMonitor->name, lookAheadNewMonitor->name))
|
||||||
|
lookAheadNewMonitor = lookAheadNewMonitor->next;
|
||||||
|
|
||||||
|
if (!lookAheadOldMonitor)
|
||||||
|
{
|
||||||
|
// nothing found in the old monitor list, that matches the current new monitor.
|
||||||
|
_glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED);
|
||||||
|
curNewMonitor = curNewMonitor->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (strcmp(curOldMonitor->name, lookAheadOldMonitor->name))
|
||||||
|
{
|
||||||
|
_glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED);
|
||||||
|
curOldMonitor = curOldMonitor->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lookAheadNewMonitor)
|
||||||
|
{
|
||||||
|
// nothing found in the new monitor list, that matches the current old monitor.
|
||||||
|
_glfwLibrary.monitorCallback(curOldMonitor, GLFW_MONITOR_DISCONNECTED);
|
||||||
|
curOldMonitor = curOldMonitor->next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while (strcmp(curNewMonitor->name, lookAheadNewMonitor->name))
|
||||||
|
{
|
||||||
|
_glfwLibrary.monitorCallback(curNewMonitor, GLFW_MONITOR_CONNECTED);
|
||||||
|
curNewMonitor = curNewMonitor->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_glfwTerminateMonitors();
|
||||||
|
_glfwLibrary.monitorListHead = newMonitorList;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateMonitors(void)
|
||||||
|
{
|
||||||
|
while (_glfwLibrary.monitorListHead)
|
||||||
|
_glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead);
|
||||||
|
}
|
||||||
|
|
@ -47,6 +47,7 @@
|
|||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <mmsystem.h>
|
#include <mmsystem.h>
|
||||||
|
#include <Dbt.h>
|
||||||
|
|
||||||
// This path may need to be changed if you build GLFW using your own setup
|
// This path may need to be changed if you build GLFW using your own setup
|
||||||
// We ship and use our own copy of wglext.h since GLFW uses fairly new
|
// We ship and use our own copy of wglext.h since GLFW uses fairly new
|
||||||
@ -210,6 +211,7 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
|
|||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32
|
||||||
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryWin32 Win32
|
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryWin32 Win32
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL WGL
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorWin32 Win32
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -318,6 +320,14 @@ typedef struct _GLFWlibraryWin32
|
|||||||
|
|
||||||
} _GLFWlibraryWin32;
|
} _GLFWlibraryWin32;
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Platform-specific monitor structure
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
typedef struct _GLFWmonitorWin32
|
||||||
|
{
|
||||||
|
char name[32];
|
||||||
|
|
||||||
|
} _GLFWmonitorWin32;
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Prototypes for platform specific internal functions
|
// Prototypes for platform specific internal functions
|
||||||
@ -326,6 +336,11 @@ typedef struct _GLFWlibraryWin32
|
|||||||
// Time
|
// Time
|
||||||
void _glfwInitTimer(void);
|
void _glfwInitTimer(void);
|
||||||
|
|
||||||
|
// Monitor support
|
||||||
|
void _glfwInitMonitors(void);
|
||||||
|
void _glfwRefreshMonitors(void);
|
||||||
|
void _glfwTerminateMonitors(void);
|
||||||
|
|
||||||
// Fullscreen support
|
// Fullscreen support
|
||||||
void _glfwSetVideoMode(int* width, int* height,
|
void _glfwSetVideoMode(int* width, int* height,
|
||||||
int* bpp, int* refreshRate,
|
int* bpp, int* refreshRate,
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
|
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
@ -1079,6 +1078,16 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case WM_DEVICECHANGE:
|
||||||
|
{
|
||||||
|
if (DBT_DEVNODES_CHANGED == wParam)
|
||||||
|
{
|
||||||
|
_glfwRefreshMonitors();
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pass all unhandled messages to DefWindowProc
|
// Pass all unhandled messages to DefWindowProc
|
||||||
@ -1780,7 +1789,7 @@ void _glfwPlatformPollEvents(void)
|
|||||||
window = _glfwLibrary.activeWindow;
|
window = _glfwLibrary.activeWindow;
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
window->Win32.cursorCentered = GL_FALSE;
|
window->Win32.cursorCentered = GL_TRUE;
|
||||||
window->Win32.oldMouseX = window->width / 2;
|
window->Win32.oldMouseX = window->width / 2;
|
||||||
window->Win32.oldMouseY = window->height / 2;
|
window->Win32.oldMouseY = window->height / 2;
|
||||||
}
|
}
|
||||||
@ -1902,3 +1911,4 @@ void _glfwPlatformSetCursorMode(_GLFWwindow* window, int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -316,11 +316,26 @@ struct _glfwResolution
|
|||||||
int height;
|
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
|
// List available video modes
|
||||||
//========================================================================
|
//========================================================================
|
||||||
|
|
||||||
int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
int _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, GLFWvidmode* list, int maxcount)
|
||||||
{
|
{
|
||||||
int count, k, l, r, g, b, rgba, gl;
|
int count, k, l, r, g, b, rgba, gl;
|
||||||
int depth, screen;
|
int depth, screen;
|
||||||
@ -380,23 +395,37 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount)
|
|||||||
if (_glfwLibrary.X11.RandR.available)
|
if (_glfwLibrary.X11.RandR.available)
|
||||||
{
|
{
|
||||||
#if defined(_GLFW_HAS_XRANDR)
|
#if defined(_GLFW_HAS_XRANDR)
|
||||||
XRRScreenConfiguration* sc;
|
XRRScreenResources* resource;
|
||||||
XRRScreenSize* sizelist;
|
unsigned int a;
|
||||||
int sizecount;
|
resource = XRRGetScreenResources(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
|
||||||
|
|
||||||
sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root);
|
resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * monitor->X11.output->nmode);
|
||||||
sizelist = XRRConfigSizes(sc, &sizecount);
|
|
||||||
|
|
||||||
resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * sizecount);
|
for (k = 0; k < monitor->X11.output->nmode; k++)
|
||||||
|
|
||||||
for (k = 0; k < sizecount; k++)
|
|
||||||
{
|
{
|
||||||
resarray[rescount].width = sizelist[k].width;
|
for (a = 0; a < resource->nmode; a++)
|
||||||
resarray[rescount].height = sizelist[k].height;
|
{
|
||||||
rescount++;
|
if (resource->modes[a].id != monitor->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*/
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
}
|
}
|
||||||
else if (_glfwLibrary.X11.VidMode.available)
|
else if (_glfwLibrary.X11.VidMode.available)
|
||||||
|
@ -578,6 +578,8 @@ int _glfwPlatformInit(void)
|
|||||||
|
|
||||||
_glfwInitJoysticks();
|
_glfwInitJoysticks();
|
||||||
|
|
||||||
|
_glfwInitMonitors();
|
||||||
|
|
||||||
// Start the timer
|
// Start the timer
|
||||||
_glfwInitTimer();
|
_glfwInitTimer();
|
||||||
|
|
||||||
@ -599,6 +601,8 @@ int _glfwPlatformTerminate(void)
|
|||||||
|
|
||||||
terminateDisplay();
|
terminateDisplay();
|
||||||
|
|
||||||
|
_glfwTerminateMonitors();
|
||||||
|
|
||||||
_glfwTerminateJoysticks();
|
_glfwTerminateJoysticks();
|
||||||
|
|
||||||
// Unload libGL.so if necessary
|
// Unload libGL.so if necessary
|
||||||
|
136
src/x11_monitor.c
Normal file
136
src/x11_monitor.c
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
//========================================================================
|
||||||
|
// GLFW - An OpenGL library
|
||||||
|
// Platform: X11 (Unix)
|
||||||
|
// API version: 3.0
|
||||||
|
// WWW: http://www.glfw.org/
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||||
|
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
//
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
//
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would
|
||||||
|
// be appreciated but is not required.
|
||||||
|
//
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not
|
||||||
|
// be misrepresented as being the original software.
|
||||||
|
//
|
||||||
|
// 3. This notice may not be removed or altered from any source
|
||||||
|
// distribution.
|
||||||
|
//
|
||||||
|
//========================================================================
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
////// GLFW platform API //////
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#if defined (_GLFW_HAS_XRANDR)
|
||||||
|
_GLFWmonitor** _glfwCreateMonitor(_GLFWmonitor** current,
|
||||||
|
XRROutputInfo* outputInfo,
|
||||||
|
XRRCrtcInfo* crtcInfo)
|
||||||
|
{
|
||||||
|
*current = _glfwMalloc(sizeof(_GLFWmonitor));
|
||||||
|
memset(*current, 0, sizeof(_GLFWmonitor));
|
||||||
|
|
||||||
|
(*current)->physicalWidth = outputInfo->mm_width;
|
||||||
|
(*current)->physicalHeight = outputInfo->mm_height;
|
||||||
|
|
||||||
|
(*current)->name = _glfwMalloc(strlen(outputInfo->name) + 1);
|
||||||
|
memcpy((*current)->name, outputInfo->name, strlen(outputInfo->name) + 1);
|
||||||
|
(*current)->name[strlen(outputInfo->name)] = '\0';
|
||||||
|
|
||||||
|
(*current)->screenX = crtcInfo->x;
|
||||||
|
(*current)->screenY = crtcInfo->y;
|
||||||
|
|
||||||
|
(*current)->X11.output = outputInfo;
|
||||||
|
return &((*current)->next);
|
||||||
|
}
|
||||||
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
|
|
||||||
|
_GLFWmonitor* _glfwDestroyMonitor(_GLFWmonitor* monitor)
|
||||||
|
{
|
||||||
|
_GLFWmonitor* result;
|
||||||
|
|
||||||
|
result = monitor->next;
|
||||||
|
|
||||||
|
#if defined (_GLFW_HAS_XRANDR)
|
||||||
|
XRRFreeOutputInfo(monitor->X11.output);
|
||||||
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
|
|
||||||
|
_glfwFree(monitor->name);
|
||||||
|
_glfwFree(monitor);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwInitMonitors(void)
|
||||||
|
{
|
||||||
|
_glfwLibrary.monitorListHead = NULL;
|
||||||
|
|
||||||
|
if (_glfwLibrary.X11.RandR.available)
|
||||||
|
{
|
||||||
|
#if defined (_GLFW_HAS_XRANDR)
|
||||||
|
XRRScreenResources* resources;
|
||||||
|
int outputIDX;
|
||||||
|
_GLFWmonitor** curMonitor;
|
||||||
|
|
||||||
|
curMonitor = &_glfwLibrary.monitorListHead;
|
||||||
|
|
||||||
|
resources = XRRGetScreenResources(_glfwLibrary.X11.display,
|
||||||
|
_glfwLibrary.X11.root);
|
||||||
|
|
||||||
|
for (outputIDX = 0; outputIDX < resources->noutput; outputIDX++)
|
||||||
|
{
|
||||||
|
// physical device
|
||||||
|
XRROutputInfo* outputInfo = NULL;
|
||||||
|
// logical surface
|
||||||
|
XRRCrtcInfo* crtcInfo = NULL;
|
||||||
|
int crtcIDX;
|
||||||
|
|
||||||
|
outputInfo = XRRGetOutputInfo(_glfwLibrary.X11.display,
|
||||||
|
resources,
|
||||||
|
resources->outputs[outputIDX]);
|
||||||
|
|
||||||
|
if (outputInfo->connection == RR_Connected)
|
||||||
|
{
|
||||||
|
for (crtcIDX = 0; crtcIDX < outputInfo->ncrtc; crtcIDX++)
|
||||||
|
{
|
||||||
|
if (outputInfo->crtc == outputInfo->crtcs[crtcIDX])
|
||||||
|
{
|
||||||
|
crtcInfo = XRRGetCrtcInfo(_glfwLibrary.X11.display,
|
||||||
|
resources,
|
||||||
|
outputInfo->crtcs[crtcIDX]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curMonitor = _glfwCreateMonitor(curMonitor, outputInfo, crtcInfo);
|
||||||
|
|
||||||
|
// Freeing of the outputInfo is done in _glfwDestroyMonitor
|
||||||
|
XRRFreeCrtcInfo(crtcInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glfwTerminateMonitors(void)
|
||||||
|
{
|
||||||
|
while (_glfwLibrary.monitorListHead)
|
||||||
|
_glfwLibrary.monitorListHead = _glfwDestroyMonitor(_glfwLibrary.monitorListHead);
|
||||||
|
}
|
||||||
|
|
@ -91,6 +91,7 @@
|
|||||||
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11
|
#define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowX11 X11
|
||||||
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
#define _GLFW_PLATFORM_LIBRARY_STATE _GLFWlibraryX11 X11
|
||||||
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextGLX GLX
|
||||||
|
#define _GLFW_PLATFORM_MONITOR_STATE _GLFWmonitorX11 X11
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -247,6 +248,20 @@ GLFWGLOBAL struct {
|
|||||||
} _glfwJoy[GLFW_JOYSTICK_LAST + 1];
|
} _glfwJoy[GLFW_JOYSTICK_LAST + 1];
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Platform-specific window structure
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
typedef struct _GLFWmonitorX11
|
||||||
|
{
|
||||||
|
#if defined(_GLFW_HAS_XRANDR)
|
||||||
|
XRROutputInfo* output;
|
||||||
|
#else
|
||||||
|
int dummy;
|
||||||
|
#endif /*_GLFW_HAS_XRANDR*/
|
||||||
|
|
||||||
|
} _GLFWmonitorX11;
|
||||||
|
|
||||||
|
|
||||||
//========================================================================
|
//========================================================================
|
||||||
// Prototypes for platform specific internal functions
|
// Prototypes for platform specific internal functions
|
||||||
//========================================================================
|
//========================================================================
|
||||||
@ -264,6 +279,10 @@ void _glfwRestoreVideoMode(int screen);
|
|||||||
void _glfwInitJoysticks(void);
|
void _glfwInitJoysticks(void);
|
||||||
void _glfwTerminateJoysticks(void);
|
void _glfwTerminateJoysticks(void);
|
||||||
|
|
||||||
|
// Monitors
|
||||||
|
void _glfwInitMonitors(void);
|
||||||
|
void _glfwTerminateMonitors(void);
|
||||||
|
|
||||||
// Unicode support
|
// Unicode support
|
||||||
long _glfwKeySym2Unicode(KeySym keysym);
|
long _glfwKeySym2Unicode(KeySym keysym);
|
||||||
|
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||||
set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY})
|
||||||
|
|
||||||
|
if (UNIX AND NOT APPLE AND NOT CYGWIN)
|
||||||
|
find_library(MATH_LIBRARY m)
|
||||||
|
find_library(REALTIME_LIBRARY rt)
|
||||||
|
link_libraries(${MATH_LIBRARY} ${REALTIME_LIBRARY})
|
||||||
|
endif (UNIX AND NOT APPLE AND NOT CYGWIN)
|
||||||
|
|
||||||
include_directories(${GLFW_SOURCE_DIR}/include
|
include_directories(${GLFW_SOURCE_DIR}/include
|
||||||
${GLFW_SOURCE_DIR}/support
|
${GLFW_SOURCE_DIR}/support
|
||||||
${OPENGL_INCLUDE_DIR})
|
${OPENGL_INCLUDE_DIR})
|
||||||
|
@ -216,6 +216,19 @@ static const char* get_character_string(int character)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char* get_monitor_event_name(int event)
|
||||||
|
{
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case GLFW_MONITOR_CONNECTED:
|
||||||
|
return "connected";
|
||||||
|
case GLFW_MONITOR_DISCONNECTED:
|
||||||
|
return "disconnected";
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void window_size_callback(GLFWwindow window, int width, int height)
|
static void window_size_callback(GLFWwindow window, int width, int height)
|
||||||
{
|
{
|
||||||
printf("%08x at %0.3f: Window size: %i %i\n",
|
printf("%08x at %0.3f: Window size: %i %i\n",
|
||||||
@ -330,6 +343,16 @@ static void char_callback(GLFWwindow window, int character)
|
|||||||
get_character_string(character));
|
get_character_string(character));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void monitor_callback(GLFWmonitor monitor, int event)
|
||||||
|
{
|
||||||
|
printf("%08x at %0.3f: Monitor %s %s",
|
||||||
|
counter++,
|
||||||
|
glfwGetTime(),
|
||||||
|
glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
|
||||||
|
get_monitor_event_name(event));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
GLFWwindow window;
|
GLFWwindow window;
|
||||||
@ -354,6 +377,7 @@ int main(void)
|
|||||||
glfwSetScrollCallback(scroll_callback);
|
glfwSetScrollCallback(scroll_callback);
|
||||||
glfwSetKeyCallback(key_callback);
|
glfwSetKeyCallback(key_callback);
|
||||||
glfwSetCharCallback(char_callback);
|
glfwSetCharCallback(char_callback);
|
||||||
|
glfwSetMonitorDeviceCallback(monitor_callback);
|
||||||
|
|
||||||
window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Event Linter", NULL);
|
window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Event Linter", NULL);
|
||||||
if (!window)
|
if (!window)
|
||||||
|
@ -18,6 +18,7 @@ static void print_mode(GLFWvidmode* mode)
|
|||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
GLFWmonitor monitor;
|
||||||
GLFWvidmode dtmode, modes[400];
|
GLFWvidmode dtmode, modes[400];
|
||||||
int modecount, i;
|
int modecount, i;
|
||||||
|
|
||||||
@ -32,16 +33,30 @@ int main(void)
|
|||||||
printf("Desktop mode: ");
|
printf("Desktop mode: ");
|
||||||
print_mode(&dtmode);
|
print_mode(&dtmode);
|
||||||
|
|
||||||
// List available video modes
|
monitor = NULL;
|
||||||
modecount = glfwGetVideoModes(modes, sizeof(modes) / sizeof(GLFWvidmode));
|
|
||||||
printf("Available modes:\n");
|
while ((monitor = glfwGetNextMonitor(monitor)))
|
||||||
for (i = 0; i < modecount; i++)
|
|
||||||
{
|
{
|
||||||
printf("%3i: ", i);
|
printf("Monitor name: %s\n"
|
||||||
print_mode(modes + i);
|
"Physical dimensions: %dmm x %dmm\n"
|
||||||
|
"Logical position: (%d,%d)\n",
|
||||||
|
glfwGetMonitorString(monitor, GLFW_MONITOR_NAME),
|
||||||
|
glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_WIDTH),
|
||||||
|
glfwGetMonitorParam(monitor, GLFW_MONITOR_PHYSICAL_HEIGHT),
|
||||||
|
glfwGetMonitorParam(monitor, GLFW_MONITOR_SCREEN_POS_X),
|
||||||
|
glfwGetMonitorParam(monitor, GLFW_MONITOR_SCREEN_POS_Y));
|
||||||
|
|
||||||
|
// List available video modes
|
||||||
|
modecount = glfwGetVideoModes(monitor, modes, sizeof(modes) / sizeof(GLFWvidmode));
|
||||||
|
printf("Available modes:\n");
|
||||||
|
|
||||||
|
for (i = 0; i < modecount; i++)
|
||||||
|
{
|
||||||
|
printf("%3i: ", i);
|
||||||
|
print_mode(modes + i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glfwTerminate();
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user