diff --git a/.gitignore b/.gitignore index 678ddf95..fad26de1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ CMakeCache.txt Makefile cmake_uninstall.cmake .DS_Store +docs/Doxyfile src/config.h src/libglfw.pc src/libglfw.so @@ -32,6 +33,7 @@ tests/peter tests/reopen tests/sharing tests/tearing +tests/title tests/windows tests/*.app tests/*.exe diff --git a/CMake/CheckX11Extensions.cmake b/CMake/CheckX11Extensions.cmake deleted file mode 100644 index a6f9b18b..00000000 --- a/CMake/CheckX11Extensions.cmake +++ /dev/null @@ -1,88 +0,0 @@ -# - Check if X11 RandR extension is available -# Check if the X11 extension RandR is available. -# This macro defines : -# - X11_RANDR_FOUND, If set to NO RandR is not available. -# - X11_RANDR_INCLUDE_DIR, includes directory containing the RandR header. -# - X11_RANDR_LIBRARIES, libraries to link in the library to use RandR. -# -# Created by Olivier Delannoy. -macro(CHECK_X11_XRANDR) - message(STATUS "Checking for X11 extension XRandR") - set(X11_XRANDR_FOUND "NO") - find_path(X11_XRANDR_INCLUDE_DIR "X11/extensions/Xrandr.h" - PATHS - /usr/local/include - /usr/local/X11/include - /usr/local/X11R6/include - /usr/include - /usr/X11/include - /usr/X11R6/include) - - find_library(X11_XRANDR_LIBRARIES NAMES Xrandr - PATHS - /usr/local/lib - /usr/local/X11/lib - /usr/local/X11R6/lib - /usr/lib - /usr/X11/lib - /usr/X11R6/lib) - # Create check if file compiles with randr - - if (X11_XRANDR_LIBRARIES AND X11_XRANDR_INCLUDE_DIR) - set(X11_XRANDR_FOUND "YES") - endif (X11_XRANDR_LIBRARIES AND X11_XRANDR_INCLUDE_DIR) - - if (X11_XRANDR_FOUND) - message(STATUS "Checking for X11 extension XRandR -- found") - else (X11_XRANDR_FOUND) - message(STATUS "Checking for X11 extension XRandR -- not found") - endif (X11_XRANDR_FOUND) - - mark_as_advanced(X11_XRANDR_LIBRARIES X11_XRANDR_INCLUDE_DIR) -endmacro(CHECK_X11_XRANDR) - - -# - Check if X11 VidMod extension is available -# Check if the X11 extension VidMod is available. -# This macro defines : -# - X11_VIDMOD_FOUND, If set to NO VidMod is not available. -# - X11_VIDMOD_INCLUDE_DIR, includes directory containing the headers. -# - X11_VIDMOD_LIBRARIES, libraries to link in the libraries. -# -# Created by Olivier Delannoy. -macro(CHECK_X11_XF86VIDMODE) - message(STATUS "Checking for X11 extension xf86vidmode") - set(X11_XF86VIDMODE_FOUND "NO") - find_path(X11_XF86VIDMODE_INCLUDE_DIR "X11/extensions/xf86vmode.h" - PATHS - /usr/local/include - /usr/local/X11/include - /usr/local/X11R6/include - /usr/include - /usr/X11/include - /usr/X11R6/include) - - find_library(X11_XF86VIDMODE_LIBRARIES NAMES Xxf86vm PATHS - /usr/local/lib - /usr/local/X11/lib - /usr/local/X11R6/lib - /usr/lib - /usr/X11/lib - /usr/X11R6/lib) - # Add a test case here - if (X11_XF86VIDMODE_LIBRARIES AND X11_XF86VIDMODE_INCLUDE_DIR) - set(X11_XF86VIDMODE_FOUND "YES") - endif (X11_XF86VIDMODE_LIBRARIES AND X11_XF86VIDMODE_INCLUDE_DIR) - - if (X11_XF86VIDMODE_FOUND) - message(STATUS "Checking for X11 extension xf86vidmode -- found") - else (X11_XF86VIDMODE_FOUND) - message(STATUS "Checking for X11 extension xf86vidmode -- not found") - endif(X11_XF86VIDMODE_FOUND) - - mark_as_advanced( - X11_XF86VIDMODE_LIBRARIES - X11_XF86VIDMODE_INCLUDE_DIR - ) - -endmacro(CHECK_X11_XF86VIDMODE) diff --git a/CMake/README.txt b/CMake/README.txt index d24854ed..9581f832 100644 --- a/CMake/README.txt +++ b/CMake/README.txt @@ -1,10 +1,19 @@ -This folder contains a collection of toolchains definition in order to -support cross compilation. The naming scheme is the following: +This directory contains a collection of toolchain definitions for cross +compilation, currently limited to compiling Win32 binaries on Linux. + +The toolchain file naming scheme is as follows: + host-system-compiler.cmake -to use this at the time you run the initial cmake command use the -following parameter - -DCMAKE_TOOLCHAIN_FILE=./toolchains/XXX-XXX-XXX.cmake - which maps to file in this folder. +To use these files you add a special parameter when configuring the source tree: + + cmake -DCMAKE_TOOLCHAIN_FILE= . + +For example, to use the Debian GNU/Linux MinGW package, run CMake like this: + + cmake -DCMAKE_TOOLCHAIN_FILE=CMake/linux-i586-mingw32msvc.cmake . + +For more details see this article: + + http://www.paraview.org/Wiki/CMake_Cross_Compiling -For more details see: http://www.paraview.org/Wiki/CMake_Cross_Compiling diff --git a/CMake/linux-mingw32msvc.cmake b/CMake/linux-i586-mingw32msvc.cmake similarity index 100% rename from CMake/linux-mingw32msvc.cmake rename to CMake/linux-i586-mingw32msvc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ce887061..f27cf7cd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,6 @@ project(GLFW C) -cmake_minimum_required(VERSION 2.4) -cmake_policy(VERSION 2.4) +cmake_minimum_required(VERSION 2.8) set(GLFW_VERSION_MAJOR "3") set(GLFW_VERSION_MINOR "0") @@ -27,7 +26,7 @@ if (WIN32) # Set up library and include paths list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR}) list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) -endif (WIN32) +endif() #-------------------------------------------------------------------- # Set up GLFW for Xlib and GLX on Unix-like systems with X Windows @@ -38,6 +37,8 @@ if (UNIX AND NOT APPLE) # Define the platform identifier set(_GLFW_X11_GLX 1) + find_package(X11 REQUIRED) + # Set up library and include paths list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) list(APPEND GLFW_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) @@ -45,61 +46,58 @@ if (UNIX AND NOT APPLE) find_library(MATH_LIBRARY m) if (MATH_LIBRARY) list(APPEND GLFW_LIBRARIES ${MATH_LIBRARY}) - endif(MATH_LIBRARY) + endif() find_library(RT_LIBRARY rt) if (RT_LIBRARY) list(APPEND GLFW_LIBRARIES ${RT_LIBRARY}) - endif(RT_LIBRARY) + endif() include(CheckFunctionExists) include(CheckSymbolExists) - include(${GLFW_SOURCE_DIR}/CMake/CheckX11Extensions.cmake) set(CMAKE_REQUIRED_LIBRARIES ${GLFW_LIBRARIES}) # Check for XRandR (modern resolution switching extension) - check_x11_xrandr() - if (X11_XRANDR_FOUND) + if (X11_Xrandr_FOUND) set(_GLFW_HAS_XRANDR 1) - list(APPEND GLFW_INCLUDE_DIR ${X11_XRANDR_INCLUDE_DIR}) - list(APPEND GLFW_LIBRARIES ${X11_XRANDR_LIBRARIES}) - endif(X11_XRANDR_FOUND) + list(APPEND GLFW_INCLUDE_DIR ${X11_Xrandr_INCLUDE_PATH}) + list(APPEND GLFW_LIBRARIES ${X11_Xrandr_LIB}) + endif() # Check for Xf86VidMode (fallback legacy resolution switching extension) - check_x11_xf86vidmode() - if (X11_XF86VIDMODE_FOUND) + if (X11_xf86vmode_FOUND) set(_GLFW_HAS_XF86VIDMODE 1) - list(APPEND GLFW_INCLUDE_DIR ${X11_XF86VIDMODE_INCLUDE_DIR}) - list(APPEND GLFW_LIBRARIES ${X11_XF86VIDMODE_LIBRARIES}) - endif(X11_XF86VIDMODE_FOUND) + list(APPEND GLFW_INCLUDE_DIR ${X11_xf86vmode_INCLUDE_PATH}) + endif() # Check for Xkb (X keyboard extension) - check_function_exists(XkbQueryExtension _GLFW_HAS_XKB) + if (X11_Xkb_FOUND) + set(_GLFW_HAS_XKB 1) + list(APPEND GLFW_INCLUDE_DIR ${X11_Xkb_INCLUDE_PATH}) + endif() # Check for glXGetProcAddress check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS) check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS) + endif() if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) + endif() if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) message(WARNING "No glXGetProcAddressXXX variant found") - endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND - NOT _GLFW_HAS_GLXGETPROCADDRESSARB AND - NOT _GLFW_HAS_GLXGETPROCADDRESSEXT) + endif() if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(_GLFW_USE_LINUX_JOYSTICKS 1) - endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") -endif(UNIX AND NOT APPLE) + endif() +endif() #-------------------------------------------------------------------- # Set up GLFW for Cocoa and NSOpenGL on Mac OS X @@ -120,7 +118,7 @@ if (UNIX AND APPLE) set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5") else(GLFW_BUILD_UNIVERSAL) message(STATUS "Building GLFW only for the native architecture") - endif(GLFW_BUILD_UNIVERSAL) + endif() # Set up library and include paths find_library(COCOA_FRAMEWORK Cocoa) @@ -130,7 +128,7 @@ if (UNIX AND APPLE) list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) list(APPEND GLFW_LIBRARIES ${IOKIT_FRAMEWORK}) list(APPEND GLFW_LIBRARIES ${CORE_FOUNDATION_FRAMEWORK}) -endif(UNIX AND APPLE) +endif() #-------------------------------------------------------------------- # Add subdirectories @@ -139,11 +137,11 @@ add_subdirectory(src) if (GLFW_BUILD_EXAMPLES) add_subdirectory(examples) -endif(GLFW_BUILD_EXAMPLES) +endif() if (GLFW_BUILD_TESTS) add_subdirectory(tests) -endif(GLFW_BUILD_TESTS) +endif() #-------------------------------------------------------------------- # Create shared configuration header @@ -161,23 +159,20 @@ install(DIRECTORY include/GL DESTINATION include install(FILES COPYING.txt readme.html DESTINATION share/doc/glfw-${GLFW_VERSION_FULL}/) -# The respective port's CMakeLists.txt file installs the library +# The src directory's CMakeLists.txt file installs the library #-------------------------------------------------------------------- # -- Documentation generation #-------------------------------------------------------------------- -#include("${GLFW_SOURCE_DIR}/documentation.cmake") -#configure_file("${GLFW_SOURCE_DIR}/Doxyfile.in" -# "${GLFW_BINARY_DIR}/Doxyfile" -# IMMEDIATE @ONLY) -#add_doxygen_target("${GLFW_BINARY_DIR}/Doxyfile") -#add_subdirectory(docs) +configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" + "${GLFW_BINARY_DIR}/docs/Doxyfile" + @ONLY) #-------------------------------------------------------------------- # Uninstall operation # Don't generate this target if a higher-level project already has #-------------------------------------------------------------------- -if(NOT TARGET uninstall) +if (NOT TARGET uninstall) configure_file(${GLFW_SOURCE_DIR}/cmake_uninstall.cmake.in ${GLFW_BINARY_DIR}/cmake_uninstall.cmake IMMEDIATE @ONLY) diff --git a/docs/Doxyfile.in b/docs/Doxyfile.in new file mode 100644 index 00000000..1d524c11 --- /dev/null +++ b/docs/Doxyfile.in @@ -0,0 +1,1687 @@ +# Doxyfile 1.7.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = GLFW + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @GLFW_VERSION_FULL@ + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewer +# a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @GLFW_BINARY_DIR@/docs + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing +# a simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still +# accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 0 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = @GLFW_BINARY_DIR@/docs/warnings.txt + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @GLFW_SOURCE_DIR@/include/GL/glfw3.h + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = APIENTRY GLFWAPI + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = glfw GLFW_ + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [0,1..20]) that +# doxygen will group on one line in the generated HTML documentation. Note that +# a value of 0 will completely suppress the enum values from appearing in the +# overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the +# mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = YES + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = YES + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = GLFWAPI= + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that +# overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, svg, gif or svg. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index d511b22d..a644b987 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -7,28 +7,42 @@ include_directories(${GLFW_SOURCE_DIR}/include ${GLFW_SOURCE_DIR}/support ${OPENGL_INCLUDE_DIR}) -if(APPLE) - # Set fancy names for bundles - add_executable(Boing MACOSX_BUNDLE boing.c) - add_executable(Gears MACOSX_BUNDLE gears.c) - add_executable("Split View" MACOSX_BUNDLE splitview.c) - add_executable(Triangle MACOSX_BUNDLE triangle.c) - add_executable(Wave MACOSX_BUNDLE wave.c) -else(APPLE) - # Set boring names for executables - add_executable(boing WIN32 boing.c) - add_executable(gears WIN32 gears.c) - add_executable(heightmap WIN32 heightmap.c getopt.c) - add_executable(splitview WIN32 splitview.c) - add_executable(triangle WIN32 triangle.c) - add_executable(wave WIN32 wave.c) -endif(APPLE) +if (APPLE) + # Set fancy names for bundles + add_executable(Boing MACOSX_BUNDLE boing.c) + add_executable(Gears MACOSX_BUNDLE gears.c) + add_executable("Split View" MACOSX_BUNDLE splitview.c) + add_executable(Triangle MACOSX_BUNDLE triangle.c) + add_executable(Wave MACOSX_BUNDLE wave.c) -set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave) + set_target_properties(Boing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Boing") + set_target_properties(Gears PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Gears") + set_target_properties("Split View" PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Split View") + set_target_properties(Triangle PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Triangle") + set_target_properties(Wave PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Wave") +else() + # Set boring names for executables + add_executable(boing WIN32 boing.c) + add_executable(gears WIN32 gears.c) + add_executable(heightmap WIN32 heightmap.c getopt.c) + add_executable(splitview WIN32 splitview.c) + add_executable(triangle WIN32 triangle.c) + add_executable(wave WIN32 wave.c) +endif() -if(MSVC) - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif(MSVC) +if (MSVC) + set(WINDOWS_BINARIES boing gears heightmap splitview triangle wave) + + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set(BUNDLE_BINARIES Boing Gears "Split View" Triangle Wave) + + set_target_properties(${BUNDLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() diff --git a/examples/boing.c b/examples/boing.c index 914d1291..33696e46 100644 --- a/examples/boing.c +++ b/examples/boing.c @@ -586,7 +586,7 @@ int main( void ) } glfwSetWindowSizeCallback( reshape ); - glfwEnable( window, GLFW_STICKY_KEYS ); + glfwSetInputMode( window, GLFW_STICKY_KEYS, GL_TRUE ); glfwSwapInterval( 1 ); glfwSetTime( 0.0 ); diff --git a/examples/gears.c b/examples/gears.c index cb31b1f8..53d601f3 100644 --- a/examples/gears.c +++ b/examples/gears.c @@ -339,7 +339,7 @@ int main(int argc, char *argv[]) exit( EXIT_FAILURE ); } - glfwEnable( window, GLFW_KEY_REPEAT ); + glfwSetInputMode( window, GLFW_KEY_REPEAT, GL_TRUE ); glfwSwapInterval( 1 ); // Parse command-line options diff --git a/examples/heightmap.c b/examples/heightmap.c index b4dcf082..f4bec28c 100644 --- a/examples/heightmap.c +++ b/examples/heightmap.c @@ -573,7 +573,7 @@ int main(int argc, char** argv) } } - if (GL_TRUE != glfwInit()) + if (!glfwInit()) { fprintf(stderr, "ERROR: Unable to initialize GLFW\n"); usage(); diff --git a/examples/splitview.c b/examples/splitview.c index f37c4142..2cd43fdf 100644 --- a/examples/splitview.c +++ b/examples/splitview.c @@ -462,10 +462,10 @@ int main(void) glfwSwapInterval(1); // Enable sticky keys - glfwEnable(window, GLFW_STICKY_KEYS); + glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Enable mouse cursor (only needed for fullscreen mode) - glfwSetCursorMode(window, GLFW_CURSOR_NORMAL); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); // Set callback functions glfwSetWindowSizeCallback(windowSizeFun); diff --git a/examples/triangle.c b/examples/triangle.c index c61baeff..e61ea9ab 100644 --- a/examples/triangle.c +++ b/examples/triangle.c @@ -30,7 +30,7 @@ int main(void) } // Ensure we can capture the escape key being pressed below - glfwEnable(window, GLFW_STICKY_KEYS); + glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE); // Enable vertical sync (on cards that support it) glfwSwapInterval(1); diff --git a/examples/wave.c b/examples/wave.c index 26a0ca1a..1eb8b855 100644 --- a/examples/wave.c +++ b/examples/wave.c @@ -309,13 +309,13 @@ void mouse_button_callback(GLFWwindow window, int button, int action) if (action == GLFW_PRESS) { - glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED); locked = GL_TRUE; } else { locked = GL_FALSE; - glfwSetCursorMode(window, GLFW_CURSOR_NORMAL); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); } } @@ -396,7 +396,7 @@ int main(int argc, char* argv[]) // Keyboard handler glfwSetKeyCallback(key_callback); - glfwEnable(window, GLFW_KEY_REPEAT); + glfwSetInputMode(window, GLFW_KEY_REPEAT, GL_TRUE); // Window resize handler glfwSetWindowSizeCallback(window_resize_callback); diff --git a/include/GL/glfw3.h b/include/GL/glfw3.h index 31d8f199..7271e628 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -136,10 +136,6 @@ extern "C" { /* -------------------- END SYSTEM/COMPILER SPECIFIC --------------------- */ -/* Include the declaration of the size_t type used below. - */ -#include - /* Include standard OpenGL headers: GLFW uses GL_FALSE/GL_TRUE, and it is * convenient for the user to only have to include . This also * solves the problem with Windows and needing some @@ -427,13 +423,14 @@ extern "C" { #define GLFW_OPENGL_COMPAT_PROFILE 0x00000002 #define GLFW_OPENGL_ES2_PROFILE 0x00000004 -/* glfwEnable/glfwDisable tokens */ +/* glfwGetInputMode/glfwSetInputMode tokens */ +#define GLFW_CURSOR_MODE 0x00030001 #define GLFW_STICKY_KEYS 0x00030002 #define GLFW_STICKY_MOUSE_BUTTONS 0x00030003 #define GLFW_SYSTEM_KEYS 0x00030004 #define GLFW_KEY_REPEAT 0x00030005 -/* glfwSetCursorMode tokens */ +/* GLFW_CURSOR_MODE values */ #define GLFW_CURSOR_NORMAL 0x00040001 #define GLFW_CURSOR_HIDDEN 0x00040002 #define GLFW_CURSOR_CAPTURED 0x00040003 @@ -478,8 +475,6 @@ typedef void (* GLFWcursorenterfun)(GLFWwindow,int); typedef void (* GLFWscrollfun)(GLFWwindow,int,int); typedef void (* GLFWkeyfun)(GLFWwindow,int,int); typedef void (* GLFWcharfun)(GLFWwindow,int); -typedef void* (* GLFWmallocfun)(size_t); -typedef void (* GLFWfreefun)(void*); /* The video mode structure used by glfwGetVideoModes */ typedef struct @@ -499,19 +494,6 @@ typedef struct unsigned short blue[GLFW_GAMMA_RAMP_SIZE]; } GLFWgammaramp; -/* Custom memory allocator interface */ -typedef struct -{ - GLFWmallocfun malloc; - GLFWfreefun free; -} GLFWallocator; - -/* Custom threading model interface */ -typedef struct -{ - int dummy; -} GLFWthreadmodel; - /************************************************************************* * Prototypes @@ -519,7 +501,6 @@ typedef struct /* Initialization, termination and version querying */ GLFWAPI int glfwInit(void); -GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator); GLFWAPI void glfwTerminate(void); GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev); GLFWAPI const char* glfwGetVersionString(void); @@ -564,11 +545,12 @@ GLFWAPI void glfwPollEvents(void); GLFWAPI void glfwWaitEvents(void); /* Input handling */ +GLFWAPI int glfwGetInputMode(GLFWwindow window, int mode); +GLFWAPI void glfwSetInputMode(GLFWwindow window, int mode, int value); GLFWAPI int glfwGetKey(GLFWwindow window, int key); GLFWAPI int glfwGetMouseButton(GLFWwindow window, int button); GLFWAPI void glfwGetMousePos(GLFWwindow window, int* xpos, int* ypos); GLFWAPI void glfwSetMousePos(GLFWwindow window, int xpos, int ypos); -GLFWAPI void glfwSetCursorMode(GLFWwindow window, int mode); GLFWAPI void glfwGetScrollOffset(GLFWwindow window, int* xoffset, int* yoffset); GLFWAPI void glfwSetKeyCallback(GLFWkeyfun cbfun); GLFWAPI void glfwSetCharCallback(GLFWcharfun cbfun); @@ -595,10 +577,6 @@ GLFWAPI int glfwExtensionSupported(const char* extension); GLFWAPI void* glfwGetProcAddress(const char* procname); GLFWAPI void glfwCopyContext(GLFWwindow src, GLFWwindow dst, unsigned long mask); -/* Enable/disable functions */ -GLFWAPI void glfwEnable(GLFWwindow window, int token); -GLFWAPI void glfwDisable(GLFWwindow window, int token); - /************************************************************************* * Global definition cleanup diff --git a/readme.html b/readme.html index 49eaa376..ea2d34da 100644 --- a/readme.html +++ b/readme.html @@ -272,9 +272,7 @@ version of GLFW.

  • Added glfwSetWindowFocusCallback function and GLFWwindowfocusfun type for receiving window focus events
  • Added glfwSetWindowIconifyCallback function and GLFWwindowiconifyfun type for receiving window iconification events
  • Added glfwGetCurrentContext function for retrieving the window whose OpenGL context is current
  • -
  • Added glfwInitWithModels function and GLFWallocator and GLFWthreadmodel types for pluggable memory allocation and threading models
  • Added glfwCopyContext function for copying OpenGL state categories between contexts
  • -
  • Added glfwSetCursorMode function for controlling per-window cursor mode, replacing GLFW_MOUSE_CURSOR
  • Added GLFW_OPENGL_ES2_PROFILE profile for creating OpenGL ES 2.0 contexts using the GLX_EXT_create_context_es2_profile and WGL_EXT_create_context_es2_profile extensions
  • Added GLFW_OPENGL_ROBUSTNESS window hint and associated strategy tokens for GL_ARB_robustness support
  • Added GLFW_OPENGL_REVISION window parameter to make up for removal of glfwGetGLVersion
  • @@ -282,10 +280,12 @@ version of GLFW.

  • Added windows simple multi-window test program
  • Added sharing simple OpenGL object sharing test program
  • Added dynamic simple dynamic linking test program
  • +
  • Added modes video mode enumeration and setting test program
  • Added a parameter to glfwOpenWindow for specifying a context the new window's context will share objects with
  • Added initial window title parameter to glfwOpenWindow
  • Added glfwSetGamma, glfwSetGammaRamp and glfwGetGammaRamp functions and GLFWgammaramp type for monitor gamma ramp control
  • Changed buffer bit depth parameters of glfwOpenWindow to window hints
  • +
  • Changed glfwOpenWindow and glfwSetWindowTitle to use UTF-8 encoded strings
  • Renamed glfw.h to glfw3.h to avoid conflicts with 2.x series
  • Renamed GLFW_WINDOW token to GLFW_WINDOWED
  • Renamed GLFW_WINDOW_NO_RESIZE to GLFW_WINDOW_RESIZABLE
  • @@ -293,6 +293,7 @@ version of GLFW.

  • Replaced ad hoc build system with CMake
  • Replaced layout-dependent key codes with single, platform-independent set based on US layout
  • Replaced mouse wheel interface with two-dimensional scrolling interface
  • +
  • Replaced glfwEnable and glfwDisable with glfwGetInputMode and glfwSetInputMode
  • Made Unicode character input unaffected by GLFW_KEY_REPEAT
  • Removed event auto-polling and the GLFW_AUTO_POLL_EVENTS window enable
  • Removed the Win32 port .def files
  • @@ -310,17 +311,29 @@ version of GLFW.

  • Bugfix: The FSAA test did not check for the availability of GL_ARB_multisample
  • [Cocoa] Added support for OpenGL 3.2 core profile in 10.7 Lion and above
  • [Cocoa] Added support for joysticks
  • +
  • [Cocoa] Postponed menu creation to first window creation
  • +
  • [Cocoa] Replaced NSDate time source with mach_absolute_time
  • +
  • [Cocoa] Replaced all deprecated CoreGraphics calls with non-deprecated counterparts
  • +
  • [Cocoa] Bugfix: The NSOpenGLPFAFullScreen pixel format attribute caused creation to fail on some machines
  • +
  • [Cocoa] Bugfix: glfwOpenWindow did not properly enforce the forward-compatible and context profile hints
  • [Cocoa] Bugfix: The loop condition for saving video modes used the wrong index variable
  • [Cocoa] Bugfix: The OpenGL framework was not retrieved, making glfwGetProcAddress crash
  • +
  • [Cocoa] Bugfix: glfwInit changed the current directory for unbundled executables
  • +
  • [Cocoa] Bugfix: The GLFW_WINDOW_NO_RESIZE window parameter was always zero
  • [X11] Added support for the GLX_EXT_swap_control extension as an alternative to GLX_SGI_swap_control
  • [X11] Added the POSIX CLOCK_MONOTONIC time source as the preferred method
  • [X11] Added dependency on libm, where present
  • +
  • [X11] Added support for the _NET_WM_NAME and _NET_WM_ICON_NAME EWMH window properties
  • +
  • [X11] Bugfix: Some window properties required by the ICCCM were not set
  • [X11] Bugfix: Calling glXCreateContextAttribsARB with an unavailable OpenGL version caused the application to terminate with a BadMatch Xlib error
  • [X11] Bugfix: A synchronization point necessary for jitter-free locked cursor mode was incorrectly removed
  • +
  • [Win32] Changed port to use Unicode mode only
  • [Win32] Removed explicit support for versions of Windows older than Windows XP
  • [Win32] Bugfix: Window activation and iconification did not work as expected
  • [Win32] Bugfix: Software rasterizer pixel formats were not discarded by the WGL_ARB_pixel_format code path
  • [Win32] Bugfix: The array for WGL context attributes was too small and could overflow
  • +
  • [Win32] Bugfix: Alt+F4 hot key was not translated into WM_CLOSE
  • +
  • [Win32] Bugfix: The GLFW_WINDOW_NO_RESIZE window parameter was always zero
  • v2.7

    @@ -810,6 +823,8 @@ their skills. Special thanks go out to:

      +
    • artblanc, for a patch replacing a deprecated Core Graphics call
    • +
    • Bobyshev Alexander and Martins Mozeiko, for the original proposal of an FSAA hint and their work on the Win32 implementation of FSAA
    • @@ -865,6 +880,9 @@ their skills. Special thanks go out to:

    • Tristam MacDonald, for his bug reports and feedback on the Cocoa port
    • +
    • Hans 'Hanmac' Mackowiak, for adding UTF-8 window title support on X11 and + a fix for the Xkb support
    • +
    • David Medlock, for doing the initial Lua port
    • Kenneth Miller, for his many and detailed bug reports on Win32
    • diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f15089e9..bdc4d5fe 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,43 +1,43 @@ if(UNIX) - if(_GLFW_HAS_XRANDR) + if (_GLFW_HAS_XRANDR) set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xrandr") - endif(_GLFW_HAS_XRANDR) - if(_GLFW_HAS_XF86VIDMODE) + endif() + if (_GLFW_HAS_XF86VIDMODE) set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xxf86vm") - endif(_GLFW_HAS_XF86VIDMODE) + endif() configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libglfw.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc @ONLY) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libglfw.pc DESTINATION lib/pkgconfig) -endif(UNIX) +endif() include_directories(${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${GLFW_INCLUDE_DIR}) -set(common_SOURCES enable.c error.c fullscreen.c gamma.c init.c input.c +set(common_SOURCES error.c fullscreen.c gamma.c init.c input.c joystick.c opengl.c time.c window.c) if(_GLFW_COCOA_NSGL) - set(libglfw_SOURCES ${common_SOURCES} cocoa_enable.m cocoa_fullscreen.m - cocoa_gamma.m cocoa_init.m cocoa_joystick.m - cocoa_opengl.m cocoa_time.m cocoa_window.m) + set(libglfw_SOURCES ${common_SOURCES} cocoa_fullscreen.m cocoa_gamma.c + cocoa_init.m cocoa_input.m cocoa_joystick.m + cocoa_opengl.m cocoa_time.c cocoa_window.m) # For some reason, CMake doesn't know about .m set_source_files_properties(${libglfw_SOURCES} PROPERTIES LANGUAGE C) elseif(_GLFW_WIN32_WGL) - set(libglfw_SOURCES ${common_SOURCES} win32_enable.c win32_fullscreen.c - win32_gamma.c win32_init.c win32_joystick.c + set(libglfw_SOURCES ${common_SOURCES} win32_fullscreen.c win32_gamma.c + win32_init.c win32_input.c win32_joystick.c win32_opengl.c win32_time.c win32_window.c win32_dllmain.c) elseif(_GLFW_X11_GLX) - set(libglfw_SOURCES ${common_SOURCES} x11_enable.c x11_fullscreen.c - x11_gamma.c x11_init.c x11_joystick.c + set(libglfw_SOURCES ${common_SOURCES} x11_fullscreen.c x11_gamma.c + x11_init.c x11_input.c x11_joystick.c x11_keysym2unicode.c x11_opengl.c x11_time.c x11_window.c) else() message(FATAL_ERROR "No supported platform was selected") -endif(_GLFW_COCOA_NSGL) +endif() add_library(libglfwStatic STATIC ${libglfw_SOURCES}) add_library(libglfwShared SHARED ${libglfw_SOURCES}) @@ -47,22 +47,23 @@ set_target_properties(libglfwStatic libglfwShared PROPERTIES OUTPUT_NAME glfw) if(WIN32) + target_link_libraries(libglfwShared winmm) # The GLFW DLL needs a special compile-time macro and import library name set_target_properties(libglfwShared PROPERTIES - DEFINE_SYMBOL GLFW_BUILD_DLL + COMPILE_DEFINITIONS "GLFW_BUILD_DLL;_GLFW_NO_DLOAD_GDI32;_GLFW_NO_DLOAD_WINMM" PREFIX "" IMPORT_PREFIX "" IMPORT_SUFFIX "dll.lib") -endif(WIN32) +endif() if(APPLE) # Append -fno-common to the compile flags to work around a bug in the Apple GCC get_target_property(CFLAGS libglfwShared COMPILE_FLAGS) - if(NOT CFLAGS) + if (NOT CFLAGS) set(CFLAGS "") - endif(NOT CFLAGS) + endif() set_target_properties(libglfwShared PROPERTIES COMPILE_FLAGS "${CFLAGS} -fno-common") -endif(APPLE) +endif() install(TARGETS libglfwStatic libglfwShared DESTINATION lib) diff --git a/src/cocoa_fullscreen.m b/src/cocoa_fullscreen.m index 370296b8..147913fb 100644 --- a/src/cocoa_fullscreen.m +++ b/src/cocoa_fullscreen.m @@ -29,47 +29,166 @@ #include "internal.h" +#include +#include + //======================================================================== // Check whether the display mode should be included in enumeration //======================================================================== -static BOOL modeIsGood(NSDictionary* mode) +static GLboolean modeIsGood(CGDisplayModeRef mode) { - // This is a bit controversial, if you've got something other than an - // LCD computer monitor as an output device you might not want these - // checks. You might also want to reject modes which are interlaced, - // or TV out. There is no one-size-fits-all policy that can work here. - // This seems like a decent compromise, but certain applications may - // wish to patch this... - return [[mode objectForKey:(id)kCGDisplayBitsPerPixel] intValue] >= 15 && - [mode objectForKey:(id)kCGDisplayModeIsSafeForHardware] != nil && - [mode objectForKey:(id)kCGDisplayModeIsStretched] == nil; + uint32_t flags = CGDisplayModeGetIOFlags(mode); + if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag)) + return GL_FALSE; + + if (flags & kDisplayModeInterlacedFlag) + return GL_FALSE; + + if (flags & kDisplayModeTelevisionFlag) + return GL_FALSE; + + if (flags & kDisplayModeStretchedFlag) + return GL_FALSE; + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) && + CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0)) + { + CFRelease(format); + return GL_FALSE; + } + + CFRelease(format); + return GL_TRUE; } + //======================================================================== // Convert Core Graphics display mode to GLFW video mode //======================================================================== -static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode) +static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode) { - unsigned int width = - [[mode objectForKey:(id)kCGDisplayWidth] unsignedIntValue]; - unsigned int height = - [[mode objectForKey:(id)kCGDisplayHeight] unsignedIntValue]; - unsigned int bps = - [[mode objectForKey:(id)kCGDisplayBitsPerSample] unsignedIntValue]; - GLFWvidmode result; - result.width = width; - result.height = height; - result.redBits = bps; - result.greenBits = bps; - result.blueBits = bps; + result.width = CGDisplayModeGetWidth(mode); + result.height = CGDisplayModeGetHeight(mode); + + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + { + result.redBits = 5; + result.greenBits = 5; + result.blueBits = 5; + } + else + { + result.redBits = 8; + result.greenBits = 8; + result.blueBits = 8; + } + + CFRelease(format); return result; } +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Change the current video mode +//======================================================================== + +GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate) +{ + CGDisplayModeRef bestMode = NULL; + CFArrayRef modes; + CFIndex count, i; + unsigned int leastSizeDiff = UINT_MAX; + double leastRateDiff = DBL_MAX; + + modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + count = CFArrayGetCount(modes); + + for (i = 0; i < count; i++) + { + CGDisplayModeRef mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); + if (!modeIsGood(mode)) + continue; + + int modeBPP; + + // Identify display mode pixel encoding + { + CFStringRef format = CGDisplayModeCopyPixelEncoding(mode); + + if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0) + modeBPP = 16; + else + modeBPP = 32; + + CFRelease(format); + } + + int modeWidth = (int) CGDisplayModeGetWidth(mode); + int modeHeight = (int) CGDisplayModeGetHeight(mode); + + unsigned int sizeDiff = (abs(modeBPP - *bpp) << 25) | + ((modeWidth - *width) * (modeWidth - *width) + + (modeHeight - *height) * (modeHeight - *height)); + + double rateDiff; + + if (*refreshRate > 0) + rateDiff = fabs(CGDisplayModeGetRefreshRate(mode) - *refreshRate); + else + { + // If no refresh rate was specified, then they're all the same + rateDiff = 0; + } + + if ((sizeDiff < leastSizeDiff) || + (sizeDiff == leastSizeDiff && (rateDiff < leastRateDiff))) + { + bestMode = mode; + + leastSizeDiff = sizeDiff; + leastRateDiff = rateDiff; + } + } + + if (!bestMode) + { + CFRelease(modes); + return GL_FALSE; + } + + CGDisplayCapture(CGMainDisplayID()); + CGDisplaySetDisplayMode(CGMainDisplayID(), bestMode, NULL); + + CFRelease(modes); + return GL_TRUE; +} + + +//======================================================================== +// Restore the previously saved (original) video mode +//======================================================================== + +void _glfwRestoreVideoMode(void) +{ + CGDisplaySetDisplayMode(CGMainDisplayID(), + _glfwLibrary.NS.desktopMode, + NULL); + + CGDisplayRelease(CGMainDisplayID()); +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// @@ -80,19 +199,26 @@ static GLFWvidmode vidmodeFromCGDisplayMode(NSDictionary* mode) int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) { - NSArray* modes = (NSArray*) CGDisplayAvailableModes(CGMainDisplayID()); - unsigned int i, j = 0, n = [modes count]; + CGDisplayModeRef mode; + CFArrayRef modes; + CFIndex count, i; + int stored = 0; - for (i = 0; i < n && j < (unsigned)maxcount; i++) + modes = CGDisplayCopyAllDisplayModes(CGMainDisplayID(), NULL); + count = CFArrayGetCount(modes); + + for (i = 0; i < count && stored < maxcount; i++) { - NSDictionary *mode = [modes objectAtIndex:i]; + mode = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i); if (modeIsGood(mode)) - list[j++] = vidmodeFromCGDisplayMode(mode); + list[stored++] = vidmodeFromCGDisplayMode(mode); } - return j; + CFRelease(modes); + return stored; } + //======================================================================== // Get the desktop video mode //======================================================================== diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.c similarity index 98% rename from src/cocoa_gamma.m rename to src/cocoa_gamma.c index eb291082..53c47a89 100644 --- a/src/cocoa_gamma.m +++ b/src/cocoa_gamma.c @@ -32,6 +32,8 @@ #include #include +#include + //************************************************************************ //**** GLFW internal functions **** diff --git a/src/cocoa_init.m b/src/cocoa_init.m index bf4f7c2e..16bd98eb 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -27,162 +27,45 @@ // //======================================================================== -// Needed for _NSGetProgname -#include - #include "internal.h" //======================================================================== -// GLFW application class +// Change to our application bundle's resources directory, if present //======================================================================== -@interface GLFWApplication : NSApplication -@end - -@implementation GLFWApplication - -// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost -// This works around an AppKit bug, where key up events while holding -// down the command key don't get sent to the key window. -- (void)sendEvent:(NSEvent *)event +static void changeToResourcesDirectory(void) { - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) - [[self keyWindow] sendEvent:event]; - else - [super sendEvent:event]; -} + char resourcesPath[MAXPATHLEN]; -@end + CFBundleRef bundle = CFBundleGetMainBundle(); + if (!bundle) + return; + CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle); -// Prior to Snow Leopard, we need to use this oddly-named semi-private API -// to get the application menu working properly. Need to be careful in -// case it goes away in a future OS update. -@interface NSApplication (NSAppleMenu) -- (void)setAppleMenu:(NSMenu*)m; -@end - -// Keys to search for as potential application names -NSString* GLFWNameKeys[] = -{ - @"CFBundleDisplayName", - @"CFBundleName", - @"CFBundleExecutable", -}; - - -//======================================================================== -// Try to figure out what the calling application is called -//======================================================================== -static NSString* findAppName(void) -{ - unsigned int i; - NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; - - for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) + CFStringRef last = CFURLCopyLastPathComponent(resourcesURL); + if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo) { - id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; - if (name && - [name isKindOfClass:[NSString class]] && - ![@"" isEqualToString:name]) - { - return name; - } + CFRelease(last); + CFRelease(resourcesURL); + return; } - // If we get here, we're unbundled - if (!_glfwLibrary.NS.unbundled) + CFRelease(last); + + if (!CFURLGetFileSystemRepresentation(resourcesURL, + true, + (UInt8*) resourcesPath, + MAXPATHLEN)) { - // Could do this only if we discover we're unbundled, but it should - // do no harm... - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); - - // Having the app in front of the terminal window is also generally - // handy. There is an NSApplication API to do this, but... - SetFrontProcess(&psn); - - _glfwLibrary.NS.unbundled = GL_TRUE; + CFRelease(resourcesURL); + return; } - char** progname = _NSGetProgname(); - if (progname && *progname) - { - // TODO: UTF-8? - return [NSString stringWithUTF8String:*progname]; - } + CFRelease(resourcesURL); - // Really shouldn't get here - return @"GLFW Application"; -} - -//======================================================================== -// Set up the menu bar (manually) -// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that -// could go away at any moment, lots of stuff that really should be -// localize(d|able), etc. Loading a nib would save us this horror, but that -// doesn't seem like a good thing to require of GLFW's clients. -//======================================================================== -static void setUpMenuBar(void) -{ - NSString* appName = findAppName(); - - NSMenu* bar = [[NSMenu alloc] init]; - [NSApp setMainMenu:bar]; - - NSMenuItem* appMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* appMenu = [[NSMenu alloc] init]; - [appMenuItem setSubmenu:appMenu]; - - [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] - action:@selector(orderFrontStandardAboutPanel:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - NSMenu* servicesMenu = [[NSMenu alloc] init]; - [NSApp setServicesMenu:servicesMenu]; - [[appMenu addItemWithTitle:@"Services" - action:NULL - keyEquivalent:@""] setSubmenu:servicesMenu]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] - action:@selector(hide:) - keyEquivalent:@"h"]; - [[appMenu addItemWithTitle:@"Hide Others" - action:@selector(hideOtherApplications:) - keyEquivalent:@"h"] - setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask]; - [appMenu addItemWithTitle:@"Show All" - action:@selector(unhideAllApplications:) - keyEquivalent:@""]; - [appMenu addItem:[NSMenuItem separatorItem]]; - [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] - action:@selector(terminate:) - keyEquivalent:@"q"]; - - NSMenuItem* windowMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - [NSApp setWindowsMenu:windowMenu]; - [windowMenuItem setSubmenu:windowMenu]; - - [windowMenu addItemWithTitle:@"Miniaturize" - action:@selector(performMiniaturize:) - keyEquivalent:@"m"]; - [windowMenu addItemWithTitle:@"Zoom" - action:@selector(performZoom:) - keyEquivalent:@""]; - [windowMenu addItem:[NSMenuItem separatorItem]]; - [windowMenu addItemWithTitle:@"Bring All to Front" - action:@selector(arrangeInFront:) - keyEquivalent:@""]; - - // At least guard the call to private API to avoid an exception if it - // goes away. Hopefully that means the worst we'll break in future is to - // look ugly... - if ([NSApp respondsToSelector:@selector(setAppleMenu:)]) - [NSApp setAppleMenu:appMenu]; + chdir(resourcesPath); } @@ -198,9 +81,6 @@ int _glfwPlatformInit(void) { _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; - // Implicitly create shared NSApplication instance - [GLFWApplication sharedApplication]; - _glfwLibrary.NS.OpenGLFramework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); if (_glfwLibrary.NS.OpenGLFramework == NULL) @@ -210,31 +90,30 @@ int _glfwPlatformInit(void) return GL_FALSE; } - NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; + changeToResourcesDirectory(); - if (access([resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK) == 0) - chdir([resourcePath cStringUsingEncoding:NSUTF8StringEncoding]); - - // Setting up menu bar must go exactly here else weirdness ensues - setUpMenuBar(); - - [NSApp finishLaunching]; - - _glfwPlatformSetTime(0.0); - - _glfwLibrary.NS.desktopMode = - (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID()); + _glfwLibrary.NS.desktopMode = CGDisplayCopyDisplayMode(CGMainDisplayID()); // Save the original gamma ramp _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); _glfwLibrary.currentRamp = _glfwLibrary.originalRamp; + _glfwInitTimer(); + _glfwInitJoysticks(); + _glfwLibrary.NS.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); + if (!_glfwLibrary.NS.eventSource) + return GL_FALSE; + + CGEventSourceSetLocalEventsSuppressionInterval(_glfwLibrary.NS.eventSource, + 0.0); + return GL_TRUE; } + //======================================================================== // Close window, if open, and shut down GLFW //======================================================================== @@ -243,9 +122,17 @@ int _glfwPlatformTerminate(void) { // TODO: Probably other cleanup + if (_glfwLibrary.NS.eventSource) + { + CFRelease(_glfwLibrary.NS.eventSource); + _glfwLibrary.NS.eventSource = NULL; + } + // Restore the original gamma ramp _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); + CGDisplayModeRelease(_glfwLibrary.NS.desktopMode); + [NSApp setDelegate:nil]; [_glfwLibrary.NS.delegate release]; _glfwLibrary.NS.delegate = nil; diff --git a/src/cocoa_enable.m b/src/cocoa_input.m similarity index 100% rename from src/cocoa_enable.m rename to src/cocoa_input.m diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 5e3a6bf8..45b3be0f 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -152,7 +152,7 @@ static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement) long number; CFTypeRef refType; - _glfwJoystickElement* element = (_glfwJoystickElement*) _glfwMalloc(sizeof(_glfwJoystickElement)); + _glfwJoystickElement* element = (_glfwJoystickElement*) malloc(sizeof(_glfwJoystickElement)); CFArrayAppendValue(elementsArray, element); @@ -232,33 +232,35 @@ static long getElementValue(_glfwJoystick* joystick, _glfwJoystickElement* eleme static void removeJoystick(_glfwJoystick* joystick) { + int i; + if (joystick->present) { joystick->present = GL_FALSE; - for (int i = 0; i < joystick->numAxes; i++) + for (i = 0; i < joystick->numAxes; i++) { _glfwJoystickElement* axes = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i); - _glfwFree(axes); + free(axes); } CFArrayRemoveAllValues(joystick->axes); joystick->numAxes = 0; - for (int i = 0; i < joystick->numButtons; i++) + for (i = 0; i < joystick->numButtons; i++) { _glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i); - _glfwFree(button); + free(button); } CFArrayRemoveAllValues(joystick->buttons); joystick->numButtons = 0; - for (int i = 0; i < joystick->numHats; i++) + for (i = 0; i < joystick->numHats; i++) { _glfwJoystickElement* hat = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, i); - _glfwFree(hat); + free(hat); } CFArrayRemoveAllValues(joystick->hats); joystick->hats = 0; @@ -287,23 +289,26 @@ static void removalCallback(void* target, IOReturn result, void* refcon, void* s static void pollJoystickEvents(void) { - for (int i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) + int i; + CFIndex j; + + for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) { _glfwJoystick* joystick = &_glfwJoysticks[i]; if (joystick->present) { - for (CFIndex i = 0; i < joystick->numButtons; i++) + for (j = 0; j < joystick->numButtons; j++) { _glfwJoystickElement* button = - (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i); + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, j); button->value = getElementValue(joystick, button); } - for (CFIndex i = 0; i < joystick->numAxes; i++) + for (j = 0; j < joystick->numAxes; j++) { _glfwJoystickElement* axes = - (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i); + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j); axes->value = getElementValue(joystick, axes); } } @@ -449,7 +454,9 @@ void _glfwInitJoysticks(void) void _glfwTerminateJoysticks(void) { - for (int i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) + int i; + + for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) { _glfwJoystick* joystick = &_glfwJoysticks[i]; removeJoystick(joystick); @@ -498,6 +505,8 @@ int _glfwPlatformGetJoystickParam(int joy, int param) int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes) { + int i; + if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) return 0; @@ -514,7 +523,7 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes) // Update joystick state pollJoystickEvents(); - for (int i = 0; i < numaxes; i++) + for (i = 0; i < numaxes; i++) { _glfwJoystickElement* axes = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.axes, i); @@ -543,6 +552,8 @@ int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes) int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, int numbuttons) { + int i; + if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) return 0; @@ -559,7 +570,7 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, // Update joystick state pollJoystickEvents(); - for (int i = 0; i < numbuttons; i++) + for (i = 0; i < numbuttons; i++) { _glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i); buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE; @@ -568,4 +579,3 @@ int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, return numbuttons; } - diff --git a/src/cocoa_opengl.m b/src/cocoa_opengl.m index bd3827fc..0ea39076 100644 --- a/src/cocoa_opengl.m +++ b/src/cocoa_opengl.m @@ -59,6 +59,7 @@ void _glfwPlatformSwapBuffers(void) [window->NSGL.context flushBuffer]; } + //======================================================================== // Set double buffering swap interval //======================================================================== @@ -71,6 +72,7 @@ void _glfwPlatformSwapInterval(int interval) [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; } + //======================================================================== // Check if an OpenGL extension is available at runtime //======================================================================== @@ -81,6 +83,7 @@ int _glfwPlatformExtensionSupported(const char* extension) return GL_FALSE; } + //======================================================================== // Get the function pointer to an OpenGL function //======================================================================== @@ -99,6 +102,7 @@ void* _glfwPlatformGetProcAddress(const char* procname) return symbol; } + //======================================================================== // Copies the specified OpenGL state categories from src to dst //======================================================================== diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index d5daf775..b70fb184 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -37,6 +37,7 @@ #if defined(__OBJC__) #import #else +#include typedef void* id; #endif @@ -85,15 +86,16 @@ typedef struct _GLFWwindowNS typedef struct _GLFWlibraryNS { struct { - double t0; + double base; + double resolution; } timer; // dlopen handle for dynamically loading OpenGL extension entry points - void* OpenGLFramework; - GLboolean unbundled; - id desktopMode; - id delegate; - id autoreleasePool; + void* OpenGLFramework; + CGDisplayModeRef desktopMode; + CGEventSourceRef eventSource; + id delegate; + id autoreleasePool; } _GLFWlibraryNS; @@ -101,9 +103,15 @@ typedef struct _GLFWlibraryNS // Prototypes for platform specific internal functions //======================================================================== +// Time +void _glfwInitTimer(void); + // Joystick input void _glfwInitJoysticks(void); void _glfwTerminateJoysticks(void); +// Fullscreen +GLboolean _glfwSetVideoMode(int* width, int* height, int* bpp, int* refreshRate); +void _glfwRestoreVideoMode(void); #endif // _platform_h_ diff --git a/src/cocoa_time.m b/src/cocoa_time.c similarity index 64% rename from src/cocoa_time.m rename to src/cocoa_time.c index d7e7d2b8..745b4239 100644 --- a/src/cocoa_time.m +++ b/src/cocoa_time.c @@ -29,6 +29,36 @@ #include "internal.h" +#include + + +//======================================================================== +// Return raw time +//======================================================================== + +static uint64_t getRawTime(void) +{ + return mach_absolute_time(); +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Initialise timer +//======================================================================== + +void _glfwInitTimer(void) +{ + mach_timebase_info_data_t info; + mach_timebase_info(&info); + + _glfwLibrary.NS.timer.resolution = (double) info.numer / (info.denom * 1.0e9); + _glfwLibrary.NS.timer.base = getRawTime(); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -40,17 +70,18 @@ double _glfwPlatformGetTime(void) { - return [NSDate timeIntervalSinceReferenceDate] - - _glfwLibrary.NS.timer.t0; + return (double) (getRawTime() - _glfwLibrary.NS.timer.base) * + _glfwLibrary.NS.timer.resolution; } + //======================================================================== // Set timer value in seconds //======================================================================== void _glfwPlatformSetTime(double time) { - _glfwLibrary.NS.timer.t0 = - [NSDate timeIntervalSinceReferenceDate] - time; + _glfwLibrary.NS.timer.base = getRawTime() - + (uint64_t) (time / _glfwLibrary.NS.timer.resolution); } diff --git a/src/cocoa_window.m b/src/cocoa_window.m index ce95217d..5bb33097 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -29,6 +29,9 @@ #include "internal.h" +// Needed for _NSGetProgname +#include + //======================================================================== // Delegate for window related notifications @@ -109,6 +112,7 @@ @end + //======================================================================== // Delegate for application related notifications //======================================================================== @@ -130,142 +134,6 @@ @end -//======================================================================== -// Keyboard symbol translation table -//======================================================================== - -// TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. -static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = -{ - /* 00 */ GLFW_KEY_A, - /* 01 */ GLFW_KEY_S, - /* 02 */ GLFW_KEY_D, - /* 03 */ GLFW_KEY_F, - /* 04 */ GLFW_KEY_H, - /* 05 */ GLFW_KEY_G, - /* 06 */ GLFW_KEY_Z, - /* 07 */ GLFW_KEY_X, - /* 08 */ GLFW_KEY_C, - /* 09 */ GLFW_KEY_V, - /* 0a */ -1, - /* 0b */ GLFW_KEY_B, - /* 0c */ GLFW_KEY_Q, - /* 0d */ GLFW_KEY_W, - /* 0e */ GLFW_KEY_E, - /* 0f */ GLFW_KEY_R, - /* 10 */ GLFW_KEY_Y, - /* 11 */ GLFW_KEY_T, - /* 12 */ GLFW_KEY_1, - /* 13 */ GLFW_KEY_2, - /* 14 */ GLFW_KEY_3, - /* 15 */ GLFW_KEY_4, - /* 16 */ GLFW_KEY_6, - /* 17 */ GLFW_KEY_5, - /* 18 */ GLFW_KEY_EQUAL, - /* 19 */ GLFW_KEY_9, - /* 1a */ GLFW_KEY_7, - /* 1b */ GLFW_KEY_MINUS, - /* 1c */ GLFW_KEY_8, - /* 1d */ GLFW_KEY_0, - /* 1e */ GLFW_KEY_RIGHT_BRACKET, - /* 1f */ GLFW_KEY_O, - /* 20 */ GLFW_KEY_U, - /* 21 */ GLFW_KEY_LEFT_BRACKET, - /* 22 */ GLFW_KEY_I, - /* 23 */ GLFW_KEY_P, - /* 24 */ GLFW_KEY_ENTER, - /* 25 */ GLFW_KEY_L, - /* 26 */ GLFW_KEY_J, - /* 27 */ GLFW_KEY_APOSTROPHE, - /* 28 */ GLFW_KEY_K, - /* 29 */ GLFW_KEY_SEMICOLON, - /* 2a */ GLFW_KEY_BACKSLASH, - /* 2b */ GLFW_KEY_COMMA, - /* 2c */ GLFW_KEY_SLASH, - /* 2d */ GLFW_KEY_N, - /* 2e */ GLFW_KEY_M, - /* 2f */ GLFW_KEY_PERIOD, - /* 30 */ GLFW_KEY_TAB, - /* 31 */ GLFW_KEY_SPACE, - /* 32 */ GLFW_KEY_GRAVE_ACCENT, - /* 33 */ GLFW_KEY_BACKSPACE, - /* 34 */ -1, - /* 35 */ GLFW_KEY_ESCAPE, - /* 36 */ GLFW_KEY_RIGHT_SUPER, - /* 37 */ GLFW_KEY_LEFT_SUPER, - /* 38 */ GLFW_KEY_LEFT_SHIFT, - /* 39 */ GLFW_KEY_CAPS_LOCK, - /* 3a */ GLFW_KEY_LEFT_ALT, - /* 3b */ GLFW_KEY_LEFT_CONTROL, - /* 3c */ GLFW_KEY_RIGHT_SHIFT, - /* 3d */ GLFW_KEY_RIGHT_ALT, - /* 3e */ GLFW_KEY_RIGHT_CONTROL, - /* 3f */ -1, /* Function */ - /* 40 */ GLFW_KEY_F17, - /* 41 */ GLFW_KEY_KP_DECIMAL, - /* 42 */ -1, - /* 43 */ GLFW_KEY_KP_MULTIPLY, - /* 44 */ -1, - /* 45 */ GLFW_KEY_KP_ADD, - /* 46 */ -1, - /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ - /* 48 */ -1, /* VolumeUp */ - /* 49 */ -1, /* VolumeDown */ - /* 4a */ -1, /* Mute */ - /* 4b */ GLFW_KEY_KP_DIVIDE, - /* 4c */ GLFW_KEY_KP_ENTER, - /* 4d */ -1, - /* 4e */ GLFW_KEY_KP_SUBTRACT, - /* 4f */ GLFW_KEY_F18, - /* 50 */ GLFW_KEY_F19, - /* 51 */ GLFW_KEY_KP_EQUAL, - /* 52 */ GLFW_KEY_KP_0, - /* 53 */ GLFW_KEY_KP_1, - /* 54 */ GLFW_KEY_KP_2, - /* 55 */ GLFW_KEY_KP_3, - /* 56 */ GLFW_KEY_KP_4, - /* 57 */ GLFW_KEY_KP_5, - /* 58 */ GLFW_KEY_KP_6, - /* 59 */ GLFW_KEY_KP_7, - /* 5a */ GLFW_KEY_F20, - /* 5b */ GLFW_KEY_KP_8, - /* 5c */ GLFW_KEY_KP_9, - /* 5d */ -1, - /* 5e */ -1, - /* 5f */ -1, - /* 60 */ GLFW_KEY_F5, - /* 61 */ GLFW_KEY_F6, - /* 62 */ GLFW_KEY_F7, - /* 63 */ GLFW_KEY_F3, - /* 64 */ GLFW_KEY_F8, - /* 65 */ GLFW_KEY_F9, - /* 66 */ -1, - /* 67 */ GLFW_KEY_F11, - /* 68 */ -1, - /* 69 */ GLFW_KEY_F13, - /* 6a */ GLFW_KEY_F16, - /* 6b */ GLFW_KEY_F14, - /* 6c */ -1, - /* 6d */ GLFW_KEY_F10, - /* 6e */ -1, - /* 6f */ GLFW_KEY_F12, - /* 70 */ -1, - /* 71 */ GLFW_KEY_F15, - /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ - /* 73 */ GLFW_KEY_HOME, - /* 74 */ GLFW_KEY_PAGE_UP, - /* 75 */ GLFW_KEY_DELETE, - /* 76 */ GLFW_KEY_F4, - /* 77 */ GLFW_KEY_END, - /* 78 */ GLFW_KEY_F2, - /* 79 */ GLFW_KEY_PAGE_DOWN, - /* 7a */ GLFW_KEY_F1, - /* 7b */ GLFW_KEY_LEFT, - /* 7c */ GLFW_KEY_RIGHT, - /* 7d */ GLFW_KEY_DOWN, - /* 7e */ GLFW_KEY_UP, - /* 7f */ -1, -}; //======================================================================== // Converts a Mac OS X keycode to a GLFW keycode @@ -273,15 +141,150 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = static int convertMacKeyCode(unsigned int macKeyCode) { + // Keyboard symbol translation table + // TODO: Need to find mappings for F13-F15, volume down/up/mute, and eject. + static const unsigned int table[128] = + { + /* 00 */ GLFW_KEY_A, + /* 01 */ GLFW_KEY_S, + /* 02 */ GLFW_KEY_D, + /* 03 */ GLFW_KEY_F, + /* 04 */ GLFW_KEY_H, + /* 05 */ GLFW_KEY_G, + /* 06 */ GLFW_KEY_Z, + /* 07 */ GLFW_KEY_X, + /* 08 */ GLFW_KEY_C, + /* 09 */ GLFW_KEY_V, + /* 0a */ GLFW_KEY_GRAVE_ACCENT, + /* 0b */ GLFW_KEY_B, + /* 0c */ GLFW_KEY_Q, + /* 0d */ GLFW_KEY_W, + /* 0e */ GLFW_KEY_E, + /* 0f */ GLFW_KEY_R, + /* 10 */ GLFW_KEY_Y, + /* 11 */ GLFW_KEY_T, + /* 12 */ GLFW_KEY_1, + /* 13 */ GLFW_KEY_2, + /* 14 */ GLFW_KEY_3, + /* 15 */ GLFW_KEY_4, + /* 16 */ GLFW_KEY_6, + /* 17 */ GLFW_KEY_5, + /* 18 */ GLFW_KEY_EQUAL, + /* 19 */ GLFW_KEY_9, + /* 1a */ GLFW_KEY_7, + /* 1b */ GLFW_KEY_MINUS, + /* 1c */ GLFW_KEY_8, + /* 1d */ GLFW_KEY_0, + /* 1e */ GLFW_KEY_RIGHT_BRACKET, + /* 1f */ GLFW_KEY_O, + /* 20 */ GLFW_KEY_U, + /* 21 */ GLFW_KEY_LEFT_BRACKET, + /* 22 */ GLFW_KEY_I, + /* 23 */ GLFW_KEY_P, + /* 24 */ GLFW_KEY_ENTER, + /* 25 */ GLFW_KEY_L, + /* 26 */ GLFW_KEY_J, + /* 27 */ GLFW_KEY_APOSTROPHE, + /* 28 */ GLFW_KEY_K, + /* 29 */ GLFW_KEY_SEMICOLON, + /* 2a */ GLFW_KEY_BACKSLASH, + /* 2b */ GLFW_KEY_COMMA, + /* 2c */ GLFW_KEY_SLASH, + /* 2d */ GLFW_KEY_N, + /* 2e */ GLFW_KEY_M, + /* 2f */ GLFW_KEY_PERIOD, + /* 30 */ GLFW_KEY_TAB, + /* 31 */ GLFW_KEY_SPACE, + /* 32 */ GLFW_KEY_WORLD_1, + /* 33 */ GLFW_KEY_BACKSPACE, + /* 34 */ -1, + /* 35 */ GLFW_KEY_ESCAPE, + /* 36 */ GLFW_KEY_RIGHT_SUPER, + /* 37 */ GLFW_KEY_LEFT_SUPER, + /* 38 */ GLFW_KEY_LEFT_SHIFT, + /* 39 */ GLFW_KEY_CAPS_LOCK, + /* 3a */ GLFW_KEY_LEFT_ALT, + /* 3b */ GLFW_KEY_LEFT_CONTROL, + /* 3c */ GLFW_KEY_RIGHT_SHIFT, + /* 3d */ GLFW_KEY_RIGHT_ALT, + /* 3e */ GLFW_KEY_RIGHT_CONTROL, + /* 3f */ -1, /* Function */ + /* 40 */ GLFW_KEY_F17, + /* 41 */ GLFW_KEY_KP_DECIMAL, + /* 42 */ -1, + /* 43 */ GLFW_KEY_KP_MULTIPLY, + /* 44 */ -1, + /* 45 */ GLFW_KEY_KP_ADD, + /* 46 */ -1, + /* 47 */ GLFW_KEY_NUM_LOCK, /* Really KeypadClear... */ + /* 48 */ -1, /* VolumeUp */ + /* 49 */ -1, /* VolumeDown */ + /* 4a */ -1, /* Mute */ + /* 4b */ GLFW_KEY_KP_DIVIDE, + /* 4c */ GLFW_KEY_KP_ENTER, + /* 4d */ -1, + /* 4e */ GLFW_KEY_KP_SUBTRACT, + /* 4f */ GLFW_KEY_F18, + /* 50 */ GLFW_KEY_F19, + /* 51 */ GLFW_KEY_KP_EQUAL, + /* 52 */ GLFW_KEY_KP_0, + /* 53 */ GLFW_KEY_KP_1, + /* 54 */ GLFW_KEY_KP_2, + /* 55 */ GLFW_KEY_KP_3, + /* 56 */ GLFW_KEY_KP_4, + /* 57 */ GLFW_KEY_KP_5, + /* 58 */ GLFW_KEY_KP_6, + /* 59 */ GLFW_KEY_KP_7, + /* 5a */ GLFW_KEY_F20, + /* 5b */ GLFW_KEY_KP_8, + /* 5c */ GLFW_KEY_KP_9, + /* 5d */ -1, + /* 5e */ -1, + /* 5f */ -1, + /* 60 */ GLFW_KEY_F5, + /* 61 */ GLFW_KEY_F6, + /* 62 */ GLFW_KEY_F7, + /* 63 */ GLFW_KEY_F3, + /* 64 */ GLFW_KEY_F8, + /* 65 */ GLFW_KEY_F9, + /* 66 */ -1, + /* 67 */ GLFW_KEY_F11, + /* 68 */ -1, + /* 69 */ GLFW_KEY_F13, + /* 6a */ GLFW_KEY_F16, + /* 6b */ GLFW_KEY_F14, + /* 6c */ -1, + /* 6d */ GLFW_KEY_F10, + /* 6e */ -1, + /* 6f */ GLFW_KEY_F12, + /* 70 */ -1, + /* 71 */ GLFW_KEY_F15, + /* 72 */ GLFW_KEY_INSERT, /* Really Help... */ + /* 73 */ GLFW_KEY_HOME, + /* 74 */ GLFW_KEY_PAGE_UP, + /* 75 */ GLFW_KEY_DELETE, + /* 76 */ GLFW_KEY_F4, + /* 77 */ GLFW_KEY_END, + /* 78 */ GLFW_KEY_F2, + /* 79 */ GLFW_KEY_PAGE_DOWN, + /* 7a */ GLFW_KEY_F1, + /* 7b */ GLFW_KEY_LEFT, + /* 7c */ GLFW_KEY_RIGHT, + /* 7d */ GLFW_KEY_DOWN, + /* 7e */ GLFW_KEY_UP, + /* 7f */ -1, + }; + if (macKeyCode >= 128) return -1; // This treats keycodes as *positional*; that is, we'll return 'a' // for the key left of 's', even on an AZERTY keyboard. The charInput // function should still get 'q' though. - return MAC_TO_GLFW_KEYCODE_MAPPING[macKeyCode]; + return table[macKeyCode]; } + //======================================================================== // Content view class for the GLFW window //======================================================================== @@ -385,15 +388,15 @@ static int convertMacKeyCode(unsigned int macKeyCode) { NSUInteger i, length; NSString* characters; - int code = convertMacKeyCode([event keyCode]); + int key = convertMacKeyCode([event keyCode]); - if (code != -1) + if (key != -1) { - _glfwInputKey(window, code, GLFW_PRESS); + _glfwInputKey(window, key, GLFW_PRESS); if ([event modifierFlags] & NSCommandKeyMask) { - if (!window->sysKeysDisabled) + if (window->systemKeys) [super keyDown:event]; } else @@ -409,7 +412,7 @@ static int convertMacKeyCode(unsigned int macKeyCode) - (void)flagsChanged:(NSEvent *)event { - int mode; + int mode, key; unsigned int newModifierFlags = [event modifierFlags] | NSDeviceIndependentModifierFlagsMask; @@ -419,14 +422,17 @@ static int convertMacKeyCode(unsigned int macKeyCode) mode = GLFW_RELEASE; window->NS.modifierFlags = newModifierFlags; - _glfwInputKey(window, MAC_TO_GLFW_KEYCODE_MAPPING[[event keyCode]], mode); + + key = convertMacKeyCode([event keyCode]); + if (key != -1) + _glfwInputKey(window, key, mode); } - (void)keyUp:(NSEvent *)event { - int code = convertMacKeyCode([event keyCode]); - if (code != -1) - _glfwInputKey(window, code, GLFW_RELEASE); + int key = convertMacKeyCode([event keyCode]); + if (key != -1) + _glfwInputKey(window, key, GLFW_RELEASE); } - (void)scrollWheel:(NSEvent *)event @@ -444,19 +450,229 @@ static int convertMacKeyCode(unsigned int macKeyCode) @end -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - //======================================================================== -// Here is where the window is created, and the OpenGL rendering context is -// created +// GLFW application class //======================================================================== -int _glfwPlatformOpenWindow(_GLFWwindow* window, - const _GLFWwndconfig *wndconfig, - const _GLFWfbconfig *fbconfig) +@interface GLFWApplication : NSApplication +@end + +@implementation GLFWApplication + +// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost +// This works around an AppKit bug, where key up events while holding +// down the command key don't get sent to the key window. +- (void)sendEvent:(NSEvent *)event { + if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + [[self keyWindow] sendEvent:event]; + else + [super sendEvent:event]; +} + +@end + + +//======================================================================== +// Try to figure out what the calling application is called +//======================================================================== + +static NSString* findAppName(void) +{ + unsigned int i; + NSDictionary* infoDictionary = [[NSBundle mainBundle] infoDictionary]; + + // Keys to search for as potential application names + NSString* GLFWNameKeys[] = + { + @"CFBundleDisplayName", + @"CFBundleName", + @"CFBundleExecutable", + }; + + for (i = 0; i < sizeof(GLFWNameKeys) / sizeof(GLFWNameKeys[0]); i++) + { + id name = [infoDictionary objectForKey:GLFWNameKeys[i]]; + if (name && + [name isKindOfClass:[NSString class]] && + ![@"" isEqualToString:name]) + { + return name; + } + } + + // If we get here, we're unbundled + ProcessSerialNumber psn = { 0, kCurrentProcess }; + TransformProcessType(&psn, kProcessTransformToForegroundApplication); + + // Having the app in front of the terminal window is also generally + // handy. There is an NSApplication API to do this, but... + SetFrontProcess(&psn); + + char** progname = _NSGetProgname(); + if (progname && *progname) + { + // TODO: UTF-8? + return [NSString stringWithUTF8String:*progname]; + } + + // Really shouldn't get here + return @"GLFW Application"; +} + + +//======================================================================== +// Set up the menu bar (manually) +// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that +// could go away at any moment, lots of stuff that really should be +// localize(d|able), etc. Loading a nib would save us this horror, but that +// doesn't seem like a good thing to require of GLFW's clients. +//======================================================================== + +static void createMenuBar(void) +{ + NSString* appName = findAppName(); + + NSMenu* bar = [[NSMenu alloc] init]; + [NSApp setMainMenu:bar]; + + NSMenuItem* appMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + NSMenu* appMenu = [[NSMenu alloc] init]; + [appMenuItem setSubmenu:appMenu]; + + [appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName] + action:@selector(orderFrontStandardAboutPanel:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + NSMenu* servicesMenu = [[NSMenu alloc] init]; + [NSApp setServicesMenu:servicesMenu]; + [[appMenu addItemWithTitle:@"Services" + action:NULL + keyEquivalent:@""] setSubmenu:servicesMenu]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName] + action:@selector(hide:) + keyEquivalent:@"h"]; + [[appMenu addItemWithTitle:@"Hide Others" + action:@selector(hideOtherApplications:) + keyEquivalent:@"h"] + setKeyEquivalentModifierMask:NSAlternateKeyMask | NSCommandKeyMask]; + [appMenu addItemWithTitle:@"Show All" + action:@selector(unhideAllApplications:) + keyEquivalent:@""]; + [appMenu addItem:[NSMenuItem separatorItem]]; + [appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName] + action:@selector(terminate:) + keyEquivalent:@"q"]; + + NSMenuItem* windowMenuItem = + [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; + NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; + [NSApp setWindowsMenu:windowMenu]; + [windowMenuItem setSubmenu:windowMenu]; + + [windowMenu addItemWithTitle:@"Miniaturize" + action:@selector(performMiniaturize:) + keyEquivalent:@"m"]; + [windowMenu addItemWithTitle:@"Zoom" + action:@selector(performZoom:) + keyEquivalent:@""]; + [windowMenu addItem:[NSMenuItem separatorItem]]; + [windowMenu addItemWithTitle:@"Bring All to Front" + action:@selector(arrangeInFront:) + keyEquivalent:@""]; + + // Prior to Snow Leopard, we need to use this oddly-named semi-private API + // to get the application menu working properly. + [NSApp performSelector:@selector(setAppleMenu:) withObject:appMenu]; +} + + +//======================================================================== +// Initialize the Cocoa Application Kit +//======================================================================== + +static GLboolean initializeAppKit(void) +{ + if (NSApp) + return GL_TRUE; + + // Implicitly create shared NSApplication instance + [GLFWApplication sharedApplication]; + + // Setting up the menu bar must go between sharedApplication + // above and finishLaunching below, in order to properly emulate the + // behavior of NSApplicationMain + createMenuBar(); + + [NSApp finishLaunching]; + + return GL_TRUE; +} + + +//======================================================================== +// Create the Cocoa window +//======================================================================== + +static GLboolean createWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig) +{ + unsigned int styleMask = 0; + + if (wndconfig->mode == GLFW_WINDOWED) + { + styleMask = NSTitledWindowMask | NSClosableWindowMask | + NSMiniaturizableWindowMask; + + if (wndconfig->resizable) + styleMask |= NSResizableWindowMask; + } + else + styleMask = NSBorderlessWindowMask; + + window->NS.window = [[NSWindow alloc] + initWithContentRect:NSMakeRect(0, 0, window->width, window->height) + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:NO]; + + if (window->NS.window == nil) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Cocoa/NSOpenGL: Failed to create window"); + return GL_FALSE; + } + + [window->NS.window setTitle:[NSString stringWithUTF8String:wndconfig->title]]; + [window->NS.window setContentView:[[GLFWContentView alloc] + initWithGlfwWindow:window]]; + [window->NS.window setDelegate:window->NS.delegate]; + [window->NS.window setAcceptsMouseMovedEvents:YES]; + [window->NS.window center]; + + return GL_TRUE; +} + + +//======================================================================== +// Create the OpenGL context +//======================================================================== + +static GLboolean createContext(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) +{ + unsigned int attributeCount = 0; + + // Mac OS X needs non-zero color size, so set resonable values + int colorBits = fbconfig->redBits + fbconfig->greenBits + fbconfig->blueBits; + if (colorBits == 0) + colorBits = 24; + else if (colorBits < 15) + colorBits = 15; + #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 // Fail if any OpenGL version above 2.1 other than 3.2 was requested if (wndconfig->glMajor > 3 || @@ -468,14 +684,23 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, return GL_FALSE; } - if (wndconfig->glProfile) + if (wndconfig->glMajor > 2) { - // Fail if a profile other than core was explicitly selected + if (!wndconfig->glForward) + { + _glfwSetError(GLFW_VERSION_UNAVAILABLE, + "Cocoa/NSOpenGL: The targeted version of Mac OS X " + "only supports OpenGL 3.2 contexts if they are " + "forward-compatible"); + return GL_FALSE; + } + if (wndconfig->glProfile != GLFW_OPENGL_CORE_PROFILE) { _glfwSetError(GLFW_VERSION_UNAVAILABLE, "Cocoa/NSOpenGL: The targeted version of Mac OS X " - "only supports the OpenGL core profile"); + "only supports OpenGL 3.2 contexts if they use the " + "core profile"); return GL_FALSE; } } @@ -499,6 +724,106 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, return GL_FALSE; } +#define ADD_ATTR(x) { attributes[attributeCount++] = x; } +#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } + + // Arbitrary array size here + NSOpenGLPixelFormatAttribute attributes[24]; + + ADD_ATTR(NSOpenGLPFADoubleBuffer); + + if (wndconfig->mode == GLFW_FULLSCREEN) + { + ADD_ATTR(NSOpenGLPFANoRecovery); + ADD_ATTR2(NSOpenGLPFAScreenMask, + CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID())); + } + +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (wndconfig->glMajor > 2) + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); +#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + + if (fbconfig->alphaBits > 0) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); + + if (fbconfig->depthBits > 0) + ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); + + if (fbconfig->stencilBits > 0) + ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); + + int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits + + fbconfig->accumBlueBits + fbconfig->accumAlphaBits; + + if (accumBits > 0) + ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); + + if (fbconfig->auxBuffers > 0) + ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); + + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo); + + if (fbconfig->samples > 0) + { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } + + ADD_ATTR(0); + +#undef ADD_ATTR +#undef ADD_ATTR2 + + window->NSGL.pixelFormat = + [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + if (window->NSGL.pixelFormat == nil) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Cocoa/NSOpenGL: Failed to create OpenGL pixel format"); + return GL_FALSE; + } + + NSOpenGLContext* share = NULL; + + if (wndconfig->share) + share = wndconfig->share->NSGL.context; + + window->NSGL.context = + [[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat + shareContext:share]; + if (window->NSGL.context == nil) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Cocoa/NSOpenGL: Failed to create OpenGL context"); + return GL_FALSE; + } + + return GL_TRUE; +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Here is where the window is created, and the OpenGL rendering context is +// created +//======================================================================== + +int _glfwPlatformOpenWindow(_GLFWwindow* window, + const _GLFWwndconfig* wndconfig, + const _GLFWfbconfig* fbconfig) +{ + if (!initializeAppKit()) + return GL_FALSE; + + window->resizable = wndconfig->resizable; + // We can only have one application delegate, but we only allocate it the // first time we create a window to keep all window code in this file if (_glfwLibrary.NS.delegate == nil) @@ -530,157 +855,30 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, else if (colorBits < 15) colorBits = 15; - // Ignored hints: - // OpenGLMajor, OpenGLMinor, OpenGLForward: - // pending Mac OS X support for OpenGL 3.x - // OpenGLDebug - // pending it meaning anything on Mac OS X - // Don't use accumulation buffer support; it's not accelerated // Aux buffers probably aren't accelerated either - CFDictionaryRef fullscreenMode = NULL; - if (wndconfig->mode == GLFW_FULLSCREEN) - { - // I think it's safe to pass 0 to the refresh rate for this function - // rather than conditionalizing the code to call the version which - // doesn't specify refresh... - fullscreenMode = - CGDisplayBestModeForParametersAndRefreshRateWithProperty( - CGMainDisplayID(), - colorBits + fbconfig->alphaBits, - window->width, window->height, - wndconfig->refreshRate, - // Controversial, see macosx_fullscreen.m for discussion - kCGDisplayModeIsSafeForHardware, - NULL); - - window->width = - [[(id)fullscreenMode objectForKey:(id)kCGDisplayWidth] intValue]; - window->height = - [[(id)fullscreenMode objectForKey:(id)kCGDisplayHeight] intValue]; - } - - unsigned int styleMask = 0; - - if (wndconfig->mode == GLFW_WINDOWED) - { - styleMask = NSTitledWindowMask | NSClosableWindowMask | - NSMiniaturizableWindowMask; - - if (wndconfig->resizable) - styleMask |= NSResizableWindowMask; - } - else - styleMask = NSBorderlessWindowMask; - - window->NS.window = [[NSWindow alloc] - initWithContentRect:NSMakeRect(0, 0, window->width, window->height) - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:NO]; - - [window->NS.window setTitle:[NSString stringWithCString:wndconfig->title - encoding:NSISOLatin1StringEncoding]]; - - [window->NS.window setContentView:[[GLFWContentView alloc] initWithGlfwWindow:window]]; - [window->NS.window setDelegate:window->NS.delegate]; - [window->NS.window setAcceptsMouseMovedEvents:YES]; - [window->NS.window center]; - - if (wndconfig->mode == GLFW_FULLSCREEN) - { - CGCaptureAllDisplays(); - CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode); - } - - unsigned int attribute_count = 0; - -#define ADD_ATTR(x) { attributes[attribute_count++] = x; } -#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } - - // Arbitrary array size here - NSOpenGLPixelFormatAttribute attributes[24]; - - ADD_ATTR(NSOpenGLPFADoubleBuffer); - - if (wndconfig->mode == GLFW_FULLSCREEN) - { - ADD_ATTR(NSOpenGLPFAFullScreen); - ADD_ATTR(NSOpenGLPFANoRecovery); - ADD_ATTR2(NSOpenGLPFAScreenMask, - CGDisplayIDToOpenGLDisplayMask(CGMainDisplayID())); - } - -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (wndconfig->glMajor > 2) - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - - if (fbconfig->alphaBits > 0) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); - - if (fbconfig->depthBits > 0) - ADD_ATTR2(NSOpenGLPFADepthSize, fbconfig->depthBits); - - if (fbconfig->stencilBits > 0) - ADD_ATTR2(NSOpenGLPFAStencilSize, fbconfig->stencilBits); - - int accumBits = fbconfig->accumRedBits + fbconfig->accumGreenBits + - fbconfig->accumBlueBits + fbconfig->accumAlphaBits; - - if (accumBits > 0) - ADD_ATTR2(NSOpenGLPFAAccumSize, accumBits); - - if (fbconfig->auxBuffers > 0) - ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); - - if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo ); - - if (fbconfig->samples > 0) - { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); - } - - ADD_ATTR(0); - -#undef ADD_ATTR -#undef ADD_ATTR2 - - window->NSGL.pixelFormat = - [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - if (window->NSGL.pixelFormat == nil) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Cocoa/NSOpenGL: Failed to create pixel format"); + if (!createWindow(window, wndconfig)) return GL_FALSE; - } - NSOpenGLContext* share = NULL; - - if (wndconfig->share) - share = wndconfig->share->NSGL.context; - - window->NSGL.context = - [[NSOpenGLContext alloc] initWithFormat:window->NSGL.pixelFormat - shareContext:share]; - if (window->NSGL.context == nil) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Cocoa/NSOpenGL: Failed to create OpenGL context"); + if (!createContext(window, wndconfig, fbconfig)) return GL_FALSE; - } [window->NS.window makeKeyAndOrderFront:nil]; [window->NSGL.context setView:[window->NS.window contentView]]; if (wndconfig->mode == GLFW_FULLSCREEN) { - // TODO: Make this work on pre-Leopard systems + int bpp = colorBits + fbconfig->alphaBits; + + if (!_glfwSetVideoMode(&window->width, + &window->height, + &bpp, + &window->refreshRate)) + { + return GL_FALSE; + } + [[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; } @@ -709,9 +907,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) { [[window->NS.window contentView] exitFullScreenModeWithOptions:nil]; - CGDisplaySwitchToMode(CGMainDisplayID(), - (CFDictionaryRef) _glfwLibrary.NS.desktopMode); - CGReleaseAllDisplays(); + _glfwRestoreVideoMode(); } [window->NSGL.pixelFormat release]; @@ -731,16 +927,17 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) // TODO: Probably more cleanup } + //======================================================================== // Set the window title //======================================================================== void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) { - [window->NS.window setTitle:[NSString stringWithCString:title - encoding:NSISOLatin1StringEncoding]]; + [window->NS.window setTitle:[NSString stringWithUTF8String:title]]; } + //======================================================================== // Set the window size //======================================================================== @@ -750,6 +947,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) [window->NS.window setContentSize:NSMakeSize(width, height)]; } + //======================================================================== // Set the window position //======================================================================== @@ -770,6 +968,7 @@ void _glfwPlatformSetWindowPos(_GLFWwindow* window, int x, int y) display:YES]; } + //======================================================================== // Iconify the window //======================================================================== @@ -779,6 +978,7 @@ void _glfwPlatformIconifyWindow(_GLFWwindow* window) [window->NS.window miniaturize:nil]; } + //======================================================================== // Restore (un-iconify) the window //======================================================================== @@ -788,6 +988,7 @@ void _glfwPlatformRestoreWindow(_GLFWwindow* window) [window->NS.window deminiaturize:nil]; } + //======================================================================== // Write back window parameters into GLFW window structure //======================================================================== @@ -862,6 +1063,7 @@ void _glfwPlatformRefreshWindowParams(void) window->glDebug = GL_FALSE; } + //======================================================================== // Poll for new window and input events //======================================================================== @@ -886,6 +1088,7 @@ void _glfwPlatformPollEvents(void) _glfwLibrary.NS.autoreleasePool = [[NSAutoreleasePool alloc] init]; } + //======================================================================== // Wait for new window and input events //======================================================================== @@ -904,6 +1107,7 @@ void _glfwPlatformWaitEvents( void ) _glfwPlatformPollEvents(); } + //======================================================================== // Set physical mouse cursor position //======================================================================== @@ -921,11 +1125,6 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) // calculating the maximum y coordinate of all screens, since Cocoa's // "global coordinates" are upside down from CG's... - // Without this (once per app run, but it's convenient to do it here) - // events will be suppressed for a default of 0.25 seconds after we - // move the cursor. - CGSetLocalEventsSuppressionInterval(0.0); - NSPoint localPoint = NSMakePoint(x, y); NSPoint globalPoint = [window->NS.window convertBaseToScreen:localPoint]; CGPoint mainScreenOrigin = CGDisplayBounds(CGMainDisplayID()).origin; @@ -936,6 +1135,7 @@ void _glfwPlatformSetMouseCursorPos(_GLFWwindow* window, int x, int y) CGDisplayMoveCursorToPoint(CGMainDisplayID(), targetPoint); } + //======================================================================== // Set physical mouse cursor mode //======================================================================== diff --git a/src/config.h.in b/src/config.h.in index f966356c..46a6e2aa 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -60,11 +60,6 @@ // Define this to 1 if the Linux joystick API is available #cmakedefine _GLFW_USE_LINUX_JOYSTICKS 1 -// Define this to 1 to not load gdi32.dll dynamically -#cmakedefine _GLFW_NO_DLOAD_GDI32 1 -// Define this to 1 to not load winmm.dll dynamically -#cmakedefine _GLFW_NO_DLOAD_WINMM 1 - // The GLFW version as used by glfwGetVersionString #define _GLFW_VERSION_FULL "@GLFW_VERSION_FULL@" diff --git a/src/enable.c b/src/enable.c deleted file mode 100644 index 897f0753..00000000 --- a/src/enable.c +++ /dev/null @@ -1,192 +0,0 @@ -//======================================================================== -// GLFW - An OpenGL library -// Platform: Any -// API version: 3.0 -// WWW: http://www.glfw.org/ -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund -// -// 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" - - -//======================================================================== -// Enable and disable sticky keys mode -//======================================================================== - -static void enableStickyKeys(_GLFWwindow* window) -{ - window->stickyKeys = GL_TRUE; -} - -static void disableStickyKeys(_GLFWwindow* window) -{ - int i; - - window->stickyKeys = GL_FALSE; - - // Release all sticky keys - for (i = 0; i <= GLFW_KEY_LAST; i++) - { - if (window->key[i] == GLFW_STICK) - window->key[i] = GLFW_RELEASE; - } -} - - -//======================================================================== -// Enable and disable sticky mouse buttons mode -//======================================================================== - -static void enableStickyMouseButtons(_GLFWwindow* window) -{ - window->stickyMouseButtons = GL_TRUE; -} - -static void disableStickyMouseButtons(_GLFWwindow* window) -{ - int i; - - window->stickyMouseButtons = GL_FALSE; - - // Release all sticky mouse buttons - for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) - { - if (window->mouseButton[i] == GLFW_STICK) - window->mouseButton[i] = GLFW_RELEASE; - } -} - - -//======================================================================== -// Enable and disable system keys -//======================================================================== - -static void enableSystemKeys(_GLFWwindow* window) -{ - if (!window->sysKeysDisabled) - return; - - _glfwPlatformEnableSystemKeys(window); - - // Indicate that system keys are no longer disabled - window->sysKeysDisabled = GL_FALSE; -} - -static void disableSystemKeys(_GLFWwindow* window) -{ - if (window->sysKeysDisabled) - return; - - _glfwPlatformDisableSystemKeys(window); - - // Indicate that system keys are now disabled - window->sysKeysDisabled = GL_TRUE; -} - - -//======================================================================== -// Enable and disable key repeat -//======================================================================== - -static void enableKeyRepeat(_GLFWwindow* window) -{ - window->keyRepeat = GL_TRUE; -} - -static void disableKeyRepeat(_GLFWwindow* window) -{ - window->keyRepeat = GL_FALSE; -} - - -////////////////////////////////////////////////////////////////////////// -////// GLFW public API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Enable certain GLFW/window/system functions -//======================================================================== - -GLFWAPI void glfwEnable(GLFWwindow window, int token) -{ - if (!_glfwInitialized) - { - _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return; - } - - switch (token) - { - case GLFW_STICKY_KEYS: - enableStickyKeys(window); - break; - case GLFW_STICKY_MOUSE_BUTTONS: - enableStickyMouseButtons(window); - break; - case GLFW_SYSTEM_KEYS: - enableSystemKeys(window); - break; - case GLFW_KEY_REPEAT: - enableKeyRepeat(window); - break; - default: - _glfwSetError(GLFW_INVALID_ENUM, NULL); - break; - } -} - - -//======================================================================== -// Disable certain GLFW/window/system functions -//======================================================================== - -GLFWAPI void glfwDisable(GLFWwindow window, int token) -{ - if (!_glfwInitialized) - { - _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return; - } - - switch (token) - { - case GLFW_STICKY_KEYS: - disableStickyKeys(window); - break; - case GLFW_STICKY_MOUSE_BUTTONS: - disableStickyMouseButtons(window); - break; - case GLFW_SYSTEM_KEYS: - disableSystemKeys(window); - break; - case GLFW_KEY_REPEAT: - disableKeyRepeat(window); - break; - default: - _glfwSetError(GLFW_INVALID_ENUM, NULL); - break; - } -} - diff --git a/src/init.c b/src/init.c index 889e1770..336cfe25 100644 --- a/src/init.c +++ b/src/init.c @@ -35,30 +35,6 @@ #include -////////////////////////////////////////////////////////////////////////// -////// GLFW internal API ////// -////////////////////////////////////////////////////////////////////////// - -//======================================================================== -// Allocate memory using the allocator -//======================================================================== - -void* _glfwMalloc(size_t size) -{ - return _glfwLibrary.allocator.malloc(size); -} - - -//======================================================================== -// Free memory using the allocator -//======================================================================== - -void _glfwFree(void* ptr) -{ - _glfwLibrary.allocator.free(ptr); -} - - ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// ////////////////////////////////////////////////////////////////////////// @@ -68,43 +44,12 @@ void _glfwFree(void* ptr) //======================================================================== GLFWAPI int glfwInit(void) -{ - return glfwInitWithModels(NULL, NULL); -} - - -//======================================================================== -// Initialize various GLFW state using custom model interfaces -//======================================================================== - -GLFWAPI int glfwInitWithModels(GLFWthreadmodel* threading, GLFWallocator* allocator) { if (_glfwInitialized) return GL_TRUE; memset(&_glfwLibrary, 0, sizeof(_glfwLibrary)); - if (threading) - _glfwLibrary.threading = *threading; - - if (allocator) - { - // Verify that the specified model is complete - if (!allocator->malloc || !allocator->free) - { - _glfwSetError(GLFW_INVALID_VALUE, NULL); - return GL_FALSE; - } - - _glfwLibrary.allocator = *allocator; - } - else - { - // Use the libc malloc and free - _glfwLibrary.allocator.malloc = malloc; - _glfwLibrary.allocator.free = free; - } - // Not all window hints have zero as their default value, so this // needs to be here despite the memset above _glfwSetDefaultWindowHints(); diff --git a/src/input.c b/src/input.c index 01d99de3..1074ded5 100644 --- a/src/input.c +++ b/src/input.c @@ -31,6 +31,122 @@ #include "internal.h" +//======================================================================== +// Sets the cursor mode for the specified window +//======================================================================== + +static void setCursorMode(_GLFWwindow* window, int mode) +{ + int centerPosX, centerPosY; + + if (mode != GLFW_CURSOR_NORMAL && + mode != GLFW_CURSOR_HIDDEN && + mode != GLFW_CURSOR_CAPTURED) + { + _glfwSetError(GLFW_INVALID_ENUM, NULL); + return; + } + + if (window->cursorMode == mode) + return; + + centerPosX = window->width / 2; + centerPosY = window->height / 2; + + if (mode == GLFW_CURSOR_CAPTURED) + _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); + else if (window->cursorMode == GLFW_CURSOR_CAPTURED) + { + _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); + _glfwInputCursorMotion(window, + centerPosX - window->cursorPosX, + centerPosY - window->cursorPosY); + } + + _glfwPlatformSetCursorMode(window, mode); + + window->cursorMode = mode; +} + + +//======================================================================== +// Set sticky keys mode for the specified window +//======================================================================== + +static void setStickyKeys(_GLFWwindow* window, int enabled) +{ + if (window->stickyKeys == enabled) + return; + + if (!enabled) + { + int i; + + // Release all sticky keys + for (i = 0; i <= GLFW_KEY_LAST; i++) + { + if (window->key[i] == GLFW_STICK) + window->key[i] = GLFW_RELEASE; + } + } + + window->stickyKeys = enabled; +} + + +//======================================================================== +// Set sticky mouse buttons mode for the specified window +//======================================================================== + +static void setStickyMouseButtons(_GLFWwindow* window, int enabled) +{ + if (window->stickyMouseButtons == enabled) + return; + + if (!enabled) + { + int i; + + // Release all sticky mouse buttons + for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++) + { + if (window->mouseButton[i] == GLFW_STICK) + window->mouseButton[i] = GLFW_RELEASE; + } + } + + window->stickyMouseButtons = enabled; +} + + +//======================================================================== +// Set system keys for the specified window +//======================================================================== + +static void setSystemKeys(_GLFWwindow* window, int enabled) +{ + if (window->systemKeys == enabled) + return; + + if (enabled) + _glfwPlatformEnableSystemKeys(window); + else + _glfwPlatformDisableSystemKeys(window); + + window->systemKeys = enabled; +} + + +//======================================================================== +// Set key repeat for the specified window +//======================================================================== + +static void setKeyRepeat(_GLFWwindow* window, int enabled) +{ + window->keyRepeat = enabled; +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW internal API ////// ////////////////////////////////////////////////////////////////////////// @@ -41,7 +157,7 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) { - GLboolean keyrepeat = GL_FALSE; + GLboolean repeated = GL_FALSE; if (key < 0 || key > GLFW_KEY_LAST) return; @@ -51,16 +167,16 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) return; // Register key action - if(action == GLFW_RELEASE && window->stickyKeys) + if (action == GLFW_RELEASE && window->stickyKeys) window->key[key] = GLFW_STICK; else { - keyrepeat = (window->key[key] == GLFW_PRESS) && (action == GLFW_PRESS); + repeated = (window->key[key] == GLFW_PRESS) && (action == GLFW_PRESS); window->key[key] = (char) action; } // Call user callback function - if (_glfwLibrary.keyCallback && (window->keyRepeat || !keyrepeat)) + if (_glfwLibrary.keyCallback && (window->keyRepeat || !repeated)) _glfwLibrary.keyCallback(window, key, action); } @@ -161,6 +277,77 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered) ////// GLFW public API ////// ////////////////////////////////////////////////////////////////////////// +//======================================================================== +// Returns the specified input mode of the specified window +//======================================================================== + +GLFWAPI int glfwGetInputMode(GLFWwindow handle, int mode) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return 0; + } + + switch (mode) + { + case GLFW_CURSOR_MODE: + return window->cursorMode; + case GLFW_STICKY_KEYS: + return window->stickyKeys; + case GLFW_STICKY_MOUSE_BUTTONS: + return window->stickyMouseButtons; + case GLFW_SYSTEM_KEYS: + return window->systemKeys; + case GLFW_KEY_REPEAT: + return window->keyRepeat; + default: + _glfwSetError(GLFW_INVALID_ENUM, NULL); + return 0; + } +} + + +//======================================================================== +// Sets the specified input mode of the specified window +//======================================================================== + +GLFWAPI void glfwSetInputMode(GLFWwindow handle, int mode, int value) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + + if (!_glfwInitialized) + { + _glfwSetError(GLFW_NOT_INITIALIZED, NULL); + return; + } + + switch (mode) + { + case GLFW_CURSOR_MODE: + setCursorMode(window, value); + break; + case GLFW_STICKY_KEYS: + setStickyKeys(window, value ? GL_TRUE : GL_FALSE); + break; + case GLFW_STICKY_MOUSE_BUTTONS: + setStickyMouseButtons(window, value ? GL_TRUE : GL_FALSE); + break; + case GLFW_SYSTEM_KEYS: + setSystemKeys(window, value ? GL_TRUE : GL_FALSE); + break; + case GLFW_KEY_REPEAT: + setKeyRepeat(window, value ? GL_TRUE : GL_FALSE); + break; + default: + _glfwSetError(GLFW_INVALID_ENUM, NULL); + break; + } +} + + //======================================================================== // Returns the state of the specified key for the specified window //======================================================================== @@ -175,10 +362,8 @@ GLFWAPI int glfwGetKey(GLFWwindow handle, int key) return GLFW_RELEASE; } - // Is it a valid key? if (key < 0 || key > GLFW_KEY_LAST) { - // TODO: Decide whether key is a value or enum _glfwSetError(GLFW_INVALID_ENUM, "glfwGetKey: The specified key is invalid"); return GLFW_RELEASE; @@ -209,7 +394,6 @@ GLFWAPI int glfwGetMouseButton(GLFWwindow handle, int button) return GLFW_RELEASE; } - // Is it a valid mouse button? if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST) { _glfwSetError(GLFW_INVALID_ENUM, @@ -242,7 +426,6 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos) return; } - // Return mouse position if (xpos != NULL) *xpos = window->cursorPosX; @@ -311,51 +494,6 @@ GLFWAPI void glfwGetScrollOffset(GLFWwindow handle, int* xoffset, int* yoffset) } -//======================================================================== -// Sets the cursor mode for the specified window -//======================================================================== - -GLFWAPI void glfwSetCursorMode(GLFWwindow handle, int mode) -{ - int centerPosX, centerPosY; - _GLFWwindow* window = (_GLFWwindow*) handle; - - if (!_glfwInitialized) - { - _glfwSetError(GLFW_NOT_INITIALIZED, NULL); - return; - } - - if (mode != GLFW_CURSOR_NORMAL && - mode != GLFW_CURSOR_HIDDEN && - mode != GLFW_CURSOR_CAPTURED) - { - _glfwSetError(GLFW_INVALID_ENUM, NULL); - return; - } - - if (window->cursorMode == mode) - return; - - centerPosX = window->width / 2; - centerPosY = window->height / 2; - - if (mode == GLFW_CURSOR_CAPTURED) - _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); - else if (window->cursorMode == GLFW_CURSOR_CAPTURED) - { - _glfwPlatformSetMouseCursorPos(window, centerPosX, centerPosY); - _glfwInputCursorMotion(window, - centerPosX - window->cursorPosX, - centerPosY - window->cursorPosY); - } - - _glfwPlatformSetCursorMode(window, mode); - - window->cursorMode = mode; -} - - //======================================================================== // Set callback function for keyboard input //======================================================================== @@ -416,7 +554,6 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) return; } - // Set callback function _glfwLibrary.mousePosCallback = cbfun; // Call the callback function to let the application know the current @@ -459,7 +596,6 @@ GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun) return; } - // Set callback function _glfwLibrary.scrollCallback = cbfun; } diff --git a/src/internal.h b/src/internal.h index cabafeb4..44141e66 100644 --- a/src/internal.h +++ b/src/internal.h @@ -37,9 +37,9 @@ //======================================================================== #if defined(_init_c_) -#define GLFWGLOBAL + #define GLFWGLOBAL #else -#define GLFWGLOBAL extern + #define GLFWGLOBAL extern #endif @@ -66,13 +66,13 @@ #include "../support/GL/glext.h" #if defined(_GLFW_COCOA_NSGL) -#include "cocoa_platform.h" + #include "cocoa_platform.h" #elif defined(_GLFW_WIN32_WGL) -#include "win32_platform.h" + #include "win32_platform.h" #elif defined(_GLFW_X11_GLX) -#include "x11_platform.h" + #include "x11_platform.h" #else -#error "No supported platform selected" + #error "No supported platform selected" #endif typedef struct _GLFWhints _GLFWhints; @@ -183,7 +183,7 @@ struct _GLFWwindow GLboolean stickyKeys; GLboolean stickyMouseButtons; GLboolean keyRepeat; - GLboolean sysKeysDisabled; // system keys disabled flag + GLboolean systemKeys; // system keys enabled flag int cursorPosX, cursorPosY; int cursorMode; int scrollX, scrollY; @@ -242,9 +242,6 @@ struct _GLFWlibrary GLFWkeyfun keyCallback; GLFWcharfun charCallback; - GLFWthreadmodel threading; - GLFWallocator allocator; - GLFWgammaramp currentRamp; GLFWgammaramp originalRamp; int originalRampSize; @@ -277,7 +274,7 @@ int _glfwPlatformInit(void); int _glfwPlatformTerminate(void); const char* _glfwPlatformGetVersionString(void); -// Enable/Disable +// Input void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); @@ -327,10 +324,6 @@ void _glfwPlatformCopyContext(_GLFWwindow* src, _GLFWwindow* dst, unsigned long // Prototypes for platform independent internal functions //======================================================================== -// Memory management (init.c) -void* _glfwMalloc(size_t size); -void _glfwFree(void* ptr); - // Fullscren management (fullscreen.c) void _glfwSplitBPP(int bpp, int* red, int* green, int* blue); @@ -340,14 +333,14 @@ void _glfwSetError(int error, const char* description); // Window management (window.c) void _glfwSetDefaultWindowHints(void); -// WIndow event notification +// Window event notification (window.c) void _glfwInputWindowFocus(_GLFWwindow* window, GLboolean activated); void _glfwInputWindowPos(_GLFWwindow* window, int x, int y); void _glfwInputWindowSize(_GLFWwindow* window, int width, int height); void _glfwInputWindowIconify(_GLFWwindow* window, int iconified); void _glfwInputWindowDamage(_GLFWwindow* window); -// Input event notification +// Input event notification (input.c) void _glfwInputKey(_GLFWwindow* window, int key, int action); void _glfwInputChar(_GLFWwindow* window, int character); void _glfwInputScroll(_GLFWwindow* window, int x, int y); diff --git a/src/win32_init.c b/src/win32_init.c index 0756b0f2..4e1b7863 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -47,7 +47,7 @@ static GLboolean initLibraries(void) #ifndef _GLFW_NO_DLOAD_GDI32 // gdi32.dll (OpenGL pixel format functions & SwapBuffers) - _glfwLibrary.Win32.gdi.instance = LoadLibrary("gdi32.dll"); + _glfwLibrary.Win32.gdi.instance = LoadLibrary(L"gdi32.dll"); if (!_glfwLibrary.Win32.gdi.instance) return GL_FALSE; @@ -81,12 +81,12 @@ static GLboolean initLibraries(void) #ifndef _GLFW_NO_DLOAD_WINMM // winmm.dll (for joystick and timer support) - _glfwLibrary.Win32.winmm.instance = LoadLibrary("winmm.dll"); + _glfwLibrary.Win32.winmm.instance = LoadLibrary(L"winmm.dll"); if (!_glfwLibrary.Win32.winmm.instance) return GL_FALSE; - _glfwLibrary.Win32.winmm.joyGetDevCapsA = (JOYGETDEVCAPSA_T) - GetProcAddress(_glfwLibrary.Win32.winmm.instance, "joyGetDevCapsA"); + _glfwLibrary.Win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T) + GetProcAddress(_glfwLibrary.Win32.winmm.instance, "joyGetDevCapsW"); _glfwLibrary.Win32.winmm.joyGetPos = (JOYGETPOS_T) GetProcAddress(_glfwLibrary.Win32.winmm.instance, "joyGetPos"); _glfwLibrary.Win32.winmm.joyGetPosEx = (JOYGETPOSEX_T) @@ -94,7 +94,7 @@ static GLboolean initLibraries(void) _glfwLibrary.Win32.winmm.timeGetTime = (TIMEGETTIME_T) GetProcAddress(_glfwLibrary.Win32.winmm.instance, "timeGetTime"); - if (!_glfwLibrary.Win32.winmm.joyGetDevCapsA || + if (!_glfwLibrary.Win32.winmm.joyGetDevCaps || !_glfwLibrary.Win32.winmm.joyGetPos || !_glfwLibrary.Win32.winmm.joyGetPosEx || !_glfwLibrary.Win32.winmm.timeGetTime) @@ -131,6 +131,60 @@ static void freeLibraries(void) } +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Returns a wide string version of the specified UTF-8 string +//======================================================================== + +WCHAR* _glfwCreateWideStringFromUTF8(const char* source) +{ + WCHAR* target; + int length; + + length = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0); + if (!length) + return NULL; + + target = (WCHAR*) malloc(sizeof(WCHAR) * (length + 1)); + + if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, length + 1)) + { + free(target); + return NULL; + } + + return target; +} + + +//======================================================================== +// Returns a UTF-8 string version of the specified wide string +//======================================================================== + +char* _glfwCreateUTF8FromWideString(const WCHAR* source) +{ + char* target; + int length; + + length = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL); + if (!length) + return NULL; + + target = (char*) malloc(length + 1); + + if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, length + 1, NULL, NULL)) + { + free(target); + return NULL; + } + + return target; +} + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// diff --git a/src/win32_enable.c b/src/win32_input.c similarity index 100% rename from src/win32_enable.c rename to src/win32_input.c diff --git a/src/win32_platform.h b/src/win32_platform.h index 074e28ba..82b8c9ca 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -45,6 +45,14 @@ // thinks it is the only one that gets to do so #undef APIENTRY +// GLFW on Windows is Unicode only and does not work in MBCS mode +#ifndef UNICODE + #define UNICODE +#endif + +// GLFW requires Windows XP +#define WINVER 0x0501 + #include #include @@ -61,10 +69,10 @@ // Some old versions of w32api (used by MinGW and Cygwin) define // WH_KEYBOARD_LL without typedef:ing KBDLLHOOKSTRUCT (!) #if defined(__MINGW32__) || defined(__CYGWIN__) -#include -#if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2) -#undef WH_KEYBOARD_LL -#endif + #include + #if defined(WH_KEYBOARD_LL) && (__W32API_MAJOR_VERSION == 1) && (__W32API_MINOR_VERSION <= 2) + #undef WH_KEYBOARD_LL + #endif #endif //------------------------------------------------------------------------ @@ -84,64 +92,64 @@ typedef struct tagKBDLLHOOKSTRUCT { #endif // WH_KEYBOARD_LL #ifndef LLKHF_ALTDOWN -#define LLKHF_ALTDOWN 0x00000020 + #define LLKHF_ALTDOWN 0x00000020 #endif #ifndef SPI_SETSCREENSAVERRUNNING -#define SPI_SETSCREENSAVERRUNNING 97 + #define SPI_SETSCREENSAVERRUNNING 97 #endif #ifndef SPI_GETANIMATION -#define SPI_GETANIMATION 72 + #define SPI_GETANIMATION 72 #endif #ifndef SPI_SETANIMATION -#define SPI_SETANIMATION 73 + #define SPI_SETANIMATION 73 #endif #ifndef SPI_GETFOREGROUNDLOCKTIMEOUT -#define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 + #define SPI_GETFOREGROUNDLOCKTIMEOUT 0x2000 #endif #ifndef SPI_SETFOREGROUNDLOCKTIMEOUT -#define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 + #define SPI_SETFOREGROUNDLOCKTIMEOUT 0x2001 #endif #ifndef CDS_FULLSCREEN -#define CDS_FULLSCREEN 4 + #define CDS_FULLSCREEN 4 #endif #ifndef PFD_GENERIC_ACCELERATED -#define PFD_GENERIC_ACCELERATED 0x00001000 + #define PFD_GENERIC_ACCELERATED 0x00001000 #endif #ifndef PFD_DEPTH_DONTCARE -#define PFD_DEPTH_DONTCARE 0x20000000 + #define PFD_DEPTH_DONTCARE 0x20000000 #endif #ifndef ENUM_CURRENT_SETTINGS -#define ENUM_CURRENT_SETTINGS -1 + #define ENUM_CURRENT_SETTINGS -1 #endif #ifndef ENUM_REGISTRY_SETTINGS -#define ENUM_REGISTRY_SETTINGS -2 + #define ENUM_REGISTRY_SETTINGS -2 #endif #ifndef WM_MOUSEWHEEL -#define WM_MOUSEWHEEL 0x020A + #define WM_MOUSEWHEEL 0x020A #endif #ifndef WHEEL_DELTA -#define WHEEL_DELTA 120 + #define WHEEL_DELTA 120 #endif #ifndef WM_MOUSEHWHEEL -#define WM_MOUSEHWHEEL 0x020E + #define WM_MOUSEHWHEEL 0x020E #endif #ifndef WM_XBUTTONDOWN -#define WM_XBUTTONDOWN 0x020B + #define WM_XBUTTONDOWN 0x020B #endif #ifndef WM_XBUTTONUP -#define WM_XBUTTONUP 0x020C + #define WM_XBUTTONUP 0x020C #endif #ifndef XBUTTON1 -#define XBUTTON1 1 + #define XBUTTON1 1 #endif #ifndef XBUTTON2 -#define XBUTTON2 2 + #define XBUTTON2 2 #endif @@ -162,7 +170,7 @@ typedef BOOL (WINAPI * SETDEVICEGAMMARAMP_T) (HDC,PVOID); // winmm.dll function pointer typedefs #ifndef _GLFW_NO_DLOAD_WINMM -typedef MMRESULT (WINAPI * JOYGETDEVCAPSA_T) (UINT,LPJOYCAPSA,UINT); +typedef MMRESULT (WINAPI * JOYGETDEVCAPS_T) (UINT,LPJOYCAPS,UINT); typedef MMRESULT (WINAPI * JOYGETPOS_T) (UINT,LPJOYINFO); typedef MMRESULT (WINAPI * JOYGETPOSEX_T) (UINT,LPJOYINFOEX); typedef DWORD (WINAPI * TIMEGETTIME_T) (void); @@ -171,40 +179,40 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void); // gdi32.dll shortcuts #ifndef _GLFW_NO_DLOAD_GDI32 -#define _glfw_ChoosePixelFormat _glfwLibrary.Win32.gdi.ChoosePixelFormat -#define _glfw_DescribePixelFormat _glfwLibrary.Win32.gdi.DescribePixelFormat -#define _glfw_GetPixelFormat _glfwLibrary.Win32.gdi.GetPixelFormat -#define _glfw_SetPixelFormat _glfwLibrary.Win32.gdi.SetPixelFormat -#define _glfw_SwapBuffers _glfwLibrary.Win32.gdi.SwapBuffers -#define _glfw_GetDeviceGammaRamp _glfwLibrary.Win32.gdi.GetDeviceGammaRamp -#define _glfw_SetDeviceGammaRamp _glfwLibrary.Win32.gdi.SetDeviceGammaRamp + #define _glfw_ChoosePixelFormat _glfwLibrary.Win32.gdi.ChoosePixelFormat + #define _glfw_DescribePixelFormat _glfwLibrary.Win32.gdi.DescribePixelFormat + #define _glfw_GetPixelFormat _glfwLibrary.Win32.gdi.GetPixelFormat + #define _glfw_SetPixelFormat _glfwLibrary.Win32.gdi.SetPixelFormat + #define _glfw_SwapBuffers _glfwLibrary.Win32.gdi.SwapBuffers + #define _glfw_GetDeviceGammaRamp _glfwLibrary.Win32.gdi.GetDeviceGammaRamp + #define _glfw_SetDeviceGammaRamp _glfwLibrary.Win32.gdi.SetDeviceGammaRamp #else -#define _glfw_ChoosePixelFormat ChoosePixelFormat -#define _glfw_DescribePixelFormat DescribePixelFormat -#define _glfw_GetPixelFormat GetPixelFormat -#define _glfw_SetPixelFormat SetPixelFormat -#define _glfw_SwapBuffers SwapBuffers -#define _glfw_GetDeviceGammaRamp GetDeviceGammaRamp -#define _glfw_SetDeviceGammaRamp SetDeviceGammaRamp + #define _glfw_ChoosePixelFormat ChoosePixelFormat + #define _glfw_DescribePixelFormat DescribePixelFormat + #define _glfw_GetPixelFormat GetPixelFormat + #define _glfw_SetPixelFormat SetPixelFormat + #define _glfw_SwapBuffers SwapBuffers + #define _glfw_GetDeviceGammaRamp GetDeviceGammaRamp + #define _glfw_SetDeviceGammaRamp SetDeviceGammaRamp #endif // _GLFW_NO_DLOAD_GDI32 // winmm.dll shortcuts #ifndef _GLFW_NO_DLOAD_WINMM -#define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCapsA -#define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos -#define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx -#define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime + #define _glfw_joyGetDevCaps _glfwLibrary.Win32.winmm.joyGetDevCaps + #define _glfw_joyGetPos _glfwLibrary.Win32.winmm.joyGetPos + #define _glfw_joyGetPosEx _glfwLibrary.Win32.winmm.joyGetPosEx + #define _glfw_timeGetTime _glfwLibrary.Win32.winmm.timeGetTime #else -#define _glfw_joyGetDevCaps joyGetDevCapsA -#define _glfw_joyGetPos joyGetPos -#define _glfw_joyGetPosEx joyGetPosEx -#define _glfw_timeGetTime timeGetTime + #define _glfw_joyGetDevCaps joyGetDevCaps + #define _glfw_joyGetPos joyGetPos + #define _glfw_joyGetPosEx joyGetPosEx + #define _glfw_timeGetTime timeGetTime #endif // _GLFW_NO_DLOAD_WINMM // We use versioned window class names in order not to cause conflicts // between applications using different versions of GLFW -#define _GLFW_WNDCLASSNAME "GLFW30" +#define _GLFW_WNDCLASSNAME L"GLFW30" #define _GLFW_PLATFORM_WINDOW_STATE _GLFWwindowWin32 Win32 @@ -309,7 +317,7 @@ typedef struct _GLFWlibraryWin32 // winmm.dll struct { HINSTANCE instance; - JOYGETDEVCAPSA_T joyGetDevCapsA; + JOYGETDEVCAPS_T joyGetDevCaps; JOYGETPOS_T joyGetPos; JOYGETPOSEX_T joyGetPosEx; TIMEGETTIME_T timeGetTime; @@ -323,6 +331,10 @@ typedef struct _GLFWlibraryWin32 // Prototypes for platform specific internal functions //======================================================================== +// Wide strings +WCHAR* _glfwCreateWideStringFromUTF8(const char* source); +char* _glfwCreateUTF8FromWideString(const WCHAR* source); + // Time void _glfwInitTimer(void); diff --git a/src/win32_window.c b/src/win32_window.c index e2619acf..0f3c67d0 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -195,7 +195,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) return NULL; } - result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count); + result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); if (!result) { _glfwSetError(GLFW_OUT_OF_MEMORY, @@ -895,7 +895,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, if (_glfwLibrary.charCallback) translateChar(window, (DWORD) wParam, (DWORD) lParam); - return 0; + break; } case WM_KEYUP: @@ -910,7 +910,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, else _glfwInputKey(window, translateKey(wParam, lParam), GLFW_RELEASE); - return 0; + break; } case WM_LBUTTONDOWN: @@ -1220,7 +1220,7 @@ static ATOM registerWindowClass(void) wc.lpszClassName = _GLFW_WNDCLASSNAME; // Set class name // Load user-provided icon if available - wc.hIcon = LoadIcon(_glfwLibrary.Win32.instance, "GLFW_ICON"); + wc.hIcon = LoadIcon(_glfwLibrary.Win32.instance, L"GLFW_ICON"); if (!wc.hIcon) { // Load default icon @@ -1257,13 +1257,13 @@ static int choosePixelFormat(_GLFWwindow* window, const _GLFWfbconfig* fbconfig) closest = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); if (!closest) { - _glfwFree(fbconfigs); + free(fbconfigs); return 0; } pixelFormat = (int) closest->platformID; - _glfwFree(fbconfigs); + free(fbconfigs); fbconfigs = NULL; closest = NULL; @@ -1283,6 +1283,7 @@ static int createWindow(_GLFWwindow* window, int pixelFormat, fullWidth, fullHeight; RECT wa; POINT pos; + WCHAR* wideTitle; // Set common window styles dwStyle = WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE; @@ -1331,9 +1332,17 @@ static int createWindow(_GLFWwindow* window, else SystemParametersInfo(SPI_GETWORKAREA, 0, &wa, 0); + wideTitle = _glfwCreateWideStringFromUTF8(wndconfig->title); + if (!wideTitle) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "glfwOpenWindow: Failed to convert title to wide string"); + return GL_FALSE; + } + window->Win32.handle = CreateWindowEx(window->Win32.dwExStyle, _GLFW_WNDCLASSNAME, - wndconfig->title, + wideTitle, window->Win32.dwStyle, wa.left, wa.top, // Window position fullWidth, // Decorated window width @@ -1349,6 +1358,8 @@ static int createWindow(_GLFWwindow* window, return GL_FALSE; } + free(wideTitle); + window->WGL.DC = GetDC(window->Win32.handle); if (!window->WGL.DC) { @@ -1430,6 +1441,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, GLboolean recreateContext = GL_FALSE; window->Win32.desiredRefreshRate = wndconfig->refreshRate; + window->resizable = wndconfig->resizable; if (!_glfwLibrary.Win32.classAtom) { @@ -1568,7 +1580,17 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) { - SetWindowText(window->Win32.handle, title); + WCHAR* wideTitle = _glfwCreateWideStringFromUTF8(title); + if (!wideTitle) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "glfwSetWindowTitle: Failed to convert title to wide string"); + return; + } + + SetWindowText(window->Win32.handle, wideTitle); + + free(wideTitle); } diff --git a/src/window.c b/src/window.c index 88b3dc18..f8939e37 100644 --- a/src/window.c +++ b/src/window.c @@ -291,7 +291,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, height = 480; } - window = (_GLFWwindow*) _glfwMalloc(sizeof(_GLFWwindow)); + window = (_GLFWwindow*) malloc(sizeof(_GLFWwindow)); if (!window) { _glfwSetError(GLFW_OUT_OF_MEMORY, @@ -309,6 +309,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, window->height = height; window->mode = mode; window->cursorMode = GLFW_CURSOR_NORMAL; + window->systemKeys = GL_TRUE; // Open the actual window and create its context if (!_glfwPlatformOpenWindow(window, &wndconfig, &fbconfig)) @@ -330,7 +331,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, // The GLFW specification states that fullscreen windows have the cursor // captured by default if (mode == GLFW_FULLSCREEN) - glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED); // Clearing the front buffer to black to avoid garbage pixels left over // from previous uses of our bit of VRAM @@ -491,7 +492,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle) *prev = window->next; } - _glfwFree(window); + free(window); } @@ -654,7 +655,6 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow handle) if (!window->iconified) return; - // Restore iconified window _glfwPlatformRestoreWindow(window); if (window->mode == GLFW_FULLSCREEN) diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index bb0a3d53..f7855c4b 100644 --- a/src/x11_fullscreen.c +++ b/src/x11_fullscreen.c @@ -339,7 +339,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) return 0; } - rgbarray = (int*) _glfwMalloc(sizeof(int) * viscount); + rgbarray = (int*) malloc(sizeof(int) * viscount); rgbcount = 0; // Build RGB array @@ -372,6 +372,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) } } + XFree(vislist); + rescount = 0; resarray = NULL; @@ -387,7 +389,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) sc = XRRGetScreenInfo(_glfwLibrary.X11.display, _glfwLibrary.X11.root); sizelist = XRRConfigSizes(sc, &sizecount); - resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * sizecount); + resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * sizecount); for (k = 0; k < sizecount; k++) { @@ -407,7 +409,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) XF86VidModeGetAllModeLines(_glfwLibrary.X11.display, screen, &modecount, &modelist); - resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * modecount); + resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * modecount); for (k = 0; k < modecount; k++) { @@ -436,7 +438,7 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) if (!resarray) { rescount = 1; - resarray = (struct _glfwResolution*) _glfwMalloc(sizeof(struct _glfwResolution) * rescount); + resarray = (struct _glfwResolution*) malloc(sizeof(struct _glfwResolution) * rescount); resarray[0].width = DisplayWidth(_glfwLibrary.X11.display, screen); resarray[0].height = DisplayHeight(_glfwLibrary.X11.display, screen); @@ -457,10 +459,8 @@ int _glfwPlatformGetVideoModes(GLFWvidmode* list, int maxcount) } } - XFree(vislist); - - _glfwFree(resarray); - _glfwFree(rgbarray); + free(resarray); + free(rgbarray); return count; } diff --git a/src/x11_init.c b/src/x11_init.c index 4d3c0f74..3ed9ab13 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -79,7 +79,11 @@ static int keyCodeToGLFWKeyCode(int keyCode) // Note: This way we always force "NumLock = ON", which is intentional // since the returned key code should correspond to a physical // location. +#if defined(_GLFW_HAS_XKB) + keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1, 0); +#else keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 1); +#endif switch (keySym) { case XK_KP_0: return GLFW_KEY_KP_0; @@ -102,7 +106,12 @@ static int keyCodeToGLFWKeyCode(int keyCode) // Now try pimary keysym for function keys (non-printable keys). These // should not be layout dependent (i.e. US layout and international // layouts should give the same result). +#if defined(_GLFW_HAS_XKB) + keySym = XkbKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0, 0); +#else keySym = XKeycodeToKeysym(_glfwLibrary.X11.display, keyCode, 0); +#endif + switch (keySym) { case XK_Escape: return GLFW_KEY_ESCAPE; diff --git a/src/x11_enable.c b/src/x11_input.c similarity index 100% rename from src/x11_enable.c rename to src/x11_input.c diff --git a/src/x11_opengl.c b/src/x11_opengl.c index 9ba89c9f..fd8bd313 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -31,8 +31,7 @@ #include "internal.h" -void (*glXGetProcAddress(const GLubyte* procName))(); -void (*glXGetProcAddressARB(const GLubyte* procName))(); +// This is the only glXGetProcAddress variant not declared by glxext.h void (*glXGetProcAddressEXT(const GLubyte* procName))(); diff --git a/src/x11_platform.h b/src/x11_platform.h index 46f09f1a..3b824d64 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -46,13 +46,6 @@ // extensions and not all operating systems come with an up-to-date version #include "../support/GL/glxext.h" - -// We need declarations for GLX version 1.3 or above even if the server doesn't -// support version 1.3 -#ifndef GLX_VERSION_1_3 - #error "GLX header version 1.3 or above is required" -#endif - // With XFree86, we can use the XF86VidMode extension #if defined(_GLFW_HAS_XF86VIDMODE) #include @@ -141,6 +134,8 @@ typedef struct _GLFWwindowX11 Colormap colormap; // Window colormap Window handle; // Window handle Atom wmDeleteWindow; // WM_DELETE_WINDOW atom + Atom wmName; // _NET_WM_NAME atom + Atom wmIconName; // _NET_WM_ICON_NAME atom Atom wmPing; // _NET_WM_PING atom Atom wmState; // _NET_WM_STATE atom Atom wmStateFullscreen; // _NET_WM_STATE_FULLSCREEN atom diff --git a/src/x11_time.c b/src/x11_time.c index e2203941..4184d326 100644 --- a/src/x11_time.c +++ b/src/x11_time.c @@ -39,7 +39,7 @@ static uint64_t getRawTime(void) { -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) +#if defined(CLOCK_MONOTONIC) if (_glfwLibrary.X11.timer.monotonic) { struct timespec ts; @@ -64,7 +64,7 @@ static uint64_t getRawTime(void) void _glfwInitTimer(void) { -#if defined(_POSIX_TIMERS) && defined(_POSIX_MONOTONIC_CLOCK) +#if defined(CLOCK_MONOTONIC) struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) diff --git a/src/x11_window.c b/src/x11_window.c index ffe27722..fe3b98a1 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -195,6 +195,12 @@ static GLboolean hasEWMH(_GLFWwindow* window) window->X11.wmStateFullscreen = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE_FULLSCREEN"); + window->X11.wmName = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_NAME"); + + window->X11.wmIconName = + getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_ICON_NAME"); + window->X11.wmPing = getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_PING"); @@ -310,7 +316,7 @@ static _GLFWfbconfig* getFBConfigs(_GLFWwindow* window, unsigned int* found) } } - result = (_GLFWfbconfig*) _glfwMalloc(sizeof(_GLFWfbconfig) * count); + result = (_GLFWfbconfig*) malloc(sizeof(_GLFWfbconfig) * count); if (!result) { _glfwSetError(GLFW_OUT_OF_MEMORY, @@ -1444,12 +1450,12 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, result = _glfwChooseFBConfig(fbconfig, fbconfigs, fbcount); if (!result) { - _glfwFree(fbconfigs); + free(fbconfigs); return GL_FALSE; } closest = *result; - _glfwFree(fbconfigs); + free(fbconfigs); } if (!createContext(window, wndconfig, (GLXFBConfigID) closest.platformID)) @@ -1544,9 +1550,39 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char* title) { - // Set window & icon title - XStoreName(_glfwLibrary.X11.display, window->X11.handle, title); - XSetIconName(_glfwLibrary.X11.display, window->X11.handle, title); + Atom type = XInternAtom(_glfwLibrary.X11.display, "UTF8_STRING", False); + +#if defined(X_HAVE_UTF8_STRING) + Xutf8SetWMProperties(_glfwLibrary.X11.display, + window->X11.handle, + title, title, + NULL, 0, + NULL, NULL, NULL); +#else + // This may be a slightly better fallback than using XStoreName and + // XSetIconName, which always store their arguments using STRING + XmbSetWMProperties(_glfwLibrary.X11.display, + window->X11.handle, + title, title, + NULL, 0, + NULL, NULL, NULL); +#endif + + if (window->X11.wmName != None) + { + XChangeProperty(_glfwLibrary.X11.display, window->X11.handle, + window->X11.wmName, type, 8, + PropModeReplace, + (unsigned char*) title, strlen(title)); + } + + if (window->X11.wmIconName != None) + { + XChangeProperty(_glfwLibrary.X11.display, window->X11.handle, + window->X11.wmIconName, type, 8, + PropModeReplace, + (unsigned char*) title, strlen(title)); + } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5adbf351..7a166881 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -36,6 +36,9 @@ target_link_libraries(joysticks ${STATIC_DEPS}) add_executable(listmodes listmodes.c) target_link_libraries(listmodes ${STATIC_DEPS}) +add_executable(modes modes.c getopt.c) +target_link_libraries(modes ${STATIC_DEPS}) + add_executable(peter peter.c) target_link_libraries(peter ${STATIC_DEPS}) @@ -44,23 +47,37 @@ target_link_libraries(reopen ${STATIC_DEPS}) add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) target_link_libraries(accuracy ${STATIC_DEPS}) +set_target_properties(accuracy PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Accuracy") add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) target_link_libraries(sharing ${STATIC_DEPS}) +set_target_properties(sharing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Sharing") add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c) target_link_libraries(tearing ${STATIC_DEPS}) +set_target_properties(tearing PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Tearing") + +add_executable(title WIN32 MACOSX_BUNDLE title.c) +target_link_libraries(title ${STATIC_DEPS}) +set_target_properties(title PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Title") add_executable(windows WIN32 MACOSX_BUNDLE windows.c) target_link_libraries(windows ${STATIC_DEPS}) +set_target_properties(windows PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "Windows") -set(WINDOWS_BINARIES accuracy sharing tearing windows) +set(WINDOWS_BINARIES accuracy sharing tearing title windows) set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma glfwinfo iconify - joysticks listmodes peter reopen) + joysticks listmodes modes peter reopen) -if(MSVC) - # Tell MSVC to use main instead of WinMain for Windows subsystem executables - set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - LINK_FLAGS "/ENTRY:mainCRTStartup") -endif(MSVC) +if (MSVC) + # Tell MSVC to use main instead of WinMain for Windows subsystem executables + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup") +endif() + +if (APPLE) + set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES + MACOSX_BUNDLE_SHORT_VERSION_STRING ${GLFW_VERSION} + MACOSX_BUNDLE_LONG_VERSION_STRING ${GLFW_VERSION_FULL}) +endif() diff --git a/tests/events.c b/tests/events.c index f276573e..3bf2ca6c 100644 --- a/tests/events.c +++ b/tests/events.c @@ -40,8 +40,9 @@ #include #include -static GLboolean keyrepeat = 0; -static GLboolean systemkeys = 1; +static GLboolean keyrepeat = GL_FALSE; +static GLboolean systemkeys = GL_TRUE; +static GLboolean closeable = GL_TRUE; static unsigned int counter = 0; static const char* get_key_name(int key) @@ -230,7 +231,7 @@ static void window_size_callback(GLFWwindow window, int width, int height) static int window_close_callback(GLFWwindow window) { printf("%08x at %0.3f: Window close\n", counter++, glfwGetTime()); - return 1; + return closeable; } static void window_refresh_callback(GLFWwindow window) @@ -306,10 +307,7 @@ static void key_callback(GLFWwindow window, int key, int action) case GLFW_KEY_R: { keyrepeat = !keyrepeat; - if (keyrepeat) - glfwEnable(window, GLFW_KEY_REPEAT); - else - glfwDisable(window, GLFW_KEY_REPEAT); + glfwSetInputMode(window, GLFW_KEY_REPEAT, keyrepeat); printf("(( key repeat %s ))\n", keyrepeat ? "enabled" : "disabled"); break; @@ -318,14 +316,19 @@ static void key_callback(GLFWwindow window, int key, int action) case GLFW_KEY_S: { systemkeys = !systemkeys; - if (systemkeys) - glfwEnable(window, GLFW_SYSTEM_KEYS); - else - glfwDisable(window, GLFW_SYSTEM_KEYS); + glfwSetInputMode(window, GLFW_SYSTEM_KEYS, systemkeys); printf("(( system keys %s ))\n", systemkeys ? "enabled" : "disabled"); break; } + + case GLFW_KEY_C: + { + closeable = !closeable; + + printf("(( closing %s ))\n", closeable ? "enabled" : "disabled"); + break; + } } } diff --git a/tests/fsfocus.c b/tests/fsfocus.c index 5392c5e7..951409a6 100644 --- a/tests/fsfocus.c +++ b/tests/fsfocus.c @@ -91,7 +91,7 @@ int main(void) } glfwSwapInterval(1); - glfwSetCursorMode(window, GLFW_CURSOR_NORMAL); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); glfwSetWindowFocusCallback(window_focus_callback); glfwSetKeyCallback(window_key_callback); diff --git a/tests/gamma.c b/tests/gamma.c index 981cbcc4..b8ec6c45 100644 --- a/tests/gamma.c +++ b/tests/gamma.c @@ -35,11 +35,20 @@ #include "getopt.h" +#define STEP_SIZE 0.1f + static GLfloat gamma = 1.0f; static void usage(void) { - printf("Usage: gammatest [-h] [-f]\n"); + printf("Usage: gamma [-h] [-f]\n"); +} + +static void set_gamma(float value) +{ + gamma = value; + printf("Gamma: %f\n", gamma); + glfwSetGamma(gamma); } static void key_callback(GLFWwindow window, int key, int action) @@ -50,20 +59,26 @@ static void key_callback(GLFWwindow window, int key, int action) switch (key) { case GLFW_KEY_ESCAPE: + { glfwCloseWindow(window); break; + } + case GLFW_KEY_KP_ADD: case GLFW_KEY_Q: - gamma += 0.1f; - printf("Gamma: %f\n", gamma); - glfwSetGamma(gamma); + { + set_gamma(gamma + STEP_SIZE); break; + } + case GLFW_KEY_KP_SUBTRACT: case GLFW_KEY_W: - gamma -= 0.1f; - printf("Gamma: %f\n", gamma); - glfwSetGamma(gamma); + { + if (gamma - STEP_SIZE > 0.f) + set_gamma(gamma - STEP_SIZE); + break; + } } } @@ -124,7 +139,7 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } - printf("Gamma: %f\n", gamma); + set_gamma(1.f); glfwSwapInterval(1); glfwSetKeyCallback(key_callback); diff --git a/tests/glfwinfo.c b/tests/glfwinfo.c index 4de6634d..45cb8616 100644 --- a/tests/glfwinfo.c +++ b/tests/glfwinfo.c @@ -51,7 +51,7 @@ static void usage(void) { - printf("Usage: version [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n"); + printf("Usage: glfwinfo [-h] [-m MAJOR] [-n MINOR] [-d] [-l] [-f] [-p PROFILE] [-r STRATEGY]\n"); printf("available profiles: " PROFILE_NAME_CORE " " PROFILE_NAME_COMPAT " " PROFILE_NAME_ES2 "\n"); printf("available strategies: " STRATEGY_NAME_NONE " " STRATEGY_NAME_LOSE "\n"); } @@ -263,7 +263,7 @@ int main(int argc, char** argv) if (major > 3 || (major == 3 && minor >= 2)) { glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask); - printf("OpenGL profile mask: 0x%08x (%s)\n", mask, get_profile_name(mask)); + printf("OpenGL profile mask: %s (0x%08x)\n", get_profile_name(mask), mask); printf("OpenGL profile parsed by GLFW: %s\n", get_glfw_profile_name(glfwGetWindowParam(window, GLFW_OPENGL_PROFILE))); diff --git a/tests/iconify.c b/tests/iconify.c index 6d001ea5..dbc4d9cf 100644 --- a/tests/iconify.c +++ b/tests/iconify.c @@ -62,6 +62,8 @@ static void key_callback(GLFWwindow window, int key, int action) static void size_callback(GLFWwindow window, int width, int height) { + printf("%0.2f Size %ix%i\n", glfwGetTime(), width, height); + glViewport(0, 0, width, height); } diff --git a/tests/modes.c b/tests/modes.c new file mode 100644 index 00000000..de3aec8a --- /dev/null +++ b/tests/modes.c @@ -0,0 +1,225 @@ +//======================================================================== +// Video mode test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test enumerates or verifies video modes +// +//======================================================================== + +#include + +#include +#include + +#include "getopt.h" + +static GLFWwindow window = NULL; + +enum Mode +{ + NO_MODE, + LIST_MODE, + TEST_MODE +}; + +static void usage(void) +{ + printf("Usage: modes -l\n"); + printf(" modes -t\n"); + printf(" modes -h\n"); +} + +static void print_mode(GLFWvidmode* mode) +{ + printf("%i x %i x %i (%i %i %i)", + mode->width, mode->height, + mode->redBits + mode->greenBits + mode->blueBits, + mode->redBits, mode->greenBits, mode->blueBits); +} + +static void error_callback(int error, const char* description) +{ + fprintf(stderr, "Error: %s\n", description); +} + +static void window_size_callback(GLFWwindow window, int width, int height) +{ + printf("Window resized to %ix%i\n", width, height); + + glViewport(0, 0, width, height); +} + +static int window_close_callback(GLFWwindow dummy) +{ + window = NULL; + return GL_TRUE; +} + +static void list_modes(GLFWvidmode* modes, int count) +{ + int i; + GLFWvidmode mode; + + glfwGetDesktopMode(&mode); + printf("Desktop mode: "); + print_mode(&mode); + putchar('\n'); + + for (i = 0; i < count; i++) + { + printf("%3i: ", i); + print_mode(modes + i); + putchar('\n'); + } +} + +static void test_modes(GLFWvidmode* modes, int count) +{ + int i, width, height; + + glfwSetWindowSizeCallback(window_size_callback); + glfwSetWindowCloseCallback(window_close_callback); + + for (i = 0; i < count; i++) + { + glfwOpenWindowHint(GLFW_RED_BITS, modes[i].redBits); + glfwOpenWindowHint(GLFW_GREEN_BITS, modes[i].greenBits); + glfwOpenWindowHint(GLFW_BLUE_BITS, modes[i].blueBits); + + printf("Opening "); + print_mode(modes + i); + printf(" window\n"); + + window = glfwOpenWindow(modes[i].width, modes[i].height, + GLFW_FULLSCREEN, "Video Mode Test", + NULL); + if (!window) + { + printf("Failed to enter mode %i: ", i); + print_mode(modes + i); + putchar('\n'); + continue; + } + + glfwSetTime(0.0); + glfwSwapInterval(1); + + while (glfwGetTime() < 5.0) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(); + glfwPollEvents(); + + if (!window) + { + printf("User terminated program\n"); + exit(EXIT_SUCCESS); + } + } + + if (glfwGetWindowParam(window, GLFW_RED_BITS) != modes[i].redBits || + glfwGetWindowParam(window, GLFW_GREEN_BITS) != modes[i].greenBits || + glfwGetWindowParam(window, GLFW_BLUE_BITS) != modes[i].blueBits) + { + printf("*** Color bit mismatch: (%i %i %i) instead of (%i %i %i)\n", + glfwGetWindowParam(window, GLFW_RED_BITS), + glfwGetWindowParam(window, GLFW_GREEN_BITS), + glfwGetWindowParam(window, GLFW_BLUE_BITS), + modes[i].redBits, + modes[i].greenBits, + modes[i].blueBits); + } + + glfwGetWindowSize(window, &width, &height); + + if (width != modes[i].width || height != height) + { + printf("*** Size mismatch: %ix%i instead of %ix%i\n", + width, height, + modes[i].width, modes[i].height); + } + + printf("Closing window\n"); + + glfwCloseWindow(window); + glfwPollEvents(); + window = NULL; + + sleep(5); + } +} + +int main(int argc, char** argv) +{ + int ch, found, count = 0, mode = NO_MODE; + GLFWvidmode* modes = NULL; + + while ((ch = getopt(argc, argv, "lth")) != -1) + { + switch (ch) + { + case 'h': + usage(); + exit(EXIT_SUCCESS); + case 'l': + mode = LIST_MODE; + break; + case 't': + mode = TEST_MODE; + break; + default: + usage(); + exit(EXIT_FAILURE); + } + } + + argc -= optind; + argv += optind; + + glfwSetErrorCallback(error_callback); + + if (!glfwInit()) + exit(EXIT_FAILURE); + + for (;;) + { + count += 256; + modes = realloc(modes, sizeof(GLFWvidmode) * count); + + found = glfwGetVideoModes(modes, count); + if (found < count) + break; + } + + if (mode == LIST_MODE) + list_modes(modes, found); + else if (mode == TEST_MODE) + test_modes(modes, found); + + free(modes); + modes = NULL; + + exit(EXIT_SUCCESS); +} + diff --git a/tests/peter.c b/tests/peter.c index cefdb103..5ae7ba5d 100644 --- a/tests/peter.c +++ b/tests/peter.c @@ -35,7 +35,6 @@ #include #include -static GLboolean cursor_captured = GL_FALSE; static GLFWwindow window_handle = NULL; static int cursor_x; static int cursor_y; @@ -44,18 +43,16 @@ static GLboolean open_window(void); static void toggle_mouse_cursor(GLFWwindow window) { - if (cursor_captured) + if (glfwGetInputMode(window, GLFW_CURSOR_MODE) == GLFW_CURSOR_CAPTURED) { printf("Released cursor\n"); - glfwSetCursorMode(window, GLFW_CURSOR_NORMAL); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_NORMAL); } else { printf("Captured cursor\n"); - glfwSetCursorMode(window, GLFW_CURSOR_CAPTURED); + glfwSetInputMode(window, GLFW_CURSOR_MODE, GLFW_CURSOR_CAPTURED); } - - cursor_captured = !cursor_captured; } static void mouse_position_callback(GLFWwindow window, int x, int y) diff --git a/tests/sharing.c b/tests/sharing.c index 942ec2c6..7d774151 100644 --- a/tests/sharing.c +++ b/tests/sharing.c @@ -92,8 +92,6 @@ static void draw_quad(GLuint texture) glBindTexture(GL_TEXTURE_2D, texture); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - glColor3f(0.6f, 0.f, 0.6f); - glBegin(GL_QUADS); glTexCoord2f(0.f, 0.f); @@ -142,6 +140,11 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } + // Set drawing color for the first context and copy it to the second + glfwMakeContextCurrent(windows[0]); + glColor3f(0.6f, 0.f, 0.6f); + glfwCopyContext(windows[0], windows[1], GL_CURRENT_BIT); + // Put the second window to the right of the first one glfwGetWindowPos(windows[0], &x, &y); glfwSetWindowPos(windows[1], x + WIDTH + 50, y); diff --git a/tests/tearing.c b/tests/tearing.c index 10170b0f..1eab454e 100644 --- a/tests/tearing.c +++ b/tests/tearing.c @@ -34,11 +34,30 @@ #include #include +static int swap_interval; + +static void set_swap_interval(int value) +{ + char title[256]; + + swap_interval = value; + glfwSwapInterval(swap_interval); + + sprintf(title, "Tearing detector (interval %i)", swap_interval); + glfwSetWindowTitle(glfwGetCurrentContext(), title); +} + static void window_size_callback(GLFWwindow window, int width, int height) { glViewport(0, 0, width, height); } +static void key_callback(GLFWwindow window, int key, int action) +{ + if (key == GLFW_KEY_SPACE && action == GLFW_PRESS) + set_swap_interval(!swap_interval); +} + int main(void) { float position; @@ -50,7 +69,7 @@ int main(void) exit(EXIT_FAILURE); } - window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Tearing Detector", NULL); + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "", NULL); if (!window) { glfwTerminate(); @@ -59,8 +78,10 @@ int main(void) exit(EXIT_FAILURE); } + set_swap_interval(1); + glfwSetWindowSizeCallback(window_size_callback); - glfwSwapInterval(1); + glfwSetKeyCallback(key_callback); glMatrixMode(GL_PROJECTION); glOrtho(-1.f, 1.f, -1.f, 1.f, 1.f, -1.f); diff --git a/tests/title.c b/tests/title.c new file mode 100644 index 00000000..7b342d94 --- /dev/null +++ b/tests/title.c @@ -0,0 +1,70 @@ +//======================================================================== +// UTF-8 window title test +// Copyright (c) Camilla Berglund +// +// 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. +// +//======================================================================== +// +// This test sets a UTF-8 window title +// +//======================================================================== + +#include + +#include +#include + +static void window_size_callback(GLFWwindow window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(void) +{ + GLFWwindow window; + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW: %s\n", glfwErrorString(glfwGetError())); + exit(EXIT_FAILURE); + } + + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "English 日本語 русский язык 官話", NULL); + if (!window) + { + fprintf(stderr, "Failed to open GLFW window: %s\n", glfwErrorString(glfwGetError())); + exit(EXIT_FAILURE); + } + + glfwSwapInterval(1); + + glfwSetWindowSizeCallback(window_size_callback); + + while (glfwIsWindow(window) == GL_TRUE) + { + glClear(GL_COLOR_BUFFER_BIT); + glfwSwapBuffers(); + glfwWaitEvents(); + } + + exit(EXIT_SUCCESS); +} +