Merge remote-tracking branch 'upstream/master'

This commit is contained in:
David Avedissian 2014-02-13 12:04:26 +00:00
commit 588be5bb53
55 changed files with 928 additions and 496 deletions

View File

@ -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)

View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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

View File

@ -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)
*/

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.0 - www.glfw.org
// GLFW 3.1 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
//

View File

@ -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>
//

View File

@ -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>
//

View File

@ -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

View File

@ -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));

View File

@ -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;
}

View File

@ -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_

View File

@ -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>
//

View File

@ -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];

View File

@ -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>

View File

@ -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>

View File

@ -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_

View File

@ -1,5 +1,5 @@
//========================================================================
// GLFW 3.0 - www.glfw.org
// GLFW 3.1 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2010 Camilla Berglund <elmindreda@elmindreda.org>
//

View File

@ -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@

View File

@ -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

View File

@ -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>

View File

@ -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_

View File

@ -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;

View File

@ -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;
}

View File

@ -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_

View File

@ -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>

View File

@ -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);
}

View File

@ -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>
//

View File

@ -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_

View File

@ -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>

View File

@ -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>

View File

@ -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_

View File

@ -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>
//

View File

@ -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>
//

View File

@ -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");

View File

@ -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>

View File

@ -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));

View File

@ -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);

View File

@ -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>

View File

@ -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");

View File

@ -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>

View File

@ -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>
//

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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>

View File

@ -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;

View File

@ -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);

View File

@ -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>

View File

@ -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;
}

View File

@ -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);

View File

@ -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);