From 18c635f474d504f24e73cb22a3e6bf006dbeed41 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 14:16:51 +0100 Subject: [PATCH 01/39] Replaced Free Getopt with getopt_port. --- README.md | 2 +- deps/getopt.c | 467 +++++++++++++++++++++++--------------------------- deps/getopt.h | 94 +++++----- 3 files changed, 260 insertions(+), 303 deletions(-) diff --git a/README.md b/README.md index bd28c1548..06fa7d2da 100644 --- a/README.md +++ b/README.md @@ -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) diff --git a/deps/getopt.c b/deps/getopt.c index 7b3decd21..f7f667a98 100644 --- a/deps/getopt.c +++ b/deps/getopt.c @@ -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 -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* 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 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. -*/ -#ifndef _CRT_SECURE_NO_WARNINGS -#define _CRT_SECURE_NO_WARNINGS -#endif +/* 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: + * * 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. + * + * 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. + */ -#include -#include -#include #include "getopt.h" -/* 2013-01-06 Camilla Berglund - * - * Only define _CRT_SECURE_NO_WARNINGS if not already defined. - */ -/* 2012-08-12 Lambert Clara - * - * Constify third argument of getopt. - */ -/* 2011-07-27 Camilla Berglund - * - * Added _CRT_SECURE_NO_WARNINGS macro. - */ -/* 2009-10-12 Camilla Berglund - * - * Removed unused global static variable 'ID'. - */ +#include +#include -char* optarg = NULL; -int optind = 0; -int opterr = 1; -int optopt = '?'; +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** 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 char* optcursor = NULL; -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; -} +/* Implemented based on [1] and [2] for optional arguments. + optopt is handled FreeBSD-style, per [3]. + Other GNU and FreeBSD extensions are purely accidental. - -/* -* Permutes argv[] so that the argument currently being processed is moved -* to the end. +[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 */ -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]; +int getopt(int argc, char* const argv[], const char* optstring) { + int optchar = -1; + const char* optdecl = NULL; - /* 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; + optarg = NULL; + opterr = 0; + optopt = 0; - nonopt++; - return 0; - } + /* 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 (optcursor == NULL || *optcursor == '\0') + optcursor = argv[optind] + 1; + + optchar = *optcursor; + + /* FreeBSD: The variable optopt saves the last known option character + returned by getopt(). */ + optopt = optchar; + + /* 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. + + 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]. -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; - - /* Dash-dash check */ - if(argv[argv_index] && !strcmp(argv[argv_index], "--")) - { - dashdash = 1; - increment_index(); - } - - /* 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; - - /* 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; - - /* Grab the option */ - c = argv[argv_index][opt_offset++]; - - /* 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); - } - - 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 +[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; +} diff --git a/deps/getopt.h b/deps/getopt.h index 6d2e4afe3..e1eb540fd 100644 --- a/deps/getopt.h +++ b/deps/getopt.h @@ -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 -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* 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 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. -*/ -#ifndef GETOPT_H_ -#define GETOPT_H_ +/* 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: + * * 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. + * + * 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 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 From 7bbd3943c99737804b055655a6aee14773b00818 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 15:03:35 +0100 Subject: [PATCH 02/39] Removed superfluous display sorting. --- src/cocoa_monitor.m | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 77ff59dc8..400fa4ce9 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -278,17 +278,6 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) 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; - } - } - NSArray* screens = [NSScreen screens]; for (i = 0; i < monitorCount; i++) From 6eec7970c1b52f622a16be7cf5c8ea7655fa736c Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 15:14:14 +0100 Subject: [PATCH 03/39] Made NSScreen to CGDisplay matching fail softly. --- src/cocoa_monitor.m | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index 400fa4ce9..a44e8fb50 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -252,37 +252,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); + CGGetActiveDisplayList(displayCount, displays, &displayCount); - for (i = 0; i < monitorCount; i++) + NSArray* screens = [NSScreen screens]; + + for (i = 0; i < displayCount; i++) { + int j; 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); - - NSArray* screens = [NSScreen screens]; - - for (i = 0; i < monitorCount; i++) - { - int j; for (j = 0; j < [screens count]; j++) { @@ -290,26 +283,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; + _glfwDestroyMonitor(monitors[found]); + monitors[found] = NULL; } } - *count = monitorCount; + free(displays); + + *count = found; return monitors; } From beb7e5909f3c9a62c8d5f0233f12c633dd651aa1 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 15:17:28 +0100 Subject: [PATCH 04/39] Added comment on headless Macs. --- src/cocoa_monitor.m | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index a44e8fb50..cdf871278 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -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); From 0548c713e864c901f3622ac6117ef26d1ee078fa Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 15:23:11 +0100 Subject: [PATCH 05/39] Renamed monitor helper functions for clarity. --- src/cocoa_monitor.m | 6 +++--- src/init.c | 2 +- src/internal.h | 6 +++--- src/monitor.c | 12 ++++++------ src/win32_monitor.c | 4 ++-- src/x11_monitor.c | 14 +++++++------- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index cdf871278..a0d20ff63 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -273,8 +273,8 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) int j; const CGSize size = CGDisplayScreenSize(displays[i]); - monitors[found] = _glfwCreateMonitor(getDisplayName(displays[i]), - size.width, size.height); + monitors[found] = _glfwAllocMonitor(getDisplayName(displays[i]), + size.width, size.height); monitors[found]->ns.displayID = displays[i]; @@ -299,7 +299,7 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) "Cocoa: Failed to find NSScreen for CGDisplay %s", monitors[found]->name); - _glfwDestroyMonitor(monitors[found]); + _glfwFreeMonitor(monitors[found]); monitors[found] = NULL; } } diff --git a/src/init.c b/src/init.c index d34abea7a..ea826a0e4 100644 --- a/src/init.c +++ b/src/init.c @@ -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; diff --git a/src/internal.h b/src/internal.h index 748d27b11..ea95b0838 100644 --- a/src/internal.h +++ b/src/internal.h @@ -761,15 +761,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_ diff --git a/src/monitor.c b/src/monitor.c index f80d5e9d5..ecae3dd2f 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -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); } diff --git a/src/win32_monitor.c b/src/win32_monitor.c index fb62cc609..acd6d8207 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -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)); diff --git a/src/x11_monitor.c b/src/x11_monitor.c index 052b3c09a..e314c7b6f 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -218,8 +218,8 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) continue; } - monitors[found] = _glfwCreateMonitor(oi->name, - oi->mm_width, oi->mm_height); + monitors[found] = _glfwAllocMonitor(oi->name, + oi->mm_width, oi->mm_height); monitors[found]->x11.output = output; monitors[found]->x11.crtc = oi->crtc; @@ -254,11 +254,11 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) else { monitors = calloc(1, sizeof(_GLFWmonitor*)); - monitors[0] = _glfwCreateMonitor("Display", - DisplayWidthMM(_glfw.x11.display, - _glfw.x11.screen), - DisplayHeightMM(_glfw.x11.display, - _glfw.x11.screen)); + monitors[0] = _glfwAllocMonitor("Display", + DisplayWidthMM(_glfw.x11.display, + _glfw.x11.screen), + DisplayHeightMM(_glfw.x11.display, + _glfw.x11.screen)); *count = 1; } From 89d0723ba3c100b8f2bc7740ad874205e2d97005 Mon Sep 17 00:00:00 2001 From: arturo Date: Wed, 10 Jul 2013 11:42:14 +0200 Subject: [PATCH 06/39] Initial drag and drop support. --- include/GLFW/glfw3.h | 30 ++++++++++ src/cocoa_window.m | 78 +++++++++++++++++++++++++- src/input.c | 17 ++++++ src/internal.h | 9 +++ src/win32_init.c | 5 +- src/win32_platform.h | 2 + src/win32_window.c | 37 ++++++++++++ src/x11_init.c | 17 +++++- src/x11_platform.h | 18 ++++++ src/x11_window.c | 130 ++++++++++++++++++++++++++++++++++++++++++- 10 files changed, 338 insertions(+), 5 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index ed301997d..b229bb9e5 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -773,6 +773,20 @@ 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] string The string descriptor for the dropped object. + * + * @sa glfwSetDropCallback + * + * @ingroup input + */ +typedef void (* GLFWdropfun)(GLFWwindow*,const char*); + /*! @brief The function signature for monitor configuration callbacks. * * This is the function signature for monitor configuration callback functions. @@ -2014,6 +2028,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. diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 4b873fe96..eca989954 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -413,6 +413,8 @@ static int translateKey(unsigned int key) @interface GLFWContentView : NSView { _GLFWwindow* window; + char * fileNamesForDrag; + int fileNamesSize; NSTrackingArea* trackingArea; } @@ -443,8 +445,15 @@ static int translateKey(unsigned int key) { window = initWindow; trackingArea = nil; - + + fileNamesForDrag = (char*)malloc(1024); + fileNamesSize = 1024; + [self updateTrackingAreas]; + + + [self registerForDraggedTypes:[NSArray arrayWithObjects: + NSFilenamesPboardType, nil]]; } return self; @@ -453,6 +462,7 @@ static int translateKey(unsigned int key) -(void)dealloc { [trackingArea release]; + free(fileNamesForDrag); [super dealloc]; } @@ -657,6 +667,72 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } + +// arturoc: this makes the cursor dissapear when the window is +// resized or received a drag operation +/*- (void)resetCursorRects +{ + [self discardCursorRects]; + [self addCursorRect:[self bounds] cursor:_glfw.ns.cursor]; +}*/ + +- (NSDragOperation)draggingEntered:(id )sender +{ + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) { + + [self setNeedsDisplay:YES]; + + return NSDragOperationGeneric; + + } + + return NSDragOperationNone; +} + +- (BOOL)prepareForDragOperation:(id )sender { + [self setNeedsDisplay:YES]; + return YES; +} + +- (BOOL)performDragOperation:(id )sender { + NSPasteboard *zPasteboard = [sender draggingPasteboard]; + NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType]; + + // set the first char to 0 so strcat + // starts to add from the beginning + fileNamesForDrag[0] = 0; + + int dragX = [sender draggingLocation].x; + int dragY = [sender draggingLocation].y; + + int dragSize = 1; + if ([files count]) { + NSEnumerator *filenameEnum = [files objectEnumerator]; + NSString *name; + while (name = [filenameEnum nextObject]) { + dragSize += [name length]+1; + if (dragSize > fileNamesSize){ + fileNamesSize *= 2; + fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize); + } + strcat(fileNamesForDrag, [name UTF8String]); + strcat(fileNamesForDrag, "\n"); + } + } + + int height; + _glfwPlatformGetWindowSize(window, NULL, &height); + _glfwInputCursorMotion(window, dragX, height-dragY); + _glfwInputDrop(window, fileNamesForDrag); + + return YES; +} + +- (void)concludeDragOperation:(id )sender { + [self setNeedsDisplay:YES]; +} + @end diff --git a/src/input.c b/src/input.c index 9e628f062..b7e090c67 100644 --- a/src/input.c +++ b/src/input.c @@ -211,6 +211,12 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered) window->callbacks.cursorEnter((GLFWwindow*) window, entered); } +void _glfwInputDrop(_GLFWwindow* window, const char* dropString){ + + if (window->callbacks.drop) + window->callbacks.drop((GLFWwindow*) window, dropString); +} + ////////////////////////////////////////////////////////////////////////// ////// GLFW public API ////// @@ -394,3 +400,14 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, return cbfun; } +GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) +{ + _GLFWwindow* window = (_GLFWwindow*) handle; + GLFWdropfun previous; + + _GLFW_REQUIRE_INIT_OR_RETURN(NULL); + + previous = window->callbacks.drop; + window->callbacks.drop = cbfun; + return previous; +} diff --git a/src/internal.h b/src/internal.h index ea95b0838..08f849deb 100644 --- a/src/internal.h +++ b/src/internal.h @@ -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] dropString The string descriptor of the dropped object + * description. + * @ingroup event + */ +void _glfwInputDrop(_GLFWwindow* window, const char* dropString); + //======================================================================== // Utility functions diff --git a/src/win32_init.c b/src/win32_init.c index aae46a9b8..d7ed7938c 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -98,7 +98,7 @@ static GLboolean initLibraries(void) _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); } - + return GL_TRUE; } @@ -214,6 +214,9 @@ int _glfwPlatformInit(void) if (!_glfwInitContextAPI()) return GL_FALSE; + + _glfw.win32.dropString = (char*)malloc(1000); + _glfw.win32.dropStringSize = 1000; _glfwInitTimer(); _glfwInitJoysticks(); diff --git a/src/win32_platform.h b/src/win32_platform.h index 11d774b71..723da793b 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -169,6 +169,8 @@ typedef struct _GLFWlibraryWin32 ATOM classAtom; DWORD foregroundLockTimeout; char* clipboardString; + char* dropString; + int dropStringSize; // Timer data struct { diff --git a/src/win32_window.c b/src/win32_window.c index aa2aa4bbf..08108ed0f 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -29,7 +29,9 @@ #include #include +#include #include +#include #define _GLFW_KEY_INVALID -2 @@ -747,6 +749,39 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } + case WM_DROPFILES: + { + TCHAR szName[MAX_PATH]; + HDROP hDrop = (HDROP)wParam; + POINT pt; + int numFiles = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); + int currentSize = 1; + int i; + char* utf8str; + DragQueryPoint(hDrop, &pt); + + // Move the mouse to the position of the drop + _glfwInputCursorMotion(window,pt.x,pt.y); + + memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); + for(i = 0; i < numFiles; i++) + { + DragQueryFile(hDrop, i, szName, MAX_PATH); + utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName); + currentSize += strlen(utf8str); + if(_glfw.win32.dropStringSize < currentSize){ + _glfw.win32.dropStringSize *= 2; + _glfw.win32.dropString = (char*)realloc(_glfw.win32.dropString,_glfw.win32.dropStringSize); + } + strcat(_glfw.win32.dropString, utf8str); + strcat(_glfw.win32.dropString, "\n"); + free(utf8str); + } + + _glfwInputDrop(window,_glfw.win32.dropString); + DragFinish(hDrop); + break; + } } return DefWindowProc(hWnd, uMsg, wParam, lParam); @@ -865,6 +900,8 @@ static int createWindow(_GLFWwindow* window, window); // Pass object to WM_CREATE free(wideTitle); + + DragAcceptFiles(window->win32.handle, TRUE); if (!window->win32.handle) { diff --git a/src/x11_init.c b/src/x11_init.c index 5b477f045..22097afb5 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -32,6 +32,7 @@ #include #include #include +#include // Translate an X11 key code to a GLFW key code. @@ -394,7 +395,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 +539,21 @@ static GLboolean initExtensions(void) _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); + // Find or create drag and drop atoms + + //Atoms for Xdnd + _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; } diff --git a/src/x11_platform.h b/src/x11_platform.h index e1e1e7cc8..72db890e7 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -119,6 +119,24 @@ typedef struct _GLFWlibraryX11 Atom NET_ACTIVE_WINDOW; Atom MOTIF_WM_HINTS; + // Atoms for Xdnd + Atom XdndAware; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + struct{ + Window sourceWindow; + char* string; + char* type1; + char* type2; + char* type3; + } xdnd; + // Selection atoms Atom TARGETS; Atom MULTIPLE; diff --git a/src/x11_window.c b/src/x11_window.c index 0dd5f30e6..78082cd0e 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -306,6 +306,14 @@ static GLboolean createWindow(_GLFWwindow* window, XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } + // Enable Xdnd + if(_glfw.x11.XdndAware!=None) + { + //Announce XDND support + 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 +502,7 @@ static void leaveFullscreenMode(_GLFWwindow* window) } } + // Process the specified X event // static void processEvent(XEvent *event) @@ -703,10 +712,128 @@ static void processEvent(XEvent *event) False, SubstructureNotifyMask | SubstructureRedirectMask, event); + + } + else if(event->xclient.message_type == _glfw.x11.XdndEnter) + { + // Xdnd Enter: the drag&drop event has started in the window, + // we could be getting the type and possible conversions here + // but since we use always string conversion we don't need + // it + } + else if(event->xclient.message_type == _glfw.x11.XdndDrop) + { + // Xdnd Drop: The drag&drop event has finished dropping on + // the window, ask to convert the selection + _glfw.x11.xdnd.sourceWindow = 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.XdndLeave) + { + + } + else if(event->xclient.message_type == _glfw.x11.XdndPosition) + { + // Xdnd Position: get coordinates of the mouse inside the window + // and update the mouse position + int absX = (event->xclient.data.l[2]>>16) & 0xFFFF; + int absY = (event->xclient.data.l[2]) & 0xFFFF; + int x; + int y; + + _glfwPlatformGetWindowPos(window,&x,&y); + + _glfwInputCursorMotion(window,absX-x,absY-y); + + // Xdnd: reply with an XDND status message + XClientMessageEvent m; + memset(&m, sizeof(m), 0); + m.type = ClientMessage; + m.display = event->xclient.display; + m.window = event->xclient.data.l[0]; + m.message_type = _glfw.x11.XdndStatus; + m.format=32; + m.data.l[0] = window->x11.handle; + m.data.l[1] = 1; // Always accept the dnd with no rectangle + m.data.l[2] = 0; // Specify an empty rectangle + m.data.l[3] = 0; + m.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying + + XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); + XFlush(_glfw.x11.display); } break; } + case SelectionNotify: + { + if(event->xselection.property != None) + { + // Xdnd: got a selection notification from the conversion + // we asked for, get the data and finish the d&d event + char* data; + free(_glfw.x11.xdnd.string); + _glfw.x11.xdnd.string = NULL; + int result = _glfwGetWindowProperty(event->xselection.requestor, + event->xselection.property, + event->xselection.target, + (unsigned char**) &data); + + if(result){ + // nautilus seems to add a \r at the end of the paths + // remove it so paths can be directly used + _glfw.x11.xdnd.string = malloc(strlen(data)); + char *to = _glfw.x11.xdnd.string; + const char *from = data; + const char *current = strchr(from, '\r'); + while(current) + { + int charsToCopy = current - from; + memcpy(to, from, (size_t)charsToCopy); + to += charsToCopy; + + from = current+1; + current = strchr(from, '\r'); + } + + size_t remaining = strlen(from); + + memcpy(to, from, remaining); + to += remaining; + *to = 0; + } + + XClientMessageEvent m; + memset(&m, sizeof(m), 0); + m.type = ClientMessage; + m.display = _glfw.x11.display; + m.window = _glfw.x11.xdnd.sourceWindow; + m.message_type = _glfw.x11.XdndFinished; + m.format=32; + m.data.l[0] = window->x11.handle; + m.data.l[1] = result; + m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. + + // Reply that all is well. + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); + + XSync(_glfw.x11.display, False); + + XFree(data); + + if(result) + { + _glfwInputDrop(window,_glfw.x11.xdnd.string); + + } + } + break; + } case MapNotify: { @@ -897,7 +1024,7 @@ unsigned long _glfwGetWindowProperty(Window window, &bytesAfter, value); - if (actualType != type) + if (type != AnyPropertyType && actualType != type) return 0; return itemCount; @@ -1001,7 +1128,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); From 8ae063bb1b61cf0daa9c4d4c10d6a189e8cad121 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 16:38:56 +0100 Subject: [PATCH 07/39] Cleanup. --- src/cocoa_window.m | 88 ++++++++++---------- src/input.c | 13 ++- src/win32_init.c | 6 +- src/win32_window.c | 67 ++++++++------- src/x11_init.c | 4 - src/x11_platform.h | 29 +++---- src/x11_window.c | 197 ++++++++++++++++++++++----------------------- 7 files changed, 203 insertions(+), 201 deletions(-) diff --git a/src/cocoa_window.m b/src/cocoa_window.m index eca989954..4b14ef4a6 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -445,13 +445,11 @@ static int translateKey(unsigned int key) { window = initWindow; trackingArea = nil; - - fileNamesForDrag = (char*)malloc(1024); + + fileNamesForDrag = malloc(1024); fileNamesSize = 1024; - + [self updateTrackingAreas]; - - [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]]; } @@ -667,69 +665,75 @@ static int translateKey(unsigned int key) _glfwInputScroll(window, deltaX, deltaY); } - -// arturoc: this makes the cursor dissapear when the window is -// resized or received a drag operation -/*- (void)resetCursorRects +- (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 )sender { - if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) - == NSDragOperationGeneric) { - - [self setNeedsDisplay:YES]; - + if ((NSDragOperationGeneric & [sender draggingSourceOperationMask]) + == NSDragOperationGeneric) + { + [self setNeedsDisplay:YES]; return NSDragOperationGeneric; - } - - return NSDragOperationNone; + + return NSDragOperationNone; } -- (BOOL)prepareForDragOperation:(id )sender { +- (BOOL)prepareForDragOperation:(id )sender +{ [self setNeedsDisplay:YES]; return YES; } -- (BOOL)performDragOperation:(id )sender { - NSPasteboard *zPasteboard = [sender draggingPasteboard]; - NSArray *files = [zPasteboard propertyListForType:NSFilenamesPboardType]; - +- (BOOL)performDragOperation:(id )sender +{ + NSPasteboard* pasteboard = [sender draggingPasteboard]; + NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; + // set the first char to 0 so strcat // starts to add from the beginning - fileNamesForDrag[0] = 0; + fileNamesForDrag[0] = 0; - int dragX = [sender draggingLocation].x; - int dragY = [sender draggingLocation].y; - - int dragSize = 1; - if ([files count]) { - NSEnumerator *filenameEnum = [files objectEnumerator]; - NSString *name; - while (name = [filenameEnum nextObject]) { - dragSize += [name length]+1; - if (dragSize > fileNamesSize){ + const int dragX = [sender draggingLocation].x; + const int dragY = [sender draggingLocation].y; + int dragSize = 1; + + if ([files count]) + { + NSEnumerator* filenameEnum = [files objectEnumerator]; + NSString* name; + + while (name = [filenameEnum nextObject]) + { + dragSize += [name length] + 1; + + if (dragSize > fileNamesSize) + { fileNamesSize *= 2; fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize); } + strcat(fileNamesForDrag, [name UTF8String]); strcat(fileNamesForDrag, "\n"); - } - } - + } + } + int height; - _glfwPlatformGetWindowSize(window, NULL, &height); - _glfwInputCursorMotion(window, dragX, height-dragY); + _glfwPlatformGetWindowSize(window, NULL, &height); + _glfwInputCursorMotion(window, dragX, height - dragY); _glfwInputDrop(window, fileNamesForDrag); - - return YES; + + return YES; } -- (void)concludeDragOperation:(id )sender { +- (void)concludeDragOperation:(id )sender +{ [self setNeedsDisplay:YES]; } diff --git a/src/input.c b/src/input.c index b7e090c67..2fd23a122 100644 --- a/src/input.c +++ b/src/input.c @@ -211,8 +211,8 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered) window->callbacks.cursorEnter((GLFWwindow*) window, entered); } -void _glfwInputDrop(_GLFWwindow* window, const char* dropString){ - +void _glfwInputDrop(_GLFWwindow* window, const char* dropString) +{ if (window->callbacks.drop) window->callbacks.drop((GLFWwindow*) window, dropString); } @@ -403,11 +403,8 @@ GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle, GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun) { _GLFWwindow* window = (_GLFWwindow*) handle; - GLFWdropfun previous; - _GLFW_REQUIRE_INIT_OR_RETURN(NULL); - - previous = window->callbacks.drop; - window->callbacks.drop = cbfun; - return previous; + _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun); + return cbfun; } + diff --git a/src/win32_init.c b/src/win32_init.c index d7ed7938c..2063000e2 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -98,7 +98,7 @@ static GLboolean initLibraries(void) _glfw.win32.dwmapi.DwmIsCompositionEnabled = (DWMISCOMPOSITIONENABLED_T) GetProcAddress(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled"); } - + return GL_TRUE; } @@ -214,8 +214,8 @@ int _glfwPlatformInit(void) if (!_glfwInitContextAPI()) return GL_FALSE; - - _glfw.win32.dropString = (char*)malloc(1000); + + _glfw.win32.dropString = malloc(1000); _glfw.win32.dropStringSize = 1000; _glfwInitTimer(); diff --git a/src/win32_window.c b/src/win32_window.c index 08108ed0f..4cd69bc5c 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -749,38 +749,43 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, // TODO: Restore vsync if compositing was disabled break; } + case WM_DROPFILES: { - TCHAR szName[MAX_PATH]; - HDROP hDrop = (HDROP)wParam; - POINT pt; - int numFiles = DragQueryFile(hDrop, 0xFFFFFFFF, szName, MAX_PATH); - int currentSize = 1; - int i; - char* utf8str; - DragQueryPoint(hDrop, &pt); + WCHAR szName[MAX_PATH]; + HDROP hDrop = (HDROP) wParam; + POINT pt; + const int numFiles = DragQueryFile(hDrop, 0xffffffff, szName, MAX_PATH); + int i, currentSize = 1; + char* utf8str; - // Move the mouse to the position of the drop - _glfwInputCursorMotion(window,pt.x,pt.y); - - memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); - for(i = 0; i < numFiles; i++) - { - DragQueryFile(hDrop, i, szName, MAX_PATH); - utf8str = _glfwCreateUTF8FromWideString((const wchar_t*)szName); - currentSize += strlen(utf8str); - if(_glfw.win32.dropStringSize < currentSize){ - _glfw.win32.dropStringSize *= 2; - _glfw.win32.dropString = (char*)realloc(_glfw.win32.dropString,_glfw.win32.dropStringSize); - } - strcat(_glfw.win32.dropString, utf8str); - strcat(_glfw.win32.dropString, "\n"); - free(utf8str); - } - - _glfwInputDrop(window,_glfw.win32.dropString); - DragFinish(hDrop); - break; + // Move the mouse to the position of the drop + DragQueryPoint(hDrop, &pt); + _glfwInputCursorMotion(window, pt.x, pt.y); + + memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); + + for (i = 0; i < numFiles; i++) + { + DragQueryFile(hDrop, i, szName, MAX_PATH); + utf8str = _glfwCreateUTF8FromWideString((const WCHAR*) szName); + currentSize += strlen(utf8str); + + if (_glfw.win32.dropStringSize < currentSize) + { + _glfw.win32.dropStringSize *= 2; + _glfw.win32.dropString = realloc(_glfw.win32.dropString, + _glfw.win32.dropStringSize); + } + + strcat(_glfw.win32.dropString, utf8str); + strcat(_glfw.win32.dropString, "\n"); + free(utf8str); + } + + _glfwInputDrop(window,_glfw.win32.dropString); + DragFinish(hDrop); + break; } } @@ -900,8 +905,8 @@ static int createWindow(_GLFWwindow* window, window); // Pass object to WM_CREATE free(wideTitle); - - DragAcceptFiles(window->win32.handle, TRUE); + + DragAcceptFiles(window->win32.handle, TRUE); if (!window->win32.handle) { diff --git a/src/x11_init.c b/src/x11_init.c index 22097afb5..5571e08aa 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -540,8 +540,6 @@ static GLboolean initExtensions(void) XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); // Find or create drag and drop atoms - - //Atoms for Xdnd _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); @@ -552,8 +550,6 @@ static GLboolean initExtensions(void) _glfw.x11.XdndFinished = XInternAtom(_glfw.x11.display, "XdndFinished", True); _glfw.x11.XdndSelection = XInternAtom(_glfw.x11.display, "XdndSelection", True); - - return GL_TRUE; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 72db890e7..95682cf0c 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -121,20 +121,21 @@ typedef struct _GLFWlibraryX11 // Atoms for Xdnd Atom XdndAware; - Atom XdndEnter; - Atom XdndPosition; - Atom XdndStatus; - Atom XdndActionCopy; - Atom XdndDrop; - Atom XdndLeave; - Atom XdndFinished; - Atom XdndSelection; - struct{ - Window sourceWindow; - char* string; - char* type1; - char* type2; - char* type3; + Atom XdndEnter; + Atom XdndPosition; + Atom XdndStatus; + Atom XdndActionCopy; + Atom XdndDrop; + Atom XdndLeave; + Atom XdndFinished; + Atom XdndSelection; + + struct { + Window sourceWindow; + char* string; + char* type1; + char* type2; + char* type3; } xdnd; // Selection atoms diff --git a/src/x11_window.c b/src/x11_window.c index 78082cd0e..0d749bebe 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -306,12 +306,14 @@ static GLboolean createWindow(_GLFWwindow* window, XISelectEvents(_glfw.x11.display, window->x11.handle, &eventmask, 1); } - // Enable Xdnd - if(_glfw.x11.XdndAware!=None) + if (_glfw.x11.XdndAware) { - //Announce XDND support - Atom version=5; - XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, PropModeReplace, (unsigned char*)&version, 1); + // Announce support for XDND version 5 and below + + 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); @@ -714,126 +716,123 @@ static void processEvent(XEvent *event) event); } - else if(event->xclient.message_type == _glfw.x11.XdndEnter) + else if (event->xclient.message_type == _glfw.x11.XdndEnter) { - // Xdnd Enter: the drag&drop event has started in the window, - // we could be getting the type and possible conversions here - // but since we use always string conversion we don't need - // it + // Xdnd Enter: the drag&drop event has started in the window, we + // could be getting the type and possible conversions here but + // since we use always string conversion we don't need it } - else if(event->xclient.message_type == _glfw.x11.XdndDrop) + else if (event->xclient.message_type == _glfw.x11.XdndDrop) { - // Xdnd Drop: The drag&drop event has finished dropping on - // the window, ask to convert the selection - _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; - XConvertSelection(_glfw.x11.display, - _glfw.x11.XdndSelection, - _glfw.x11.UTF8_STRING, - _glfw.x11.XdndSelection, - window->x11.handle, CurrentTime); - + // Xdnd Drop: The drag&drop event has finished dropping on + // the window, ask to convert the selection + _glfw.x11.xdnd.sourceWindow = 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.XdndLeave) + else if (event->xclient.message_type == _glfw.x11.XdndLeave) { - } - else if(event->xclient.message_type == _glfw.x11.XdndPosition) + else if (event->xclient.message_type == _glfw.x11.XdndPosition) { - // Xdnd Position: get coordinates of the mouse inside the window - // and update the mouse position - int absX = (event->xclient.data.l[2]>>16) & 0xFFFF; - int absY = (event->xclient.data.l[2]) & 0xFFFF; - int x; - int y; + // Xdnd Position: get coordinates of the mouse inside the window + // and update the mouse position + 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); + _glfwPlatformGetWindowPos(window, &x, &y); + _glfwInputCursorMotion(window, absX - x, absY - y); - _glfwInputCursorMotion(window,absX-x,absY-y); + // Xdnd: reply with an XDND status message + XEvent reply; + memset(&reply, sizeof(reply), 0); - // Xdnd: reply with an XDND status message - XClientMessageEvent m; - memset(&m, sizeof(m), 0); - m.type = ClientMessage; - m.display = event->xclient.display; - m.window = event->xclient.data.l[0]; - m.message_type = _glfw.x11.XdndStatus; - m.format=32; - m.data.l[0] = window->x11.handle; - m.data.l[1] = 1; // Always accept the dnd with no rectangle - m.data.l[2] = 0; // Specify an empty rectangle - m.data.l[3] = 0; - m.data.l[4] = _glfw.x11.XdndActionCopy; // We only accept copying + 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; // We only accept copying - XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, (XEvent*)&m); - XFlush(_glfw.x11.display); + XSendEvent(_glfw.x11.display, window->x11.handle, + False, NoEventMask, &reply); + XFlush(_glfw.x11.display); } break; } + case SelectionNotify: - { - if(event->xselection.property != None) - { - // Xdnd: got a selection notification from the conversion - // we asked for, get the data and finish the d&d event - char* data; - free(_glfw.x11.xdnd.string); - _glfw.x11.xdnd.string = NULL; - int result = _glfwGetWindowProperty(event->xselection.requestor, - event->xselection.property, - event->xselection.target, - (unsigned char**) &data); + { + if (event->xselection.property != None) + { + // Xdnd: got a selection notification from the conversion + // we asked for, get the data and finish the d&d event + char* data; - if(result){ - // nautilus seems to add a \r at the end of the paths - // remove it so paths can be directly used - _glfw.x11.xdnd.string = malloc(strlen(data)); - char *to = _glfw.x11.xdnd.string; - const char *from = data; - const char *current = strchr(from, '\r'); - while(current) - { - int charsToCopy = current - from; - memcpy(to, from, (size_t)charsToCopy); - to += charsToCopy; + free(_glfw.x11.xdnd.string); + _glfw.x11.xdnd.string = NULL; - from = current+1; - current = strchr(from, '\r'); - } + const int result = _glfwGetWindowProperty(event->xselection.requestor, + event->xselection.property, + event->xselection.target, + (unsigned char**) &data); - size_t remaining = strlen(from); + if (result) + { + // Nautilus seems to add a \r at the end of the paths + // remove it so paths can be directly used + _glfw.x11.xdnd.string = malloc(strlen(data)); + char *to = _glfw.x11.xdnd.string; + const char *from = data; + const char *current = strchr(from, '\r'); - memcpy(to, from, remaining); - to += remaining; - *to = 0; - } + while (current) + { + const int charsToCopy = current - from; + memcpy(to, from, (size_t) charsToCopy); + to += charsToCopy; - XClientMessageEvent m; - memset(&m, sizeof(m), 0); - m.type = ClientMessage; - m.display = _glfw.x11.display; - m.window = _glfw.x11.xdnd.sourceWindow; - m.message_type = _glfw.x11.XdndFinished; - m.format=32; - m.data.l[0] = window->x11.handle; - m.data.l[1] = result; - m.data.l[2] = _glfw.x11.XdndActionCopy; //We only ever copy. + from = current + 1; + current = strchr(from, '\r'); + } - // Reply that all is well. - XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, (XEvent*)&m); + const size_t remaining = strlen(from); - XSync(_glfw.x11.display, False); + memcpy(to, from, remaining); + to += remaining; + *to = 0; + } - XFree(data); + XEvent reply; + memset(&reply, sizeof(reply), 0); + reply.type = ClientMessage; + reply.xclient.window = _glfw.x11.xdnd.sourceWindow; + 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; // We only ever copy - if(result) - { - _glfwInputDrop(window,_glfw.x11.xdnd.string); + // Reply that all is well + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, + False, NoEventMask, &reply); + XSync(_glfw.x11.display, False); + XFree(data); - } - } - break; - } + if (result) + _glfwInputDrop(window, _glfw.x11.xdnd.string); + } + + break; + } case MapNotify: { From ad9f880d619fbcd05585bf27b9954e2f57d879ff Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 16:40:06 +0100 Subject: [PATCH 08/39] Fixed broken calls to memset. --- src/x11_window.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/x11_window.c b/src/x11_window.c index 0d749bebe..e5bf436a7 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -749,7 +749,7 @@ static void processEvent(XEvent *event) // Xdnd: reply with an XDND status message XEvent reply; - memset(&reply, sizeof(reply), 0); + memset(&reply, 0, sizeof(reply)); reply.type = ClientMessage; reply.xclient.window = event->xclient.data.l[0]; @@ -812,7 +812,8 @@ static void processEvent(XEvent *event) } XEvent reply; - memset(&reply, sizeof(reply), 0); + memset(&reply, 0, sizeof(reply)); + reply.type = ClientMessage; reply.xclient.window = _glfw.x11.xdnd.sourceWindow; reply.xclient.message_type = _glfw.x11.XdndFinished; From 2b876da52ddc16a3aca9168e1cfb95fb568efd4f Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 16:47:03 +0100 Subject: [PATCH 09/39] Fixed broken includes. --- src/win32_window.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/win32_window.c b/src/win32_window.c index 4cd69bc5c..bcf82e1c5 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -29,9 +29,8 @@ #include #include -#include #include -#include +#include #define _GLFW_KEY_INVALID -2 From cd54dc84c4de9f78b2e0e1f019b2cb6c4fc099f4 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 20:03:55 +0100 Subject: [PATCH 10/39] Fixed off-by-one error. --- src/x11_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_window.c b/src/x11_window.c index e5bf436a7..31c13a8be 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -789,7 +789,7 @@ static void processEvent(XEvent *event) { // Nautilus seems to add a \r at the end of the paths // remove it so paths can be directly used - _glfw.x11.xdnd.string = malloc(strlen(data)); + _glfw.x11.xdnd.string = malloc(strlen(data) + 1); char *to = _glfw.x11.xdnd.string; const char *from = data; const char *current = strchr(from, '\r'); From ed4c8b27f1a748153cecf426e7566954b10f4b57 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 16:50:01 +0100 Subject: [PATCH 11/39] Added drop reporting to events test. --- tests/events.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/events.c b/tests/events.c index 7ac69c8e8..d5e2ce497 100644 --- a/tests/events.c +++ b/tests/events.c @@ -381,6 +381,14 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint) get_character_string(codepoint)); } +static void drop_callback(GLFWwindow* window, const char* descriptor) +{ + printf("%08x at %0.3f: Drop of \"%s\" input\n", + counter++, + glfwGetTime(), + descriptor); +} + void monitor_callback(GLFWmonitor* monitor, int event) { if (event == GLFW_CONNECTED) @@ -457,6 +465,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); From 8f349e84ae92671fd6756343d1661aa9f63d24d9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Sun, 22 Dec 2013 19:28:46 +0100 Subject: [PATCH 12/39] Cleaned up drop callback design. --- README.md | 1 + include/GLFW/glfw3.h | 5 ++- src/cocoa_window.m | 55 ++++++++++----------------- src/input.c | 4 +- src/internal.h | 6 +-- src/win32_init.c | 3 -- src/win32_platform.h | 2 - src/win32_window.c | 36 ++++++++---------- src/x11_platform.h | 4 -- src/x11_window.c | 88 +++++++++++++++++++++++++++----------------- tests/events.c | 12 +++--- 11 files changed, 106 insertions(+), 110 deletions(-) diff --git a/README.md b/README.md index 06fa7d2da..d5916f586 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,7 @@ 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] Bugfix: Using a 1x1 cursor for hidden mode caused some screen recorders to fail diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index b229bb9e5..c94c34818 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -779,13 +779,14 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * This is the function signature for drop callbacks. * * @param[in] window The window that received the event. - * @param[in] string The string descriptor for the dropped object. + * @param[in] count The number of dropped objects. + * @param[in] names The names of the dropped object. * * @sa glfwSetDropCallback * * @ingroup input */ -typedef void (* GLFWdropfun)(GLFWwindow*,const char*); +typedef void (* GLFWdropfun)(GLFWwindow*,int,const char**); /*! @brief The function signature for monitor configuration callbacks. * diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 4b14ef4a6..0af84e00c 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -413,8 +413,6 @@ static int translateKey(unsigned int key) @interface GLFWContentView : NSView { _GLFWwindow* window; - char * fileNamesForDrag; - int fileNamesSize; NSTrackingArea* trackingArea; } @@ -446,9 +444,6 @@ static int translateKey(unsigned int key) window = initWindow; trackingArea = nil; - fileNamesForDrag = malloc(1024); - fileNamesSize = 1024; - [self updateTrackingAreas]; [self registerForDraggedTypes:[NSArray arrayWithObjects: NSFilenamesPboardType, nil]]; @@ -460,7 +455,6 @@ static int translateKey(unsigned int key) -(void)dealloc { [trackingArea release]; - free(fileNamesForDrag); [super dealloc]; } @@ -696,38 +690,27 @@ static int translateKey(unsigned int key) NSPasteboard* pasteboard = [sender draggingPasteboard]; NSArray* files = [pasteboard propertyListForType:NSFilenamesPboardType]; - // set the first char to 0 so strcat - // starts to add from the beginning - fileNamesForDrag[0] = 0; - - const int dragX = [sender draggingLocation].x; - const int dragY = [sender draggingLocation].y; - int dragSize = 1; - - if ([files count]) - { - NSEnumerator* filenameEnum = [files objectEnumerator]; - NSString* name; - - while (name = [filenameEnum nextObject]) - { - dragSize += [name length] + 1; - - if (dragSize > fileNamesSize) - { - fileNamesSize *= 2; - fileNamesForDrag = realloc(fileNamesForDrag, fileNamesSize); - } - - strcat(fileNamesForDrag, [name UTF8String]); - strcat(fileNamesForDrag, "\n"); - } - } - int height; _glfwPlatformGetWindowSize(window, NULL, &height); - _glfwInputCursorMotion(window, dragX, height - dragY); - _glfwInputDrop(window, fileNamesForDrag); + _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; } diff --git a/src/input.c b/src/input.c index 2fd23a122..642c37f81 100644 --- a/src/input.c +++ b/src/input.c @@ -211,10 +211,10 @@ void _glfwInputCursorEnter(_GLFWwindow* window, int entered) window->callbacks.cursorEnter((GLFWwindow*) window, entered); } -void _glfwInputDrop(_GLFWwindow* window, const char* dropString) +void _glfwInputDrop(_GLFWwindow* window, int count, const char** names) { if (window->callbacks.drop) - window->callbacks.drop((GLFWwindow*) window, dropString); + window->callbacks.drop((GLFWwindow*) window, count, names); } diff --git a/src/internal.h b/src/internal.h index 08f849deb..a29703789 100644 --- a/src/internal.h +++ b/src/internal.h @@ -681,11 +681,11 @@ void _glfwInputError(int error, const char* format, ...); /*! @brief Notifies dropped object over window. * @param[in] window The window that received the event. - * @param[in] dropString The string descriptor of the dropped object - * description. + * @param[in] count The number of dropped objects. + * @param[in] names The names of the dropped objects. * @ingroup event */ -void _glfwInputDrop(_GLFWwindow* window, const char* dropString); +void _glfwInputDrop(_GLFWwindow* window, int count, const char** names); //======================================================================== diff --git a/src/win32_init.c b/src/win32_init.c index 2063000e2..aae46a9b8 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -215,9 +215,6 @@ int _glfwPlatformInit(void) if (!_glfwInitContextAPI()) return GL_FALSE; - _glfw.win32.dropString = malloc(1000); - _glfw.win32.dropStringSize = 1000; - _glfwInitTimer(); _glfwInitJoysticks(); diff --git a/src/win32_platform.h b/src/win32_platform.h index 723da793b..11d774b71 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -169,8 +169,6 @@ typedef struct _GLFWlibraryWin32 ATOM classAtom; DWORD foregroundLockTimeout; char* clipboardString; - char* dropString; - int dropStringSize; // Timer data struct { diff --git a/src/win32_window.c b/src/win32_window.c index bcf82e1c5..32e9376f6 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -751,38 +751,34 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, case WM_DROPFILES: { - WCHAR szName[MAX_PATH]; HDROP hDrop = (HDROP) wParam; POINT pt; - const int numFiles = DragQueryFile(hDrop, 0xffffffff, szName, MAX_PATH); - int i, currentSize = 1; - char* utf8str; + 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); - memset(_glfw.win32.dropString, 0, _glfw.win32.dropStringSize); - - for (i = 0; i < numFiles; i++) + for (i = 0; i < count; i++) { - DragQueryFile(hDrop, i, szName, MAX_PATH); - utf8str = _glfwCreateUTF8FromWideString((const WCHAR*) szName); - currentSize += strlen(utf8str); + const UINT length = DragQueryFile(hDrop, i, NULL, 0); + WCHAR* buffer = calloc(length + 1, sizeof(WCHAR)); - if (_glfw.win32.dropStringSize < currentSize) - { - _glfw.win32.dropStringSize *= 2; - _glfw.win32.dropString = realloc(_glfw.win32.dropString, - _glfw.win32.dropStringSize); - } + DragQueryFile(hDrop, i, buffer, length + 1); + names[i] = _glfwCreateUTF8FromWideString(buffer); - strcat(_glfw.win32.dropString, utf8str); - strcat(_glfw.win32.dropString, "\n"); - free(utf8str); + free(buffer); } - _glfwInputDrop(window,_glfw.win32.dropString); + _glfwInputDrop(window, count, (const char**) names); + + for (i = 0; i < count; i++) + free(names[i]); + free(names); + DragFinish(hDrop); break; } diff --git a/src/x11_platform.h b/src/x11_platform.h index 95682cf0c..603ad817a 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -132,10 +132,6 @@ typedef struct _GLFWlibraryX11 struct { Window sourceWindow; - char* string; - char* type1; - char* type2; - char* type3; } xdnd; // Selection atoms diff --git a/src/x11_window.c b/src/x11_window.c index 31c13a8be..774192792 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -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, @@ -714,7 +759,6 @@ static void processEvent(XEvent *event) False, SubstructureNotifyMask | SubstructureRedirectMask, event); - } else if (event->xclient.message_type == _glfw.x11.XdndEnter) { @@ -733,9 +777,6 @@ static void processEvent(XEvent *event) _glfw.x11.XdndSelection, window->x11.handle, CurrentTime); } - else if (event->xclient.message_type == _glfw.x11.XdndLeave) - { - } else if (event->xclient.message_type == _glfw.x11.XdndPosition) { // Xdnd Position: get coordinates of the mouse inside the window @@ -771,15 +812,12 @@ static void processEvent(XEvent *event) case SelectionNotify: { - if (event->xselection.property != None) + if (event->xselection.property) { // Xdnd: got a selection notification from the conversion // we asked for, get the data and finish the d&d event char* data; - free(_glfw.x11.xdnd.string); - _glfw.x11.xdnd.string = NULL; - const int result = _glfwGetWindowProperty(event->xselection.requestor, event->xselection.property, event->xselection.target, @@ -787,30 +825,18 @@ static void processEvent(XEvent *event) if (result) { - // Nautilus seems to add a \r at the end of the paths - // remove it so paths can be directly used - _glfw.x11.xdnd.string = malloc(strlen(data) + 1); - char *to = _glfw.x11.xdnd.string; - const char *from = data; - const char *current = strchr(from, '\r'); + int i, count; + char** names = splitUriList(data, &count); - while (current) - { - const int charsToCopy = current - from; - memcpy(to, from, (size_t) charsToCopy); - to += charsToCopy; + _glfwInputDrop(window, count, (const char**) names); - from = current + 1; - current = strchr(from, '\r'); - } - - const size_t remaining = strlen(from); - - memcpy(to, from, remaining); - to += remaining; - *to = 0; + for (i = 0; i < count; i++) + free(names[i]); + free(names); } + XFree(data); + XEvent reply; memset(&reply, 0, sizeof(reply)); @@ -825,11 +851,7 @@ static void processEvent(XEvent *event) // Reply that all is well XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, False, NoEventMask, &reply); - XSync(_glfw.x11.display, False); - XFree(data); - - if (result) - _glfwInputDrop(window, _glfw.x11.xdnd.string); + XFlush(_glfw.x11.display); } break; diff --git a/tests/events.c b/tests/events.c index d5e2ce497..28c70c274 100644 --- a/tests/events.c +++ b/tests/events.c @@ -381,12 +381,14 @@ static void char_callback(GLFWwindow* window, unsigned int codepoint) get_character_string(codepoint)); } -static void drop_callback(GLFWwindow* window, const char* descriptor) +static void drop_callback(GLFWwindow* window, int count, const char** names) { - printf("%08x at %0.3f: Drop of \"%s\" input\n", - counter++, - glfwGetTime(), - descriptor); + 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) From 313480a09c5a541c601a4f5aac2770f7ee393835 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 20:54:42 +0100 Subject: [PATCH 13/39] Added XDND note to conformance page. --- docs/compat.dox | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/compat.dox b/docs/compat.dox index e14263f6d..3dceb1933 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -48,6 +48,11 @@ 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. + @section compat_glx GLX extensions The GLX API is the default API used to create OpenGL contexts on Unix-like From 0b8cd09435a54ba352baa1b7ba6745da7d68ad1e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 20:57:18 +0100 Subject: [PATCH 14/39] Updated title of X11 conformance section. --- docs/compat.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/compat.dox b/docs/compat.dox index 3dceb1933..f9df20110 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -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 From d73e15d08f0ca859bdd93fb908a7d61b1052efee Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 20:59:54 +0100 Subject: [PATCH 15/39] Added mention of encoding to GLFWdropfun. --- include/GLFW/glfw3.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index c94c34818..7cd8e00fa 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -780,7 +780,7 @@ typedef void (* GLFWcharfun)(GLFWwindow*,unsigned int); * * @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 object. + * @param[in] names The UTF-8 encoded names of the dropped objects. * * @sa glfwSetDropCallback * From b4001b78b9b671d11d7902b98cbc03b11ac7f57a Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 21:15:53 +0100 Subject: [PATCH 16/39] X11 conformance updates. --- docs/compat.dox | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/docs/compat.dox b/docs/compat.dox index f9df20110..9353fab24 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -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/) From 2edc25b729e00ce56e9f2bea83425b3f9b8e9e2e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 21:33:11 +0100 Subject: [PATCH 17/39] Added extensions to X11 conformance section. --- docs/compat.dox | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/compat.dox b/docs/compat.dox index 9353fab24..7d8a5d7d4 100644 --- a/docs/compat.dox +++ b/docs/compat.dox @@ -62,6 +62,23 @@ GLFW uses the 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 From 040552fccaa05ed84af26a65182b5562e77a0dc4 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 21 Jan 2014 22:40:19 +0100 Subject: [PATCH 18/39] Added file drop support to news page. --- docs/news.dox | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/news.dox b/docs/news.dox index bbce25fd1..ff0918297 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -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 From 0163bc05d6b4d193251c5464e377bb25cebc077b Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 01:23:35 +0100 Subject: [PATCH 19/39] Moved internal context function declarations. --- src/cocoa_platform.h | 8 -------- src/egl_platform.h | 14 ++++++++++++++ src/glx_platform.h | 11 +++++++++++ src/nsgl_platform.h | 11 +++++++++++ src/wgl_platform.h | 14 ++++++++++++++ src/win32_platform.h | 11 ----------- src/x11_platform.h | 8 -------- 7 files changed, 50 insertions(+), 27 deletions(-) diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 0e92c4a25..4eb56e228 100644 --- a/src/cocoa_platform.h +++ b/src/cocoa_platform.h @@ -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_ diff --git a/src/egl_platform.h b/src/egl_platform.h index 1109eb9be..db9d837e5 100644 --- a/src/egl_platform.h +++ b/src/egl_platform.h @@ -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_ diff --git a/src/glx_platform.h b/src/glx_platform.h index 4b133a2d4..a8aaeeb6e 100644 --- a/src/glx_platform.h +++ b/src/glx_platform.h @@ -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_ diff --git a/src/nsgl_platform.h b/src/nsgl_platform.h index 31da2f675..79158b57e 100644 --- a/src/nsgl_platform.h +++ b/src/nsgl_platform.h @@ -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_ diff --git a/src/wgl_platform.h b/src/wgl_platform.h index bffdf742b..ae17a16ef 100644 --- a/src/wgl_platform.h +++ b/src/wgl_platform.h @@ -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_ diff --git a/src/win32_platform.h b/src/win32_platform.h index 11d774b71..7b626e8cf 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -238,17 +238,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); diff --git a/src/x11_platform.h b/src/x11_platform.h index 603ad817a..0f760e9c3 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -239,14 +239,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); From 611006af185ffd35b99173d4ec2fe22d55d5b230 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 01:32:00 +0100 Subject: [PATCH 20/39] Updated API version in comment headers. --- include/GLFW/glfw3.h | 2 +- src/clipboard.c | 2 +- src/cocoa_clipboard.m | 2 +- src/cocoa_gamma.c | 2 +- src/cocoa_init.m | 2 +- src/cocoa_joystick.m | 2 +- src/cocoa_monitor.m | 2 +- src/cocoa_platform.h | 2 +- src/cocoa_time.c | 2 +- src/cocoa_window.m | 2 +- src/context.c | 2 +- src/egl_context.c | 2 +- src/egl_platform.h | 2 +- src/gamma.c | 2 +- src/glx_context.c | 2 +- src/glx_platform.h | 2 +- src/init.c | 2 +- src/input.c | 2 +- src/internal.h | 2 +- src/joystick.c | 2 +- src/monitor.c | 2 +- src/nsgl_context.m | 2 +- src/nsgl_platform.h | 2 +- src/time.c | 2 +- src/wgl_context.c | 2 +- src/wgl_platform.h | 2 +- src/win32_clipboard.c | 2 +- src/win32_gamma.c | 2 +- src/win32_init.c | 2 +- src/win32_joystick.c | 2 +- src/win32_monitor.c | 2 +- src/win32_platform.h | 2 +- src/win32_time.c | 2 +- src/win32_window.c | 2 +- src/window.c | 2 +- src/x11_clipboard.c | 2 +- src/x11_gamma.c | 2 +- src/x11_init.c | 2 +- src/x11_joystick.c | 2 +- src/x11_monitor.c | 2 +- src/x11_platform.h | 2 +- src/x11_time.c | 2 +- src/x11_unicode.c | 2 +- src/x11_window.c | 2 +- 44 files changed, 44 insertions(+), 44 deletions(-) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index 7cd8e00fa..282443703 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -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 diff --git a/src/clipboard.c b/src/clipboard.c index f28c5c6ed..b5426c44f 100644 --- a/src/clipboard.c +++ b/src/clipboard.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 - www.glfw.org +// GLFW 3.1 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/cocoa_clipboard.m b/src/cocoa_clipboard.m index a58eb5c01..6af5df61f 100644 --- a/src/cocoa_clipboard.m +++ b/src/cocoa_clipboard.m @@ -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 // diff --git a/src/cocoa_gamma.c b/src/cocoa_gamma.c index f2905f4c1..85fb50ad4 100644 --- a/src/cocoa_gamma.c +++ b/src/cocoa_gamma.c @@ -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 // diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 42b31c54e..b60506325 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -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 // diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 7af1042b5..1e1576378 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -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 // Copyright (c) 2012 Torsten Walluhn diff --git a/src/cocoa_monitor.m b/src/cocoa_monitor.m index a0d20ff63..2f53a328b 100644 --- a/src/cocoa_monitor.m +++ b/src/cocoa_monitor.m @@ -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 diff --git a/src/cocoa_platform.h b/src/cocoa_platform.h index 4eb56e228..ea512e49c 100644 --- a/src/cocoa_platform.h +++ b/src/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 // diff --git a/src/cocoa_time.c b/src/cocoa_time.c index cb294cb65..0ecb4c132 100644 --- a/src/cocoa_time.c +++ b/src/cocoa_time.c @@ -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 // diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 0af84e00c..6e24fe784 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -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 // diff --git a/src/context.c b/src/context.c index 3bc86bc50..93b77d653 100644 --- a/src/context.c +++ b/src/context.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 diff --git a/src/egl_context.c b/src/egl_context.c index bab955ff3..f874f8ae8 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -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 diff --git a/src/egl_platform.h b/src/egl_platform.h index db9d837e5..38581aea8 100644 --- a/src/egl_platform.h +++ b/src/egl_platform.h @@ -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 diff --git a/src/gamma.c b/src/gamma.c index 8d7830401..a7ddfcd9f 100644 --- a/src/gamma.c +++ b/src/gamma.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 - www.glfw.org +// GLFW 3.1 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/glx_context.c b/src/glx_context.c index 6b87000da..5c4cf1d79 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -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 diff --git a/src/glx_platform.h b/src/glx_platform.h index a8aaeeb6e..f07029798 100644 --- a/src/glx_platform.h +++ b/src/glx_platform.h @@ -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 diff --git a/src/init.c b/src/init.c index ea826a0e4..4541462db 100644 --- a/src/init.c +++ b/src/init.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 diff --git a/src/input.c b/src/input.c index 642c37f81..493f2446e 100644 --- a/src/input.c +++ b/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 diff --git a/src/internal.h b/src/internal.h index a29703789..1e06460ee 100644 --- a/src/internal.h +++ b/src/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 diff --git a/src/joystick.c b/src/joystick.c index b53ea11d4..52aee9b62 100644 --- a/src/joystick.c +++ b/src/joystick.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 diff --git a/src/monitor.c b/src/monitor.c index ecae3dd2f..02f7c6af2 100644 --- a/src/monitor.c +++ b/src/monitor.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 diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 71638ad19..d3213dab2 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -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 // diff --git a/src/nsgl_platform.h b/src/nsgl_platform.h index 79158b57e..ad2ee782b 100644 --- a/src/nsgl_platform.h +++ b/src/nsgl_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 // diff --git a/src/time.c b/src/time.c index 6af4813da..1a8712584 100644 --- a/src/time.c +++ b/src/time.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 diff --git a/src/wgl_context.c b/src/wgl_context.c index 0b3610bd9..49e4f6274 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -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 diff --git a/src/wgl_platform.h b/src/wgl_platform.h index ae17a16ef..5e793410e 100644 --- a/src/wgl_platform.h +++ b/src/wgl_platform.h @@ -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 diff --git a/src/win32_clipboard.c b/src/win32_clipboard.c index 8fcba4679..1b7f97238 100644 --- a/src/win32_clipboard.c +++ b/src/win32_clipboard.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 Win32 - www.glfw.org +// GLFW 3.1 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/win32_gamma.c b/src/win32_gamma.c index b062bcf46..71abacc29 100644 --- a/src/win32_gamma.c +++ b/src/win32_gamma.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 Win32 - www.glfw.org +// GLFW 3.1 Win32 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/win32_init.c b/src/win32_init.c index aae46a9b8..47653a300 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -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 diff --git a/src/win32_joystick.c b/src/win32_joystick.c index 1a1723687..a68a9b4d1 100644 --- a/src/win32_joystick.c +++ b/src/win32_joystick.c @@ -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 diff --git a/src/win32_monitor.c b/src/win32_monitor.c index acd6d8207..ae4524609 100644 --- a/src/win32_monitor.c +++ b/src/win32_monitor.c @@ -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 diff --git a/src/win32_platform.h b/src/win32_platform.h index 7b626e8cf..5f781eb08 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -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 diff --git a/src/win32_time.c b/src/win32_time.c index 6c9089550..4331119bf 100644 --- a/src/win32_time.c +++ b/src/win32_time.c @@ -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 diff --git a/src/win32_window.c b/src/win32_window.c index 32e9376f6..3a0073d35 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -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 diff --git a/src/window.c b/src/window.c index 4e2b27701..03d08fa3b 100644 --- a/src/window.c +++ b/src/window.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 diff --git a/src/x11_clipboard.c b/src/x11_clipboard.c index 614ba363e..d8fd4d394 100644 --- a/src/x11_clipboard.c +++ b/src/x11_clipboard.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 X11 - www.glfw.org +// GLFW 3.1 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/x11_gamma.c b/src/x11_gamma.c index 1831263d7..8d3bb417b 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c @@ -1,5 +1,5 @@ //======================================================================== -// GLFW 3.0 X11 - www.glfw.org +// GLFW 3.1 X11 - www.glfw.org //------------------------------------------------------------------------ // Copyright (c) 2010 Camilla Berglund // diff --git a/src/x11_init.c b/src/x11_init.c index 5571e08aa..98df59631 100644 --- a/src/x11_init.c +++ b/src/x11_init.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 diff --git a/src/x11_joystick.c b/src/x11_joystick.c index 248ab127c..0c49e618d 100644 --- a/src/x11_joystick.c +++ b/src/x11_joystick.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 diff --git a/src/x11_monitor.c b/src/x11_monitor.c index e314c7b6f..b5113ca40 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.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 diff --git a/src/x11_platform.h b/src/x11_platform.h index 0f760e9c3..d798f521f 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -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 diff --git a/src/x11_time.c b/src/x11_time.c index d787d895d..da8350f5b 100644 --- a/src/x11_time.c +++ b/src/x11_time.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 diff --git a/src/x11_unicode.c b/src/x11_unicode.c index b847e0f69..445f14f00 100644 --- a/src/x11_unicode.c +++ b/src/x11_unicode.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 diff --git a/src/x11_window.c b/src/x11_window.c index 774192792..ff2963d36 100644 --- a/src/x11_window.c +++ b/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 From a4b8b0f114e3259679885bf913bfb14099e3da38 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 16:34:43 +0100 Subject: [PATCH 21/39] Removed superfluous test for RandR version. --- src/x11_gamma.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/x11_gamma.c b/src/x11_gamma.c index 8d3bb417b..734639c84 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c @@ -38,11 +38,7 @@ // 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 From 13156de8c3414ae40ccd34b5f71637bccfdc8db3 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 16:36:51 +0100 Subject: [PATCH 22/39] Updated stale X11 gamma comments. --- src/x11_gamma.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/x11_gamma.c b/src/x11_gamma.c index 734639c84..f86e96573 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c @@ -40,17 +40,13 @@ void _glfwInitGammaRamp(void) { 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, _glfw.x11.root); if (XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0]) == 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 _glfw.x11.randr.gammaBroken = GL_TRUE; } From dd02b96c94446a9101aa79665290407b19311d2d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 16:39:34 +0100 Subject: [PATCH 23/39] Added flag for non-functional RandR monitor path. --- README.md | 1 + src/x11_monitor.c | 24 ++++++++++++++---------- src/x11_platform.h | 1 + 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d5916f586..afbe8052e 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ The following dependencies are needed by the examples and test programs: - Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files - [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen recorders to fail + - [X11] Bugfix: The case of finding no usable CRTCs was not detected ## Contact diff --git a/src/x11_monitor.c b/src/x11_monitor.c index b5113ca40..97eaf1abc 100644 --- a/src/x11_monitor.c +++ b/src/x11_monitor.c @@ -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; @@ -245,13 +245,16 @@ _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] = _glfwAllocMonitor("Display", @@ -259,9 +262,10 @@ _GLFWmonitor** _glfwPlatformGetMonitors(int* count) _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; diff --git a/src/x11_platform.h b/src/x11_platform.h index d798f521f..b3ca83fb7 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -164,6 +164,7 @@ typedef struct _GLFWlibraryX11 int versionMajor; int versionMinor; GLboolean gammaBroken; + GLboolean monitorBroken; } randr; struct { From 5ed23e593c277fa8c6fc578acc52dd57d4e02c11 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 17:24:00 +0100 Subject: [PATCH 24/39] Handle case of no available CRTCs. --- README.md | 2 ++ src/x11_gamma.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index afbe8052e..914702bb4 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,8 @@ The following dependencies are needed by the examples and test programs: - [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen recorders to fail - [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 ## Contact diff --git a/src/x11_gamma.c b/src/x11_gamma.c index f86e96573..6fb1b741f 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c @@ -43,10 +43,12 @@ void _glfwInitGammaRamp(void) XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); - if (XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0]) == 0) + if (!rr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[0])) { // This is probably older Nvidia RandR with broken gamma support // 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; } From 58db8622bd0afdec6ecebd0d053d81c5ced58f5f Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 22 Jan 2014 01:34:44 +0100 Subject: [PATCH 25/39] Cleanup. --- src/x11_gamma.c | 6 +++--- src/x11_init.c | 2 +- src/x11_platform.h | 12 ++++++------ src/x11_unicode.c | 28 +++++++++++++--------------- src/x11_window.c | 31 +++++++++++++------------------ 5 files changed, 36 insertions(+), 43 deletions(-) diff --git a/src/x11_gamma.c b/src/x11_gamma.c index 6fb1b741f..2582500ac 100644 --- a/src/x11_gamma.c +++ b/src/x11_gamma.c @@ -40,10 +40,10 @@ void _glfwInitGammaRamp(void) { if (_glfw.x11.randr.available) { - XRRScreenResources* rr = XRRGetScreenResources(_glfw.x11.display, + XRRScreenResources* sr = XRRGetScreenResources(_glfw.x11.display, _glfw.x11.root); - if (!rr->ncrtc || !XRRGetCrtcGammaSize(_glfw.x11.display, rr->crtcs[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 fall back to Xf86VidMode, if available @@ -52,7 +52,7 @@ void _glfwInitGammaRamp(void) _glfw.x11.randr.gammaBroken = GL_TRUE; } - XRRFreeScreenResources(rr); + XRRFreeScreenResources(sr); } } diff --git a/src/x11_init.c b/src/x11_init.c index 98df59631..1f029791c 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -539,7 +539,7 @@ static GLboolean initExtensions(void) _glfw.x11.SAVE_TARGETS = XInternAtom(_glfw.x11.display, "SAVE_TARGETS", False); - // Find or create drag and drop atoms + // 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); diff --git a/src/x11_platform.h b/src/x11_platform.h index b3ca83fb7..398af82ad 100644 --- a/src/x11_platform.h +++ b/src/x11_platform.h @@ -119,7 +119,7 @@ typedef struct _GLFWlibraryX11 Atom NET_ACTIVE_WINDOW; Atom MOTIF_WM_HINTS; - // Atoms for Xdnd + // Xdnd (drag and drop) atoms Atom XdndAware; Atom XdndEnter; Atom XdndPosition; @@ -130,11 +130,7 @@ typedef struct _GLFWlibraryX11 Atom XdndFinished; Atom XdndSelection; - struct { - Window sourceWindow; - } xdnd; - - // Selection atoms + // Selection (clipboard) atoms Atom TARGETS; Atom MULTIPLE; Atom CLIPBOARD; @@ -205,6 +201,10 @@ typedef struct _GLFWlibraryX11 char* string; } selection; + struct { + Window source; + } xdnd; + struct { int present; int fd; diff --git a/src/x11_unicode.c b/src/x11_unicode.c index 445f14f00..6b6a13db6 100644 --- a/src/x11_unicode.c +++ b/src/x11_unicode.c @@ -854,38 +854,36 @@ static struct codepair { // Convert X11 KeySym to Unicode // -long _glfwKeySym2Unicode( KeySym keysym ) +long _glfwKeySym2Unicode(KeySym keysym) { int min = 0; int max = sizeof(keysymtab) / sizeof(struct codepair) - 1; int mid; - /* First check for Latin-1 characters (1:1 mapping) */ - if( (keysym >= 0x0020 && keysym <= 0x007e) || - (keysym >= 0x00a0 && keysym <= 0x00ff) ) - { return keysym; + // First check for Latin-1 characters (1:1 mapping) + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + { + return keysym; } - /* Also check for directly encoded 24-bit UCS characters */ - if( (keysym & 0xff000000) == 0x01000000 ) + // Also check for directly encoded 24-bit UCS characters + if ((keysym & 0xff000000) == 0x01000000) return keysym & 0x00ffffff; - /* Binary search in table */ - while( max >= min ) + // Binary search in table + while (max >= min) { mid = (min + max) / 2; - if( keysymtab[mid].keysym < keysym ) + if (keysymtab[mid].keysym < keysym) min = mid + 1; - else if( keysymtab[mid].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; } diff --git a/src/x11_window.c b/src/x11_window.c index ff2963d36..776fba38c 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -353,8 +353,7 @@ static GLboolean createWindow(_GLFWwindow* window, if (_glfw.x11.XdndAware) { - // Announce support for XDND version 5 and below - + // Announce support for Xdnd (drag and drop) const Atom version = 5; XChangeProperty(_glfw.x11.display, window->x11.handle, _glfw.x11.XdndAware, XA_ATOM, 32, @@ -762,15 +761,14 @@ static void processEvent(XEvent *event) } else if (event->xclient.message_type == _glfw.x11.XdndEnter) { - // Xdnd Enter: the drag&drop event has started in the window, we - // could be getting the type and possible conversions here but - // since we use always string conversion we don't need it + // 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) { - // Xdnd Drop: The drag&drop event has finished dropping on - // the window, ask to convert the selection - _glfw.x11.xdnd.sourceWindow = event->xclient.data.l[0]; + // 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, @@ -779,8 +777,7 @@ static void processEvent(XEvent *event) } else if (event->xclient.message_type == _glfw.x11.XdndPosition) { - // Xdnd Position: get coordinates of the mouse inside the window - // and update the mouse position + // 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; @@ -788,7 +785,7 @@ static void processEvent(XEvent *event) _glfwPlatformGetWindowPos(window, &x, &y); _glfwInputCursorMotion(window, absX - x, absY - y); - // Xdnd: reply with an XDND status message + // Reply that we are ready to copy the dragged data XEvent reply; memset(&reply, 0, sizeof(reply)); @@ -800,7 +797,7 @@ static void processEvent(XEvent *event) 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; // We only accept copying + reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; XSendEvent(_glfw.x11.display, window->x11.handle, False, NoEventMask, &reply); @@ -814,10 +811,8 @@ static void processEvent(XEvent *event) { if (event->xselection.property) { - // Xdnd: got a selection notification from the conversion - // we asked for, get the data and finish the d&d event + // The converted data from the drag operation has arrived char* data; - const int result = _glfwGetWindowProperty(event->xselection.requestor, event->xselection.property, event->xselection.target, @@ -841,15 +836,15 @@ static void processEvent(XEvent *event) memset(&reply, 0, sizeof(reply)); reply.type = ClientMessage; - reply.xclient.window = _glfw.x11.xdnd.sourceWindow; + 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; // We only ever copy + reply.xclient.data.l[2] = _glfw.x11.XdndActionCopy; // Reply that all is well - XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.sourceWindow, + XSendEvent(_glfw.x11.display, _glfw.x11.xdnd.source, False, NoEventMask, &reply); XFlush(_glfw.x11.display); } From 1d3f3e65a002514b6a1db3a4838771cca7e79580 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Fri, 24 Jan 2014 02:28:56 +0100 Subject: [PATCH 26/39] Added high-DPI note to transition guide. --- docs/moving.dox | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/moving.dox b/docs/moving.dox index 8d5c2e83c..04f7e7dc4 100644 --- a/docs/moving.dox +++ b/docs/moving.dox @@ -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. From 5114339136a59474fe5a94f2e9d0fada7c4fc680 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Fri, 24 Jan 2014 02:29:15 +0100 Subject: [PATCH 27/39] Added high-DPI viewport note to news. --- docs/news.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/news.dox b/docs/news.dox index ff0918297..b02861ec6 100644 --- a/docs/news.dox +++ b/docs/news.dox @@ -88,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 From a70bcb97bb42241795b5cb62c3e0804ccb262af6 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Wed, 29 Jan 2014 15:14:49 +0100 Subject: [PATCH 28/39] Added missing winmm loading errors. --- README.md | 2 ++ src/win32_init.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 914702bb4..5fc1194ec 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,8 @@ The following dependencies are needed by the examples and test programs: - Added `glfwSetDropCallback` and `GLFWdropfun` for receiving dropped files - [Cocoa] Bugfix: Using a 1x1 cursor for hidden mode caused some screen recorders to fail + - [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 diff --git a/src/win32_init.c b/src/win32_init.c index 47653a300..94190398f 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -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 From b4c03b992cb6ccd2380b726dcc0e7dfb145bdb64 Mon Sep 17 00:00:00 2001 From: Shane Liesegang Date: Thu, 6 Feb 2014 09:37:37 -0800 Subject: [PATCH 29/39] Fixing memory leak in cocoa_joystick Making sure that propsRef and valueRef get released no matter when we break out of the loop. Resolves #231. --- src/cocoa_joystick.m | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/cocoa_joystick.m b/src/cocoa_joystick.m index 1e1576378..dc798b8be 100644 --- a/src/cocoa_joystick.m +++ b/src/cocoa_joystick.m @@ -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)); From 84377c6175e566607255002a32827f843270517d Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 13:45:13 +0100 Subject: [PATCH 30/39] Added _GLFW_USE_RETINA. --- CMakeLists.txt | 5 +++++ README.md | 2 ++ docs/compile.dox | 5 +++++ src/cocoa_init.m | 3 +++ src/cocoa_window.m | 2 ++ src/glfw_config.h.in | 2 ++ 6 files changed, 19 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index dcc7c59d6..60f23022c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() @@ -340,6 +341,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) diff --git a/README.md b/README.md index 5fc1194ec..c41e0aec3 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,8 @@ The following dependencies are needed by the examples and test programs: - 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 - [Win32] Bugfix: Failure to load winmm or its functions was not reported to diff --git a/docs/compile.dox b/docs/compile.dox index ef6c3b931..dee7bd9c3 100644 --- a/docs/compile.dox +++ b/docs/compile.dox @@ -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) */ diff --git a/src/cocoa_init.m b/src/cocoa_init.m index b60506325..afb1a542a 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -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 diff --git a/src/cocoa_window.m b/src/cocoa_window.m index 6e24fe784..b0f59e905 100644 --- a/src/cocoa_window.m +++ b/src/cocoa_window.m @@ -940,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]; diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index a7318602e..e49532452 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -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_MENUBAR // Define this to 1 if using OpenGL as the client library #cmakedefine _GLFW_USE_OPENGL From 9cc8107c6b9177e2fc7e09c71daf649c21c95ad7 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 14:19:11 +0100 Subject: [PATCH 31/39] Fixed X11 drop support. This was broken by 8ae063bb1b61cf0daa9c4d4c10d6a189e8cad121. Fixes #224. --- src/x11_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/x11_window.c b/src/x11_window.c index 776fba38c..fd7fbd219 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -799,7 +799,7 @@ static void processEvent(XEvent *event) reply.xclient.data.l[3] = 0; reply.xclient.data.l[4] = _glfw.x11.XdndActionCopy; - XSendEvent(_glfw.x11.display, window->x11.handle, + XSendEvent(_glfw.x11.display, event->xclient.data.l[0], False, NoEventMask, &reply); XFlush(_glfw.x11.display); } From 6fef0f1351b4238d3dee9ae180414549a7fad16a Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 14:27:49 +0100 Subject: [PATCH 32/39] Updated changelog to include #231. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c41e0aec3..37653e0a1 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,8 @@ The following dependencies are needed by the examples and test programs: 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] 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 From cf177905e506cdd21e86896e24201230aff953d9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 15:03:23 +0100 Subject: [PATCH 33/39] Allowed drops from less privileged processes. By default, UAC will prevent less privileged processes from sending these messages. This resolves that on Windows 7 and later. Windows Vista is still affected by this issue, as it has UAC but lacks ChangeWindowMessageFilterEx. Fixes #227. --- src/win32_init.c | 2 ++ src/win32_platform.h | 17 +++++++++++++++++ src/win32_window.c | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/src/win32_init.c b/src/win32_init.c index 94190398f..cc33bc38c 100644 --- a/src/win32_init.c +++ b/src/win32_init.c @@ -96,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"); diff --git a/src/win32_platform.h b/src/win32_platform.h index 5f781eb08..c0395bb90 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -77,6 +77,20 @@ #ifndef WM_DWMCOMPOSITIONCHANGED #define WM_DWMCOMPOSITIONCHANGED 0x031E #endif +#ifndef WM_COPYGLOBALDATA + #define WM_COPYGLOBALDATA 0x0049 +#endif +#ifndef MSGFLT_ALLOW + #define MSGFLT_ALLOW 1 +#endif + +#if defined(__MINGW32__) +typedef struct tagCHANGEFILTERSTRUCT +{ + DWORD cbSize; + DWORD ExtStatus; +} CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT; +#endif /*__MINGW32__*/ //======================================================================== @@ -107,7 +121,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 +208,7 @@ typedef struct _GLFWlibraryWin32 struct { HINSTANCE instance; SETPROCESSDPIAWARE_T SetProcessDPIAware; + CHANGEWINDOWMESSAGEFILTEREX_T ChangeWindowMessageFilterEx; } user32; // dwmapi.dll diff --git a/src/win32_window.c b/src/win32_window.c index 3a0073d35..87831d213 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -901,6 +901,16 @@ 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) From 0cd31782d480f6a81369f09ffeb0f7da7eed4da7 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 15:30:51 +0100 Subject: [PATCH 34/39] Enabled pkg-config file generation on MinGW. Fixes #220. --- CMakeLists.txt | 25 +++++++++++++------------ README.md | 1 + 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 60f23022c..d10f10dc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,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) @@ -180,8 +183,12 @@ 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() #-------------------------------------------------------------------- @@ -308,9 +315,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() + set(GLFW_PKG_DEPS "${GLFW_PKG_DEPS} egl") if (_GLFW_USE_OPENGL) list(APPEND glfw_LIBRARIES ${OPENGL_gl_LIBRARY}) @@ -397,10 +402,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() +configure_file(${GLFW_SOURCE_DIR}/src/glfw3.pc.in + ${GLFW_BINARY_DIR}/src/glfw3.pc @ONLY) #-------------------------------------------------------------------- # Add subdirectories @@ -431,11 +434,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() + install(EXPORT glfwTargets DESTINATION lib${LIB_SUFFIX}/cmake/glfw) + install(FILES ${GLFW_BINARY_DIR}/src/glfw3.pc + DESTINATION lib${LIB_SUFFIX}/pkgconfig) # Only generate this target if no higher-level project already has if (NOT TARGET uninstall) diff --git a/README.md b/README.md index 37653e0a1..df5337cd0 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ The following dependencies are needed by the examples and test programs: 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 From c1446618cf7d1aad8d9b52c3405390f5e3c1d71e Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 15:33:41 +0100 Subject: [PATCH 35/39] Blurb nomenclature fix. --- README.md | 2 +- src/glfw3.pc.in | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index df5337cd0..1056e140f 100644 --- a/README.md +++ b/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. diff --git a/src/glfw3.pc.in b/src/glfw3.pc.in index d56a4944c..f2e4d9769 100644 --- a/src/glfw3.pc.in +++ b/src/glfw3.pc.in @@ -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@ From 9beba1ba31fc50c7fd22222186f36dc04743bbb2 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 19:10:57 +0100 Subject: [PATCH 36/39] Fixed copypaste mistake. --- src/glfw_config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/glfw_config.h.in b/src/glfw_config.h.in index e49532452..7234eb954 100644 --- a/src/glfw_config.h.in +++ b/src/glfw_config.h.in @@ -74,7 +74,7 @@ // 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_MENUBAR +#cmakedefine _GLFW_USE_RETINA // Define this to 1 if using OpenGL as the client library #cmakedefine _GLFW_USE_OPENGL From d0d2332193a1152b84d708691b3512dff6decece Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Mon, 10 Feb 2014 21:12:20 +0100 Subject: [PATCH 37/39] WINVER fixes for MinGW and VC++. --- CMakeLists.txt | 5 +++-- src/win32_platform.h | 11 ++++++----- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d10f10dc6..22a3ef36b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -175,8 +175,9 @@ 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() #-------------------------------------------------------------------- diff --git a/src/win32_platform.h b/src/win32_platform.h index c0395bb90..ce80e4d80 100644 --- a/src/win32_platform.h +++ b/src/win32_platform.h @@ -80,17 +80,18 @@ #ifndef WM_COPYGLOBALDATA #define WM_COPYGLOBALDATA 0x0049 #endif -#ifndef MSGFLT_ALLOW - #define MSGFLT_ALLOW 1 -#endif -#if defined(__MINGW32__) +#if WINVER < 0x0601 typedef struct tagCHANGEFILTERSTRUCT { DWORD cbSize; DWORD ExtStatus; + } CHANGEFILTERSTRUCT, *PCHANGEFILTERSTRUCT; -#endif /*__MINGW32__*/ +#ifndef MSGFLT_ALLOW + #define MSGFLT_ALLOW 1 +#endif +#endif /*Windows 7*/ //======================================================================== From 7f4e947447cb4d0968f47934124a08738de2736b Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 11 Feb 2014 00:56:52 +0100 Subject: [PATCH 38/39] Fixed return value for WM_DROPFILES. --- src/win32_window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/win32_window.c b/src/win32_window.c index 87831d213..ae520c447 100644 --- a/src/win32_window.c +++ b/src/win32_window.c @@ -780,7 +780,7 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, free(names); DragFinish(hDrop); - break; + return 0; } } From 69e10b88b0a62542fe2324290637d76c565382f9 Mon Sep 17 00:00:00 2001 From: Camilla Berglund Date: Tue, 11 Feb 2014 15:46:54 +0100 Subject: [PATCH 39/39] Fixed uncaught BadWindow in EWMH check. Fixes #234. --- README.md | 2 ++ src/x11_init.c | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/README.md b/README.md index 1056e140f..80bc5c8d4 100644 --- a/README.md +++ b/README.md @@ -59,6 +59,8 @@ The following dependencies are needed by the examples and test programs: - [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 diff --git a/src/x11_init.c b/src/x11_init.c index 1f029791c..84ecbf523 100644 --- a/src/x11_init.c +++ b/src/x11_init.c @@ -359,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, @@ -371,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) {