mirror of
https://github.com/glfw/glfw.git
synced 2025-10-03 13:20:58 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
588be5bb53
@ -26,6 +26,7 @@ if (APPLE)
|
||||
option(GLFW_BUILD_UNIVERSAL "Build GLFW as a Universal Binary" OFF)
|
||||
option(GLFW_USE_CHDIR "Make glfwInit chdir to Contents/Resources" ON)
|
||||
option(GLFW_USE_MENUBAR "Populate the menu bar on first window creation" ON)
|
||||
option(GLFW_USE_RETINA "Use the full resolution of Retina displays" ON)
|
||||
else()
|
||||
option(GLFW_USE_EGL "Use EGL for context creation" OFF)
|
||||
endif()
|
||||
@ -153,6 +154,9 @@ endif()
|
||||
# Use Win32 for window creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_WIN32)
|
||||
|
||||
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lgdi32 -lwinmm")
|
||||
|
||||
# The DLL links against winmm; the static library loads it
|
||||
# That way, both code paths receive testing
|
||||
if (BUILD_SHARED_LIBS)
|
||||
@ -171,16 +175,21 @@ if (_GLFW_WIN32)
|
||||
# the inclusion of stddef.h (by glfw3.h), which is itself included before
|
||||
# win32_platform.h. We define them here until a saner solution can be found
|
||||
# NOTE: MinGW-w64 and Visual C++ do /not/ need this hack.
|
||||
add_definitions(-DUNICODE)
|
||||
add_definitions(-DWINVER=0x0501)
|
||||
if (CMAKE_COMPILER_IS_GNUC)
|
||||
add_definitions(-DUNICODE -DWINVER=0x0501)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Use WGL for context creation
|
||||
#--------------------------------------------------------------------
|
||||
if (_GLFW_WGL)
|
||||
|
||||
set(GLFW_PKG_LIBS "${GLFW_PKG_LIBS} -lopengl32")
|
||||
|
||||
list(APPEND glfw_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
|
||||
list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
|
||||
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
@ -307,9 +316,7 @@ if (_GLFW_EGL)
|
||||
list(APPEND glfw_INCLUDE_DIRS ${EGL_INCLUDE_DIR})
|
||||
list(APPEND glfw_LIBRARIES ${EGL_LIBRARY})
|
||||
|
||||
if (UNIX)
|
||||
set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} egl")
|
||||
endif()
|
||||
|
||||
if (_GLFW_USE_OPENGL)
|
||||
list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY})
|
||||
@ -340,6 +347,10 @@ if (_GLFW_COCOA AND _GLFW_NSGL)
|
||||
set(_GLFW_USE_CHDIR 1)
|
||||
endif()
|
||||
|
||||
if (GLFW_USE_RETINA)
|
||||
set(_GLFW_USE_RETINA 1)
|
||||
endif()
|
||||
|
||||
if (GLFW_BUILD_UNIVERSAL)
|
||||
message(STATUS "Building GLFW as Universal Binaries")
|
||||
set(CMAKE_OSX_ARCHITECTURES i386;x86_64)
|
||||
@ -392,10 +403,8 @@ configure_file(${GLFW_SOURCE_DIR}/src/glfwConfig.cmake.in
|
||||
configure_file(${GLFW_SOURCE_DIR}/src/glfwConfigVersion.cmake.in
|
||||
${GLFW_BINARY_DIR}/src/glfwConfigVersion.cmake @ONLY)
|
||||
|
||||
if (UNIX)
|
||||
configure_file(${GLFW_SOURCE_DIR}/src/glfw3.pc.in
|
||||
${GLFW_BINARY_DIR}/src/glfw3.pc @ONLY)
|
||||
endif()
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
# Add subdirectories
|
||||
@ -426,11 +435,9 @@ if (GLFW_INSTALL)
|
||||
${GLFW_BINARY_DIR}/src/glfwConfigVersion.cmake
|
||||
DESTINATION lib${LIB_SUFFIX}/cmake/glfw)
|
||||
|
||||
if (UNIX)
|
||||
install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw)
|
||||
install(FILES ${GLFW_BINARY_DIR}/src/glfw3.pc
|
||||
DESTINATION lib${LIB_SUFFIX}/pkgconfig)
|
||||
endif()
|
||||
|
||||
# Only generate this target if no higher-level project already has
|
||||
if (NOT TARGET uninstall)
|
||||
|
17
README.md
17
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
## Introduction
|
||||
|
||||
GLFW is a free, Open Source, portable library for OpenGL and OpenGL ES
|
||||
GLFW is a free, Open Source, multi-platform library for OpenGL and OpenGL ES
|
||||
application development. It provides a simple, platform-independent API for
|
||||
creating windows and contexts, reading input, handling events, etc.
|
||||
|
||||
@ -38,7 +38,7 @@ The following dependencies are needed by GLFW:
|
||||
|
||||
The following dependencies are needed by the examples and test programs:
|
||||
|
||||
- [Free Getopt](http://freegetopt.sourceforge.net/) for getopt
|
||||
- [getopt\_port](https://github.com/kimgr/getopt_port/) for getopt
|
||||
- [TinyCThread](https://gitorious.org/tinythread/tinycthread/) for threading
|
||||
- An OpenGL loader generated by [glad](https://github.com/Dav1dde/glad)
|
||||
|
||||
@ -46,8 +46,21 @@ The following dependencies are needed by the examples and test programs:
|
||||
## Changelog
|
||||
|
||||
- Added native monitor handle access to native API
|
||||
- Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files
|
||||
- [Cocoa] Added `_GLFW_USE_RETINA` to control whether windows will use the full
|
||||
resolution on Retina displays
|
||||
- [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen
|
||||
recorders to fail
|
||||
- [Cocoa] Bugfix: Some Core Foundation objects were leaked during joystick
|
||||
enumeration
|
||||
- [Win32] Enabled generation of pkg-config file for MinGW
|
||||
- [Win32] Bugfix: Failure to load winmm or its functions was not reported to
|
||||
the error callback
|
||||
- [X11] Bugfix: The case of finding no usable CRTCs was not detected
|
||||
- [X11] Bugfix: Detection of broken Nvidia RandR gamma support did not verify
|
||||
that at least one CRTC was present
|
||||
- [X11] Bugfix: A stale `_NET_SUPPORTING_WM_CHECK` root window property would
|
||||
cause an uncaught `BadWindow` error
|
||||
|
||||
|
||||
## Contact
|
||||
|
459
deps/getopt.c
vendored
459
deps/getopt.c
vendored
@ -1,267 +1,230 @@
|
||||
/*****************************************************************************
|
||||
* getopt.c - competent and free getopt library.
|
||||
* $Header: /cvsroot/freegetopt/freegetopt/getopt.c,v 1.2 2003/10/26 03:10:20 vindaci Exp $
|
||||
*
|
||||
* Copyright (c)2002-2003 Mark K. Kim
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the original author of this software nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "getopt.h"
|
||||
|
||||
/* 2013-01-06 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
*
|
||||
* Only define _CRT_SECURE_NO_WARNINGS if not already defined.
|
||||
*/
|
||||
/* 2012-08-12 Lambert Clara <lambert.clara@yahoo.fr>
|
||||
*
|
||||
* Constify third argument of getopt.
|
||||
*/
|
||||
/* 2011-07-27 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
*
|
||||
* Added _CRT_SECURE_NO_WARNINGS macro.
|
||||
*/
|
||||
/* 2009-10-12 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
*
|
||||
* Removed unused global static variable 'ID'.
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const int no_argument = 0;
|
||||
const int required_argument = 1;
|
||||
const int optional_argument = 2;
|
||||
|
||||
char* optarg;
|
||||
int optopt;
|
||||
/* The variable optind [...] shall be initialized to 1 by the system. */
|
||||
int optind = 1;
|
||||
int opterr;
|
||||
|
||||
static char* optcursor = NULL;
|
||||
|
||||
/* Implemented based on [1] and [2] for optional arguments.
|
||||
optopt is handled FreeBSD-style, per [3].
|
||||
Other GNU and FreeBSD extensions are purely accidental.
|
||||
|
||||
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
|
||||
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
|
||||
*/
|
||||
int getopt(int argc, char* const argv[], const char* optstring) {
|
||||
int optchar = -1;
|
||||
const char* optdecl = NULL;
|
||||
|
||||
char* optarg = NULL;
|
||||
int optind = 0;
|
||||
int opterr = 1;
|
||||
int optopt = '?';
|
||||
|
||||
|
||||
static char** prev_argv = NULL; /* Keep a copy of argv and argc to */
|
||||
static int prev_argc = 0; /* tell if getopt params change */
|
||||
static int argv_index = 0; /* Option we're checking */
|
||||
static int argv_index2 = 0; /* Option argument we're checking */
|
||||
static int opt_offset = 0; /* Index into compounded "-option" */
|
||||
static int dashdash = 0; /* True if "--" option reached */
|
||||
static int nonopt = 0; /* How many nonopts we've found */
|
||||
|
||||
static void increment_index()
|
||||
{
|
||||
/* Move onto the next option */
|
||||
if(argv_index < argv_index2)
|
||||
{
|
||||
while(prev_argv[++argv_index] && prev_argv[argv_index][0] != '-'
|
||||
&& argv_index < argv_index2+1);
|
||||
}
|
||||
else argv_index++;
|
||||
opt_offset = 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Permutes argv[] so that the argument currently being processed is moved
|
||||
* to the end.
|
||||
*/
|
||||
static int permute_argv_once()
|
||||
{
|
||||
/* Movability check */
|
||||
if(argv_index + nonopt >= prev_argc) return 1;
|
||||
/* Move the current option to the end, bring the others to front */
|
||||
else
|
||||
{
|
||||
char* tmp = prev_argv[argv_index];
|
||||
|
||||
/* Move the data */
|
||||
memmove(&prev_argv[argv_index], &prev_argv[argv_index+1],
|
||||
sizeof(char**) * (prev_argc - argv_index - 1));
|
||||
prev_argv[prev_argc - 1] = tmp;
|
||||
|
||||
nonopt++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int getopt(int argc, char** argv, const char* optstr)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
/* If we have new argv, reinitialize */
|
||||
if(prev_argv != argv || prev_argc != argc)
|
||||
{
|
||||
/* Initialize variables */
|
||||
prev_argv = argv;
|
||||
prev_argc = argc;
|
||||
argv_index = 1;
|
||||
argv_index2 = 1;
|
||||
opt_offset = 1;
|
||||
dashdash = 0;
|
||||
nonopt = 0;
|
||||
}
|
||||
|
||||
/* Jump point in case we want to ignore the current argv_index */
|
||||
getopt_top:
|
||||
|
||||
/* Misc. initializations */
|
||||
optarg = NULL;
|
||||
opterr = 0;
|
||||
optopt = 0;
|
||||
|
||||
/* Dash-dash check */
|
||||
if(argv[argv_index] && !strcmp(argv[argv_index], "--"))
|
||||
{
|
||||
dashdash = 1;
|
||||
increment_index();
|
||||
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
|
||||
if (optind >= argc)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
|
||||
shall return -1 without changing optind. */
|
||||
if (argv[optind] == NULL)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called *argv[optind] is not the character '-',
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (*argv[optind] != '-')
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "-",
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (strcmp(argv[optind], "-") == 0)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "--",
|
||||
getopt() shall return -1 after incrementing optind. */
|
||||
if (strcmp(argv[optind], "--") == 0) {
|
||||
++optind;
|
||||
goto no_more_optchars;
|
||||
}
|
||||
|
||||
/* If we're at the end of argv, that's it. */
|
||||
if(argv[argv_index] == NULL)
|
||||
{
|
||||
c = -1;
|
||||
}
|
||||
/* Are we looking at a string? Single dash is also a string */
|
||||
else if(dashdash || argv[argv_index][0] != '-' || !strcmp(argv[argv_index], "-"))
|
||||
{
|
||||
/* If we want a string... */
|
||||
if(optstr[0] == '-')
|
||||
{
|
||||
c = 1;
|
||||
optarg = argv[argv_index];
|
||||
increment_index();
|
||||
}
|
||||
/* If we really don't want it (we're in POSIX mode), we're done */
|
||||
else if(optstr[0] == '+' || getenv("POSIXLY_CORRECT"))
|
||||
{
|
||||
c = -1;
|
||||
if (optcursor == NULL || *optcursor == '\0')
|
||||
optcursor = argv[optind] + 1;
|
||||
|
||||
/* Everything else is a non-opt argument */
|
||||
nonopt = argc - argv_index;
|
||||
}
|
||||
/* If we mildly don't want it, then move it back */
|
||||
else
|
||||
{
|
||||
if(!permute_argv_once()) goto getopt_top;
|
||||
else c = -1;
|
||||
}
|
||||
}
|
||||
/* Otherwise we're looking at an option */
|
||||
else
|
||||
{
|
||||
char* opt_ptr = NULL;
|
||||
optchar = *optcursor;
|
||||
|
||||
/* Grab the option */
|
||||
c = argv[argv_index][opt_offset++];
|
||||
/* FreeBSD: The variable optopt saves the last known option character
|
||||
returned by getopt(). */
|
||||
optopt = optchar;
|
||||
|
||||
/* Is the option in the optstr? */
|
||||
if(optstr[0] == '-') opt_ptr = strchr(optstr+1, c);
|
||||
else opt_ptr = strchr(optstr, c);
|
||||
/* Invalid argument */
|
||||
if(!opt_ptr)
|
||||
{
|
||||
if(opterr)
|
||||
{
|
||||
fprintf(stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||
}
|
||||
/* The getopt() function shall return the next option character (if one is
|
||||
found) from argv that matches a character in optstring, if there is
|
||||
one that matches. */
|
||||
optdecl = strchr(optstring, optchar);
|
||||
if (optdecl) {
|
||||
/* [I]f a character is followed by a colon, the option takes an
|
||||
argument. */
|
||||
if (optdecl[1] == ':') {
|
||||
optarg = ++optcursor;
|
||||
if (*optarg == '\0') {
|
||||
/* GNU extension: Two colons mean an option takes an
|
||||
optional arg; if there is text in the current argv-element
|
||||
(i.e., in the same word as the option name itself, for example,
|
||||
"-oarg"), then it is returned in optarg, otherwise optarg is set
|
||||
to zero. */
|
||||
if (optdecl[2] != ':') {
|
||||
/* If the option was the last character in the string pointed to by
|
||||
an element of argv, then optarg shall contain the next element
|
||||
of argv, and optind shall be incremented by 2. If the resulting
|
||||
value of optind is greater than argc, this indicates a missing
|
||||
option-argument, and getopt() shall return an error indication.
|
||||
|
||||
optopt = c;
|
||||
c = '?';
|
||||
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
/* Option takes argument */
|
||||
else if(opt_ptr[1] == ':')
|
||||
{
|
||||
/* ie, -oARGUMENT, -xxxoARGUMENT, etc. */
|
||||
if(argv[argv_index][opt_offset] != '\0')
|
||||
{
|
||||
optarg = &argv[argv_index][opt_offset];
|
||||
increment_index();
|
||||
}
|
||||
/* ie, -o ARGUMENT (only if it's a required argument) */
|
||||
else if(opt_ptr[2] != ':')
|
||||
{
|
||||
/* One of those "you're not expected to understand this" moment */
|
||||
if(argv_index2 < argv_index) argv_index2 = argv_index;
|
||||
while(argv[++argv_index2] && argv[argv_index2][0] == '-');
|
||||
optarg = argv[argv_index2];
|
||||
|
||||
/* Don't cross into the non-option argument list */
|
||||
if(argv_index2 + nonopt >= prev_argc) optarg = NULL;
|
||||
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move onto the next option */
|
||||
increment_index();
|
||||
}
|
||||
|
||||
/* In case we got no argument for an option with required argument */
|
||||
if(optarg == NULL && opt_ptr[2] != ':')
|
||||
{
|
||||
optopt = c;
|
||||
c = '?';
|
||||
|
||||
if(opterr)
|
||||
{
|
||||
fprintf(stderr,"%s: option requires an argument -- %c\n",
|
||||
argv[0], optopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Option does not take argument */
|
||||
else
|
||||
{
|
||||
/* Next argv_index */
|
||||
if(argv[argv_index][opt_offset] == '\0')
|
||||
{
|
||||
increment_index();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate optind */
|
||||
if(c == -1)
|
||||
{
|
||||
optind = argc - nonopt;
|
||||
}
|
||||
else
|
||||
{
|
||||
optind = argv_index;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/* vim:ts=3
|
||||
Otherwise, optarg shall point to the string following the
|
||||
option character in that element of argv, and optind shall be
|
||||
incremented by 1.
|
||||
*/
|
||||
if (++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
} else {
|
||||
/* If it detects a missing option-argument, it shall return the
|
||||
colon character ( ':' ) if the first character of optstring
|
||||
was a colon, or a question-mark character ( '?' ) otherwise.
|
||||
*/
|
||||
optarg = NULL;
|
||||
optchar = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
optcursor = NULL;
|
||||
}
|
||||
} else {
|
||||
/* If getopt() encounters an option character that is not contained in
|
||||
optstring, it shall return the question-mark ( '?' ) character. */
|
||||
optchar = '?';
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *++optcursor == '\0')
|
||||
++optind;
|
||||
|
||||
return optchar;
|
||||
|
||||
no_more_optchars:
|
||||
optcursor = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Implementation based on [1].
|
||||
|
||||
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
*/
|
||||
int getopt_long(int argc, char* const argv[], const char* optstring,
|
||||
const struct option* longopts, int* longindex) {
|
||||
const struct option* o = longopts;
|
||||
const struct option* match = NULL;
|
||||
int num_matches = 0;
|
||||
size_t argument_name_length = 0;
|
||||
const char* current_argument = NULL;
|
||||
int retval = -1;
|
||||
|
||||
optarg = NULL;
|
||||
optopt = 0;
|
||||
|
||||
if (optind >= argc)
|
||||
return -1;
|
||||
|
||||
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
|
||||
return getopt(argc, argv, optstring);
|
||||
|
||||
/* It's an option; starts with -- and is longer than two chars. */
|
||||
current_argument = argv[optind] + 2;
|
||||
argument_name_length = strcspn(current_argument, "=");
|
||||
for (; o->name; ++o) {
|
||||
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
|
||||
match = o;
|
||||
++num_matches;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matches == 1) {
|
||||
/* If longindex is not NULL, it points to a variable which is set to the
|
||||
index of the long option relative to longopts. */
|
||||
if (longindex)
|
||||
*longindex = (match - longopts);
|
||||
|
||||
/* If flag is NULL, then getopt_long() shall return val.
|
||||
Otherwise, getopt_long() returns 0, and flag shall point to a variable
|
||||
which shall be set to val if the option is found, but left unchanged if
|
||||
the option is not found. */
|
||||
if (match->flag)
|
||||
*(match->flag) = match->val;
|
||||
|
||||
retval = match->flag ? 0 : match->val;
|
||||
|
||||
if (match->has_arg != no_argument) {
|
||||
optarg = strchr(argv[optind], '=');
|
||||
if (optarg != NULL)
|
||||
++optarg;
|
||||
|
||||
if (match->has_arg == required_argument) {
|
||||
/* Only scan the next argv for required arguments. Behavior is not
|
||||
specified, but has been observed with Ubuntu and Mac OSX. */
|
||||
if (optarg == NULL && ++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
}
|
||||
|
||||
if (optarg == NULL)
|
||||
retval = ':';
|
||||
}
|
||||
} else if (strchr(argv[optind], '=')) {
|
||||
/* An argument was provided to a non-argument option.
|
||||
I haven't seen this specified explicitly, but both GNU and BSD-based
|
||||
implementations show this behavior.
|
||||
*/
|
||||
retval = '?';
|
||||
}
|
||||
} else {
|
||||
/* Unknown option or ambiguous match. */
|
||||
retval = '?';
|
||||
}
|
||||
|
||||
++optind;
|
||||
return retval;
|
||||
}
|
||||
|
84
deps/getopt.h
vendored
84
deps/getopt.h
vendored
@ -1,63 +1,57 @@
|
||||
/*****************************************************************************
|
||||
* getopt.h - competent and free getopt library.
|
||||
* $Header: /cvsroot/freegetopt/freegetopt/getopt.h,v 1.2 2003/10/26 03:10:20 vindaci Exp $
|
||||
*
|
||||
* Copyright (c)2002-2003 Mark K. Kim
|
||||
/* Copyright (c) 2012, Kim Gräsman
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* * Neither the name of Kim Gräsman nor the names of contributors may be used
|
||||
* to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* * Neither the original author of this software nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef GETOPT_H_
|
||||
#define GETOPT_H_
|
||||
|
||||
#ifndef INCLUDED_GETOPT_PORT_H
|
||||
#define INCLUDED_GETOPT_PORT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const int no_argument;
|
||||
extern const int required_argument;
|
||||
extern const int optional_argument;
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind;
|
||||
extern int opterr;
|
||||
extern int optopt;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
int getopt(int argc, char** argv, const char* optstr);
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt(int argc, char* const argv[], const char* optstring);
|
||||
|
||||
#ifdef __cplusplus
|
||||
int getopt_long(int argc, char* const argv[],
|
||||
const char* optstring, const struct option* longopts, int* longindex);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* GETOPT_H_ */
|
||||
|
||||
|
||||
/* vim:ts=3
|
||||
*/
|
||||
#endif // INCLUDED_GETOPT_PORT_H
|
||||
|
@ -14,7 +14,7 @@ specification but merely list some of the preconditions for certain parts of the
|
||||
API to function on a given machine. As such, any part of it may change in
|
||||
future versions without this being considered a breaking API change.
|
||||
|
||||
@section compat_wm ICCCM and EWMH conformance
|
||||
@section compat_x11 X11 extensions, protocols and IPC standards
|
||||
|
||||
As GLFW uses Xlib, directly, without any intervening toolkit
|
||||
library, it has sole responsibility for interacting well with the many and
|
||||
@ -27,6 +27,10 @@ X11 API; most importantly the
|
||||
[Extended Window Manager Hints](http://standards.freedesktop.org/wm-spec/wm-spec-latest.html)
|
||||
(EWMH) standards.
|
||||
|
||||
GLFW uses the `_MOTIF_WM_HINTS` window property to support borderless windows.
|
||||
If the running window manager does not support this property, the
|
||||
`GLFW_DECORATED` hint will have no effect.
|
||||
|
||||
GLFW uses the ICCCM `WM_DELETE_WINDOW` protocol to intercept the user
|
||||
attempting to close the GLFW window. If the running window manager does not
|
||||
support this protocol, the close callback will never be called.
|
||||
@ -36,11 +40,16 @@ the user when the application has stopped responding, i.e. when it has ceased to
|
||||
process events. If the running window manager does not support this protocol,
|
||||
the user will not be notified if the application locks up.
|
||||
|
||||
GLFW uses the EWMH `_NET_WM_STATE` protocol to tell the window manager to make
|
||||
the GLFW window full screen. If the running window manager does not support this
|
||||
protocol, full screen windows may not work properly. GLFW has a fallback code
|
||||
path in case this protocol is unavailable, but every window manager behaves
|
||||
slightly differently in this regard.
|
||||
GLFW uses the EWMH `_NET_WM_STATE_FULLSCREEN` window state to tell the window
|
||||
manager to make the GLFW window full screen. If the running window manager does
|
||||
not support this state, full screen windows may not work properly. GLFW has
|
||||
a fallback code path in case this state is unavailable, but every window manager
|
||||
behaves slightly differently in this regard.
|
||||
|
||||
GLFW uses the EWMH `_NET_WM_BYPASS_COMPOSITOR` window property to tell a
|
||||
compositing window manager to un-redirect full screen GLFW windows. If the
|
||||
running window manager uses compositing but does not support this property then
|
||||
additional copying may be performed for each buffer swap of full screen windows.
|
||||
|
||||
GLFW uses the
|
||||
[clipboard manager protocol](http://www.freedesktop.org/wiki/ClipboardManager/)
|
||||
@ -48,6 +57,28 @@ to push a clipboard string (i.e. selection) owned by a GLFW window about to be
|
||||
destroyed to the clipboard manager. If there is no running clipboard manager,
|
||||
the clipboard string will be unavailable once the window has been destroyed.
|
||||
|
||||
GLFW uses the
|
||||
[X drag-and-drop protocol](http://www.freedesktop.org/wiki/Specifications/XDND/)
|
||||
to provide file drop events. If the application originating the drag does not
|
||||
support this protocol, drag and drop will not work.
|
||||
|
||||
GLFW uses the XInput 2 extension to provide sub-pixel cursor motion events. If
|
||||
the running X server does not support this version of this extension, cursor
|
||||
motion will be snapped to the pixel grid.
|
||||
|
||||
GLFW uses the XRandR 1.3 extension to provide multi-monitor support. If the
|
||||
running X server does not support this version of this extension, multi-monitor
|
||||
support will not function and only a single, desktop-spanning monitor will be
|
||||
reported.
|
||||
|
||||
GLFW uses the XRandR 1.3 and Xf86vidmode extensions to provide gamma ramp
|
||||
support. If the running X server does not support either or both of these
|
||||
extensions, gamma ramp support will not function.
|
||||
|
||||
GLFW requires the Xkb extension with detectable auto-repeat to provide keyboard
|
||||
input. If the running X server does not support this extension and detectable
|
||||
auto-repeat, `glfwInit` will fail.
|
||||
|
||||
@section compat_glx GLX extensions
|
||||
|
||||
The GLX API is the default API used to create OpenGL contexts on Unix-like
|
||||
|
@ -165,6 +165,9 @@ directory of bundled applications to the `Contents/Resources` directory.
|
||||
`GLFW_USE_MENUBAR` determines whether the first call to
|
||||
`glfwCreateWindow` sets up a minimal menu bar.
|
||||
|
||||
`GLFW_USE_RETINA` determines whether windows will use the full resolution of
|
||||
Retina displays.
|
||||
|
||||
`GLFW_BUILD_UNIVERSAL` determines whether to build Universal Binaries.
|
||||
|
||||
|
||||
@ -257,5 +260,7 @@ available:
|
||||
application bundle during @ref glfwInit (recommended)
|
||||
- `_GLFW_USE_MENUBAR` to create and populate the menu bar when the first window
|
||||
is created (recommended)
|
||||
- `_GLFW_USE_RETINA` to have windows use the full resolution of Retina displays
|
||||
(recommended)
|
||||
|
||||
*/
|
||||
|
@ -174,6 +174,17 @@ window to use. There is @ref glfwGetPrimaryMonitor that provides behaviour
|
||||
similar to that of GLFW 2.
|
||||
|
||||
|
||||
@subsection moving_hidpi Separation of window and framebuffer sizes
|
||||
|
||||
Window positions and sizes now use screen coordinates, which may not be the same
|
||||
as pixels on machines with high-DPI monitors. This is important as OpenGL uses
|
||||
pixels, not screen coordinates. Most commonly, the rectangle specified with
|
||||
`glViewport` needs to use pixels. Therefore, framebuffer size functions have
|
||||
been added. You can retrieve the size of the framebuffer of a window with @ref
|
||||
glfwGetFramebufferSize function. A framebuffer size callback has been added,
|
||||
which can be set with @ref glfwSetFramebufferSizeCallback.
|
||||
|
||||
|
||||
@subsection moving_window_close Window closing
|
||||
|
||||
Window closing initiated by the user is now just an event like any other.
|
||||
|
@ -5,6 +5,14 @@
|
||||
@tableofcontents
|
||||
|
||||
|
||||
@section news_31 New features in version 3.1
|
||||
|
||||
@subsection news_31_drop Drop event support
|
||||
|
||||
GLFW now provides a callback for receiving the paths of files dropped onto GLFW
|
||||
windows. The callback is set with the @ref glfwSetDropCallback function.
|
||||
|
||||
|
||||
@section news_30 New features in version 3.0
|
||||
|
||||
@subsection news_30_cmake CMake build system
|
||||
@ -80,7 +88,7 @@ GLFW now supports high-DPI monitors on both Windows and OS X, giving windows ful
|
||||
resolution framebuffers where other UI elements are scaled up. To achieve this,
|
||||
@ref glfwGetFramebufferSize and @ref glfwSetFramebufferSizeCallback have been
|
||||
added. These work with pixels, while the rest of the GLFW API works with screen
|
||||
coordinates.
|
||||
coordinates. This is important as OpenGL uses pixels, not screen coordinates.
|
||||
|
||||
|
||||
@subsection news_30_error Error callback
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.0 - www.glfw.org
|
||||
* GLFW 3.1 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
@ -773,6 +773,21 @@ typedef void (* GLFWkeyfun)(GLFWwindow*,int,int,int,int);
|
||||
*/
|
||||
typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int);
|
||||
|
||||
|
||||
/*! @brief The function signature for drop callbacks.
|
||||
*
|
||||
* This is the function signature for drop callbacks.
|
||||
*
|
||||
* @param[in] window The window that received the event.
|
||||
* @param[in] count The number of dropped objects.
|
||||
* @param[in] names The UTF-8 encoded names of the dropped objects.
|
||||
*
|
||||
* @sa glfwSetDropCallback
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**);
|
||||
|
||||
/*! @brief The function signature for monitor configuration callbacks.
|
||||
*
|
||||
* This is the function signature for monitor configuration callback functions.
|
||||
@ -2014,6 +2029,22 @@ GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* window, GLFWcu
|
||||
*/
|
||||
GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* window, GLFWscrollfun cbfun);
|
||||
|
||||
/*! @brief Sets the drop callback.
|
||||
*
|
||||
* This function sets the drop callback of the specified window, which is
|
||||
* called when an object is dropped over the window.
|
||||
*
|
||||
*
|
||||
* @param[in] window The window whose callback to set.
|
||||
* @param[in] cbfun The new drop callback, or `NULL` to remove the currently
|
||||
* set callback.
|
||||
* @return The previously set callback, or `NULL` if no callback was set or an
|
||||
* error occurred.
|
||||
*
|
||||
* @ingroup input
|
||||
*/
|
||||
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* window, GLFWdropfun cbfun);
|
||||
|
||||
/*! @brief Returns whether the specified joystick is present.
|
||||
*
|
||||
* This function returns whether the specified joystick is present.
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
@ -132,6 +132,9 @@ const char* _glfwPlatformGetVersionString(void)
|
||||
#if defined(_GLFW_USE_MENUBAR)
|
||||
" menubar"
|
||||
#endif
|
||||
#if defined(_GLFW_USE_RETINA)
|
||||
" retina"
|
||||
#endif
|
||||
#if defined(_GLFW_BUILD_DLL)
|
||||
" dynamic"
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
|
||||
@ -343,6 +343,7 @@ void _glfwInitJoysticks(void)
|
||||
{
|
||||
// This device is not relevant to GLFW
|
||||
CFRelease(valueRef);
|
||||
CFRelease(propsRef);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -360,6 +361,7 @@ void _glfwInitJoysticks(void)
|
||||
{
|
||||
// This device is not relevant to GLFW
|
||||
CFRelease(valueRef);
|
||||
CFRelease(propsRef);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -376,7 +378,11 @@ void _glfwInitJoysticks(void)
|
||||
&score);
|
||||
|
||||
if (kIOReturnSuccess != result)
|
||||
{
|
||||
CFRelease(valueRef);
|
||||
CFRelease(propsRef);
|
||||
return;
|
||||
}
|
||||
|
||||
plugInResult = (*ppPlugInInterface)->QueryInterface(
|
||||
ppPlugInInterface,
|
||||
@ -384,7 +390,11 @@ void _glfwInitJoysticks(void)
|
||||
(void *) &(joystick->interface));
|
||||
|
||||
if (plugInResult != S_OK)
|
||||
{
|
||||
CFRelease(valueRef);
|
||||
CFRelease(propsRef);
|
||||
return;
|
||||
}
|
||||
|
||||
(*ppPlugInInterface)->Release(ppPlugInInterface);
|
||||
|
||||
@ -419,6 +429,7 @@ void _glfwInitJoysticks(void)
|
||||
(void*) joystick);
|
||||
CFRelease(valueRef);
|
||||
}
|
||||
CFRelease(propsRef);
|
||||
|
||||
joystick->axes = calloc(CFArrayGetCount(joystick->axisElements),
|
||||
sizeof(float));
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -52,6 +52,7 @@ static const char* getDisplayName(CGDirectDisplayID displayID)
|
||||
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
|
||||
(const void**) &value))
|
||||
{
|
||||
// This may happen if a desktop Mac is running headless
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Failed to retrieve display name");
|
||||
|
||||
CFRelease(info);
|
||||
@ -252,48 +253,30 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
||||
|
||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
{
|
||||
uint32_t i, found = 0, monitorCount;
|
||||
uint32_t i, found = 0, displayCount;
|
||||
_GLFWmonitor** monitors;
|
||||
CGDirectDisplayID* displays;
|
||||
|
||||
*count = 0;
|
||||
|
||||
CGGetActiveDisplayList(0, NULL, &monitorCount);
|
||||
CGGetActiveDisplayList(0, NULL, &displayCount);
|
||||
|
||||
displays = calloc(monitorCount, sizeof(CGDirectDisplayID));
|
||||
monitors = calloc(monitorCount, sizeof(_GLFWmonitor*));
|
||||
displays = calloc(displayCount, sizeof(CGDirectDisplayID));
|
||||
monitors = calloc(displayCount, sizeof(_GLFWmonitor*));
|
||||
|
||||
CGGetActiveDisplayList(monitorCount, displays, &monitorCount);
|
||||
|
||||
for (i = 0; i < monitorCount; i++)
|
||||
{
|
||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||
|
||||
monitors[found] = _glfwCreateMonitor(getDisplayName(displays[i]),
|
||||
size.width, size.height);
|
||||
|
||||
monitors[found]->ns.displayID = displays[i];
|
||||
found++;
|
||||
}
|
||||
|
||||
free(displays);
|
||||
|
||||
for (i = 0; i < monitorCount; i++)
|
||||
{
|
||||
if (CGDisplayIsMain(monitors[i]->ns.displayID))
|
||||
{
|
||||
_GLFWmonitor* temp = monitors[0];
|
||||
monitors[0] = monitors[i];
|
||||
monitors[i] = temp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CGGetActiveDisplayList(displayCount, displays, &displayCount);
|
||||
|
||||
NSArray* screens = [NSScreen screens];
|
||||
|
||||
for (i = 0; i < monitorCount; i++)
|
||||
for (i = 0; i < displayCount; i++)
|
||||
{
|
||||
int j;
|
||||
const CGSize size = CGDisplayScreenSize(displays[i]);
|
||||
|
||||
monitors[found] = _glfwAllocMonitor(getDisplayName(displays[i]),
|
||||
size.width, size.height);
|
||||
|
||||
monitors[found]->ns.displayID = displays[i];
|
||||
|
||||
for (j = 0; j < [screens count]; j++)
|
||||
{
|
||||
@ -301,26 +284,29 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
NSDictionary* dictionary = [screen deviceDescription];
|
||||
NSNumber* number = [dictionary objectForKey:@"NSScreenNumber"];
|
||||
|
||||
if (monitors[i]->ns.displayID == [number unsignedIntegerValue])
|
||||
if (monitors[found]->ns.displayID == [number unsignedIntegerValue])
|
||||
{
|
||||
monitors[i]->ns.screen = screen;
|
||||
monitors[found]->ns.screen = screen;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (monitors[i]->ns.screen == nil)
|
||||
if (monitors[found]->ns.screen)
|
||||
found++;
|
||||
else
|
||||
{
|
||||
_glfwDestroyMonitors(monitors, monitorCount);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Cocoa: Failed to find NSScreen for CGDisplay %s",
|
||||
monitors[i]->name);
|
||||
monitors[found]->name);
|
||||
|
||||
free(monitors);
|
||||
return NULL;
|
||||
_glfwFreeMonitor(monitors[found]);
|
||||
monitors[found] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
*count = monitorCount;
|
||||
free(displays);
|
||||
|
||||
*count = found;
|
||||
return monitors;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
@ -138,12 +138,4 @@ void _glfwTerminateJoysticks(void);
|
||||
GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoMode(_GLFWmonitor* monitor);
|
||||
|
||||
// OpenGL support
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
|
||||
#endif // _cocoa_platform_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
@ -445,6 +445,8 @@ static int translateKey(unsigned int key)
|
||||
trackingArea = nil;
|
||||
|
||||
[self updateTrackingAreas];
|
||||
[self registerForDraggedTypes:[NSArray arrayWithObjects:
|
||||
NSFilenamesPboardType, nil]];
|
||||
}
|
||||
|
||||
return self;
|
||||
@ -657,6 +659,67 @@ static int translateKey(unsigned int key)
|
||||
_glfwInputScroll(window, deltaX, deltaY);
|
||||
}
|
||||
|
||||
- (void)resetCursorRects
|
||||
{
|
||||
// This makes the cursor dissapear when the window is
|
||||
// resized or received a drag operation
|
||||
[self discardCursorRects];
|
||||
[self addCursorRect:[self bounds] cursor:_glfw.ns.cursor];
|
||||
}
|
||||
|
||||
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
if ((NSDragOperationGeneric & [sender draggingSourceOperationMask])
|
||||
== NSDragOperationGeneric)
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
return NSDragOperationGeneric;
|
||||
}
|
||||
|
||||
return NSDragOperationNone;
|
||||
}
|
||||
|
||||
- (BOOL)prepareForDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
NSPasteboard* pasteboard = [sender draggingPasteboard];
|
||||
NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType];
|
||||
|
||||
int height;
|
||||
_glfwPlatformGetWindowSize(window, NULL, &height);
|
||||
_glfwInputCursorMotion(window,
|
||||
[sender draggingLocation].x,
|
||||
height - [sender draggingLocation].y);
|
||||
|
||||
const int count = [files count];
|
||||
if (count)
|
||||
{
|
||||
NSEnumerator* e = [files objectEnumerator];
|
||||
char** names = calloc(count, sizeof(char*));
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
names[i] = strdup([[e nextObject] UTF8String]);
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) names);
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
free(names[i]);
|
||||
free(names);
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)concludeDragOperation:(id <NSDraggingInfo>)sender
|
||||
{
|
||||
[self setNeedsDisplay:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -877,7 +940,9 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
|
||||
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
|
||||
{
|
||||
#if defined(_GLFW_USE_RETINA)
|
||||
[window->ns.view setWantsBestResolutionOpenGLSurface:YES];
|
||||
#endif
|
||||
|
||||
if (wndconfig->resizable)
|
||||
[window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 EGL - www.glfw.org
|
||||
// GLFW 3.1 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 EGL - www.glfw.org
|
||||
// GLFW 3.1 EGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -77,4 +77,18 @@ typedef struct _GLFWlibraryEGL
|
||||
} _GLFWlibraryEGL;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Prototypes for platform specific internal functions
|
||||
//========================================================================
|
||||
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
int _glfwAnalyzeContext(const _GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
#endif // _egl_platform_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -4,7 +4,7 @@ includedir=${prefix}/include
|
||||
libdir=${exec_prefix}/lib@LIB_SUFFIX@
|
||||
|
||||
Name: GLFW
|
||||
Description: A portable library for OpenGL, window and input
|
||||
Description: A multi-platform library for OpenGL, window and input
|
||||
Version: @GLFW_VERSION_FULL@
|
||||
URL: http://www.glfw.org/
|
||||
Requires.private: @GLFW_PKG_DEPS@
|
||||
|
@ -73,6 +73,8 @@
|
||||
#cmakedefine _GLFW_USE_CHDIR
|
||||
// Define this to 1 if glfwCreateWindow should populate the menu bar
|
||||
#cmakedefine _GLFW_USE_MENUBAR
|
||||
// Define this to 1 if windows should use full resolution on Retina displays
|
||||
#cmakedefine _GLFW_USE_RETINA
|
||||
|
||||
// Define this to 1 if using OpenGL as the client library
|
||||
#cmakedefine _GLFW_USE_OPENGL
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 GLX - www.glfw.org
|
||||
// GLFW 3.1 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 GLX - www.glfw.org
|
||||
// GLFW 3.1 GLX - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -122,4 +122,15 @@ typedef struct _GLFWlibraryGLX
|
||||
} _GLFWlibraryGLX;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Prototypes for platform specific internal functions
|
||||
//========================================================================
|
||||
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
|
||||
#endif // _glx_platform_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -163,7 +163,7 @@ GLFWAPI void glfwTerminate(void)
|
||||
_glfwPlatformSetGammaRamp(monitor, &monitor->originalRamp);
|
||||
}
|
||||
|
||||
_glfwDestroyMonitors(_glfw.monitors, _glfw.monitorCount);
|
||||
_glfwFreeMonitors(_glfw.monitors, _glfw.monitorCount);
|
||||
_glfw.monitors = NULL;
|
||||
_glfw.monitorCount = 0;
|
||||
|
||||
|
16
src/input.c
16
src/input.c
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -211,6 +211,12 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered)
|
||||
window->callbacks.cursorEnter((GLFWwindow*) window, entered);
|
||||
}
|
||||
|
||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names)
|
||||
{
|
||||
if (window->callbacks.drop)
|
||||
window->callbacks.drop((GLFWwindow*) window, count, names);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
////// GLFW public API //////
|
||||
@ -394,3 +400,11 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
|
||||
{
|
||||
_GLFWwindow* window = (_GLFWwindow*) handle;
|
||||
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
|
||||
_GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
|
||||
return cbfun;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -239,6 +239,7 @@ struct _GLFWwindow
|
||||
GLFWscrollfun scroll;
|
||||
GLFWkeyfun key;
|
||||
GLFWcharfun character;
|
||||
GLFWdropfun drop;
|
||||
} callbacks;
|
||||
|
||||
// This is defined in the window API's platform.h
|
||||
@ -678,6 +679,14 @@ void _glfwInputMonitorChange(void);
|
||||
*/
|
||||
void _glfwInputError(int error, const char* format, ...);
|
||||
|
||||
/*! @brief Notifies dropped object over window.
|
||||
* @param[in] window The window that received the event.
|
||||
* @param[in] count The number of dropped objects.
|
||||
* @param[in] names The names of the dropped objects.
|
||||
* @ingroup event
|
||||
*/
|
||||
void _glfwInputDrop(_GLFWwindow* window, int count, const char** names);
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Utility functions
|
||||
@ -761,15 +770,15 @@ void _glfwFreeGammaArrays(GLFWgammaramp* ramp);
|
||||
* @return The newly created object.
|
||||
* @ingroup utility
|
||||
*/
|
||||
_GLFWmonitor* _glfwCreateMonitor(const char* name, int widthMM, int heightMM);
|
||||
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM);
|
||||
|
||||
/*! @brief Frees a monitor object and any data associated with it.
|
||||
* @ingroup utility
|
||||
*/
|
||||
void _glfwDestroyMonitor(_GLFWmonitor* monitor);
|
||||
void _glfwFreeMonitor(_GLFWmonitor* monitor);
|
||||
|
||||
/*! @ingroup utility
|
||||
*/
|
||||
void _glfwDestroyMonitors(_GLFWmonitor** monitors, int count);
|
||||
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count);
|
||||
|
||||
#endif // _internal_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -113,7 +113,7 @@ void _glfwInputMonitorChange(void)
|
||||
{
|
||||
if (_glfwPlatformIsSameMonitor(_glfw.monitors[i], monitors[j]))
|
||||
{
|
||||
_glfwDestroyMonitor(_glfw.monitors[i]);
|
||||
_glfwFreeMonitor(_glfw.monitors[i]);
|
||||
_glfw.monitors[i] = monitors[j];
|
||||
break;
|
||||
}
|
||||
@ -167,7 +167,7 @@ void _glfwInputMonitorChange(void)
|
||||
_glfw.callbacks.monitor((GLFWmonitor*) _glfw.monitors[i], GLFW_CONNECTED);
|
||||
}
|
||||
|
||||
_glfwDestroyMonitors(monitors, monitorCount);
|
||||
_glfwFreeMonitors(monitors, monitorCount);
|
||||
}
|
||||
|
||||
|
||||
@ -175,7 +175,7 @@ void _glfwInputMonitorChange(void)
|
||||
////// GLFW internal API //////
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
_GLFWmonitor* _glfwCreateMonitor(const char* name, int widthMM, int heightMM)
|
||||
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
|
||||
{
|
||||
_GLFWmonitor* monitor = calloc(1, sizeof(_GLFWmonitor));
|
||||
monitor->name = strdup(name);
|
||||
@ -185,7 +185,7 @@ _GLFWmonitor* _glfwCreateMonitor(const char* name, int widthMM, int heightMM)
|
||||
return monitor;
|
||||
}
|
||||
|
||||
void _glfwDestroyMonitor(_GLFWmonitor* monitor)
|
||||
void _glfwFreeMonitor(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (monitor == NULL)
|
||||
return;
|
||||
@ -198,12 +198,12 @@ void _glfwDestroyMonitor(_GLFWmonitor* monitor)
|
||||
free(monitor);
|
||||
}
|
||||
|
||||
void _glfwDestroyMonitors(_GLFWmonitor** monitors, int count)
|
||||
void _glfwFreeMonitors(_GLFWmonitor** monitors, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
_glfwDestroyMonitor(monitors[i]);
|
||||
_glfwFreeMonitor(monitors[i]);
|
||||
|
||||
free(monitors);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 OS X - www.glfw.org
|
||||
// GLFW 3.1 OS X - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2009-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
@ -61,4 +61,15 @@ typedef struct _GLFWlibraryNSGL
|
||||
} _GLFWlibraryNSGL;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Prototypes for platform specific internal functions
|
||||
//========================================================================
|
||||
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
|
||||
#endif // _nsgl_platform_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 WGL - www.glfw.org
|
||||
// GLFW 3.1 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 WGL - www.glfw.org
|
||||
// GLFW 3.1 WGL - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -85,4 +85,18 @@ typedef struct _GLFWlibraryWGL
|
||||
} _GLFWlibraryWGL;
|
||||
|
||||
|
||||
//========================================================================
|
||||
// Prototypes for platform specific internal functions
|
||||
//========================================================================
|
||||
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
int _glfwAnalyzeContext(const _GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
#endif // _wgl_platform_h_
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -65,7 +65,11 @@ static GLboolean initLibraries(void)
|
||||
|
||||
_glfw.win32.winmm.instance = LoadLibrary(L"winmm.dll");
|
||||
if (!_glfw.win32.winmm.instance)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to load winmm.dll");
|
||||
return GL_FALSE;
|
||||
}
|
||||
|
||||
_glfw.win32.winmm.joyGetDevCaps = (JOYGETDEVCAPS_T)
|
||||
GetProcAddress(_glfw.win32.winmm.instance, "joyGetDevCapsW");
|
||||
@ -81,6 +85,8 @@ static GLboolean initLibraries(void)
|
||||
!_glfw.win32.winmm.joyGetPosEx ||
|
||||
!_glfw.win32.winmm.timeGetTime)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Win32: Failed to load winmm functions");
|
||||
return GL_FALSE;
|
||||
}
|
||||
#endif // _GLFW_NO_DLOAD_WINMM
|
||||
@ -90,6 +96,8 @@ static GLboolean initLibraries(void)
|
||||
{
|
||||
_glfw.win32.user32.SetProcessDPIAware = (SETPROCESSDPIAWARE_T)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "SetProcessDPIAware");
|
||||
_glfw.win32.user32.ChangeWindowMessageFilterEx = (CHANGEWINDOWMESSAGEFILTEREX_T)
|
||||
GetProcAddress(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
|
||||
}
|
||||
|
||||
_glfw.win32.dwmapi.instance = LoadLibrary(L"dwmapi.dll");
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -148,7 +148,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
name = _glfwCreateUTF8FromWideString(display.DeviceString);
|
||||
if (!name)
|
||||
{
|
||||
_glfwDestroyMonitors(monitors, found);
|
||||
_glfwFreeMonitors(monitors, found);
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"Failed to convert string to UTF-8");
|
||||
|
||||
@ -156,7 +156,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
monitors[found] = _glfwCreateMonitor(name,
|
||||
monitors[found] = _glfwAllocMonitor(name,
|
||||
GetDeviceCaps(dc, HORZSIZE),
|
||||
GetDeviceCaps(dc, VERTSIZE));
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -77,6 +77,21 @@
|
||||
#ifndef WM_DWMCOMPOSITIONCHANGED
|
||||
#define WM_DWMCOMPOSITIONCHANGED 0x031E
|
||||
#endif
|
||||
#ifndef WM_COPYGLOBALDATA
|
||||
#define WM_COPYGLOBALDATA 0x0049
|
||||
#endif
|
||||
|
||||
#if WINVER < 0x0601
|
||||
typedef struct tagCHANGEFILTERSTRUCT
|
||||
{
|
||||
DWORD cbSize;
|
||||
DWORD ExtStatus;
|
||||
|
||||
} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT;
|
||||
#ifndef MSGFLT_ALLOW
|
||||
#define MSGFLT_ALLOW 1
|
||||
#endif
|
||||
#endif /*Windows 7*/
|
||||
|
||||
|
||||
//========================================================================
|
||||
@ -107,7 +122,9 @@ typedef DWORD (WINAPI * TIMEGETTIME_T) (void);
|
||||
|
||||
// user32.dll function pointer typedefs
|
||||
typedef BOOL (WINAPI * SETPROCESSDPIAWARE_T)(void);
|
||||
typedef BOOL (WINAPI * CHANGEWINDOWMESSAGEFILTEREX_T)(HWND,UINT,DWORD,PCHANGEFILTERSTRUCT);
|
||||
#define _glfw_SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware
|
||||
#define _glfw_ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx
|
||||
|
||||
// dwmapi.dll function pointer typedefs
|
||||
typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*);
|
||||
@ -192,6 +209,7 @@ typedef struct _GLFWlibraryWin32
|
||||
struct {
|
||||
HINSTANCE instance;
|
||||
SETPROCESSDPIAWARE_T SetProcessDPIAware;
|
||||
CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx;
|
||||
} user32;
|
||||
|
||||
// dwmapi.dll
|
||||
@ -238,17 +256,6 @@ void _glfwInitTimer(void);
|
||||
void _glfwInitJoysticks(void);
|
||||
void _glfwTerminateJoysticks(void);
|
||||
|
||||
// OpenGL support
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
int _glfwAnalyzeContext(const _GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
|
||||
// Fullscreen support
|
||||
GLboolean _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoMode(_GLFWmonitor* monitor);
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 Win32 - www.glfw.org
|
||||
// GLFW 3.1 Win32 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -30,6 +30,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <malloc.h>
|
||||
#include <windowsx.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
#define _GLFW_KEY_INVALID -2
|
||||
|
||||
@ -747,6 +748,40 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg,
|
||||
// TODO: Restore vsync if compositing was disabled
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_DROPFILES:
|
||||
{
|
||||
HDROP hDrop = (HDROP) wParam;
|
||||
POINT pt;
|
||||
int i;
|
||||
|
||||
const int count = DragQueryFile(hDrop, 0xffffffff, NULL, 0);
|
||||
char** names = calloc(count, sizeof(char*));
|
||||
|
||||
// Move the mouse to the position of the drop
|
||||
DragQueryPoint(hDrop, &pt);
|
||||
_glfwInputCursorMotion(window, pt.x, pt.y);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
const UINT length = DragQueryFile(hDrop, i, NULL, 0);
|
||||
WCHAR* buffer = calloc(length + 1, sizeof(WCHAR));
|
||||
|
||||
DragQueryFile(hDrop, i, buffer, length + 1);
|
||||
names[i] = _glfwCreateUTF8FromWideString(buffer);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) names);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
free(names[i]);
|
||||
free(names);
|
||||
|
||||
DragFinish(hDrop);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
@ -866,6 +901,18 @@ static int createWindow(_GLFWwindow* window,
|
||||
|
||||
free(wideTitle);
|
||||
|
||||
if (_glfw_ChangeWindowMessageFilterEx)
|
||||
{
|
||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_DROPFILES, MSGFLT_ALLOW, NULL);
|
||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_COPYDATA, MSGFLT_ALLOW, NULL);
|
||||
_glfw_ChangeWindowMessageFilterEx(window->win32.handle,
|
||||
WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL);
|
||||
}
|
||||
|
||||
DragAcceptFiles(window->win32.handle, TRUE);
|
||||
|
||||
if (!window->win32.handle)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create window");
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 - www.glfw.org
|
||||
// GLFW 3.1 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
//
|
||||
@ -38,27 +38,21 @@
|
||||
//
|
||||
void _glfwInitGammaRamp(void)
|
||||
{
|
||||
// RandR gamma support is only available with version 1.2 and above
|
||||
if (_glfw.x11.randr.available &&
|
||||
(_glfw.x11.randr.versionMajor > 1 ||
|
||||
(_glfw.x11.randr.versionMajor == 1 &&
|
||||
_glfw.x11.randr.versionMinor >= 2)))
|
||||
if (_glfw.x11.randr.available)
|
||||
{
|
||||
// FIXME: Assumes that all monitors have the same size gamma tables
|
||||
// This is reasonable as I suspect the that if they did differ, it
|
||||
// would imply that setting the gamma size to an arbitary size is
|
||||
// possible as well.
|
||||
XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display,
|
||||
XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display,
|
||||
_glfw.x11.root);
|
||||
|
||||
if (XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0]) == 0)
|
||||
if (!sr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, sr->crtcs[0]))
|
||||
{
|
||||
// This is probably older Nvidia RandR with broken gamma support
|
||||
// Flag it as useless and try Xf86VidMode below, if available
|
||||
// Flag it as useless and fall back to Xf86VidMode, if available
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: RandR gamma ramp support seems broken");
|
||||
_glfw.x11.randr.gammaBroken = GL_TRUE;
|
||||
}
|
||||
|
||||
XRRFreeScreenResources(rr);
|
||||
XRRFreeScreenResources(sr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -32,6 +32,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
// Translate an X11 key code to a GLFW key code.
|
||||
@ -358,6 +359,8 @@ static void detectEWMH(void)
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwGrabXErrorHandler();
|
||||
|
||||
// It should be the ID of a child window (of the root)
|
||||
// Then we look for the same property on the child window
|
||||
if (_glfwGetWindowProperty(*windowFromRoot,
|
||||
@ -370,6 +373,10 @@ static void detectEWMH(void)
|
||||
return;
|
||||
}
|
||||
|
||||
_glfwReleaseXErrorHandler();
|
||||
if (_glfw.x11.errorCode != Success)
|
||||
return;
|
||||
|
||||
// It should be the ID of that same child window
|
||||
if (*windowFromRoot != *windowFromChild)
|
||||
{
|
||||
@ -394,7 +401,6 @@ static void detectEWMH(void)
|
||||
(unsigned char**) &supportedAtoms);
|
||||
|
||||
// See which of the atoms we support that are supported by the WM
|
||||
|
||||
_glfw.x11.NET_WM_STATE =
|
||||
getSupportedAtom(supportedAtoms, atomCount, "_NET_WM_STATE");
|
||||
_glfw.x11.NET_WM_STATE_FULLSCREEN =
|
||||
@ -539,6 +545,17 @@ static GLboolean initExtensions(void)
|
||||
_glfw.x11.SAVE_TARGETS =
|
||||
XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False);
|
||||
|
||||
// Find Xdnd (drag and drop) atoms, if available
|
||||
_glfw.x11.XdndAware = XInternAtom(_glfw.x11.display, "XdndAware", True);
|
||||
_glfw.x11.XdndEnter = XInternAtom(_glfw.x11.display, "XdndEnter", True);
|
||||
_glfw.x11.XdndPosition = XInternAtom(_glfw.x11.display, "XdndPosition", True);
|
||||
_glfw.x11.XdndStatus = XInternAtom(_glfw.x11.display, "XdndStatus", True);
|
||||
_glfw.x11.XdndActionCopy = XInternAtom(_glfw.x11.display, "XdndActionCopy", True);
|
||||
_glfw.x11.XdndDrop = XInternAtom(_glfw.x11.display, "XdndDrop", True);
|
||||
_glfw.x11.XdndLeave = XInternAtom(_glfw.x11.display, "XdndLeave", True);
|
||||
_glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True);
|
||||
_glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True);
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -62,7 +62,7 @@ static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
|
||||
//
|
||||
void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
{
|
||||
if (_glfw.x11.randr.available)
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j;
|
||||
XRRScreenResources* sr;
|
||||
@ -136,7 +136,7 @@ void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired)
|
||||
//
|
||||
void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
||||
{
|
||||
if (_glfw.x11.randr.available)
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
@ -170,13 +170,13 @@ void _glfwRestoreVideoMode(_GLFWmonitor* monitor)
|
||||
|
||||
_GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
{
|
||||
int i, found = 0;
|
||||
_GLFWmonitor** monitors = NULL;
|
||||
|
||||
*count = 0;
|
||||
|
||||
if (_glfw.x11.randr.available)
|
||||
{
|
||||
int i, found = 0;
|
||||
RROutput primary;
|
||||
XRRScreenResources* sr;
|
||||
|
||||
@ -218,7 +218,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
continue;
|
||||
}
|
||||
|
||||
monitors[found] = _glfwCreateMonitor(oi->name,
|
||||
monitors[found] = _glfwAllocMonitor(oi->name,
|
||||
oi->mm_width, oi->mm_height);
|
||||
|
||||
monitors[found]->x11.output = output;
|
||||
@ -245,23 +245,27 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count)
|
||||
|
||||
if (found == 0)
|
||||
{
|
||||
_glfwInputError(GLFW_PLATFORM_ERROR,
|
||||
"X11: RandR monitor support seems broken");
|
||||
_glfw.x11.randr.monitorBroken = GL_TRUE;
|
||||
|
||||
free(monitors);
|
||||
monitors = NULL;
|
||||
}
|
||||
|
||||
*count = found;
|
||||
}
|
||||
else
|
||||
|
||||
if (!monitors)
|
||||
{
|
||||
monitors = calloc(1, sizeof(_GLFWmonitor*));
|
||||
monitors[0] = _glfwCreateMonitor("Display",
|
||||
monitors[0] = _glfwAllocMonitor("Display",
|
||||
DisplayWidthMM(_glfw.x11.display,
|
||||
_glfw.x11.screen),
|
||||
DisplayHeightMM(_glfw.x11.display,
|
||||
_glfw.x11.screen));
|
||||
*count = 1;
|
||||
found = 1;
|
||||
}
|
||||
|
||||
*count = found;
|
||||
return monitors;
|
||||
}
|
||||
|
||||
@ -272,7 +276,7 @@ GLboolean _glfwPlatformIsSameMonitor(_GLFWmonitor* first, _GLFWmonitor* second)
|
||||
|
||||
void _glfwPlatformGetMonitorPos(_GLFWmonitor* monitor, int* xpos, int* ypos)
|
||||
{
|
||||
if (_glfw.x11.randr.available)
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
@ -309,7 +313,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
|
||||
// Build array of available resolutions
|
||||
|
||||
if (_glfw.x11.randr.available)
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
int i, j;
|
||||
XRRScreenResources* sr;
|
||||
@ -375,7 +379,7 @@ GLFWvidmode* _glfwPlatformGetVideoModes(_GLFWmonitor* monitor, int* found)
|
||||
|
||||
void _glfwPlatformGetVideoMode(_GLFWmonitor* monitor, GLFWvidmode* mode)
|
||||
{
|
||||
if (_glfw.x11.randr.available)
|
||||
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
|
||||
{
|
||||
XRRScreenResources* sr;
|
||||
XRRCrtcInfo* ci;
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -119,7 +119,18 @@ typedef struct _GLFWlibraryX11
|
||||
Atom NET_ACTIVE_WINDOW;
|
||||
Atom MOTIF_WM_HINTS;
|
||||
|
||||
// Selection atoms
|
||||
// Xdnd (drag and drop) atoms
|
||||
Atom XdndAware;
|
||||
Atom XdndEnter;
|
||||
Atom XdndPosition;
|
||||
Atom XdndStatus;
|
||||
Atom XdndActionCopy;
|
||||
Atom XdndDrop;
|
||||
Atom XdndLeave;
|
||||
Atom XdndFinished;
|
||||
Atom XdndSelection;
|
||||
|
||||
// Selection (clipboard) atoms
|
||||
Atom TARGETS;
|
||||
Atom MULTIPLE;
|
||||
Atom CLIPBOARD;
|
||||
@ -149,6 +160,7 @@ typedef struct _GLFWlibraryX11
|
||||
int versionMajor;
|
||||
int versionMinor;
|
||||
GLboolean gammaBroken;
|
||||
GLboolean monitorBroken;
|
||||
} randr;
|
||||
|
||||
struct {
|
||||
@ -189,6 +201,10 @@ typedef struct _GLFWlibraryX11
|
||||
char* string;
|
||||
} selection;
|
||||
|
||||
struct {
|
||||
Window source;
|
||||
} xdnd;
|
||||
|
||||
struct {
|
||||
int present;
|
||||
int fd;
|
||||
@ -224,14 +240,6 @@ void _glfwInitTimer(void);
|
||||
// Gamma
|
||||
void _glfwInitGammaRamp(void);
|
||||
|
||||
// OpenGL support
|
||||
int _glfwInitContextAPI(void);
|
||||
void _glfwTerminateContextAPI(void);
|
||||
int _glfwCreateContext(_GLFWwindow* window,
|
||||
const _GLFWwndconfig* wndconfig,
|
||||
const _GLFWfbconfig* fbconfig);
|
||||
void _glfwDestroyContext(_GLFWwindow* window);
|
||||
|
||||
// Fullscreen support
|
||||
void _glfwSetVideoMode(_GLFWmonitor* monitor, const GLFWvidmode* desired);
|
||||
void _glfwRestoreVideoMode(_GLFWmonitor* monitor);
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
|
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -860,17 +860,18 @@ long _glfwKeySym2Unicode( KeySym keysym )
|
||||
int max = sizeof(keysymtab) / sizeof(struct codepair) - 1;
|
||||
int mid;
|
||||
|
||||
/* First check for Latin-1 characters (1:1 mapping) */
|
||||
// First check for Latin-1 characters (1:1 mapping)
|
||||
if ((keysym >= 0x0020 && keysym <= 0x007e) ||
|
||||
(keysym >= 0x00a0 && keysym <= 0x00ff))
|
||||
{ return keysym;
|
||||
{
|
||||
return keysym;
|
||||
}
|
||||
|
||||
/* Also check for directly encoded 24-bit UCS characters */
|
||||
// Also check for directly encoded 24-bit UCS characters
|
||||
if ((keysym & 0xff000000) == 0x01000000)
|
||||
return keysym & 0x00ffffff;
|
||||
|
||||
/* Binary search in table */
|
||||
// Binary search in table
|
||||
while (max >= min)
|
||||
{
|
||||
mid = (min + max) / 2;
|
||||
@ -879,13 +880,10 @@ long _glfwKeySym2Unicode( KeySym keysym )
|
||||
else if (keysymtab[mid].keysym > keysym)
|
||||
max = mid - 1;
|
||||
else
|
||||
{
|
||||
/* Found it! */
|
||||
return keysymtab[mid].ucs;
|
||||
}
|
||||
}
|
||||
|
||||
/* No matching Unicode value found */
|
||||
// No matching Unicode value found
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
149
src/x11_window.c
149
src/x11_window.c
@ -1,5 +1,5 @@
|
||||
//========================================================================
|
||||
// GLFW 3.0 X11 - www.glfw.org
|
||||
// GLFW 3.1 X11 - www.glfw.org
|
||||
//------------------------------------------------------------------------
|
||||
// Copyright (c) 2002-2006 Marcus Geelnard
|
||||
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
|
||||
@ -97,6 +97,51 @@ static int translateChar(XKeyEvent* event)
|
||||
return (int) _glfwKeySym2Unicode(keysym);
|
||||
}
|
||||
|
||||
// Splits a text/uri-list into separate file paths
|
||||
//
|
||||
static char** splitUriList(char* text, int* count)
|
||||
{
|
||||
const char* prefix = "file://";
|
||||
char** names = NULL;
|
||||
char* line;
|
||||
|
||||
*count = 0;
|
||||
|
||||
while ((line = strtok(text, "\r\n")))
|
||||
{
|
||||
text = NULL;
|
||||
|
||||
if (*line == '#')
|
||||
continue;
|
||||
|
||||
if (strncmp(line, prefix, strlen(prefix)) == 0)
|
||||
line += strlen(prefix);
|
||||
|
||||
(*count)++;
|
||||
|
||||
char* name = calloc(strlen(line) + 1, 1);
|
||||
names = realloc(names, *count * sizeof(char*));
|
||||
names[*count - 1] = name;
|
||||
|
||||
while (*line)
|
||||
{
|
||||
if (line[0] == '%' && line[1] && line[2])
|
||||
{
|
||||
const char digits[3] = { line[1], line[2], '\0' };
|
||||
*name = strtol(digits, NULL, 16);
|
||||
line += 2;
|
||||
}
|
||||
else
|
||||
*name = *line;
|
||||
|
||||
name++;
|
||||
line++;
|
||||
}
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
// Create the X11 window (and its colormap)
|
||||
//
|
||||
static GLboolean createWindow(_GLFWwindow* window,
|
||||
@ -306,6 +351,15 @@ static GLboolean createWindow(_GLFWwindow* window,
|
||||
XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1);
|
||||
}
|
||||
|
||||
if (_glfw.x11.XdndAware)
|
||||
{
|
||||
// Announce support for Xdnd (drag and drop)
|
||||
const Atom version = 5;
|
||||
XChangeProperty(_glfw.x11.display, window->x11.handle,
|
||||
_glfw.x11.XdndAware, XA_ATOM, 32,
|
||||
PropModeReplace, (unsigned char*) &version, 1);
|
||||
}
|
||||
|
||||
_glfwPlatformSetWindowTitle(window, wndconfig->title);
|
||||
|
||||
XRRSelectInput(_glfw.x11.display, window->x11.handle,
|
||||
@ -494,6 +548,7 @@ static void leaveFullscreenMode(_GLFWwindow* window)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Process the specified X event
|
||||
//
|
||||
static void processEvent(XEvent *event)
|
||||
@ -704,6 +759,95 @@ static void processEvent(XEvent *event)
|
||||
SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
event);
|
||||
}
|
||||
else if (event->xclient.message_type == _glfw.x11.XdndEnter)
|
||||
{
|
||||
// A drag operation has entered the window
|
||||
// TODO: Check if UTF-8 string is supported by the source
|
||||
}
|
||||
else if (event->xclient.message_type == _glfw.x11.XdndDrop)
|
||||
{
|
||||
// The drag operation has finished dropping on
|
||||
// the window, ask to convert it to a UTF-8 string
|
||||
_glfw.x11.xdnd.source = event->xclient.data.l[0];
|
||||
XConvertSelection(_glfw.x11.display,
|
||||
_glfw.x11.XdndSelection,
|
||||
_glfw.x11.UTF8_STRING,
|
||||
_glfw.x11.XdndSelection,
|
||||
window->x11.handle, CurrentTime);
|
||||
}
|
||||
else if (event->xclient.message_type == _glfw.x11.XdndPosition)
|
||||
{
|
||||
// The drag operation has moved over the window
|
||||
const int absX = (event->xclient.data.l[2] >> 16) & 0xFFFF;
|
||||
const int absY = (event->xclient.data.l[2]) & 0xFFFF;
|
||||
int x, y;
|
||||
|
||||
_glfwPlatformGetWindowPos(window, &x, &y);
|
||||
_glfwInputCursorMotion(window, absX - x, absY - y);
|
||||
|
||||
// Reply that we are ready to copy the dragged data
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
reply.type = ClientMessage;
|
||||
reply.xclient.window = event->xclient.data.l[0];
|
||||
reply.xclient.message_type = _glfw.x11.XdndStatus;
|
||||
reply.xclient.format = 32;
|
||||
reply.xclient.data.l[0] = window->x11.handle;
|
||||
reply.xclient.data.l[1] = 1; // Always accept the dnd with no rectangle
|
||||
reply.xclient.data.l[2] = 0; // Specify an empty rectangle
|
||||
reply.xclient.data.l[3] = 0;
|
||||
reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy;
|
||||
|
||||
XSendEvent(_glfw.x11.display, event->xclient.data.l[0],
|
||||
False, NoEventMask, &reply);
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SelectionNotify:
|
||||
{
|
||||
if (event->xselection.property)
|
||||
{
|
||||
// The converted data from the drag operation has arrived
|
||||
char* data;
|
||||
const int result = _glfwGetWindowProperty(event->xselection.requestor,
|
||||
event->xselection.property,
|
||||
event->xselection.target,
|
||||
(unsigned char**) &data);
|
||||
|
||||
if (result)
|
||||
{
|
||||
int i, count;
|
||||
char** names = splitUriList(data, &count);
|
||||
|
||||
_glfwInputDrop(window, count, (const char**) names);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
free(names[i]);
|
||||
free(names);
|
||||
}
|
||||
|
||||
XFree(data);
|
||||
|
||||
XEvent reply;
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
|
||||
reply.type = ClientMessage;
|
||||
reply.xclient.window = _glfw.x11.xdnd.source;
|
||||
reply.xclient.message_type = _glfw.x11.XdndFinished;
|
||||
reply.xclient.format = 32;
|
||||
reply.xclient.data.l[0] = window->x11.handle;
|
||||
reply.xclient.data.l[1] = result;
|
||||
reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy;
|
||||
|
||||
// Reply that all is well
|
||||
XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source,
|
||||
False, NoEventMask, &reply);
|
||||
XFlush(_glfw.x11.display);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
@ -897,7 +1041,7 @@ unsigned long _glfwGetWindowProperty(Window window,
|
||||
&bytesAfter,
|
||||
value);
|
||||
|
||||
if (actualType != type)
|
||||
if (type != AnyPropertyType && actualType != type)
|
||||
return 0;
|
||||
|
||||
return itemCount;
|
||||
@ -1001,7 +1145,6 @@ void _glfwPlatformGetWindowPos(_GLFWwindow* window, int* xpos, int* ypos)
|
||||
if (child)
|
||||
{
|
||||
int left, top;
|
||||
|
||||
XTranslateCoordinates(_glfw.x11.display, window->x11.handle, child,
|
||||
0, 0, &left, &top, &child);
|
||||
|
||||
|
@ -381,6 +381,16 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint)
|
||||
get_character_string(codepoint));
|
||||
}
|
||||
|
||||
static void drop_callback(GLFWwindow* window, int count, const char** names)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("%08x at %0.3f: Drop input\n", counter++, glfwGetTime());
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
printf(" %i: \"%s\"\n", i, names[i]);
|
||||
}
|
||||
|
||||
void monitor_callback(GLFWmonitor* monitor, int event)
|
||||
{
|
||||
if (event == GLFW_CONNECTED)
|
||||
@ -457,6 +467,7 @@ int main(int argc, char** argv)
|
||||
glfwSetScrollCallback(window, scroll_callback);
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
glfwSetCharCallback(window, char_callback);
|
||||
glfwSetDropCallback(window, drop_callback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwSwapInterval(1);
|
||||
|
Loading…
Reference in New Issue
Block a user