diff --git a/.gitignore b/.gitignore index bccab087..fad26de1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,37 @@ cmake_install.cmake CMakeCache.txt Makefile cmake_uninstall.cmake +.DS_Store +docs/Doxyfile src/config.h -src/x11/libglfw.pc -src/win32/libglfw.pc -src/cocoa/libglfw.pc -*.so -*.a +src/libglfw.pc +src/libglfw.so +src/libglfw.a +src/libglfw.dylib +examples/boing +examples/gears +examples/heightmap +examples/splitview +examples/triangle +examples/wave +examples/*.app +examples/*.exe +tests/accuracy +tests/defaults +tests/dynamic +tests/events +tests/fsaa +tests/fsfocus +tests/gamma +tests/glfwinfo +tests/iconify +tests/joysticks +tests/listmodes +tests/peter +tests/reopen +tests/sharing +tests/tearing +tests/title +tests/windows +tests/*.app +tests/*.exe diff --git a/CMakeLists.txt b/CMakeLists.txt index 83eb8bf8..57967600 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,9 +13,6 @@ set(GLFW_VERSION_FULL "${GLFW_VERSION}.${GLFW_VERSION_PATCH}${GLFW_VERSION_EXTRA option(GLFW_BUILD_EXAMPLES "Build the GLFW example programs" ON) option(GLFW_BUILD_TESTS "Build the GLFW test programs" ON) -include(CheckFunctionExists) -include(CheckSymbolExists) - find_package(OpenGL REQUIRED) #-------------------------------------------------------------------- @@ -28,7 +25,6 @@ if (WIN32) set(_GLFW_WIN32_WGL 1) # Set up library and include paths - set(CMAKE_REQUIRED_LIBRARIES ${OPENGL_gl_LIBRARY}) list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR}) list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) endif (WIN32) @@ -36,23 +32,34 @@ endif (WIN32) #-------------------------------------------------------------------- # Set up GLFW for Xlib and GLX on Unix-like systems with X Windows #-------------------------------------------------------------------- -if (UNIX AND NOT APPLE AND NOT CYGWIN) +if (UNIX AND NOT APPLE) message(STATUS "Building GLFW for X11 and GLX on a Unix-like system") # Define the platform identifier set(_GLFW_X11_GLX 1) # Set up library and include paths - set(CMAKE_REQUIRED_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) - list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH}) - list(APPEND GLFW_LIBRARIES ${X11_X11_LIB}) - list(APPEND GLFW_INCLUDE_DIR ${OPENGL_INCLUDE_DIR}) - list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) + list(APPEND GLFW_INCLUDE_DIR ${X11_X11_INCLUDE_PATH} ${OPENGL_INCLUDE_DIR}) + list(APPEND GLFW_LIBRARIES ${X11_X11_LIB} ${OPENGL_gl_LIBRARY}) - include(${CMAKE_CURRENT_SOURCE_DIR}/CMake/CheckX11Extensions.cmake) + find_library(MATH_LIBRARY m) + if (MATH_LIBRARY) + list(APPEND GLFW_LIBRARIES ${MATH_LIBRARY}) + endif(MATH_LIBRARY) + + find_library(RT_LIBRARY rt) + if (RT_LIBRARY) + list(APPEND GLFW_LIBRARIES ${RT_LIBRARY}) + endif(RT_LIBRARY) + + 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() + check_x11_xrandr() if (X11_XRANDR_FOUND) set(_GLFW_HAS_XRANDR 1) list(APPEND GLFW_INCLUDE_DIR ${X11_XRANDR_INCLUDE_DIR}) @@ -60,7 +67,7 @@ if (UNIX AND NOT APPLE AND NOT CYGWIN) endif(X11_XRANDR_FOUND) # Check for Xf86VidMode (fallback legacy resolution switching extension) - CHECK_X11_XF86VIDMODE() + check_x11_xf86vidmode() if (X11_XF86VIDMODE_FOUND) set(_GLFW_HAS_XF86VIDMODE 1) list(APPEND GLFW_INCLUDE_DIR ${X11_XF86VIDMODE_INCLUDE_DIR}) @@ -68,17 +75,17 @@ if (UNIX AND NOT APPLE AND NOT CYGWIN) endif(X11_XF86VIDMODE_FOUND) # Check for Xkb (X keyboard extension) - CHECK_FUNCTION_EXISTS(XkbQueryExtension _GLFW_HAS_XKB) + check_function_exists(XkbQueryExtension _GLFW_HAS_XKB) # Check for glXGetProcAddress - CHECK_FUNCTION_EXISTS(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) + check_function_exists(glXGetProcAddress _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS) - CHECK_FUNCTION_EXISTS(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) + check_function_exists(glXGetProcAddressARB _GLFW_HAS_GLXGETPROCADDRESSARB) endif (NOT _GLFW_HAS_GLXGETPROCADDRESS) if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) - CHECK_FUNCTION_EXISTS(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) + check_function_exists(glXGetProcAddressEXT _GLFW_HAS_GLXGETPROCADDRESSEXT) endif (NOT _GLFW_HAS_GLXGETPROCADDRESS AND NOT _GLFW_HAS_GLXGETPROCADDRESSARB) if (NOT _GLFW_HAS_GLXGETPROCADDRESS AND @@ -92,7 +99,7 @@ if (UNIX AND NOT APPLE AND NOT CYGWIN) if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(_GLFW_USE_LINUX_JOYSTICKS 1) endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") -endif(UNIX AND NOT APPLE AND NOT CYGWIN) +endif(UNIX AND NOT APPLE) #-------------------------------------------------------------------- # Set up GLFW for Cocoa and NSOpenGL on Mac OS X @@ -105,20 +112,24 @@ if (UNIX AND APPLE) option(GLFW_BUILD_UNIVERSAL "Build the GLFW library and examples as Universal Binaries" FALSE) - # Universal build, decent set of warning flags... + # Universal build if (GLFW_BUILD_UNIVERSAL) message(STATUS "Building GLFW as Universal Binaries") set(CMAKE_OSX_ARCHITECTURES ppc;i386;ppc64;x86_64) set(CMAKE_OSX_SYSROOT /Developer/SDKs/MacOSX10.5.sdk) - set(CMAKE_C_FLAGS "-mmacosx-version-min=10.5 -Wall -Wextra -Wno-unused-parameter -Werror") + 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) # Set up library and include paths find_library(COCOA_FRAMEWORK Cocoa) + find_library(IOKIT_FRAMEWORK IOKit) + find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation) list(APPEND GLFW_LIBRARIES ${COCOA_FRAMEWORK}) list(APPEND GLFW_LIBRARIES ${OPENGL_gl_LIBRARY}) + list(APPEND GLFW_LIBRARIES ${IOKIT_FRAMEWORK}) + list(APPEND GLFW_LIBRARIES ${CORE_FOUNDATION_FRAMEWORK}) endif(UNIX AND APPLE) #-------------------------------------------------------------------- @@ -155,12 +166,9 @@ install(FILES COPYING.txt readme.html #-------------------------------------------------------------------- # -- Documentation generation #-------------------------------------------------------------------- -#include("${CMAKE_CURRENT_SOURCE_DIR}/documentation.cmake") -#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in" -# "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile" -# IMMEDIATE @ONLY) -#add_doxygen_target("${CMAKE_CURRENT_BINARY_DIR}/Doxyfile") -#add_subdirectory(docs) +configure_file("${GLFW_SOURCE_DIR}/docs/Doxyfile.in" + "${GLFW_BINARY_DIR}/docs/Doxyfile" + @ONLY) #-------------------------------------------------------------------- # Uninstall operation 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 345631cc..d511b22d 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -32,10 +32,3 @@ if(MSVC) LINK_FLAGS "/ENTRY:mainCRTStartup") endif(MSVC) -if(CYGWIN) - # Set cross-compile and subsystem compile and link flags - set_target_properties(${WINDOWS_BINARIES} PROPERTIES - COMPILE_FLAGS "-mno-cygwin" - LINK_FLAGS "-mno-cygwin -mwindows") -endif(CYGWIN) - 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 1d3dd72e..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(); @@ -583,7 +583,7 @@ int main(int argc, char** argv) exit(EXIT_FAILURE); } - glfwOpenWindowHint(GLFW_WINDOW_NO_RESIZE, GL_TRUE); + glfwOpenWindowHint(GLFW_WINDOW_RESIZABLE, GL_FALSE); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MAJOR, 3); glfwOpenWindowHint(GLFW_OPENGL_VERSION_MINOR, 2); glfwOpenWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); 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 7f054e5f..5ad6f289 100644 --- a/include/GL/glfw3.h +++ b/include/GL/glfw3.h @@ -39,16 +39,6 @@ extern "C" { * Global definitions *************************************************************************/ -/* We need a NULL pointer from time to time */ -#ifndef NULL - #ifdef __cplusplus - #define NULL 0 - #else - #define NULL ((void*) 0) - #endif -#endif /* NULL */ - - /* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ /* Please report any probles that you find with your compiler, which may @@ -75,7 +65,6 @@ extern "C" { #else #define APIENTRY #endif - #define GLFW_APIENTRY_DEFINED #endif /* APIENTRY */ @@ -418,7 +407,7 @@ extern "C" { #define GLFW_ACCUM_ALPHA_BITS 0x0002100A #define GLFW_AUX_BUFFERS 0x0002100B #define GLFW_STEREO 0x0002100C -#define GLFW_WINDOW_NO_RESIZE 0x0002100D +#define GLFW_WINDOW_RESIZABLE 0x0002100D #define GLFW_FSAA_SAMPLES 0x0002100E #define GLFW_OPENGL_VERSION_MAJOR 0x0002100F #define GLFW_OPENGL_VERSION_MINOR 0x00021010 @@ -438,13 +427,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 @@ -494,8 +484,6 @@ typedef void (* GLFWmouseposfun)(GLFWwindow,int,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 @@ -515,19 +503,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 @@ -535,7 +510,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); @@ -580,11 +554,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); @@ -614,10 +589,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 @@ -625,11 +596,6 @@ GLFWAPI void glfwDisable(GLFWwindow window, int token); /* ------------------- BEGIN SYSTEM/COMPILER SPECIFIC -------------------- */ -#ifdef GLFW_APIENTRY_DEFINED - #undef APIENTRY - #undef GLFW_APIENTRY_DEFINED -#endif - #ifdef GLFW_WINGDIAPI_DEFINED #undef WINGDIAPI #undef GLFW_WINGDIAPI_DEFINED diff --git a/readme.html b/readme.html index a028b45b..36c5add2 100644 --- a/readme.html +++ b/readme.html @@ -272,25 +272,27 @@ 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
  • Added GLFW_INCLUDE_GL3 macro for telling the GLFW header to include gl3.h header instead of gl.h
  • Added windows simple multi-window test program
  • Added sharing simple OpenGL object sharing test program
  • +
  • Added dynamic simple dynamic linking 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
  • Renamed version test to glfwinfo
  • 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
  • @@ -307,15 +309,24 @@ version of GLFW.

  • Bugfix: The OpenGL profile and forward-compatibility window parameters were not saved after context creation
  • 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] Replaced NSDate time source with mach_absolute_time
  • [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
  • [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
  • v2.7

    @@ -857,6 +868,8 @@ 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
  • +
  • David Medlock, for doing the initial Lua port
  • Kenneth Miller, for his many and detailed bug reports on Win32
  • @@ -886,6 +899,9 @@ their skills. Special thanks go out to:

  • Johannes Stein, for maintaining the Pascal bindings
  • +
  • Sergey Tikhomirov, for the initial implementation of joystick support on + Mac OS X
  • +
  • Samuli Tuomola, for support, bug reports and testing
  • Frank Wille, for helping with the AmigaOS port and making GLFW diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08ce8365..6b040867 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,16 +1,4 @@ -if(CYGWIN) - - # These lines are intended to remove the --export-all-symbols - # flag added in the Modules/Platform/CYGWIN.cmake file of the - # CMake distribution. - # This is a HACK. If you have trouble _linking_ the GLFW - # _shared_ library on Cygwin, try disabling this. - set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-shared") - set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS ${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS}) - -endif(CYGWIN) - if(UNIX) if(_GLFW_HAS_XRANDR) set(GLFW_PKGLIBS "${GLFW_PKGLIBS} xrandr") @@ -27,27 +15,25 @@ include_directories(${GLFW_SOURCE_DIR}/src ${GLFW_BINARY_DIR}/src ${GLFW_INCLUDE_DIR}) -set(common_SOURCES clipboard.c enable.c error.c fullscreen.c gamma.c init.c input.c +set(common_SOURCES clipboard.c 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_clipboard.c - cocoa_enable.m cocoa_fullscreen.m - cocoa_gamma.m cocoa_init.m cocoa_joystick.m + set(libglfw_SOURCES ${common_SOURCES} cocoa_clipboard.m + cocoa_fullscreen.m cocoa_gamma.m + cocoa_init.m cocoa_input.m cocoa_joystick.m cocoa_opengl.m cocoa_time.m 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_clipboard.c - win32_enable.c win32_fullscreen.c - win32_gamma.c win32_init.c win32_joystick.c + set(libglfw_SOURCES ${common_SOURCES} win32_clipboard.c 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_clipboard.c - x11_enable.c x11_fullscreen.c - x11_gamma.c x11_init.c x11_joystick.c + set(libglfw_SOURCES ${common_SOURCES} x11_clipboard.c 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() @@ -70,13 +56,6 @@ if(WIN32) IMPORT_SUFFIX "dll.lib") endif(WIN32) -if(CYGWIN) - # Build for the regular Win32 environment (not Cygwin) - set_target_properties(libglfwStatic libglfwShared PROPERTIES - COMPILE_FLAGS "-mwin32 -mno-cygwin" - LINK_FLAGS "-mwin32 -mno-cygwin") -endif(CYGWIN) - 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) diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.m index 4f21314a..eb291082 100644 --- a/src/cocoa_gamma.m +++ b/src/cocoa_gamma.m @@ -48,13 +48,11 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; - + // For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE - // i.e. 256. I don't think anyone would want to change the gamma on - // Mac anyway... if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE) return; - + CGGetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue, &sampleCount); @@ -78,13 +76,11 @@ void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; - + // For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE - // i.e. 256. I don't think anyone would want to change the gamma on - // Mac anyway... if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE) return; - + // Convert to float & take the difference of the original gamma and // the linear function. for (i = 0; i < size; i++) @@ -93,6 +89,7 @@ void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) green[i] = ramp->green[i] / 65535.f; blue[i] = ramp->blue[i] / 65535.f; } + CGSetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue); } diff --git a/src/cocoa_init.m b/src/cocoa_init.m index c7c0d6c5..c8d5aed7 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -72,6 +72,18 @@ NSString* GLFWNameKeys[] = }; +//======================================================================== +// Change to our application bundle's resources directory, if present +//======================================================================== +static void changeToResourcesDirectory(void) +{ + char* resourcePath = [[[NSBundle mainBundle] resourcePath] UTF8String]; + + if (access(resourcePath, R_OK) == 0) + chdir(resourcePath); +} + + //======================================================================== // Try to figure out what the calling application is called //======================================================================== @@ -87,29 +99,23 @@ static NSString* findAppName(void) [name isKindOfClass:[NSString class]] && ![@"" isEqualToString:name]) { + _glfwLibrary.NS.bundled = GL_TRUE; return name; } } // If we get here, we're unbundled - if (!_glfwLibrary.NS.unbundled) - { - // Could do this only if we discover we're unbundled, but it should - // do no harm... - ProcessSerialNumber psn = { 0, kCurrentProcess }; - TransformProcessType(&psn, kProcessTransformToForegroundApplication); + 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; - } + // 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: UTF8? + // TODO: UTF-8? return [NSString stringWithUTF8String:*progname]; } @@ -202,7 +208,7 @@ int _glfwPlatformInit(void) [GLFWApplication sharedApplication]; _glfwLibrary.NS.OpenGLFramework = - CFBundleGetBundleWithIdentifier( CFSTR( "com.apple.opengl" ) ); + CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); if (_glfwLibrary.NS.OpenGLFramework == NULL) { _glfwSetError(GLFW_PLATFORM_ERROR, @@ -210,16 +216,16 @@ int _glfwPlatformInit(void) return GL_FALSE; } - NSString* resourcePath = [[NSBundle mainBundle] resourcePath]; - - if (access([resourcePath cStringUsingEncoding:NSUTF8StringEncoding], R_OK) == 0) - chdir([resourcePath cStringUsingEncoding:NSUTF8StringEncoding]); - - // Setting up menu bar must go exactly here else weirdness ensues + // Setting up the menu bar must go between sharedApplication + // above and finishLaunching below, in order to properly emulate the + // behavior of NSApplicationMain setUpMenuBar(); [NSApp finishLaunching]; + if (_glfwLibrary.NS.bundled) + changeToResourcesDirectory(); + _glfwPlatformSetTime(0.0); _glfwLibrary.NS.desktopMode = @@ -229,7 +235,11 @@ int _glfwPlatformInit(void) _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); _glfwLibrary.currentRamp = _glfwLibrary.originalRamp; - + + _glfwInitTimer(); + + _glfwInitJoysticks(); + return GL_TRUE; } @@ -240,10 +250,10 @@ int _glfwPlatformInit(void) int _glfwPlatformTerminate(void) { // TODO: Probably other cleanup - + // Restore the original gamma ramp _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); - + [NSApp setDelegate:nil]; [_glfwLibrary.NS.delegate release]; _glfwLibrary.NS.delegate = nil; @@ -251,6 +261,8 @@ int _glfwPlatformTerminate(void) [_glfwLibrary.NS.autoreleasePool release]; _glfwLibrary.NS.autoreleasePool = nil; + _glfwTerminateJoysticks(); + return GL_TRUE; } @@ -261,7 +273,7 @@ int _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = "GLFW " _GLFW_VERSION_FULL " Cocoa"; + const char* version = _GLFW_VERSION_FULL " Cocoa"; return version; } 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 d56ff679..a167692f 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -29,6 +29,440 @@ #include "internal.h" +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------ +// Joystick element information +//------------------------------------------------------------------------ + +typedef struct +{ + IOHIDElementCookie cookie; + + long value; + + long min; + long max; + + long minReport; + long maxReport; + +} _glfwJoystickElement; + + +//------------------------------------------------------------------------ +// Joystick information & state +//------------------------------------------------------------------------ + +typedef struct +{ + int present; + char product[256]; + + IOHIDDeviceInterface** interface; + + int numAxes; + int numButtons; + int numHats; + + CFMutableArrayRef axes; + CFMutableArrayRef buttons; + CFMutableArrayRef hats; + +} _glfwJoystick; + +static _glfwJoystick _glfwJoysticks[GLFW_JOYSTICK_LAST + 1]; + + +void GetElementsCFArrayHandler(const void* value, void* parameter); + + +//======================================================================== +// Adds an element to the specified joystick +//======================================================================== + +static void addJoystickElement(_glfwJoystick* joystick, CFTypeRef refElement) +{ + long elementType, usagePage, usage; + CFTypeRef refElementType, refUsagePage, refUsage; + + refElementType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementTypeKey)); + refUsagePage = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsagePageKey)); + refUsage = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementUsageKey)); + + CFMutableArrayRef elementsArray = NULL; + + CFNumberGetValue(refElementType, kCFNumberLongType, &elementType); + CFNumberGetValue(refUsagePage, kCFNumberLongType, &usagePage); + CFNumberGetValue(refUsage, kCFNumberLongType, &usage); + + if ((elementType == kIOHIDElementTypeInput_Axis) || + (elementType == kIOHIDElementTypeInput_Button) || + (elementType == kIOHIDElementTypeInput_Misc)) + { + switch (usagePage) /* only interested in kHIDPage_GenericDesktop and kHIDPage_Button */ + { + case kHIDPage_GenericDesktop: + { + switch (usage) + { + case kHIDUsage_GD_X: + case kHIDUsage_GD_Y: + case kHIDUsage_GD_Z: + case kHIDUsage_GD_Rx: + case kHIDUsage_GD_Ry: + case kHIDUsage_GD_Rz: + case kHIDUsage_GD_Slider: + case kHIDUsage_GD_Dial: + case kHIDUsage_GD_Wheel: + joystick->numAxes++; + elementsArray = joystick->axes; + break; + case kHIDUsage_GD_Hatswitch: + joystick->numHats++; + elementsArray = joystick->hats; + break; + } + + break; + } + + case kHIDPage_Button: + joystick->numButtons++; + elementsArray = joystick->buttons; + break; + default: + break; + } + + if (elementsArray) + { + long number; + CFTypeRef refType; + + _glfwJoystickElement* element = (_glfwJoystickElement*) malloc(sizeof(_glfwJoystickElement)); + + CFArrayAppendValue(elementsArray, element); + + refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementCookieKey)); + if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number)) + element->cookie = (IOHIDElementCookie) number; + + refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMinKey)); + if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number)) + element->minReport = element->min = number; + + refType = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementMaxKey)); + if (refType && CFNumberGetValue(refType, kCFNumberLongType, &number)) + element->maxReport = element->max = number; + } + } + else + { + CFTypeRef refElementTop = CFDictionaryGetValue(refElement, CFSTR(kIOHIDElementKey)); + if (refElementTop) + { + CFTypeID type = CFGetTypeID (refElementTop); + if (type == CFArrayGetTypeID()) /* if element is an array */ + { + CFRange range = {0, CFArrayGetCount (refElementTop)}; + CFArrayApplyFunction(refElementTop, range, GetElementsCFArrayHandler, joystick); + } + } + } +} + + +//======================================================================== +// Adds an element to the specified joystick +//======================================================================== + +void GetElementsCFArrayHandler(const void* value, void* parameter) +{ + if (CFGetTypeID(value) == CFDictionaryGetTypeID()) + addJoystickElement((_glfwJoystick*) parameter, (CFTypeRef) value); +} + + +//======================================================================== +// Returns the value of the specified element of the specified joystick +//======================================================================== + +static long getElementValue(_glfwJoystick* joystick, _glfwJoystickElement* element) +{ + IOReturn result = kIOReturnSuccess; + IOHIDEventStruct hidEvent; + hidEvent.value = 0; + + if (joystick && element && joystick->interface) + { + result = (*(joystick->interface))->getElementValue(joystick->interface, + element->cookie, + &hidEvent); + if (kIOReturnSuccess == result) + { + /* record min and max for auto calibration */ + if (hidEvent.value < element->minReport) + element->minReport = hidEvent.value; + if (hidEvent.value > element->maxReport) + element->maxReport = hidEvent.value; + } + } + + /* auto user scale */ + return (long) hidEvent.value; +} + + +//======================================================================== +// Removes the specified joystick +//======================================================================== + +static void removeJoystick(_glfwJoystick* joystick) +{ + int i; + + if (joystick->present) + { + joystick->present = GL_FALSE; + + for (i = 0; i < joystick->numAxes; i++) + { + _glfwJoystickElement* axes = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, i); + free(axes); + } + CFArrayRemoveAllValues(joystick->axes); + joystick->numAxes = 0; + + for (i = 0; i < joystick->numButtons; i++) + { + _glfwJoystickElement* button = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, i); + free(button); + } + CFArrayRemoveAllValues(joystick->buttons); + joystick->numButtons = 0; + + for (i = 0; i < joystick->numHats; i++) + { + _glfwJoystickElement* hat = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->hats, i); + free(hat); + } + CFArrayRemoveAllValues(joystick->hats); + joystick->hats = 0; + + (*(joystick->interface))->close(joystick->interface); + (*(joystick->interface))->Release(joystick->interface); + + joystick->interface = NULL; + } +} + + +//======================================================================== +// Callback for user-initiated joystick removal +//======================================================================== + +static void removalCallback(void* target, IOReturn result, void* refcon, void* sender) +{ + removeJoystick((_glfwJoystick*) refcon); +} + + +//======================================================================== +// Polls for joystick events and updates GFLW state +//======================================================================== + +static void pollJoystickEvents(void) +{ + int i; + CFIndex j; + + for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) + { + _glfwJoystick* joystick = &_glfwJoysticks[i]; + + if (joystick->present) + { + for (j = 0; j < joystick->numButtons; j++) + { + _glfwJoystickElement* button = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->buttons, j); + button->value = getElementValue(joystick, button); + } + + for (j = 0; j < joystick->numAxes; j++) + { + _glfwJoystickElement* axes = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick->axes, j); + axes->value = getElementValue(joystick, axes); + } + } + } +} + + +////////////////////////////////////////////////////////////////////////// +////// GLFW internal API ////// +////////////////////////////////////////////////////////////////////////// + +//======================================================================== +// Initialize joystick interface +//======================================================================== + +void _glfwInitJoysticks(void) +{ + int deviceCounter = 0; + IOReturn result = kIOReturnSuccess; + mach_port_t masterPort = 0; + io_iterator_t objectIterator = 0; + CFMutableDictionaryRef hidMatchDictionary = NULL; + io_object_t ioHIDDeviceObject = 0; + + result = IOMasterPort(bootstrap_port, &masterPort); + hidMatchDictionary = IOServiceMatching(kIOHIDDeviceKey); + if (kIOReturnSuccess != result || !hidMatchDictionary) + return; + + result = IOServiceGetMatchingServices(masterPort, + hidMatchDictionary, + &objectIterator); + if (result != kIOReturnSuccess) + return; + + if (!objectIterator) /* there are no joysticks */ + return; + + while ((ioHIDDeviceObject = IOIteratorNext(objectIterator))) + { + CFMutableDictionaryRef hidProperties = 0; + kern_return_t result; + CFTypeRef refCF = 0; + + IOCFPlugInInterface** ppPlugInInterface = NULL; + HRESULT plugInResult = S_OK; + SInt32 score = 0; + + long usagePage, usage; + + result = IORegistryEntryCreateCFProperties(ioHIDDeviceObject, + &hidProperties, + kCFAllocatorDefault, + kNilOptions); + + if (result != kIOReturnSuccess) + continue; + + /* Check device type */ + refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsagePageKey)); + if (refCF) + CFNumberGetValue(refCF, kCFNumberLongType, &usagePage); + + refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDPrimaryUsageKey)); + if (refCF) + CFNumberGetValue(refCF, kCFNumberLongType, &usage); + + if ((usagePage != kHIDPage_GenericDesktop) || + (usage != kHIDUsage_GD_Joystick && + usage != kHIDUsage_GD_GamePad && + usage != kHIDUsage_GD_MultiAxisController)) + { + /* We don't interested in this device */ + continue; + } + + _glfwJoystick* joystick = &_glfwJoysticks[deviceCounter]; + + joystick->present = GL_TRUE; + + result = IOCreatePlugInInterfaceForService(ioHIDDeviceObject, + kIOHIDDeviceUserClientTypeID, + kIOCFPlugInInterfaceID, + &ppPlugInInterface, + &score); + + if (kIOReturnSuccess != result) + return; + + plugInResult = (*ppPlugInInterface)->QueryInterface( + ppPlugInInterface, + CFUUIDGetUUIDBytes(kIOHIDDeviceInterfaceID), + (void *) &(joystick->interface)); + + if (plugInResult != S_OK) + return; + + (*ppPlugInInterface)->Release(ppPlugInInterface); + + (*(joystick->interface))->open(joystick->interface, 0); + (*(joystick->interface))->setRemovalCallback(joystick->interface, + removalCallback, + joystick, + joystick); + + /* Get product string */ + refCF = CFDictionaryGetValue(hidProperties, CFSTR(kIOHIDProductKey)); + if (refCF) + { + CFStringGetCString(refCF, + (char*) &(joystick->product), + 256, + CFStringGetSystemEncoding()); + } + + joystick->numAxes = 0; + joystick->numButtons = 0; + joystick->numHats = 0; + joystick->axes = CFArrayCreateMutable(NULL, 0, NULL); + joystick->buttons = CFArrayCreateMutable(NULL, 0, NULL); + joystick->hats = CFArrayCreateMutable(NULL, 0, NULL); + + CFTypeRef refTopElement = CFDictionaryGetValue(hidProperties, + CFSTR(kIOHIDElementKey)); + CFTypeID type = CFGetTypeID(refTopElement); + if (type == CFArrayGetTypeID()) + { + CFRange range = { 0, CFArrayGetCount(refTopElement) }; + CFArrayApplyFunction(refTopElement, + range, + GetElementsCFArrayHandler, + (void*) joystick); + } + + deviceCounter++; + } +} + + +//======================================================================== +// Close all opened joystick handles +//======================================================================== + +void _glfwTerminateJoysticks(void) +{ + int i; + + for (i = 0; i < GLFW_JOYSTICK_LAST + 1; i++) + { + _glfwJoystick* joystick = &_glfwJoysticks[i]; + removeJoystick(joystick); + } +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// @@ -38,29 +472,111 @@ // Determine joystick capabilities //======================================================================== -int _glfwPlatformGetJoystickParam( int joy, int param ) +int _glfwPlatformGetJoystickParam(int joy, int param) { - // TODO: Implement this. - return 0; + if (!_glfwJoysticks[joy].present) + { + // TODO: Figure out if this is an error + return GL_FALSE; + } + + switch (param) + { + case GLFW_PRESENT: + return GL_TRUE; + + case GLFW_AXES: + return (int) CFArrayGetCount(_glfwJoysticks[joy].axes); + + case GLFW_BUTTONS: + return (int) CFArrayGetCount(_glfwJoysticks[joy].buttons); + + default: + break; + } + + return GL_FALSE; } + //======================================================================== // Get joystick axis positions //======================================================================== -int _glfwPlatformGetJoystickPos( int joy, float *pos, int numaxes ) +int _glfwPlatformGetJoystickPos(int joy, float* pos, int numaxes) { - // TODO: Implement this. - return 0; + int i; + + if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) + return 0; + + _glfwJoystick joystick = _glfwJoysticks[joy]; + + if (!joystick.present) + { + // TODO: Figure out if this is an error + return 0; + } + + numaxes = numaxes < joystick.numAxes ? numaxes : joystick.numAxes; + + // Update joystick state + pollJoystickEvents(); + + for (i = 0; i < numaxes; i++) + { + _glfwJoystickElement* axes = + (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.axes, i); + + long readScale = axes->maxReport - axes->minReport; + + if (readScale == 0) + pos[i] = axes->value; + else + pos[i] = (2.0f * (axes->value - axes->minReport) / readScale) - 1.0f; + + //printf("%ld, %ld, %ld\n", axes->value, axes->minReport, axes->maxReport); + + if (i & 1) + pos[i] = -pos[i]; + } + + return numaxes; } + //======================================================================== // Get joystick button states //======================================================================== -int _glfwPlatformGetJoystickButtons( int joy, unsigned char *buttons, int numbuttons ) +int _glfwPlatformGetJoystickButtons(int joy, unsigned char* buttons, + int numbuttons) { - // TODO: Implement this. - return 0; + int i; + + if (joy < GLFW_JOYSTICK_1 || joy > GLFW_JOYSTICK_LAST) + return 0; + + _glfwJoystick joystick = _glfwJoysticks[joy]; + + if (!joystick.present) + { + // TODO: Figure out if this is an error + return 0; + } + + numbuttons = numbuttons < joystick.numButtons ? numbuttons : joystick.numButtons; + + // Update joystick state + pollJoystickEvents(); + + for (i = 0; i < numbuttons; i++) + { + _glfwJoystickElement* button = (_glfwJoystickElement*) CFArrayGetValueAtIndex(joystick.buttons, i); + buttons[i] = button->value ? GLFW_PRESS : GLFW_RELEASE; + } + + return numbuttons; } + diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 17e92a8f..582b338d 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -85,16 +85,29 @@ 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; + GLboolean bundled; id desktopMode; id delegate; id autoreleasePool; } _GLFWlibraryNS; +//======================================================================== +// Prototypes for platform specific internal functions +//======================================================================== + +// Time +void _glfwInitTimer(void); + +// Joystick input +void _glfwInitJoysticks(void); +void _glfwTerminateJoysticks(void); + + #endif // _platform_h_ diff --git a/src/cocoa_time.m b/src/cocoa_time.m index d7e7d2b8..4facbffb 100644 --- a/src/cocoa_time.m +++ b/src/cocoa_time.m @@ -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,8 +70,8 @@ double _glfwPlatformGetTime(void) { - return [NSDate timeIntervalSinceReferenceDate] - - _glfwLibrary.NS.timer.t0; + return (double) (getRawTime() - _glfwLibrary.NS.timer.base) * + _glfwLibrary.NS.timer.resolution; } //======================================================================== @@ -50,7 +80,7 @@ double _glfwPlatformGetTime(void) 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 4f662faf..b5dfb436 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -147,7 +147,7 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = /* 07 */ GLFW_KEY_X, /* 08 */ GLFW_KEY_C, /* 09 */ GLFW_KEY_V, - /* 0a */ -1, + /* 0a */ GLFW_KEY_GRAVE_ACCENT, /* 0b */ GLFW_KEY_B, /* 0c */ GLFW_KEY_Q, /* 0d */ GLFW_KEY_W, @@ -187,7 +187,7 @@ static const unsigned int MAC_TO_GLFW_KEYCODE_MAPPING[128] = /* 2f */ GLFW_KEY_PERIOD, /* 30 */ GLFW_KEY_TAB, /* 31 */ GLFW_KEY_SPACE, - /* 32 */ GLFW_KEY_GRAVE_ACCENT, + /* 32 */ GLFW_KEY_WORLD_1, /* 33 */ GLFW_KEY_BACKSPACE, /* 34 */ -1, /* 35 */ GLFW_KEY_ESCAPE, @@ -393,7 +393,7 @@ static int convertMacKeyCode(unsigned int macKeyCode) if ([event modifierFlags] & NSCommandKeyMask) { - if (!window->sysKeysDisabled) + if (window->systemKeys) [super keyDown:event]; } else @@ -443,20 +443,66 @@ static int convertMacKeyCode(unsigned int macKeyCode) @end - -////////////////////////////////////////////////////////////////////////// -////// GLFW platform API ////// -////////////////////////////////////////////////////////////////////////// - //======================================================================== -// Here is where the window is created, and the OpenGL rendering context is -// created +// Create the Cocoa window //======================================================================== -int _glfwPlatformOpenWindow(_GLFWwindow* window, - const _GLFWwndconfig *wndconfig, - const _GLFWfbconfig *fbconfig) +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 || @@ -499,104 +545,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, return GL_FALSE; } - // 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) - { - _glfwLibrary.NS.delegate = [[GLFWApplicationDelegate alloc] init]; - if (_glfwLibrary.NS.delegate == nil) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Cocoa/NSOpenGL: Failed to create application " - "delegate"); - return GL_FALSE; - } - - [NSApp setDelegate:_glfwLibrary.NS.delegate]; - } - - window->NS.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window]; - if (window->NS.delegate == nil) - { - _glfwSetError(GLFW_PLATFORM_ERROR, - "Cocoa/NSOpenGL: Failed to create window delegate"); - return GL_FALSE; - } - - // 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; - - // 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->windowNoResize) - 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_ATTR(x) { attributes[attributeCount++] = x; } #define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } // Arbitrary array size here @@ -638,7 +587,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, ADD_ATTR2(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers); if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo ); + ADD_ATTR(NSOpenGLPFAStereo); if (fbconfig->samples > 0) { @@ -656,7 +605,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, if (window->NSGL.pixelFormat == nil) { _glfwSetError(GLFW_PLATFORM_ERROR, - "Cocoa/NSOpenGL: Failed to create pixel format"); + "Cocoa/NSOpenGL: Failed to create OpenGL pixel format"); return GL_FALSE; } @@ -675,12 +624,93 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, 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) +{ + // 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) + { + _glfwLibrary.NS.delegate = [[GLFWApplicationDelegate alloc] init]; + if (_glfwLibrary.NS.delegate == nil) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Cocoa/NSOpenGL: Failed to create application " + "delegate"); + return GL_FALSE; + } + + [NSApp setDelegate:_glfwLibrary.NS.delegate]; + } + + window->NS.delegate = [[GLFWWindowDelegate alloc] initWithGlfwWindow:window]; + if (window->NS.delegate == nil) + { + _glfwSetError(GLFW_PLATFORM_ERROR, + "Cocoa/NSOpenGL: Failed to create window delegate"); + return GL_FALSE; + } + + // 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; + + // 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]; + } + + if (!createWindow(window, wndconfig)) + return GL_FALSE; + + 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 + CGCaptureAllDisplays(); + CGDisplaySwitchToMode(CGMainDisplayID(), fullscreenMode); + [[window->NS.window contentView] enterFullScreenMode:[NSScreen mainScreen] withOptions:nil]; } @@ -691,7 +721,7 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, window->cursorPosX = point.x; window->cursorPosY = point.y; - window->windowNoResize = wndconfig->windowNoResize; + window->resizable = wndconfig->resizable; return GL_TRUE; } @@ -737,8 +767,7 @@ void _glfwPlatformCloseWindow(_GLFWwindow* window) void _glfwPlatformSetWindowTitle(_GLFWwindow* window, const char *title) { - [window->NS.window setTitle:[NSString stringWithCString:title - encoding:NSISOLatin1StringEncoding]]; + [window->NS.window setTitle:[NSString stringWithUTF8String:title]]; } //======================================================================== 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/error.c b/src/error.c index 574f84cd..2b46a72c 100644 --- a/src/error.c +++ b/src/error.c @@ -117,6 +117,7 @@ GLFWAPI const char* glfwErrorString(int error) //======================================================================== // Sets the callback function for GLFW errors +// This function may be called without GLFW having been initialized //======================================================================== GLFWAPI void glfwSetErrorCallback(GLFWerrorfun cbfun) 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 56ab0e5d..ec894a27 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; @@ -55,12 +171,12 @@ void _glfwInputKey(_GLFWwindow* window, int key, int action) 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); } @@ -138,9 +254,11 @@ void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y) } if (_glfwLibrary.mousePosCallback) + { _glfwLibrary.mousePosCallback(window, window->cursorPosX, window->cursorPosY); + } } @@ -148,6 +266,77 @@ void _glfwInputCursorMotion(_GLFWwindow* window, int x, int y) ////// 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 //======================================================================== @@ -162,10 +351,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; @@ -196,7 +383,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, @@ -229,7 +415,6 @@ GLFWAPI void glfwGetMousePos(GLFWwindow handle, int* xpos, int* ypos) return; } - // Return mouse position if (xpos != NULL) *xpos = window->cursorPosX; @@ -298,51 +483,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 //======================================================================== @@ -403,7 +543,6 @@ GLFWAPI void glfwSetMousePosCallback(GLFWmouseposfun cbfun) return; } - // Set callback function _glfwLibrary.mousePosCallback = cbfun; // Call the callback function to let the application know the current @@ -430,7 +569,6 @@ GLFWAPI void glfwSetScrollCallback(GLFWscrollfun cbfun) return; } - // Set callback function _glfwLibrary.scrollCallback = cbfun; } diff --git a/src/internal.h b/src/internal.h index 477032ac..83ab78ba 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; @@ -103,7 +103,7 @@ struct _GLFWhints int accumAlphaBits; int auxBuffers; GLboolean stereo; - GLboolean windowNoResize; + GLboolean resizable; int samples; int glMajor; int glMinor; @@ -125,7 +125,7 @@ struct _GLFWwndconfig int mode; const char* title; int refreshRate; - GLboolean windowNoResize; + GLboolean resizable; int glMajor; int glMinor; GLboolean glForward; @@ -175,7 +175,7 @@ struct _GLFWwindow int width, height; int positionX, positionY; int mode; // GLFW_WINDOW or GLFW_FULLSCREEN - GLboolean windowNoResize; // resize- and maximize gadgets disabled flag + GLboolean resizable; // GL_TRUE if user may resize this window int refreshRate; // monitor refresh rate void* userPointer; @@ -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; @@ -241,9 +241,6 @@ struct _GLFWlibrary GLFWkeyfun keyCallback; GLFWcharfun charCallback; - GLFWthreadmodel threading; - GLFWallocator allocator; - GLFWgammaramp currentRamp; GLFWgammaramp originalRamp; int originalRampSize; @@ -276,7 +273,7 @@ int _glfwPlatformInit(void); int _glfwPlatformTerminate(void); const char* _glfwPlatformGetVersionString(void); -// Enable/Disable +// Input void _glfwPlatformEnableSystemKeys(_GLFWwindow* window); void _glfwPlatformDisableSystemKeys(_GLFWwindow* window); @@ -330,10 +327,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); @@ -343,14 +336,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 a69cccd7..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 ////// ////////////////////////////////////////////////////////////////////////// @@ -205,7 +259,7 @@ int _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = "GLFW " _GLFW_VERSION_FULL + const char* version = _GLFW_VERSION_FULL #if defined(__MINGW32__) " MinGW" #elif defined(__CYGWIN__) 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 8aa3561b..82b8c9ca 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -40,6 +40,19 @@ #define WIN32_LEAN_AND_MEAN #endif +// This is a workaround for the fact that glfw3.h needs to export APIENTRY (to +// correctly declare a GL_ARB_debug_output callback, for example) but windows.h +// 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 @@ -56,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 //------------------------------------------------------------------------ @@ -79,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 @@ -157,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); @@ -166,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 @@ -304,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; @@ -318,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 d81da139..24788a33 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; @@ -1309,7 +1310,7 @@ static int createWindow(_GLFWwindow* window, { dwStyle |= WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; - if (!wndconfig->windowNoResize) + if (wndconfig->resizable) { dwStyle |= (WS_MAXIMIZEBOX | WS_SIZEBOX); dwExStyle |= WS_EX_WINDOWEDGE; @@ -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) { @@ -1568,7 +1579,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 68893f09..f8939e37 100644 --- a/src/window.c +++ b/src/window.c @@ -100,6 +100,9 @@ void _glfwSetDefaultWindowHints(void) // The default minimum OpenGL version is 1.0 _glfwLibrary.hints.glMajor = 1; _glfwLibrary.hints.glMinor = 0; + + // The default is to allow window resizing + _glfwLibrary.hints.resizable = GL_TRUE; } @@ -247,7 +250,7 @@ GLFWAPI GLFWwindow glfwOpenWindow(int width, int height, wndconfig.mode = mode; wndconfig.title = title; wndconfig.refreshRate = Max(_glfwLibrary.hints.refreshRate, 0); - wndconfig.windowNoResize = _glfwLibrary.hints.windowNoResize ? GL_TRUE : GL_FALSE; + wndconfig.resizable = _glfwLibrary.hints.resizable ? GL_TRUE : GL_FALSE; wndconfig.glMajor = _glfwLibrary.hints.glMajor; wndconfig.glMinor = _glfwLibrary.hints.glMinor; wndconfig.glForward = _glfwLibrary.hints.glForward ? GL_TRUE : GL_FALSE; @@ -288,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, @@ -306,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)) @@ -327,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 @@ -419,8 +423,8 @@ GLFWAPI void glfwOpenWindowHint(int target, int hint) case GLFW_STEREO: _glfwLibrary.hints.stereo = hint; break; - case GLFW_WINDOW_NO_RESIZE: - _glfwLibrary.hints.windowNoResize = hint; + case GLFW_WINDOW_RESIZABLE: + _glfwLibrary.hints.resizable = hint; break; case GLFW_FSAA_SAMPLES: _glfwLibrary.hints.samples = hint; @@ -488,7 +492,7 @@ GLFWAPI void glfwCloseWindow(GLFWwindow handle) *prev = window->next; } - _glfwFree(window); + free(window); } @@ -651,7 +655,6 @@ GLFWAPI void glfwRestoreWindow(GLFWwindow handle) if (!window->iconified) return; - // Restore iconified window _glfwPlatformRestoreWindow(window); if (window->mode == GLFW_FULLSCREEN) @@ -707,8 +710,8 @@ GLFWAPI int glfwGetWindowParam(GLFWwindow handle, int param) return window->stereo; case GLFW_REFRESH_RATE: return window->refreshRate; - case GLFW_WINDOW_NO_RESIZE: - return window->windowNoResize; + case GLFW_WINDOW_RESIZABLE: + return window->resizable; case GLFW_FSAA_SAMPLES: return window->samples; case GLFW_OPENGL_VERSION_MAJOR: diff --git a/src/x11_fullscreen.c b/src/x11_fullscreen.c index bb0a3d53..e71c2a2b 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 @@ -387,7 +387,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 +407,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 +436,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); @@ -459,8 +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 21b42240..0c529553 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -366,7 +366,7 @@ static void updateKeyCodeLUT(void) static GLboolean initDisplay(void) { - _glfwLibrary.X11.display = XOpenDisplay(0); + _glfwLibrary.X11.display = XOpenDisplay(NULL); if (!_glfwLibrary.X11.display) { _glfwSetError(GLFW_OPENGL_UNAVAILABLE, "X11/GLX: Failed to open X display"); @@ -639,7 +639,7 @@ int _glfwPlatformTerminate(void) const char* _glfwPlatformGetVersionString(void) { - const char* version = "GLFW " _GLFW_VERSION_FULL + const char* version = _GLFW_VERSION_FULL #if defined(_GLFW_HAS_XRANDR) " XRandR" #endif @@ -649,6 +649,9 @@ const char* _glfwPlatformGetVersionString(void) #if !defined(_GLFW_HAS_XRANDR) && !defined(_GLFW_HAS_XF86VIDMODE) " no-mode-switching-support" #endif +#if defined(_GLFW_HAS_XKB) + " Xkb" +#endif #if defined(_GLFW_HAS_GLXGETPROCADDRESS) " glXGetProcAddress" #elif defined(_GLFW_HAS_GLXGETPROCADDRESSARB) 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 ca4d1fd5..c6be6db3 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 @@ -152,6 +145,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_window.c b/src/x11_window.c index 8d19aff8..db630b10 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, @@ -794,7 +800,7 @@ static GLboolean createWindow(_GLFWwindow* window, hints->flags = 0; - if (wndconfig->windowNoResize) + if (!wndconfig->resizable) { hints->flags |= (PMinSize | PMaxSize); hints->min_width = hints->max_width = window->width; @@ -1426,8 +1432,8 @@ int _glfwPlatformOpenWindow(_GLFWwindow* window, { _GLFWfbconfig closest; - window->refreshRate = wndconfig->refreshRate; - window->windowNoResize = wndconfig->windowNoResize; + window->refreshRate = wndconfig->refreshRate; + window->resizable = wndconfig->resizable; initGLXExtensions(window); @@ -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)); + } } @@ -1568,7 +1604,7 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) &width, &height, &rate); } - if (window->windowNoResize) + if (!window->resizable) { // Update window size restrictions to match new window size @@ -1735,7 +1771,7 @@ void _glfwPlatformRefreshWindowParams(void) &dotclock, &modeline); pixels_per_second = 1000.0f * (float) dotclock; pixels_per_frame = (float) modeline.htotal * modeline.vtotal; - window->refreshRate = (int)(pixels_per_second/pixels_per_frame+0.5); + window->refreshRate = (int) (pixels_per_second / pixels_per_frame + 0.5); #endif /*_GLFW_HAS_XF86VIDMODE*/ } else @@ -1771,6 +1807,11 @@ void _glfwPlatformPollEvents(void) window->width / 2, window->height / 2); window->X11.cursorCentered = GL_TRUE; + + // NOTE: This is a temporary fix. It works as long as you use + // offsets accumulated over the course of a frame, instead of + // performing the necessary actions per callback call. + XFlush( _glfwLibrary.X11.display ); } } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 95d5cd06..fe1df13b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,39 +1,66 @@ -link_libraries(libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) +set(STATIC_DEPS libglfwStatic ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) +set(SHARED_DEPS libglfwShared ${GLFW_LIBRARIES} ${OPENGL_glu_LIBRARY}) include_directories(${GLFW_SOURCE_DIR}/include ${GLFW_SOURCE_DIR}/support ${OPENGL_INCLUDE_DIR}) - add_executable(clipboard clipboard.c) +target_link_libraries(clipboard ${STATIC_DEPS}) + add_executable(defaults defaults.c) +target_link_libraries(defaults ${STATIC_DEPS}) + +add_executable(dynamic dynamic.c) +target_link_libraries(dynamic ${SHARED_DEPS}) + add_executable(events events.c) +target_link_libraries(events ${STATIC_DEPS}) + add_executable(fsaa fsaa.c getopt.c) +target_link_libraries(fsaa ${STATIC_DEPS}) + add_executable(fsfocus fsfocus.c) +target_link_libraries(fsfocus ${STATIC_DEPS}) + add_executable(gamma gamma.c getopt.c) +target_link_libraries(gamma ${STATIC_DEPS}) + add_executable(glfwinfo glfwinfo.c getopt.c) +target_link_libraries(glfwinfo ${STATIC_DEPS}) + add_executable(iconify iconify.c getopt.c) +target_link_libraries(iconify ${STATIC_DEPS}) + add_executable(joysticks joysticks.c) +target_link_libraries(joysticks ${STATIC_DEPS}) + add_executable(listmodes listmodes.c) +target_link_libraries(listmodes ${STATIC_DEPS}) + add_executable(peter peter.c) +target_link_libraries(peter ${STATIC_DEPS}) + add_executable(reopen reopen.c) +target_link_libraries(reopen ${STATIC_DEPS}) -if(APPLE) - # Set fancy names for bundles - add_executable(Accuracy MACOSX_BUNDLE accuracy.c) - add_executable(Sharing MACOSX_BUNDLE sharing.c) - add_executable(Tearing MACOSX_BUNDLE tearing.c) - add_executable(Windows MACOSX_BUNDLE windows.c) -else() - # Set boring names for executables - add_executable(accuracy WIN32 accuracy.c) - add_executable(sharing WIN32 sharing.c) - add_executable(tearing WIN32 tearing.c) - add_executable(windows WIN32 windows.c) -endif(APPLE) +add_executable(accuracy WIN32 MACOSX_BUNDLE accuracy.c) +target_link_libraries(accuracy ${STATIC_DEPS}) -set(WINDOWS_BINARIES accuracy sharing tearing windows) -set(CONSOLE_BINARIES clipboard defaults events fsaa fsfocus gamma glfwinfo iconify +add_executable(sharing WIN32 MACOSX_BUNDLE sharing.c) +target_link_libraries(sharing ${STATIC_DEPS}) + +add_executable(tearing WIN32 MACOSX_BUNDLE tearing.c) +target_link_libraries(tearing ${STATIC_DEPS}) + +add_executable(title WIN32 MACOSX_BUNDLE title.c) +target_link_libraries(title ${STATIC_DEPS}) + +add_executable(windows WIN32 MACOSX_BUNDLE windows.c) +target_link_libraries(windows ${STATIC_DEPS}) + +set(WINDOWS_BINARIES accuracy sharing tearing title windows) +set(CONSOLE_BINARIES defaults events fsaa fsfocus gamma glfwinfo iconify joysticks listmodes peter reopen) if(MSVC) @@ -42,13 +69,3 @@ if(MSVC) LINK_FLAGS "/ENTRY:mainCRTStartup") endif(MSVC) -if(CYGWIN) - # Set cross-compile and subsystem compile and link flags - set_target_properties(${WINDOWS_BINARIES} ${CONSOLE_BINARIES} PROPERTIES - COMPILE_FLAGS "-mno-cygwin") - set_target_properties(${WINDOWS_BINARIES} PROPERTIES - LINK_FLAGS "-mno-cygwin -mwindows") - set_target_properties(${CONSOLE_BINARIES} PROPERTIES - LINK_FLAGS "-mno-cygwin -mconsole") -endif(CYGWIN) - diff --git a/tests/dynamic.c b/tests/dynamic.c new file mode 100644 index 00000000..8bc5568b --- /dev/null +++ b/tests/dynamic.c @@ -0,0 +1,91 @@ +//======================================================================== +// Dynamic linking 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 came about as the result of bug #3060461 +// +//======================================================================== + +#define GLFW_DLL +#include + +#include +#include + +static void window_size_callback(GLFWwindow window, int width, int height) +{ + glViewport(0, 0, width, height); +} + +int main(void) +{ + GLFWwindow window; + int major, minor, rev; + glfwGetVersion(&major, &minor, &rev); + + printf("GLFW header version: %i.%i.%i\n", + GLFW_VERSION_MAJOR, + GLFW_VERSION_MINOR, + GLFW_VERSION_REVISION); + printf("GLFW library version: %i.%i.%i\n", major, minor, rev); + printf("GLFW library version string: %s\n", glfwGetVersionString()); + + if (major != GLFW_VERSION_MAJOR || + minor != GLFW_VERSION_MINOR || + rev != GLFW_VERSION_REVISION) + { + fprintf(stderr, "GLFW library version mismatch\n"); + exit(EXIT_FAILURE); + } + + if (!glfwInit()) + { + fprintf(stderr, "Failed to initialize GLFW\n"); + exit(EXIT_FAILURE); + } + + window = glfwOpenWindow(0, 0, GLFW_WINDOWED, "Dynamic Linking Test", NULL); + if (!window) + { + glfwTerminate(); + + fprintf(stderr, "Failed to open GLFW window\n"); + exit(EXIT_FAILURE); + } + + glfwSetWindowSizeCallback(window_size_callback); + glfwSwapInterval(1); + + while (glfwIsWindow(window)) + { + glClear(GL_COLOR_BUFFER_BIT); + + glfwSwapBuffers(); + glfwPollEvents(); + } + + glfwTerminate(); + exit(EXIT_SUCCESS); +} + diff --git a/tests/events.c b/tests/events.c index ac758100..5603258b 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) @@ -298,10 +299,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; @@ -310,14 +308,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..369e6a96 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"); } 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/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); +} +