This commit is contained in:
2025-01-31 11:09:17 +01:00
commit e1f0406449
151 changed files with 658550 additions and 0 deletions

230
raylib/external/glfw/deps/getopt.c vendored Normal file
View File

@@ -0,0 +1,230 @@
/* 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 "getopt.h"
#include <stddef.h>
#include <string.h>
const int no_argument = 0;
const int required_argument = 1;
const int optional_argument = 2;
char* optarg;
int optopt;
/* The variable optind [...] shall be initialized to 1 by the system. */
int optind = 1;
int opterr;
static char* optcursor = NULL;
/* Implemented based on [1] and [2] for optional arguments.
optopt is handled FreeBSD-style, per [3].
Other GNU and FreeBSD extensions are purely accidental.
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
*/
int getopt(int argc, char* const argv[], const char* optstring) {
int optchar = -1;
const char* optdecl = NULL;
optarg = NULL;
opterr = 0;
optopt = 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].
[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 = (int) (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;
}

57
raylib/external/glfw/deps/getopt.h vendored Normal file
View File

@@ -0,0 +1,57 @@
/* 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
#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, opterr, optopt;
struct option {
const char* name;
int has_arg;
int* flag;
int val;
};
int getopt(int argc, char* const argv[], const char* optstring);
int getopt_long(int argc, char* const argv[],
const char* optstring, const struct option* longopts, int* longindex);
#if defined(__cplusplus)
}
#endif
#endif // INCLUDED_GETOPT_PORT_H

5996
raylib/external/glfw/deps/glad/gl.h vendored Normal file

File diff suppressed because it is too large Load Diff

1805
raylib/external/glfw/deps/glad/gles2.h vendored Normal file

File diff suppressed because it is too large Load Diff

6330
raylib/external/glfw/deps/glad/vulkan.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
/**
* This file has no copyright assigned and is placed in the Public Domain.
* This file is part of the mingw-w64 runtime package.
* No warranty is given; refer to the file DISCLAIMER within this package.
*/
#if defined(_MSC_VER) && !defined(_MSC_EXTENSIONS)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSSTRUCT) && \
!defined(NONAMELESSUNION)
#define NONAMELESSUNION 1
#endif
#if defined(NONAMELESSUNION) && \
!defined(NONAMELESSSTRUCT)
#define NONAMELESSSTRUCT 1
#endif
#if !defined(__GNU_EXTENSION)
#if defined(__GNUC__) || defined(__GNUG__)
#define __GNU_EXTENSION __extension__
#else
#define __GNU_EXTENSION
#endif
#endif /* __extension__ */
#ifndef __ANONYMOUS_DEFINED
#define __ANONYMOUS_DEFINED
#if defined(__GNUC__) || defined(__GNUG__)
#define _ANONYMOUS_UNION __extension__
#define _ANONYMOUS_STRUCT __extension__
#else
#define _ANONYMOUS_UNION
#define _ANONYMOUS_STRUCT
#endif
#ifndef NONAMELESSUNION
#define _UNION_NAME(x)
#define _STRUCT_NAME(x)
#else /* NONAMELESSUNION */
#define _UNION_NAME(x) x
#define _STRUCT_NAME(x) x
#endif
#endif /* __ANONYMOUS_DEFINED */
#ifndef DUMMYUNIONNAME
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME u
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# define DUMMYUNIONNAME2 u2
# define DUMMYUNIONNAME3 u3
# define DUMMYUNIONNAME4 u4
# define DUMMYUNIONNAME5 u5
# define DUMMYUNIONNAME6 u6
# define DUMMYUNIONNAME7 u7
# define DUMMYUNIONNAME8 u8
# define DUMMYUNIONNAME9 u9
# else /* NONAMELESSUNION */
# define DUMMYUNIONNAME
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# define DUMMYUNIONNAME2
# define DUMMYUNIONNAME3
# define DUMMYUNIONNAME4
# define DUMMYUNIONNAME5
# define DUMMYUNIONNAME6
# define DUMMYUNIONNAME7
# define DUMMYUNIONNAME8
# define DUMMYUNIONNAME9
# endif
#endif /* DUMMYUNIONNAME */
#if !defined(DUMMYUNIONNAME1) /* MinGW does not define this one */
# ifdef NONAMELESSUNION
# define DUMMYUNIONNAME1 u1 /* Wine uses this variant */
# else
# define DUMMYUNIONNAME1 /* Wine uses this variant */
# endif
#endif /* DUMMYUNIONNAME1 */
#ifndef DUMMYSTRUCTNAME
# ifdef NONAMELESSUNION
# define DUMMYSTRUCTNAME s
# define DUMMYSTRUCTNAME1 s1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2 s2
# define DUMMYSTRUCTNAME3 s3
# define DUMMYSTRUCTNAME4 s4
# define DUMMYSTRUCTNAME5 s5
# else
# define DUMMYSTRUCTNAME
# define DUMMYSTRUCTNAME1 /* Wine uses this variant */
# define DUMMYSTRUCTNAME2
# define DUMMYSTRUCTNAME3
# define DUMMYSTRUCTNAME4
# define DUMMYSTRUCTNAME5
# endif
#endif /* DUMMYSTRUCTNAME */
/* These are for compatibility with the Wine source tree */
#ifndef WINELIB_NAME_AW
# ifdef __MINGW_NAME_AW
# define WINELIB_NAME_AW __MINGW_NAME_AW
# else
# ifdef UNICODE
# define WINELIB_NAME_AW(func) func##W
# else
# define WINELIB_NAME_AW(func) func##A
# endif
# endif
#endif /* WINELIB_NAME_AW */
#ifndef DECL_WINELIB_TYPE_AW
# ifdef __MINGW_TYPEDEF_AW
# define DECL_WINELIB_TYPE_AW __MINGW_TYPEDEF_AW
# else
# define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type;
# endif
#endif /* DECL_WINELIB_TYPE_AW */

2467
raylib/external/glfw/deps/mingw/dinput.h vendored Normal file

File diff suppressed because it is too large Load Diff

239
raylib/external/glfw/deps/mingw/xinput.h vendored Normal file
View File

@@ -0,0 +1,239 @@
/*
* The Wine project - Xinput Joystick Library
* Copyright 2008 Andrew Fenn
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#ifndef __WINE_XINPUT_H
#define __WINE_XINPUT_H
#include <windef.h>
/*
* Bitmasks for the joysticks buttons, determines what has
* been pressed on the joystick, these need to be mapped
* to whatever device you're using instead of an xbox 360
* joystick
*/
#define XINPUT_GAMEPAD_DPAD_UP 0x0001
#define XINPUT_GAMEPAD_DPAD_DOWN 0x0002
#define XINPUT_GAMEPAD_DPAD_LEFT 0x0004
#define XINPUT_GAMEPAD_DPAD_RIGHT 0x0008
#define XINPUT_GAMEPAD_START 0x0010
#define XINPUT_GAMEPAD_BACK 0x0020
#define XINPUT_GAMEPAD_LEFT_THUMB 0x0040
#define XINPUT_GAMEPAD_RIGHT_THUMB 0x0080
#define XINPUT_GAMEPAD_LEFT_SHOULDER 0x0100
#define XINPUT_GAMEPAD_RIGHT_SHOULDER 0x0200
#define XINPUT_GAMEPAD_A 0x1000
#define XINPUT_GAMEPAD_B 0x2000
#define XINPUT_GAMEPAD_X 0x4000
#define XINPUT_GAMEPAD_Y 0x8000
/*
* Defines the flags used to determine if the user is pushing
* down on a button, not holding a button, etc
*/
#define XINPUT_KEYSTROKE_KEYDOWN 0x0001
#define XINPUT_KEYSTROKE_KEYUP 0x0002
#define XINPUT_KEYSTROKE_REPEAT 0x0004
/*
* Defines the codes which are returned by XInputGetKeystroke
*/
#define VK_PAD_A 0x5800
#define VK_PAD_B 0x5801
#define VK_PAD_X 0x5802
#define VK_PAD_Y 0x5803
#define VK_PAD_RSHOULDER 0x5804
#define VK_PAD_LSHOULDER 0x5805
#define VK_PAD_LTRIGGER 0x5806
#define VK_PAD_RTRIGGER 0x5807
#define VK_PAD_DPAD_UP 0x5810
#define VK_PAD_DPAD_DOWN 0x5811
#define VK_PAD_DPAD_LEFT 0x5812
#define VK_PAD_DPAD_RIGHT 0x5813
#define VK_PAD_START 0x5814
#define VK_PAD_BACK 0x5815
#define VK_PAD_LTHUMB_PRESS 0x5816
#define VK_PAD_RTHUMB_PRESS 0x5817
#define VK_PAD_LTHUMB_UP 0x5820
#define VK_PAD_LTHUMB_DOWN 0x5821
#define VK_PAD_LTHUMB_RIGHT 0x5822
#define VK_PAD_LTHUMB_LEFT 0x5823
#define VK_PAD_LTHUMB_UPLEFT 0x5824
#define VK_PAD_LTHUMB_UPRIGHT 0x5825
#define VK_PAD_LTHUMB_DOWNRIGHT 0x5826
#define VK_PAD_LTHUMB_DOWNLEFT 0x5827
#define VK_PAD_RTHUMB_UP 0x5830
#define VK_PAD_RTHUMB_DOWN 0x5831
#define VK_PAD_RTHUMB_RIGHT 0x5832
#define VK_PAD_RTHUMB_LEFT 0x5833
#define VK_PAD_RTHUMB_UPLEFT 0x5834
#define VK_PAD_RTHUMB_UPRIGHT 0x5835
#define VK_PAD_RTHUMB_DOWNRIGHT 0x5836
#define VK_PAD_RTHUMB_DOWNLEFT 0x5837
/*
* Deadzones are for analogue joystick controls on the joypad
* which determine when input should be assumed to be in the
* middle of the pad. This is a threshold to stop a joypad
* controlling the game when the player isn't touching the
* controls.
*/
#define XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE 7849
#define XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE 8689
#define XINPUT_GAMEPAD_TRIGGER_THRESHOLD 30
/*
* Defines what type of abilities the type of joystick has
* DEVTYPE_GAMEPAD is available for all joysticks, however
* there may be more specific identifiers for other joysticks
* which are being used.
*/
#define XINPUT_DEVTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_GAMEPAD 0x01
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#define XINPUT_DEVSUBTYPE_FLIGHT_SICK 0x04
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
/*
* These are used with the XInputGetCapabilities function to
* determine the abilities to the joystick which has been
* plugged in.
*/
#define XINPUT_CAPS_VOICE_SUPPORTED 0x0004
#define XINPUT_FLAG_GAMEPAD 0x00000001
/*
* Defines the status of the battery if one is used in the
* attached joystick. The first two define if the joystick
* supports a battery. Disconnected means that the joystick
* isn't connected. Wired shows that the joystick is a wired
* joystick.
*/
#define BATTERY_DEVTYPE_GAMEPAD 0x00
#define BATTERY_DEVTYPE_HEADSET 0x01
#define BATTERY_TYPE_DISCONNECTED 0x00
#define BATTERY_TYPE_WIRED 0x01
#define BATTERY_TYPE_ALKALINE 0x02
#define BATTERY_TYPE_NIMH 0x03
#define BATTERY_TYPE_UNKNOWN 0xFF
#define BATTERY_LEVEL_EMPTY 0x00
#define BATTERY_LEVEL_LOW 0x01
#define BATTERY_LEVEL_MEDIUM 0x02
#define BATTERY_LEVEL_FULL 0x03
/*
* How many joysticks can be used with this library. Games that
* use the xinput library will not go over this number.
*/
#define XUSER_MAX_COUNT 4
#define XUSER_INDEX_ANY 0x000000FF
/*
* Defines the structure of an xbox 360 joystick.
*/
typedef struct _XINPUT_GAMEPAD {
WORD wButtons;
BYTE bLeftTrigger;
BYTE bRightTrigger;
SHORT sThumbLX;
SHORT sThumbLY;
SHORT sThumbRX;
SHORT sThumbRY;
} XINPUT_GAMEPAD, *PXINPUT_GAMEPAD;
typedef struct _XINPUT_STATE {
DWORD dwPacketNumber;
XINPUT_GAMEPAD Gamepad;
} XINPUT_STATE, *PXINPUT_STATE;
/*
* Defines the structure of how much vibration is set on both the
* right and left motors in a joystick. If you're not using a 360
* joystick you will have to map these to your device.
*/
typedef struct _XINPUT_VIBRATION {
WORD wLeftMotorSpeed;
WORD wRightMotorSpeed;
} XINPUT_VIBRATION, *PXINPUT_VIBRATION;
/*
* Defines the structure for what kind of abilities the joystick has
* such abilities are things such as if the joystick has the ability
* to send and receive audio, if the joystick is in fact a driving
* wheel or perhaps if the joystick is some kind of dance pad or
* guitar.
*/
typedef struct _XINPUT_CAPABILITIES {
BYTE Type;
BYTE SubType;
WORD Flags;
XINPUT_GAMEPAD Gamepad;
XINPUT_VIBRATION Vibration;
} XINPUT_CAPABILITIES, *PXINPUT_CAPABILITIES;
/*
* Defines the structure for a joystick input event which is
* retrieved using the function XInputGetKeystroke
*/
typedef struct _XINPUT_KEYSTROKE {
WORD VirtualKey;
WCHAR Unicode;
WORD Flags;
BYTE UserIndex;
BYTE HidCode;
} XINPUT_KEYSTROKE, *PXINPUT_KEYSTROKE;
typedef struct _XINPUT_BATTERY_INFORMATION
{
BYTE BatteryType;
BYTE BatteryLevel;
} XINPUT_BATTERY_INFORMATION, *PXINPUT_BATTERY_INFORMATION;
#ifdef __cplusplus
extern "C" {
#endif
void WINAPI XInputEnable(WINBOOL);
DWORD WINAPI XInputSetState(DWORD, XINPUT_VIBRATION*);
DWORD WINAPI XInputGetState(DWORD, XINPUT_STATE*);
DWORD WINAPI XInputGetKeystroke(DWORD, DWORD, PXINPUT_KEYSTROKE);
DWORD WINAPI XInputGetCapabilities(DWORD, DWORD, XINPUT_CAPABILITIES*);
DWORD WINAPI XInputGetDSoundAudioDeviceGuids(DWORD, GUID*, GUID*);
DWORD WINAPI XInputGetBatteryInformation(DWORD, BYTE, XINPUT_BATTERY_INFORMATION*);
#ifdef __cplusplus
}
#endif
#endif /* __WINE_XINPUT_H */

View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="fractional_scale_v1">
<copyright>
Copyright © 2022 Kenny Levinsen
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Protocol for requesting fractional surface scales">
This protocol allows a compositor to suggest for surfaces to render at
fractional scales.
A client can submit scaled content by utilizing wp_viewport. This is done by
creating a wp_viewport object for the surface and setting the destination
rectangle to the surface size before the scale factor is applied.
The buffer size is calculated by multiplying the surface size by the
intended scale.
The wl_surface buffer scale should remain set to 1.
If a surface has a surface-local size of 100 px by 50 px and wishes to
submit buffers with a scale of 1.5, then a buffer of 150px by 75 px should
be used and the wp_viewport destination rectangle should be 100 px by 50 px.
For toplevel surfaces, the size is rounded halfway away from zero. The
rounding algorithm for subsurface position and size is not defined.
</description>
<interface name="wp_fractional_scale_manager_v1" version="1">
<description summary="fractional surface scale information">
A global interface for requesting surfaces to use fractional scales.
</description>
<request name="destroy" type="destructor">
<description summary="unbind the fractional surface scale interface">
Informs the server that the client will not be using this protocol
object anymore. This does not affect any other objects,
wp_fractional_scale_v1 objects included.
</description>
</request>
<enum name="error">
<entry name="fractional_scale_exists" value="0"
summary="the surface already has a fractional_scale object associated"/>
</enum>
<request name="get_fractional_scale">
<description summary="extend surface interface for scale information">
Create an add-on object for the the wl_surface to let the compositor
request fractional scales. If the given wl_surface already has a
wp_fractional_scale_v1 object associated, the fractional_scale_exists
protocol error is raised.
</description>
<arg name="id" type="new_id" interface="wp_fractional_scale_v1"
summary="the new surface scale info interface id"/>
<arg name="surface" type="object" interface="wl_surface"
summary="the surface"/>
</request>
</interface>
<interface name="wp_fractional_scale_v1" version="1">
<description summary="fractional scale interface to a wl_surface">
An additional interface to a wl_surface object which allows the compositor
to inform the client of the preferred scale.
</description>
<request name="destroy" type="destructor">
<description summary="remove surface scale information for surface">
Destroy the fractional scale object. When this object is destroyed,
preferred_scale events will no longer be sent.
</description>
</request>
<event name="preferred_scale">
<description summary="notify of new preferred scale">
Notification of a new preferred scale for this surface that the
compositor suggests that the client should use.
The sent scale is the numerator of a fraction with a denominator of 120.
</description>
<arg name="scale" type="uint" summary="the new preferred scale"/>
</event>
</interface>
</protocol>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="idle_inhibit_unstable_v1">
<copyright>
Copyright © 2015 Samsung Electronics Co., Ltd
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="zwp_idle_inhibit_manager_v1" version="1">
<description summary="control behavior when display idles">
This interface permits inhibiting the idle behavior such as screen
blanking, locking, and screensaving. The client binds the idle manager
globally, then creates idle-inhibitor objects for each surface.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible changes
may be added together with the corresponding interface version bump.
Backward incompatible changes are done by bumping the version number in
the protocol and interface names and resetting the interface version.
Once the protocol is to be declared stable, the 'z' prefix and the
version number in the protocol and interface names are removed and the
interface version number is reset.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the idle inhibitor object">
Destroy the inhibit manager.
</description>
</request>
<request name="create_inhibitor">
<description summary="create a new inhibitor object">
Create a new inhibitor object associated with the given surface.
</description>
<arg name="id" type="new_id" interface="zwp_idle_inhibitor_v1"/>
<arg name="surface" type="object" interface="wl_surface"
summary="the surface that inhibits the idle behavior"/>
</request>
</interface>
<interface name="zwp_idle_inhibitor_v1" version="1">
<description summary="context object for inhibiting idle behavior">
An idle inhibitor prevents the output that the associated surface is
visible on from being set to a state where it is not visually usable due
to lack of user interaction (e.g. blanked, dimmed, locked, set to power
save, etc.) Any screensaver processes are also blocked from displaying.
If the surface is destroyed, unmapped, becomes occluded, loses
visibility, or otherwise becomes not visually relevant for the user, the
idle inhibitor will not be honored by the compositor; if the surface
subsequently regains visibility the inhibitor takes effect once again.
Likewise, the inhibitor isn't honored if the system was already idled at
the time the inhibitor was established, although if the system later
de-idles and re-idles the inhibitor will take effect.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the idle inhibitor object">
Remove the inhibitor effect from the associated wl_surface.
</description>
</request>
</interface>
</protocol>

View File

@@ -0,0 +1,339 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="pointer_constraints_unstable_v1">
<copyright>
Copyright © 2014 Jonas Ådahl
Copyright © 2015 Red Hat Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="protocol for constraining pointer motions">
This protocol specifies a set of interfaces used for adding constraints to
the motion of a pointer. Possible constraints include confining pointer
motions to a given region, or locking it to its current position.
In order to constrain the pointer, a client must first bind the global
interface "wp_pointer_constraints" which, if a compositor supports pointer
constraints, is exposed by the registry. Using the bound global object, the
client uses the request that corresponds to the type of constraint it wants
to make. See wp_pointer_constraints for more details.
Warning! The protocol described in this file is experimental and backward
incompatible changes may be made. Backward compatible changes may be added
together with the corresponding interface version bump. Backward
incompatible changes are done by bumping the version number in the protocol
and interface names and resetting the interface version. Once the protocol
is to be declared stable, the 'z' prefix and the version number in the
protocol and interface names are removed and the interface version number is
reset.
</description>
<interface name="zwp_pointer_constraints_v1" version="1">
<description summary="constrain the movement of a pointer">
The global interface exposing pointer constraining functionality. It
exposes two requests: lock_pointer for locking the pointer to its
position, and confine_pointer for locking the pointer to a region.
The lock_pointer and confine_pointer requests create the objects
wp_locked_pointer and wp_confined_pointer respectively, and the client can
use these objects to interact with the lock.
For any surface, only one lock or confinement may be active across all
wl_pointer objects of the same seat. If a lock or confinement is requested
when another lock or confinement is active or requested on the same surface
and with any of the wl_pointer objects of the same seat, an
'already_constrained' error will be raised.
</description>
<enum name="error">
<description summary="wp_pointer_constraints error values">
These errors can be emitted in response to wp_pointer_constraints
requests.
</description>
<entry name="already_constrained" value="1"
summary="pointer constraint already requested on that surface"/>
</enum>
<enum name="lifetime">
<description summary="constraint lifetime">
These values represent different lifetime semantics. They are passed
as arguments to the factory requests to specify how the constraint
lifetimes should be managed.
</description>
<entry name="oneshot" value="1">
<description summary="the pointer constraint is defunct once deactivated">
A oneshot pointer constraint will never reactivate once it has been
deactivated. See the corresponding deactivation event
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
details.
</description>
</entry>
<entry name="persistent" value="2">
<description summary="the pointer constraint may reactivate">
A persistent pointer constraint may again reactivate once it has
been deactivated. See the corresponding deactivation event
(wp_locked_pointer.unlocked and wp_confined_pointer.unconfined) for
details.
</description>
</entry>
</enum>
<request name="destroy" type="destructor">
<description summary="destroy the pointer constraints manager object">
Used by the client to notify the server that it will no longer use this
pointer constraints object.
</description>
</request>
<request name="lock_pointer">
<description summary="lock pointer to a position">
The lock_pointer request lets the client request to disable movements of
the virtual pointer (i.e. the cursor), effectively locking the pointer
to a position. This request may not take effect immediately; in the
future, when the compositor deems implementation-specific constraints
are satisfied, the pointer lock will be activated and the compositor
sends a locked event.
The protocol provides no guarantee that the constraints are ever
satisfied, and does not require the compositor to send an error if the
constraints cannot ever be satisfied. It is thus possible to request a
lock that will never activate.
There may not be another pointer constraint of any kind requested or
active on the surface for any of the wl_pointer objects of the seat of
the passed pointer when requesting a lock. If there is, an error will be
raised. See general pointer lock documentation for more details.
The intersection of the region passed with this request and the input
region of the surface is used to determine where the pointer must be
in order for the lock to activate. It is up to the compositor whether to
warp the pointer or require some kind of user interaction for the lock
to activate. If the region is null the surface input region is used.
A surface may receive pointer focus without the lock being activated.
The request creates a new object wp_locked_pointer which is used to
interact with the lock as well as receive updates about its state. See
the the description of wp_locked_pointer for further information.
Note that while a pointer is locked, the wl_pointer objects of the
corresponding seat will not emit any wl_pointer.motion events, but
relative motion events will still be emitted via wp_relative_pointer
objects of the same seat. wl_pointer.axis and wl_pointer.button events
are unaffected.
</description>
<arg name="id" type="new_id" interface="zwp_locked_pointer_v1"/>
<arg name="surface" type="object" interface="wl_surface"
summary="surface to lock pointer to"/>
<arg name="pointer" type="object" interface="wl_pointer"
summary="the pointer that should be locked"/>
<arg name="region" type="object" interface="wl_region" allow-null="true"
summary="region of surface"/>
<arg name="lifetime" type="uint" enum="lifetime" summary="lock lifetime"/>
</request>
<request name="confine_pointer">
<description summary="confine pointer to a region">
The confine_pointer request lets the client request to confine the
pointer cursor to a given region. This request may not take effect
immediately; in the future, when the compositor deems implementation-
specific constraints are satisfied, the pointer confinement will be
activated and the compositor sends a confined event.
The intersection of the region passed with this request and the input
region of the surface is used to determine where the pointer must be
in order for the confinement to activate. It is up to the compositor
whether to warp the pointer or require some kind of user interaction for
the confinement to activate. If the region is null the surface input
region is used.
The request will create a new object wp_confined_pointer which is used
to interact with the confinement as well as receive updates about its
state. See the the description of wp_confined_pointer for further
information.
</description>
<arg name="id" type="new_id" interface="zwp_confined_pointer_v1"/>
<arg name="surface" type="object" interface="wl_surface"
summary="surface to lock pointer to"/>
<arg name="pointer" type="object" interface="wl_pointer"
summary="the pointer that should be confined"/>
<arg name="region" type="object" interface="wl_region" allow-null="true"
summary="region of surface"/>
<arg name="lifetime" type="uint" enum="lifetime" summary="confinement lifetime"/>
</request>
</interface>
<interface name="zwp_locked_pointer_v1" version="1">
<description summary="receive relative pointer motion events">
The wp_locked_pointer interface represents a locked pointer state.
While the lock of this object is active, the wl_pointer objects of the
associated seat will not emit any wl_pointer.motion events.
This object will send the event 'locked' when the lock is activated.
Whenever the lock is activated, it is guaranteed that the locked surface
will already have received pointer focus and that the pointer will be
within the region passed to the request creating this object.
To unlock the pointer, send the destroy request. This will also destroy
the wp_locked_pointer object.
If the compositor decides to unlock the pointer the unlocked event is
sent. See wp_locked_pointer.unlock for details.
When unlocking, the compositor may warp the cursor position to the set
cursor position hint. If it does, it will not result in any relative
motion events emitted via wp_relative_pointer.
If the surface the lock was requested on is destroyed and the lock is not
yet activated, the wp_locked_pointer object is now defunct and must be
destroyed.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the locked pointer object">
Destroy the locked pointer object. If applicable, the compositor will
unlock the pointer.
</description>
</request>
<request name="set_cursor_position_hint">
<description summary="set the pointer cursor position hint">
Set the cursor position hint relative to the top left corner of the
surface.
If the client is drawing its own cursor, it should update the position
hint to the position of its own cursor. A compositor may use this
information to warp the pointer upon unlock in order to avoid pointer
jumps.
The cursor position hint is double buffered. The new hint will only take
effect when the associated surface gets it pending state applied. See
wl_surface.commit for details.
</description>
<arg name="surface_x" type="fixed"
summary="surface-local x coordinate"/>
<arg name="surface_y" type="fixed"
summary="surface-local y coordinate"/>
</request>
<request name="set_region">
<description summary="set a new lock region">
Set a new region used to lock the pointer.
The new lock region is double-buffered. The new lock region will
only take effect when the associated surface gets its pending state
applied. See wl_surface.commit for details.
For details about the lock region, see wp_locked_pointer.
</description>
<arg name="region" type="object" interface="wl_region" allow-null="true"
summary="region of surface"/>
</request>
<event name="locked">
<description summary="lock activation event">
Notification that the pointer lock of the seat's pointer is activated.
</description>
</event>
<event name="unlocked">
<description summary="lock deactivation event">
Notification that the pointer lock of the seat's pointer is no longer
active. If this is a oneshot pointer lock (see
wp_pointer_constraints.lifetime) this object is now defunct and should
be destroyed. If this is a persistent pointer lock (see
wp_pointer_constraints.lifetime) this pointer lock may again
reactivate in the future.
</description>
</event>
</interface>
<interface name="zwp_confined_pointer_v1" version="1">
<description summary="confined pointer object">
The wp_confined_pointer interface represents a confined pointer state.
This object will send the event 'confined' when the confinement is
activated. Whenever the confinement is activated, it is guaranteed that
the surface the pointer is confined to will already have received pointer
focus and that the pointer will be within the region passed to the request
creating this object. It is up to the compositor to decide whether this
requires some user interaction and if the pointer will warp to within the
passed region if outside.
To unconfine the pointer, send the destroy request. This will also destroy
the wp_confined_pointer object.
If the compositor decides to unconfine the pointer the unconfined event is
sent. The wp_confined_pointer object is at this point defunct and should
be destroyed.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the confined pointer object">
Destroy the confined pointer object. If applicable, the compositor will
unconfine the pointer.
</description>
</request>
<request name="set_region">
<description summary="set a new confine region">
Set a new region used to confine the pointer.
The new confine region is double-buffered. The new confine region will
only take effect when the associated surface gets its pending state
applied. See wl_surface.commit for details.
If the confinement is active when the new confinement region is applied
and the pointer ends up outside of newly applied region, the pointer may
warped to a position within the new confinement region. If warped, a
wl_pointer.motion event will be emitted, but no
wp_relative_pointer.relative_motion event.
The compositor may also, instead of using the new region, unconfine the
pointer.
For details about the confine region, see wp_confined_pointer.
</description>
<arg name="region" type="object" interface="wl_region" allow-null="true"
summary="region of surface"/>
</request>
<event name="confined">
<description summary="pointer confined">
Notification that the pointer confinement of the seat's pointer is
activated.
</description>
</event>
<event name="unconfined">
<description summary="pointer unconfined">
Notification that the pointer confinement of the seat's pointer is no
longer active. If this is a oneshot pointer confinement (see
wp_pointer_constraints.lifetime) this object is now defunct and should
be destroyed. If this is a persistent pointer confinement (see
wp_pointer_constraints.lifetime) this pointer confinement may again
reactivate in the future.
</description>
</event>
</interface>
</protocol>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="relative_pointer_unstable_v1">
<copyright>
Copyright © 2014 Jonas Ådahl
Copyright © 2015 Red Hat Inc.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="protocol for relative pointer motion events">
This protocol specifies a set of interfaces used for making clients able to
receive relative pointer events not obstructed by barriers (such as the
monitor edge or other pointer barriers).
To start receiving relative pointer events, a client must first bind the
global interface "wp_relative_pointer_manager" which, if a compositor
supports relative pointer motion events, is exposed by the registry. After
having created the relative pointer manager proxy object, the client uses
it to create the actual relative pointer object using the
"get_relative_pointer" request given a wl_pointer. The relative pointer
motion events will then, when applicable, be transmitted via the proxy of
the newly created relative pointer object. See the documentation of the
relative pointer interface for more details.
Warning! The protocol described in this file is experimental and backward
incompatible changes may be made. Backward compatible changes may be added
together with the corresponding interface version bump. Backward
incompatible changes are done by bumping the version number in the protocol
and interface names and resetting the interface version. Once the protocol
is to be declared stable, the 'z' prefix and the version number in the
protocol and interface names are removed and the interface version number is
reset.
</description>
<interface name="zwp_relative_pointer_manager_v1" version="1">
<description summary="get relative pointer objects">
A global interface used for getting the relative pointer object for a
given pointer.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the relative pointer manager object">
Used by the client to notify the server that it will no longer use this
relative pointer manager object.
</description>
</request>
<request name="get_relative_pointer">
<description summary="get a relative pointer object">
Create a relative pointer interface given a wl_pointer object. See the
wp_relative_pointer interface for more details.
</description>
<arg name="id" type="new_id" interface="zwp_relative_pointer_v1"/>
<arg name="pointer" type="object" interface="wl_pointer"/>
</request>
</interface>
<interface name="zwp_relative_pointer_v1" version="1">
<description summary="relative pointer object">
A wp_relative_pointer object is an extension to the wl_pointer interface
used for emitting relative pointer events. It shares the same focus as
wl_pointer objects of the same seat and will only emit events when it has
focus.
</description>
<request name="destroy" type="destructor">
<description summary="release the relative pointer object"/>
</request>
<event name="relative_motion">
<description summary="relative pointer motion">
Relative x/y pointer motion from the pointer of the seat associated with
this object.
A relative motion is in the same dimension as regular wl_pointer motion
events, except they do not represent an absolute position. For example,
moving a pointer from (x, y) to (x', y') would have the equivalent
relative motion (x' - x, y' - y). If a pointer motion caused the
absolute pointer position to be clipped by for example the edge of the
monitor, the relative motion is unaffected by the clipping and will
represent the unclipped motion.
This event also contains non-accelerated motion deltas. The
non-accelerated delta is, when applicable, the regular pointer motion
delta as it was before having applied motion acceleration and other
transformations such as normalization.
Note that the non-accelerated delta does not represent 'raw' events as
they were read from some device. Pointer motion acceleration is device-
and configuration-specific and non-accelerated deltas and accelerated
deltas may have the same value on some devices.
Relative motions are not coupled to wl_pointer.motion events, and can be
sent in combination with such events, but also independently. There may
also be scenarios where wl_pointer.motion is sent, but there is no
relative motion. The order of an absolute and relative motion event
originating from the same physical motion is not guaranteed.
If the client needs button events or focus state, it can receive them
from a wl_pointer object of the same seat that the wp_relative_pointer
object is associated with.
</description>
<arg name="utime_hi" type="uint"
summary="high 32 bits of a 64 bit timestamp with microsecond granularity"/>
<arg name="utime_lo" type="uint"
summary="low 32 bits of a 64 bit timestamp with microsecond granularity"/>
<arg name="dx" type="fixed"
summary="the x component of the motion vector"/>
<arg name="dy" type="fixed"
summary="the y component of the motion vector"/>
<arg name="dx_unaccel" type="fixed"
summary="the x component of the unaccelerated motion vector"/>
<arg name="dy_unaccel" type="fixed"
summary="the y component of the unaccelerated motion vector"/>
</event>
</interface>
</protocol>

View File

@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="viewporter">
<copyright>
Copyright © 2013-2016 Collabora, Ltd.
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="wp_viewporter" version="1">
<description summary="surface cropping and scaling">
The global interface exposing surface cropping and scaling
capabilities is used to instantiate an interface extension for a
wl_surface object. This extended interface will then allow
cropping and scaling the surface contents, effectively
disconnecting the direct relationship between the buffer and the
surface size.
</description>
<request name="destroy" type="destructor">
<description summary="unbind from the cropping and scaling interface">
Informs the server that the client will not be using this
protocol object anymore. This does not affect any other objects,
wp_viewport objects included.
</description>
</request>
<enum name="error">
<entry name="viewport_exists" value="0"
summary="the surface already has a viewport object associated"/>
</enum>
<request name="get_viewport">
<description summary="extend surface interface for crop and scale">
Instantiate an interface extension for the given wl_surface to
crop and scale its content. If the given wl_surface already has
a wp_viewport object associated, the viewport_exists
protocol error is raised.
</description>
<arg name="id" type="new_id" interface="wp_viewport"
summary="the new viewport interface id"/>
<arg name="surface" type="object" interface="wl_surface"
summary="the surface"/>
</request>
</interface>
<interface name="wp_viewport" version="1">
<description summary="crop and scale interface to a wl_surface">
An additional interface to a wl_surface object, which allows the
client to specify the cropping and scaling of the surface
contents.
This interface works with two concepts: the source rectangle (src_x,
src_y, src_width, src_height), and the destination size (dst_width,
dst_height). The contents of the source rectangle are scaled to the
destination size, and content outside the source rectangle is ignored.
This state is double-buffered, and is applied on the next
wl_surface.commit.
The two parts of crop and scale state are independent: the source
rectangle, and the destination size. Initially both are unset, that
is, no scaling is applied. The whole of the current wl_buffer is
used as the source, and the surface size is as defined in
wl_surface.attach.
If the destination size is set, it causes the surface size to become
dst_width, dst_height. The source (rectangle) is scaled to exactly
this size. This overrides whatever the attached wl_buffer size is,
unless the wl_buffer is NULL. If the wl_buffer is NULL, the surface
has no content and therefore no size. Otherwise, the size is always
at least 1x1 in surface local coordinates.
If the source rectangle is set, it defines what area of the wl_buffer is
taken as the source. If the source rectangle is set and the destination
size is not set, then src_width and src_height must be integers, and the
surface size becomes the source rectangle size. This results in cropping
without scaling. If src_width or src_height are not integers and
destination size is not set, the bad_size protocol error is raised when
the surface state is applied.
The coordinate transformations from buffer pixel coordinates up to
the surface-local coordinates happen in the following order:
1. buffer_transform (wl_surface.set_buffer_transform)
2. buffer_scale (wl_surface.set_buffer_scale)
3. crop and scale (wp_viewport.set*)
This means, that the source rectangle coordinates of crop and scale
are given in the coordinates after the buffer transform and scale,
i.e. in the coordinates that would be the surface-local coordinates
if the crop and scale was not applied.
If src_x or src_y are negative, the bad_value protocol error is raised.
Otherwise, if the source rectangle is partially or completely outside of
the non-NULL wl_buffer, then the out_of_buffer protocol error is raised
when the surface state is applied. A NULL wl_buffer does not raise the
out_of_buffer error.
If the wl_surface associated with the wp_viewport is destroyed,
all wp_viewport requests except 'destroy' raise the protocol error
no_surface.
If the wp_viewport object is destroyed, the crop and scale
state is removed from the wl_surface. The change will be applied
on the next wl_surface.commit.
</description>
<request name="destroy" type="destructor">
<description summary="remove scaling and cropping from the surface">
The associated wl_surface's crop and scale state is removed.
The change is applied on the next wl_surface.commit.
</description>
</request>
<enum name="error">
<entry name="bad_value" value="0"
summary="negative or zero values in width or height"/>
<entry name="bad_size" value="1"
summary="destination size is not integer"/>
<entry name="out_of_buffer" value="2"
summary="source rectangle extends outside of the content area"/>
<entry name="no_surface" value="3"
summary="the wl_surface was destroyed"/>
</enum>
<request name="set_source">
<description summary="set the source rectangle for cropping">
Set the source rectangle of the associated wl_surface. See
wp_viewport for the description, and relation to the wl_buffer
size.
If all of x, y, width and height are -1.0, the source rectangle is
unset instead. Any other set of values where width or height are zero
or negative, or x or y are negative, raise the bad_value protocol
error.
The crop and scale state is double-buffered state, and will be
applied on the next wl_surface.commit.
</description>
<arg name="x" type="fixed" summary="source rectangle x"/>
<arg name="y" type="fixed" summary="source rectangle y"/>
<arg name="width" type="fixed" summary="source rectangle width"/>
<arg name="height" type="fixed" summary="source rectangle height"/>
</request>
<request name="set_destination">
<description summary="set the surface size for scaling">
Set the destination size of the associated wl_surface. See
wp_viewport for the description, and relation to the wl_buffer
size.
If width is -1 and height is -1, the destination size is unset
instead. Any other pair of values for width and height that
contains zero or negative values raises the bad_value protocol
error.
The crop and scale state is double-buffered state, and will be
applied on the next wl_surface.commit.
</description>
<arg name="width" type="int" summary="surface width"/>
<arg name="height" type="int" summary="surface height"/>
</request>
</interface>
</protocol>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xdg_activation_v1">
<copyright>
Copyright © 2020 Aleix Pol Gonzalez &lt;aleixpol@kde.org&gt;
Copyright © 2020 Carlos Garnacho &lt;carlosg@gnome.org&gt;
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Protocol for requesting activation of surfaces">
The way for a client to pass focus to another toplevel is as follows.
The client that intends to activate another toplevel uses the
xdg_activation_v1.get_activation_token request to get an activation token.
This token is then forwarded to the client, which is supposed to activate
one of its surfaces, through a separate band of communication.
One established way of doing this is through the XDG_ACTIVATION_TOKEN
environment variable of a newly launched child process. The child process
should unset the environment variable again right after reading it out in
order to avoid propagating it to other child processes.
Another established way exists for Applications implementing the D-Bus
interface org.freedesktop.Application, which should get their token under
activation-token on their platform_data.
In general activation tokens may be transferred across clients through
means not described in this protocol.
The client to be activated will then pass the token
it received to the xdg_activation_v1.activate request. The compositor can
then use this token to decide how to react to the activation request.
The token the activating client gets may be ineffective either already at
the time it receives it, for example if it was not focused, for focus
stealing prevention. The activating client will have no way to discover
the validity of the token, and may still forward it to the to be activated
client.
The created activation token may optionally get information attached to it
that can be used by the compositor to identify the application that we
intend to activate. This can for example be used to display a visual hint
about what application is being started.
Warning! The protocol described in this file is currently in the testing
phase. Backward compatible changes may be added together with the
corresponding interface version bump. Backward incompatible changes can
only be done by creating a new major version of the extension.
</description>
<interface name="xdg_activation_v1" version="1">
<description summary="interface for activating surfaces">
A global interface used for informing the compositor about applications
being activated or started, or for applications to request to be
activated.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the xdg_activation object">
Notify the compositor that the xdg_activation object will no longer be
used.
The child objects created via this interface are unaffected and should
be destroyed separately.
</description>
</request>
<request name="get_activation_token">
<description summary="requests a token">
Creates an xdg_activation_token_v1 object that will provide
the initiating client with a unique token for this activation. This
token should be offered to the clients to be activated.
</description>
<arg name="id" type="new_id" interface="xdg_activation_token_v1"/>
</request>
<request name="activate">
<description summary="notify new interaction being available">
Requests surface activation. It's up to the compositor to display
this information as desired, for example by placing the surface above
the rest.
The compositor may know who requested this by checking the activation
token and might decide not to follow through with the activation if it's
considered unwanted.
Compositors can ignore unknown activation tokens when an invalid
token is passed.
</description>
<arg name="token" type="string" summary="the activation token of the initiating client"/>
<arg name="surface" type="object" interface="wl_surface"
summary="the wl_surface to activate"/>
</request>
</interface>
<interface name="xdg_activation_token_v1" version="1">
<description summary="an exported activation handle">
An object for setting up a token and receiving a token handle that can
be passed as an activation token to another client.
The object is created using the xdg_activation_v1.get_activation_token
request. This object should then be populated with the app_id, surface
and serial information and committed. The compositor shall then issue a
done event with the token. In case the request's parameters are invalid,
the compositor will provide an invalid token.
</description>
<enum name="error">
<entry name="already_used" value="0"
summary="The token has already been used previously"/>
</enum>
<request name="set_serial">
<description summary="specifies the seat and serial of the activating event">
Provides information about the seat and serial event that requested the
token.
The serial can come from an input or focus event. For instance, if a
click triggers the launch of a third-party client, the launcher client
should send a set_serial request with the serial and seat from the
wl_pointer.button event.
Some compositors might refuse to activate toplevels when the token
doesn't have a valid and recent enough event serial.
Must be sent before commit. This information is optional.
</description>
<arg name="serial" type="uint"
summary="the serial of the event that triggered the activation"/>
<arg name="seat" type="object" interface="wl_seat"
summary="the wl_seat of the event"/>
</request>
<request name="set_app_id">
<description summary="specifies the application being activated">
The requesting client can specify an app_id to associate the token
being created with it.
Must be sent before commit. This information is optional.
</description>
<arg name="app_id" type="string"
summary="the application id of the client being activated."/>
</request>
<request name="set_surface">
<description summary="specifies the surface requesting activation">
This request sets the surface requesting the activation. Note, this is
different from the surface that will be activated.
Some compositors might refuse to activate toplevels when the token
doesn't have a requesting surface.
Must be sent before commit. This information is optional.
</description>
<arg name="surface" type="object" interface="wl_surface"
summary="the requesting surface"/>
</request>
<request name="commit">
<description summary="issues the token request">
Requests an activation token based on the different parameters that
have been offered through set_serial, set_surface and set_app_id.
</description>
</request>
<event name="done">
<description summary="the exported activation token">
The 'done' event contains the unique token of this activation request
and notifies that the provider is done.
</description>
<arg name="token" type="string" summary="the exported activation token"/>
</event>
<request name="destroy" type="destructor">
<description summary="destroy the xdg_activation_token_v1 object">
Notify the compositor that the xdg_activation_token_v1 object will no
longer be used. The received token stays valid.
</description>
</request>
</interface>
</protocol>

View File

@@ -0,0 +1,156 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xdg_decoration_unstable_v1">
<copyright>
Copyright © 2018 Simon Ser
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<interface name="zxdg_decoration_manager_v1" version="1">
<description summary="window decoration manager">
This interface allows a compositor to announce support for server-side
decorations.
A window decoration is a set of window controls as deemed appropriate by
the party managing them, such as user interface components used to move,
resize and change a window's state.
A client can use this protocol to request being decorated by a supporting
compositor.
If compositor and client do not negotiate the use of a server-side
decoration using this protocol, clients continue to self-decorate as they
see fit.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible changes
may be added together with the corresponding interface version bump.
Backward incompatible changes are done by bumping the version number in
the protocol and interface names and resetting the interface version.
Once the protocol is to be declared stable, the 'z' prefix and the
version number in the protocol and interface names are removed and the
interface version number is reset.
</description>
<request name="destroy" type="destructor">
<description summary="destroy the decoration manager object">
Destroy the decoration manager. This doesn't destroy objects created
with the manager.
</description>
</request>
<request name="get_toplevel_decoration">
<description summary="create a new toplevel decoration object">
Create a new decoration object associated with the given toplevel.
Creating an xdg_toplevel_decoration from an xdg_toplevel which has a
buffer attached or committed is a client error, and any attempts by a
client to attach or manipulate a buffer prior to the first
xdg_toplevel_decoration.configure event must also be treated as
errors.
</description>
<arg name="id" type="new_id" interface="zxdg_toplevel_decoration_v1"/>
<arg name="toplevel" type="object" interface="xdg_toplevel"/>
</request>
</interface>
<interface name="zxdg_toplevel_decoration_v1" version="1">
<description summary="decoration object for a toplevel surface">
The decoration object allows the compositor to toggle server-side window
decorations for a toplevel surface. The client can request to switch to
another mode.
The xdg_toplevel_decoration object must be destroyed before its
xdg_toplevel.
</description>
<enum name="error">
<entry name="unconfigured_buffer" value="0"
summary="xdg_toplevel has a buffer attached before configure"/>
<entry name="already_constructed" value="1"
summary="xdg_toplevel already has a decoration object"/>
<entry name="orphaned" value="2"
summary="xdg_toplevel destroyed before the decoration object"/>
</enum>
<request name="destroy" type="destructor">
<description summary="destroy the decoration object">
Switch back to a mode without any server-side decorations at the next
commit.
</description>
</request>
<enum name="mode">
<description summary="window decoration modes">
These values describe window decoration modes.
</description>
<entry name="client_side" value="1"
summary="no server-side window decoration"/>
<entry name="server_side" value="2"
summary="server-side window decoration"/>
</enum>
<request name="set_mode">
<description summary="set the decoration mode">
Set the toplevel surface decoration mode. This informs the compositor
that the client prefers the provided decoration mode.
After requesting a decoration mode, the compositor will respond by
emitting an xdg_surface.configure event. The client should then update
its content, drawing it without decorations if the received mode is
server-side decorations. The client must also acknowledge the configure
when committing the new content (see xdg_surface.ack_configure).
The compositor can decide not to use the client's mode and enforce a
different mode instead.
Clients whose decoration mode depend on the xdg_toplevel state may send
a set_mode request in response to an xdg_surface.configure event and wait
for the next xdg_surface.configure event to prevent unwanted state.
Such clients are responsible for preventing configure loops and must
make sure not to send multiple successive set_mode requests with the
same decoration mode.
</description>
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
</request>
<request name="unset_mode">
<description summary="unset the decoration mode">
Unset the toplevel surface decoration mode. This informs the compositor
that the client doesn't prefer a particular decoration mode.
This request has the same semantics as set_mode.
</description>
</request>
<event name="configure">
<description summary="suggest a surface change">
The configure event asks the client to change its decoration mode. The
configured state should not be applied immediately. Clients must send an
ack_configure in response to this event. See xdg_surface.configure and
xdg_surface.ack_configure for details.
A configure event can be sent at any time. The specified mode must be
obeyed by the client.
</description>
<arg name="mode" type="uint" enum="mode" summary="the decoration mode"/>
</event>
</interface>
</protocol>

File diff suppressed because it is too large Load Diff

6547
raylib/external/glfw/include/GLFW/glfw3.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,663 @@
/*************************************************************************
* GLFW 3.4 - www.glfw.org
* A library for OpenGL, window and input
*------------------------------------------------------------------------
* Copyright (c) 2002-2006 Marcus Geelnard
* Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would
* be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not
* be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*
*************************************************************************/
#ifndef _glfw3_native_h_
#define _glfw3_native_h_
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
* Doxygen documentation
*************************************************************************/
/*! @file glfw3native.h
* @brief The header of the native access functions.
*
* This is the header file of the native access functions. See @ref native for
* more information.
*/
/*! @defgroup native Native access
* @brief Functions related to accessing native handles.
*
* **By using the native access functions you assert that you know what you're
* doing and how to fix problems caused by using them. If you don't, you
* shouldn't be using them.**
*
* Before the inclusion of @ref glfw3native.h, you may define zero or more
* window system API macro and zero or more context creation API macros.
*
* The chosen backends must match those the library was compiled for. Failure
* to do this will cause a link-time error.
*
* The available window API macros are:
* * `GLFW_EXPOSE_NATIVE_WIN32`
* * `GLFW_EXPOSE_NATIVE_COCOA`
* * `GLFW_EXPOSE_NATIVE_X11`
* * `GLFW_EXPOSE_NATIVE_WAYLAND`
*
* The available context API macros are:
* * `GLFW_EXPOSE_NATIVE_WGL`
* * `GLFW_EXPOSE_NATIVE_NSGL`
* * `GLFW_EXPOSE_NATIVE_GLX`
* * `GLFW_EXPOSE_NATIVE_EGL`
* * `GLFW_EXPOSE_NATIVE_OSMESA`
*
* These macros select which of the native access functions that are declared
* and which platform-specific headers to include. It is then up your (by
* definition platform-specific) code to handle which of these should be
* defined.
*
* If you do not want the platform-specific headers to be included, define
* `GLFW_NATIVE_INCLUDE_NONE` before including the @ref glfw3native.h header.
*
* @code
* #define GLFW_EXPOSE_NATIVE_WIN32
* #define GLFW_EXPOSE_NATIVE_WGL
* #define GLFW_NATIVE_INCLUDE_NONE
* #include <GLFW/glfw3native.h>
* @endcode
*/
/*************************************************************************
* System headers and types
*************************************************************************/
#if !defined(GLFW_NATIVE_INCLUDE_NONE)
#if defined(GLFW_EXPOSE_NATIVE_WIN32) || defined(GLFW_EXPOSE_NATIVE_WGL)
/* This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
* example to allow applications to correctly declare a GL_KHR_debug callback)
* but windows.h assumes no one will define APIENTRY before it does
*/
#if defined(GLFW_APIENTRY_DEFINED)
#undef APIENTRY
#undef GLFW_APIENTRY_DEFINED
#endif
#include <windows.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA) || defined(GLFW_EXPOSE_NATIVE_NSGL)
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
#include <ApplicationServices/ApplicationServices.h>
#include <objc/objc.h>
#endif
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11) || defined(GLFW_EXPOSE_NATIVE_GLX)
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
#include <wayland-client.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/* WGL is declared by windows.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/* NSGL is declared by Cocoa.h */
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, glx.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/glx.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
#include <EGL/egl.h>
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/* This is a workaround for the fact that glfw3.h defines GLAPIENTRY because by
* default it also acts as an OpenGL header
* However, osmesa.h will include gl.h, which will define it unconditionally
*/
#if defined(GLFW_GLAPIENTRY_DEFINED)
#undef GLAPIENTRY
#undef GLFW_GLAPIENTRY_DEFINED
#endif
#include <GL/osmesa.h>
#endif
#endif /*GLFW_NATIVE_INCLUDE_NONE*/
/*************************************************************************
* Functions
*************************************************************************/
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
/*! @brief Returns the adapter device name of the specified monitor.
*
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
* occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
/*! @brief Returns the display device name of the specified monitor.
*
* @return The UTF-8 encoded display device name (for example
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `HWND` of the specified window.
*
* @return The `HWND` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WGL)
/*! @brief Returns the `HGLRC` of the specified window.
*
* @return The `HGLRC` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @remark The `HDC` associated with the window can be queried with the
* [GetDC](https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getdc)
* function.
* @code
* HDC dc = GetDC(glfwGetWin32Window(window));
* @endcode
* This DC is private and does not need to be released.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
*
* @return The `CGDirectDisplayID` of the specified monitor, or
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
/*! @brief Returns the `NSWindow` of the specified window.
*
* @return The `NSWindow` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
/*! @brief Returns the `NSView` of the specified window.
*
* @return The `NSView` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.4.
*
* @ingroup native
*/
GLFWAPI id glfwGetCocoaView(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
/*! @brief Returns the `NSOpenGLContext` of the specified window.
*
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_X11)
/*! @brief Returns the `Display` used by GLFW.
*
* @return The `Display` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Display* glfwGetX11Display(void);
/*! @brief Returns the `RRCrtc` of the specified monitor.
*
* @return The `RRCrtc` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
/*! @brief Returns the `RROutput` of the specified monitor.
*
* @return The `RROutput` of the specified monitor, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.1.
*
* @ingroup native
*/
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
/*! @brief Returns the `Window` of the specified window.
*
* @return The `Window` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
/*! @brief Sets the current primary selection to the specified string.
*
* @param[in] string A UTF-8 encoded string.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The specified string is copied before this function
* returns.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwGetX11SelectionString
* @sa glfwSetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI void glfwSetX11SelectionString(const char* string);
/*! @brief Returns the contents of the current primary selection as a string.
*
* If the selection is empty or if its contents cannot be converted, `NULL`
* is returned and a @ref GLFW_FORMAT_UNAVAILABLE error is generated.
*
* @return The contents of the selection as a UTF-8 encoded string, or `NULL`
* if an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
*
* @pointer_lifetime The returned string is allocated and freed by GLFW. You
* should not free it yourself. It is valid until the next call to @ref
* glfwGetX11SelectionString or @ref glfwSetX11SelectionString, or until the
* library is terminated.
*
* @thread_safety This function must only be called from the main thread.
*
* @sa @ref clipboard
* @sa glfwSetX11SelectionString
* @sa glfwGetClipboardString
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI const char* glfwGetX11SelectionString(void);
#endif
#if defined(GLFW_EXPOSE_NATIVE_GLX)
/*! @brief Returns the `GLXContext` of the specified window.
*
* @return The `GLXContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
/*! @brief Returns the `GLXWindow` of the specified window.
*
* @return The `GLXWindow` of the specified window, or `None` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
/*! @brief Returns the `struct wl_display*` used by GLFW.
*
* @return The `struct wl_display*` used by GLFW, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_display* glfwGetWaylandDisplay(void);
/*! @brief Returns the `struct wl_output*` of the specified monitor.
*
* @return The `struct wl_output*` of the specified monitor, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* monitor);
/*! @brief Returns the main `struct wl_surface*` of the specified window.
*
* @return The main `struct wl_surface*` of the specified window, or `NULL` if
* an [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_UNAVAILABLE.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.2.
*
* @ingroup native
*/
GLFWAPI struct wl_surface* glfwGetWaylandWindow(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_EGL)
/*! @brief Returns the `EGLDisplay` used by GLFW.
*
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
*
* @remark Because EGL is initialized on demand, this function will return
* `EGL_NO_DISPLAY` until the first context has been created via EGL.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
/*! @brief Returns the `EGLContext` of the specified window.
*
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
/*! @brief Returns the `EGLSurface` of the specified window.
*
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.0.
*
* @ingroup native
*/
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
#endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)
/*! @brief Retrieves the color buffer associated with the specified window.
*
* @param[in] window The window whose color buffer to retrieve.
* @param[out] width Where to store the width of the color buffer, or `NULL`.
* @param[out] height Where to store the height of the color buffer, or `NULL`.
* @param[out] format Where to store the OSMesa pixel format of the color
* buffer, or `NULL`.
* @param[out] buffer Where to store the address of the color buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* window, int* width, int* height, int* format, void** buffer);
/*! @brief Retrieves the depth buffer associated with the specified window.
*
* @param[in] window The window whose depth buffer to retrieve.
* @param[out] width Where to store the width of the depth buffer, or `NULL`.
* @param[out] height Where to store the height of the depth buffer, or `NULL`.
* @param[out] bytesPerValue Where to store the number of bytes per depth
* buffer element, or `NULL`.
* @param[out] buffer Where to store the address of the depth buffer, or
* `NULL`.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* window, int* width, int* height, int* bytesPerValue, void** buffer);
/*! @brief Returns the `OSMesaContext` of the specified window.
*
* @return The `OSMesaContext` of the specified window, or `NULL` if an
* [error](@ref error_handling) occurred.
*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_NO_WINDOW_CONTEXT.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.3.
*
* @ingroup native
*/
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* window);
#endif
#ifdef __cplusplus
}
#endif
#endif /* _glfw3_native_h_ */

696
raylib/external/glfw/src/cocoa_init.m vendored Normal file
View File

@@ -0,0 +1,696 @@
//========================================================================
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_COCOA)
#include <sys/param.h> // For MAXPATHLEN
// Needed for _NSGetProgname
#include <crt_externs.h>
// Change to our application bundle's resources directory, if present
//
static void changeToResourcesDirectory(void)
{
char resourcesPath[MAXPATHLEN];
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return;
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
CFStringRef last = CFURLCopyLastPathComponent(resourcesURL);
if (CFStringCompare(CFSTR("Resources"), last, 0) != kCFCompareEqualTo)
{
CFRelease(last);
CFRelease(resourcesURL);
return;
}
CFRelease(last);
if (!CFURLGetFileSystemRepresentation(resourcesURL,
true,
(UInt8*) resourcesPath,
MAXPATHLEN))
{
CFRelease(resourcesURL);
return;
}
CFRelease(resourcesURL);
chdir(resourcesPath);
}
// Set up the menu bar (manually)
// This is nasty, nasty stuff -- calls to undocumented semi-private APIs that
// could go away at any moment, lots of stuff that really should be
// localize(d|able), etc. Add a nib to save us this horror.
//
static void createMenuBar(void)
{
NSString* appName = nil;
NSDictionary* bundleInfo = [[NSBundle mainBundle] infoDictionary];
NSString* nameKeys[] =
{
@"CFBundleDisplayName",
@"CFBundleName",
@"CFBundleExecutable",
};
// Try to figure out what the calling application is called
for (size_t i = 0; i < sizeof(nameKeys) / sizeof(nameKeys[0]); i++)
{
id name = bundleInfo[nameKeys[i]];
if (name &&
[name isKindOfClass:[NSString class]] &&
![name isEqualToString:@""])
{
appName = name;
break;
}
}
if (!appName)
{
char** progname = _NSGetProgname();
if (progname && *progname)
appName = @(*progname);
else
appName = @"GLFW Application";
}
NSMenu* bar = [[NSMenu alloc] init];
[NSApp setMainMenu:bar];
NSMenuItem* appMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
NSMenu* appMenu = [[NSMenu alloc] init];
[appMenuItem setSubmenu:appMenu];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"About %@", appName]
action:@selector(orderFrontStandardAboutPanel:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
NSMenu* servicesMenu = [[NSMenu alloc] init];
[NSApp setServicesMenu:servicesMenu];
[[appMenu addItemWithTitle:@"Services"
action:NULL
keyEquivalent:@""] setSubmenu:servicesMenu];
[servicesMenu release];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Hide %@", appName]
action:@selector(hide:)
keyEquivalent:@"h"];
[[appMenu addItemWithTitle:@"Hide Others"
action:@selector(hideOtherApplications:)
keyEquivalent:@"h"]
setKeyEquivalentModifierMask:NSEventModifierFlagOption | NSEventModifierFlagCommand];
[appMenu addItemWithTitle:@"Show All"
action:@selector(unhideAllApplications:)
keyEquivalent:@""];
[appMenu addItem:[NSMenuItem separatorItem]];
[appMenu addItemWithTitle:[NSString stringWithFormat:@"Quit %@", appName]
action:@selector(terminate:)
keyEquivalent:@"q"];
NSMenuItem* windowMenuItem =
[bar addItemWithTitle:@"" action:NULL keyEquivalent:@""];
[bar release];
NSMenu* windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
[NSApp setWindowsMenu:windowMenu];
[windowMenuItem setSubmenu:windowMenu];
[windowMenu addItemWithTitle:@"Minimize"
action:@selector(performMiniaturize:)
keyEquivalent:@"m"];
[windowMenu addItemWithTitle:@"Zoom"
action:@selector(performZoom:)
keyEquivalent:@""];
[windowMenu addItem:[NSMenuItem separatorItem]];
[windowMenu addItemWithTitle:@"Bring All to Front"
action:@selector(arrangeInFront:)
keyEquivalent:@""];
// TODO: Make this appear at the bottom of the menu (for consistency)
[windowMenu addItem:[NSMenuItem separatorItem]];
[[windowMenu addItemWithTitle:@"Enter Full Screen"
action:@selector(toggleFullScreen:)
keyEquivalent:@"f"]
setKeyEquivalentModifierMask:NSEventModifierFlagControl | NSEventModifierFlagCommand];
// Prior to Snow Leopard, we need to use this oddly-named semi-private API
// to get the application menu working properly.
SEL setAppleMenuSelector = NSSelectorFromString(@"setAppleMenu:");
[NSApp performSelector:setAppleMenuSelector withObject:appMenu];
}
// Create key code translation tables
//
static void createKeyTablesCocoa(void)
{
memset(_glfw.ns.keycodes, -1, sizeof(_glfw.ns.keycodes));
memset(_glfw.ns.scancodes, -1, sizeof(_glfw.ns.scancodes));
_glfw.ns.keycodes[0x1D] = GLFW_KEY_0;
_glfw.ns.keycodes[0x12] = GLFW_KEY_1;
_glfw.ns.keycodes[0x13] = GLFW_KEY_2;
_glfw.ns.keycodes[0x14] = GLFW_KEY_3;
_glfw.ns.keycodes[0x15] = GLFW_KEY_4;
_glfw.ns.keycodes[0x17] = GLFW_KEY_5;
_glfw.ns.keycodes[0x16] = GLFW_KEY_6;
_glfw.ns.keycodes[0x1A] = GLFW_KEY_7;
_glfw.ns.keycodes[0x1C] = GLFW_KEY_8;
_glfw.ns.keycodes[0x19] = GLFW_KEY_9;
_glfw.ns.keycodes[0x00] = GLFW_KEY_A;
_glfw.ns.keycodes[0x0B] = GLFW_KEY_B;
_glfw.ns.keycodes[0x08] = GLFW_KEY_C;
_glfw.ns.keycodes[0x02] = GLFW_KEY_D;
_glfw.ns.keycodes[0x0E] = GLFW_KEY_E;
_glfw.ns.keycodes[0x03] = GLFW_KEY_F;
_glfw.ns.keycodes[0x05] = GLFW_KEY_G;
_glfw.ns.keycodes[0x04] = GLFW_KEY_H;
_glfw.ns.keycodes[0x22] = GLFW_KEY_I;
_glfw.ns.keycodes[0x26] = GLFW_KEY_J;
_glfw.ns.keycodes[0x28] = GLFW_KEY_K;
_glfw.ns.keycodes[0x25] = GLFW_KEY_L;
_glfw.ns.keycodes[0x2E] = GLFW_KEY_M;
_glfw.ns.keycodes[0x2D] = GLFW_KEY_N;
_glfw.ns.keycodes[0x1F] = GLFW_KEY_O;
_glfw.ns.keycodes[0x23] = GLFW_KEY_P;
_glfw.ns.keycodes[0x0C] = GLFW_KEY_Q;
_glfw.ns.keycodes[0x0F] = GLFW_KEY_R;
_glfw.ns.keycodes[0x01] = GLFW_KEY_S;
_glfw.ns.keycodes[0x11] = GLFW_KEY_T;
_glfw.ns.keycodes[0x20] = GLFW_KEY_U;
_glfw.ns.keycodes[0x09] = GLFW_KEY_V;
_glfw.ns.keycodes[0x0D] = GLFW_KEY_W;
_glfw.ns.keycodes[0x07] = GLFW_KEY_X;
_glfw.ns.keycodes[0x10] = GLFW_KEY_Y;
_glfw.ns.keycodes[0x06] = GLFW_KEY_Z;
_glfw.ns.keycodes[0x27] = GLFW_KEY_APOSTROPHE;
_glfw.ns.keycodes[0x2A] = GLFW_KEY_BACKSLASH;
_glfw.ns.keycodes[0x2B] = GLFW_KEY_COMMA;
_glfw.ns.keycodes[0x18] = GLFW_KEY_EQUAL;
_glfw.ns.keycodes[0x32] = GLFW_KEY_GRAVE_ACCENT;
_glfw.ns.keycodes[0x21] = GLFW_KEY_LEFT_BRACKET;
_glfw.ns.keycodes[0x1B] = GLFW_KEY_MINUS;
_glfw.ns.keycodes[0x2F] = GLFW_KEY_PERIOD;
_glfw.ns.keycodes[0x1E] = GLFW_KEY_RIGHT_BRACKET;
_glfw.ns.keycodes[0x29] = GLFW_KEY_SEMICOLON;
_glfw.ns.keycodes[0x2C] = GLFW_KEY_SLASH;
_glfw.ns.keycodes[0x0A] = GLFW_KEY_WORLD_1;
_glfw.ns.keycodes[0x33] = GLFW_KEY_BACKSPACE;
_glfw.ns.keycodes[0x39] = GLFW_KEY_CAPS_LOCK;
_glfw.ns.keycodes[0x75] = GLFW_KEY_DELETE;
_glfw.ns.keycodes[0x7D] = GLFW_KEY_DOWN;
_glfw.ns.keycodes[0x77] = GLFW_KEY_END;
_glfw.ns.keycodes[0x24] = GLFW_KEY_ENTER;
_glfw.ns.keycodes[0x35] = GLFW_KEY_ESCAPE;
_glfw.ns.keycodes[0x7A] = GLFW_KEY_F1;
_glfw.ns.keycodes[0x78] = GLFW_KEY_F2;
_glfw.ns.keycodes[0x63] = GLFW_KEY_F3;
_glfw.ns.keycodes[0x76] = GLFW_KEY_F4;
_glfw.ns.keycodes[0x60] = GLFW_KEY_F5;
_glfw.ns.keycodes[0x61] = GLFW_KEY_F6;
_glfw.ns.keycodes[0x62] = GLFW_KEY_F7;
_glfw.ns.keycodes[0x64] = GLFW_KEY_F8;
_glfw.ns.keycodes[0x65] = GLFW_KEY_F9;
_glfw.ns.keycodes[0x6D] = GLFW_KEY_F10;
_glfw.ns.keycodes[0x67] = GLFW_KEY_F11;
_glfw.ns.keycodes[0x6F] = GLFW_KEY_F12;
_glfw.ns.keycodes[0x69] = GLFW_KEY_PRINT_SCREEN;
_glfw.ns.keycodes[0x6B] = GLFW_KEY_F14;
_glfw.ns.keycodes[0x71] = GLFW_KEY_F15;
_glfw.ns.keycodes[0x6A] = GLFW_KEY_F16;
_glfw.ns.keycodes[0x40] = GLFW_KEY_F17;
_glfw.ns.keycodes[0x4F] = GLFW_KEY_F18;
_glfw.ns.keycodes[0x50] = GLFW_KEY_F19;
_glfw.ns.keycodes[0x5A] = GLFW_KEY_F20;
_glfw.ns.keycodes[0x73] = GLFW_KEY_HOME;
_glfw.ns.keycodes[0x72] = GLFW_KEY_INSERT;
_glfw.ns.keycodes[0x7B] = GLFW_KEY_LEFT;
_glfw.ns.keycodes[0x3A] = GLFW_KEY_LEFT_ALT;
_glfw.ns.keycodes[0x3B] = GLFW_KEY_LEFT_CONTROL;
_glfw.ns.keycodes[0x38] = GLFW_KEY_LEFT_SHIFT;
_glfw.ns.keycodes[0x37] = GLFW_KEY_LEFT_SUPER;
_glfw.ns.keycodes[0x6E] = GLFW_KEY_MENU;
_glfw.ns.keycodes[0x47] = GLFW_KEY_NUM_LOCK;
_glfw.ns.keycodes[0x79] = GLFW_KEY_PAGE_DOWN;
_glfw.ns.keycodes[0x74] = GLFW_KEY_PAGE_UP;
_glfw.ns.keycodes[0x7C] = GLFW_KEY_RIGHT;
_glfw.ns.keycodes[0x3D] = GLFW_KEY_RIGHT_ALT;
_glfw.ns.keycodes[0x3E] = GLFW_KEY_RIGHT_CONTROL;
_glfw.ns.keycodes[0x3C] = GLFW_KEY_RIGHT_SHIFT;
_glfw.ns.keycodes[0x36] = GLFW_KEY_RIGHT_SUPER;
_glfw.ns.keycodes[0x31] = GLFW_KEY_SPACE;
_glfw.ns.keycodes[0x30] = GLFW_KEY_TAB;
_glfw.ns.keycodes[0x7E] = GLFW_KEY_UP;
_glfw.ns.keycodes[0x52] = GLFW_KEY_KP_0;
_glfw.ns.keycodes[0x53] = GLFW_KEY_KP_1;
_glfw.ns.keycodes[0x54] = GLFW_KEY_KP_2;
_glfw.ns.keycodes[0x55] = GLFW_KEY_KP_3;
_glfw.ns.keycodes[0x56] = GLFW_KEY_KP_4;
_glfw.ns.keycodes[0x57] = GLFW_KEY_KP_5;
_glfw.ns.keycodes[0x58] = GLFW_KEY_KP_6;
_glfw.ns.keycodes[0x59] = GLFW_KEY_KP_7;
_glfw.ns.keycodes[0x5B] = GLFW_KEY_KP_8;
_glfw.ns.keycodes[0x5C] = GLFW_KEY_KP_9;
_glfw.ns.keycodes[0x45] = GLFW_KEY_KP_ADD;
_glfw.ns.keycodes[0x41] = GLFW_KEY_KP_DECIMAL;
_glfw.ns.keycodes[0x4B] = GLFW_KEY_KP_DIVIDE;
_glfw.ns.keycodes[0x4C] = GLFW_KEY_KP_ENTER;
_glfw.ns.keycodes[0x51] = GLFW_KEY_KP_EQUAL;
_glfw.ns.keycodes[0x43] = GLFW_KEY_KP_MULTIPLY;
_glfw.ns.keycodes[0x4E] = GLFW_KEY_KP_SUBTRACT;
for (int scancode = 0; scancode < 256; scancode++)
{
// Store the reverse translation for faster key name lookup
if (_glfw.ns.keycodes[scancode] >= 0)
_glfw.ns.scancodes[_glfw.ns.keycodes[scancode]] = scancode;
}
}
// Retrieve Unicode data for the current keyboard layout
//
static GLFWbool updateUnicodeData(void)
{
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
}
_glfw.ns.inputSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!_glfw.ns.inputSource)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout input source");
return GLFW_FALSE;
}
_glfw.ns.unicodeData =
TISGetInputSourceProperty(_glfw.ns.inputSource,
kTISPropertyUnicodeKeyLayoutData);
if (!_glfw.ns.unicodeData)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to retrieve keyboard layout Unicode data");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
// Load HIToolbox.framework and the TIS symbols we need from it
//
static GLFWbool initializeTIS(void)
{
// This works only because Cocoa has already loaded it properly
_glfw.ns.tis.bundle =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.HIToolbox"));
if (!_glfw.ns.tis.bundle)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load HIToolbox.framework");
return GLFW_FALSE;
}
CFStringRef* kPropertyUnicodeKeyLayoutData =
CFBundleGetDataPointerForName(_glfw.ns.tis.bundle,
CFSTR("kTISPropertyUnicodeKeyLayoutData"));
_glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISCopyCurrentKeyboardLayoutInputSource"));
_glfw.ns.tis.GetInputSourceProperty =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("TISGetInputSourceProperty"));
_glfw.ns.tis.GetKbdType =
CFBundleGetFunctionPointerForName(_glfw.ns.tis.bundle,
CFSTR("LMGetKbdType"));
if (!kPropertyUnicodeKeyLayoutData ||
!TISCopyCurrentKeyboardLayoutInputSource ||
!TISGetInputSourceProperty ||
!LMGetKbdType)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to load TIS API symbols");
return GLFW_FALSE;
}
_glfw.ns.tis.kPropertyUnicodeKeyLayoutData =
*kPropertyUnicodeKeyLayoutData;
return updateUnicodeData();
}
@interface GLFWHelper : NSObject
@end
@implementation GLFWHelper
- (void)selectedKeyboardInputSourceChanged:(NSObject* )object
{
updateUnicodeData();
}
- (void)doNothing:(id)object
{
}
@end // GLFWHelper
@interface GLFWApplicationDelegate : NSObject <NSApplicationDelegate>
@end
@implementation GLFWApplicationDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
_glfwInputWindowCloseRequest(window);
return NSTerminateCancel;
}
- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
{
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
if (window->context.client != GLFW_NO_API)
[window->context.nsgl.object update];
}
_glfwPollMonitorsCocoa();
}
- (void)applicationWillFinishLaunching:(NSNotification *)notification
{
if (_glfw.hints.init.ns.menubar)
{
// Menu bar setup must go between sharedApplication and finishLaunching
// in order to properly emulate the behavior of NSApplicationMain
if ([[NSBundle mainBundle] pathForResource:@"MainMenu" ofType:@"nib"])
{
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:&_glfw.ns.nibObjects];
}
else
createMenuBar();
}
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification
{
_glfwPostEmptyEventCocoa();
[NSApp stop:nil];
}
- (void)applicationDidHide:(NSNotification *)notification
{
for (int i = 0; i < _glfw.monitorCount; i++)
_glfwRestoreVideoModeCocoa(_glfw.monitors[i]);
}
@end // GLFWApplicationDelegate
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwLoadLocalVulkanLoaderCocoa(void)
{
CFBundleRef bundle = CFBundleGetMainBundle();
if (!bundle)
return NULL;
CFURLRef frameworksUrl = CFBundleCopyPrivateFrameworksURL(bundle);
if (!frameworksUrl)
return NULL;
CFURLRef loaderUrl = CFURLCreateCopyAppendingPathComponent(
kCFAllocatorDefault, frameworksUrl, CFSTR("libvulkan.1.dylib"), false);
if (!loaderUrl)
{
CFRelease(frameworksUrl);
return NULL;
}
char path[PATH_MAX];
void* handle = NULL;
if (CFURLGetFileSystemRepresentation(loaderUrl, true, (UInt8*) path, sizeof(path) - 1))
handle = _glfwPlatformLoadModule(path);
CFRelease(loaderUrl);
CFRelease(frameworksUrl);
return handle;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform cocoa =
{
.platformID = GLFW_PLATFORM_COCOA,
.init = _glfwInitCocoa,
.terminate = _glfwTerminateCocoa,
.getCursorPos = _glfwGetCursorPosCocoa,
.setCursorPos = _glfwSetCursorPosCocoa,
.setCursorMode = _glfwSetCursorModeCocoa,
.setRawMouseMotion = _glfwSetRawMouseMotionCocoa,
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedCocoa,
.createCursor = _glfwCreateCursorCocoa,
.createStandardCursor = _glfwCreateStandardCursorCocoa,
.destroyCursor = _glfwDestroyCursorCocoa,
.setCursor = _glfwSetCursorCocoa,
.getScancodeName = _glfwGetScancodeNameCocoa,
.getKeyScancode = _glfwGetKeyScancodeCocoa,
.setClipboardString = _glfwSetClipboardStringCocoa,
.getClipboardString = _glfwGetClipboardStringCocoa,
.initJoysticks = _glfwInitJoysticksCocoa,
.terminateJoysticks = _glfwTerminateJoysticksCocoa,
.pollJoystick = _glfwPollJoystickCocoa,
.getMappingName = _glfwGetMappingNameCocoa,
.updateGamepadGUID = _glfwUpdateGamepadGUIDCocoa,
.freeMonitor = _glfwFreeMonitorCocoa,
.getMonitorPos = _glfwGetMonitorPosCocoa,
.getMonitorContentScale = _glfwGetMonitorContentScaleCocoa,
.getMonitorWorkarea = _glfwGetMonitorWorkareaCocoa,
.getVideoModes = _glfwGetVideoModesCocoa,
.getVideoMode = _glfwGetVideoModeCocoa,
.getGammaRamp = _glfwGetGammaRampCocoa,
.setGammaRamp = _glfwSetGammaRampCocoa,
.createWindow = _glfwCreateWindowCocoa,
.destroyWindow = _glfwDestroyWindowCocoa,
.setWindowTitle = _glfwSetWindowTitleCocoa,
.setWindowIcon = _glfwSetWindowIconCocoa,
.getWindowPos = _glfwGetWindowPosCocoa,
.setWindowPos = _glfwSetWindowPosCocoa,
.getWindowSize = _glfwGetWindowSizeCocoa,
.setWindowSize = _glfwSetWindowSizeCocoa,
.setWindowSizeLimits = _glfwSetWindowSizeLimitsCocoa,
.setWindowAspectRatio = _glfwSetWindowAspectRatioCocoa,
.getFramebufferSize = _glfwGetFramebufferSizeCocoa,
.getWindowFrameSize = _glfwGetWindowFrameSizeCocoa,
.getWindowContentScale = _glfwGetWindowContentScaleCocoa,
.iconifyWindow = _glfwIconifyWindowCocoa,
.restoreWindow = _glfwRestoreWindowCocoa,
.maximizeWindow = _glfwMaximizeWindowCocoa,
.showWindow = _glfwShowWindowCocoa,
.hideWindow = _glfwHideWindowCocoa,
.requestWindowAttention = _glfwRequestWindowAttentionCocoa,
.focusWindow = _glfwFocusWindowCocoa,
.setWindowMonitor = _glfwSetWindowMonitorCocoa,
.windowFocused = _glfwWindowFocusedCocoa,
.windowIconified = _glfwWindowIconifiedCocoa,
.windowVisible = _glfwWindowVisibleCocoa,
.windowMaximized = _glfwWindowMaximizedCocoa,
.windowHovered = _glfwWindowHoveredCocoa,
.framebufferTransparent = _glfwFramebufferTransparentCocoa,
.getWindowOpacity = _glfwGetWindowOpacityCocoa,
.setWindowResizable = _glfwSetWindowResizableCocoa,
.setWindowDecorated = _glfwSetWindowDecoratedCocoa,
.setWindowFloating = _glfwSetWindowFloatingCocoa,
.setWindowOpacity = _glfwSetWindowOpacityCocoa,
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughCocoa,
.pollEvents = _glfwPollEventsCocoa,
.waitEvents = _glfwWaitEventsCocoa,
.waitEventsTimeout = _glfwWaitEventsTimeoutCocoa,
.postEmptyEvent = _glfwPostEmptyEventCocoa,
.getEGLPlatform = _glfwGetEGLPlatformCocoa,
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayCocoa,
.getEGLNativeWindow = _glfwGetEGLNativeWindowCocoa,
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsCocoa,
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportCocoa,
.createWindowSurface = _glfwCreateWindowSurfaceCocoa
};
*platform = cocoa;
return GLFW_TRUE;
}
int _glfwInitCocoa(void)
{
@autoreleasepool {
_glfw.ns.helper = [[GLFWHelper alloc] init];
[NSThread detachNewThreadSelector:@selector(doNothing:)
toTarget:_glfw.ns.helper
withObject:nil];
[NSApplication sharedApplication];
_glfw.ns.delegate = [[GLFWApplicationDelegate alloc] init];
if (_glfw.ns.delegate == nil)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Failed to create application delegate");
return GLFW_FALSE;
}
[NSApp setDelegate:_glfw.ns.delegate];
NSEvent* (^block)(NSEvent*) = ^ NSEvent* (NSEvent* event)
{
if ([event modifierFlags] & NSEventModifierFlagCommand)
[[NSApp keyWindow] sendEvent:event];
return event;
};
_glfw.ns.keyUpMonitor =
[NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskKeyUp
handler:block];
if (_glfw.hints.init.ns.chdir)
changeToResourcesDirectory();
// Press and Hold prevents some keys from emitting repeated characters
NSDictionary* defaults = @{@"ApplePressAndHoldEnabled":@NO};
[[NSUserDefaults standardUserDefaults] registerDefaults:defaults];
[[NSNotificationCenter defaultCenter]
addObserver:_glfw.ns.helper
selector:@selector(selectedKeyboardInputSourceChanged:)
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
createKeyTablesCocoa();
_glfw.ns.eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
if (!_glfw.ns.eventSource)
return GLFW_FALSE;
CGEventSourceSetLocalEventsSuppressionInterval(_glfw.ns.eventSource, 0.0);
if (!initializeTIS())
return GLFW_FALSE;
_glfwPollMonitorsCocoa();
if (![[NSRunningApplication currentApplication] isFinishedLaunching])
[NSApp run];
// In case we are unbundled, make us a proper UI application
if (_glfw.hints.init.ns.menubar)
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
return GLFW_TRUE;
} // autoreleasepool
}
void _glfwTerminateCocoa(void)
{
@autoreleasepool {
if (_glfw.ns.inputSource)
{
CFRelease(_glfw.ns.inputSource);
_glfw.ns.inputSource = NULL;
_glfw.ns.unicodeData = nil;
}
if (_glfw.ns.eventSource)
{
CFRelease(_glfw.ns.eventSource);
_glfw.ns.eventSource = NULL;
}
if (_glfw.ns.delegate)
{
[NSApp setDelegate:nil];
[_glfw.ns.delegate release];
_glfw.ns.delegate = nil;
}
if (_glfw.ns.helper)
{
[[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.helper
name:NSTextInputContextKeyboardSelectionDidChangeNotification
object:nil];
[[NSNotificationCenter defaultCenter]
removeObserver:_glfw.ns.helper];
[_glfw.ns.helper release];
_glfw.ns.helper = nil;
}
if (_glfw.ns.keyUpMonitor)
[NSEvent removeMonitor:_glfw.ns.keyUpMonitor];
_glfw_free(_glfw.ns.clipboardString);
_glfwTerminateNSGL();
_glfwTerminateEGL();
_glfwTerminateOSMesa();
} // autoreleasepool
}
#endif // _GLFW_COCOA

View File

@@ -0,0 +1,49 @@
//========================================================================
// GLFW 3.4 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <IOKit/hid/IOHIDKeys.h>
#define GLFW_COCOA_JOYSTICK_STATE _GLFWjoystickNS ns;
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
// Cocoa-specific per-joystick data
//
typedef struct _GLFWjoystickNS
{
IOHIDDeviceRef device;
CFMutableArrayRef axes;
CFMutableArrayRef buttons;
CFMutableArrayRef hats;
} _GLFWjoystickNS;
GLFWbool _glfwInitJoysticksCocoa(void);
void _glfwTerminateJoysticksCocoa(void);
GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameCocoa(void);
void _glfwUpdateGamepadGUIDCocoa(char* guid);

View File

@@ -0,0 +1,485 @@
//========================================================================
// GLFW 3.4 Cocoa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2012 Torsten Walluhn <tw@mad-cad.net>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_COCOA)
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <CoreFoundation/CoreFoundation.h>
#include <Kernel/IOKit/hidsystem/IOHIDUsageTables.h>
// Joystick element information
//
typedef struct _GLFWjoyelementNS
{
IOHIDElementRef native;
uint32_t usage;
int index;
long minimum;
long maximum;
} _GLFWjoyelementNS;
// Returns the value of the specified element of the specified joystick
//
static long getElementValue(_GLFWjoystick* js, _GLFWjoyelementNS* element)
{
IOHIDValueRef valueRef;
long value = 0;
if (js->ns.device)
{
if (IOHIDDeviceGetValue(js->ns.device,
element->native,
&valueRef) == kIOReturnSuccess)
{
value = IOHIDValueGetIntegerValue(valueRef);
}
}
return value;
}
// Comparison function for matching the SDL element order
//
static CFComparisonResult compareElements(const void* fp,
const void* sp,
void* user)
{
const _GLFWjoyelementNS* fe = fp;
const _GLFWjoyelementNS* se = sp;
if (fe->usage < se->usage)
return kCFCompareLessThan;
if (fe->usage > se->usage)
return kCFCompareGreaterThan;
if (fe->index < se->index)
return kCFCompareLessThan;
if (fe->index > se->index)
return kCFCompareGreaterThan;
return kCFCompareEqualTo;
}
// Removes the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
_glfwInputJoystick(js, GLFW_DISCONNECTED);
for (int i = 0; i < CFArrayGetCount(js->ns.axes); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.axes, i));
CFRelease(js->ns.axes);
for (int i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.buttons, i));
CFRelease(js->ns.buttons);
for (int i = 0; i < CFArrayGetCount(js->ns.hats); i++)
_glfw_free((void*) CFArrayGetValueAtIndex(js->ns.hats, i));
CFRelease(js->ns.hats);
_glfwFreeJoystick(js);
}
// Callback for user-initiated joystick addition
//
static void matchCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
{
int jid;
char name[256];
char guid[33];
CFTypeRef property;
uint32_t vendor = 0, product = 0, version = 0;
_GLFWjoystick* js;
CFMutableArrayRef axes, buttons, hats;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].ns.device == device)
return;
}
CFArrayRef elements =
IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
// It is reportedly possible for this to fail on macOS 13 Ventura
// if the application does not have input monitoring permissions
if (!elements)
return;
axes = CFArrayCreateMutable(NULL, 0, NULL);
buttons = CFArrayCreateMutable(NULL, 0, NULL);
hats = CFArrayCreateMutable(NULL, 0, NULL);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
if (property)
{
CFStringGetCString(property,
name,
sizeof(name),
kCFStringEncodingUTF8);
}
else
strncpy(name, "Unknown", sizeof(name));
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVendorIDKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &vendor);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductIDKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &product);
property = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDVersionNumberKey));
if (property)
CFNumberGetValue(property, kCFNumberSInt32Type, &version);
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (vendor && product)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x0000%02x%02x0000",
(uint8_t) vendor, (uint8_t) (vendor >> 8),
(uint8_t) product, (uint8_t) (product >> 8),
(uint8_t) version, (uint8_t) (version >> 8));
}
else
{
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
for (CFIndex i = 0; i < CFArrayGetCount(elements); i++)
{
IOHIDElementRef native = (IOHIDElementRef)
CFArrayGetValueAtIndex(elements, i);
if (CFGetTypeID(native) != IOHIDElementGetTypeID())
continue;
const IOHIDElementType type = IOHIDElementGetType(native);
if ((type != kIOHIDElementTypeInput_Axis) &&
(type != kIOHIDElementTypeInput_Button) &&
(type != kIOHIDElementTypeInput_Misc))
{
continue;
}
CFMutableArrayRef target = NULL;
const uint32_t usage = IOHIDElementGetUsage(native);
const uint32_t page = IOHIDElementGetUsagePage(native);
if (page == kHIDPage_GenericDesktop)
{
switch (usage)
{
case kHIDUsage_GD_X:
case kHIDUsage_GD_Y:
case kHIDUsage_GD_Z:
case kHIDUsage_GD_Rx:
case kHIDUsage_GD_Ry:
case kHIDUsage_GD_Rz:
case kHIDUsage_GD_Slider:
case kHIDUsage_GD_Dial:
case kHIDUsage_GD_Wheel:
target = axes;
break;
case kHIDUsage_GD_Hatswitch:
target = hats;
break;
case kHIDUsage_GD_DPadUp:
case kHIDUsage_GD_DPadRight:
case kHIDUsage_GD_DPadDown:
case kHIDUsage_GD_DPadLeft:
case kHIDUsage_GD_SystemMainMenu:
case kHIDUsage_GD_Select:
case kHIDUsage_GD_Start:
target = buttons;
break;
}
}
else if (page == kHIDPage_Simulation)
{
switch (usage)
{
case kHIDUsage_Sim_Accelerator:
case kHIDUsage_Sim_Brake:
case kHIDUsage_Sim_Throttle:
case kHIDUsage_Sim_Rudder:
case kHIDUsage_Sim_Steering:
target = axes;
break;
}
}
else if (page == kHIDPage_Button || page == kHIDPage_Consumer)
target = buttons;
if (target)
{
_GLFWjoyelementNS* element = _glfw_calloc(1, sizeof(_GLFWjoyelementNS));
element->native = native;
element->usage = usage;
element->index = (int) CFArrayGetCount(target);
element->minimum = IOHIDElementGetLogicalMin(native);
element->maximum = IOHIDElementGetLogicalMax(native);
CFArrayAppendValue(target, element);
}
}
CFRelease(elements);
CFArraySortValues(axes, CFRangeMake(0, CFArrayGetCount(axes)),
compareElements, NULL);
CFArraySortValues(buttons, CFRangeMake(0, CFArrayGetCount(buttons)),
compareElements, NULL);
CFArraySortValues(hats, CFRangeMake(0, CFArrayGetCount(hats)),
compareElements, NULL);
js = _glfwAllocJoystick(name, guid,
(int) CFArrayGetCount(axes),
(int) CFArrayGetCount(buttons),
(int) CFArrayGetCount(hats));
js->ns.device = device;
js->ns.axes = axes;
js->ns.buttons = buttons;
js->ns.hats = hats;
_glfwInputJoystick(js, GLFW_CONNECTED);
}
// Callback for user-initiated joystick removal
//
static void removeCallback(void* context,
IOReturn result,
void* sender,
IOHIDDeviceRef device)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].connected && _glfw.joysticks[jid].ns.device == device)
{
closeJoystick(&_glfw.joysticks[jid]);
break;
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksCocoa(void)
{
CFMutableArrayRef matching;
const long usages[] =
{
kHIDUsage_GD_Joystick,
kHIDUsage_GD_GamePad,
kHIDUsage_GD_MultiAxisController
};
_glfw.ns.hidManager = IOHIDManagerCreate(kCFAllocatorDefault,
kIOHIDOptionsTypeNone);
matching = CFArrayCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeArrayCallBacks);
if (!matching)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to create array");
return GLFW_FALSE;
}
for (size_t i = 0; i < sizeof(usages) / sizeof(long); i++)
{
const long page = kHIDPage_GenericDesktop;
CFMutableDictionaryRef dict =
CFDictionaryCreateMutable(kCFAllocatorDefault,
0,
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (!dict)
continue;
CFNumberRef pageRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberLongType,
&page);
CFNumberRef usageRef = CFNumberCreate(kCFAllocatorDefault,
kCFNumberLongType,
&usages[i]);
if (pageRef && usageRef)
{
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsagePageKey),
pageRef);
CFDictionarySetValue(dict,
CFSTR(kIOHIDDeviceUsageKey),
usageRef);
CFArrayAppendValue(matching, dict);
}
if (pageRef)
CFRelease(pageRef);
if (usageRef)
CFRelease(usageRef);
CFRelease(dict);
}
IOHIDManagerSetDeviceMatchingMultiple(_glfw.ns.hidManager, matching);
CFRelease(matching);
IOHIDManagerRegisterDeviceMatchingCallback(_glfw.ns.hidManager,
&matchCallback, NULL);
IOHIDManagerRegisterDeviceRemovalCallback(_glfw.ns.hidManager,
&removeCallback, NULL);
IOHIDManagerScheduleWithRunLoop(_glfw.ns.hidManager,
CFRunLoopGetMain(),
kCFRunLoopDefaultMode);
IOHIDManagerOpen(_glfw.ns.hidManager, kIOHIDOptionsTypeNone);
// Execute the run loop once in order to register any initially-attached
// joysticks
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, false);
return GLFW_TRUE;
}
void _glfwTerminateJoysticksCocoa(void)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].connected)
closeJoystick(&_glfw.joysticks[jid]);
}
if (_glfw.ns.hidManager)
{
CFRelease(_glfw.ns.hidManager);
_glfw.ns.hidManager = NULL;
}
}
GLFWbool _glfwPollJoystickCocoa(_GLFWjoystick* js, int mode)
{
if (mode & _GLFW_POLL_AXES)
{
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.axes); i++)
{
_GLFWjoyelementNS* axis = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.axes, i);
const long raw = getElementValue(js, axis);
// Perform auto calibration
if (raw < axis->minimum)
axis->minimum = raw;
if (raw > axis->maximum)
axis->maximum = raw;
const long size = axis->maximum - axis->minimum;
if (size == 0)
_glfwInputJoystickAxis(js, (int) i, 0.f);
else
{
const float value = (2.f * (raw - axis->minimum) / size) - 1.f;
_glfwInputJoystickAxis(js, (int) i, value);
}
}
}
if (mode & _GLFW_POLL_BUTTONS)
{
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.buttons); i++)
{
_GLFWjoyelementNS* button = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.buttons, i);
const char value = getElementValue(js, button) - button->minimum;
const int state = (value > 0) ? GLFW_PRESS : GLFW_RELEASE;
_glfwInputJoystickButton(js, (int) i, state);
}
for (CFIndex i = 0; i < CFArrayGetCount(js->ns.hats); i++)
{
const int states[9] =
{
GLFW_HAT_UP,
GLFW_HAT_RIGHT_UP,
GLFW_HAT_RIGHT,
GLFW_HAT_RIGHT_DOWN,
GLFW_HAT_DOWN,
GLFW_HAT_LEFT_DOWN,
GLFW_HAT_LEFT,
GLFW_HAT_LEFT_UP,
GLFW_HAT_CENTERED
};
_GLFWjoyelementNS* hat = (_GLFWjoyelementNS*)
CFArrayGetValueAtIndex(js->ns.hats, i);
long state = getElementValue(js, hat) - hat->minimum;
if (state < 0 || state > 8)
state = 8;
_glfwInputJoystickHat(js, (int) i, states[state]);
}
}
return js->connected;
}
const char* _glfwGetMappingNameCocoa(void)
{
return "Mac OS X";
}
void _glfwUpdateGamepadGUIDCocoa(char* guid)
{
if ((strncmp(guid + 4, "000000000000", 12) == 0) &&
(strncmp(guid + 20, "000000000000", 12) == 0))
{
char original[33];
strncpy(original, guid, sizeof(original) - 1);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 16);
}
}
#endif // _GLFW_COCOA

644
raylib/external/glfw/src/cocoa_monitor.m vendored Normal file
View File

@@ -0,0 +1,644 @@
//========================================================================
// GLFW 3.4 macOS (modified for raylib) - www.glfw.org; www.raylib.com
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_COCOA)
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <IOKit/graphics/IOGraphicsLib.h>
#include <ApplicationServices/ApplicationServices.h>
// Get the name of the specified display, or NULL
//
static char* getMonitorName(CGDirectDisplayID displayID, NSScreen* screen)
{
// IOKit doesn't work on Apple Silicon anymore
// Luckily, 10.15 introduced -[NSScreen localizedName].
// Use it if available, and fall back to IOKit otherwise.
if (screen)
{
if ([screen respondsToSelector:@selector(localizedName)])
{
NSString* name = [screen valueForKey:@"localizedName"];
if (name)
return _glfw_strdup([name UTF8String]);
}
}
io_iterator_t it;
io_service_t service;
CFDictionaryRef info;
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IODisplayConnect"),
&it) != 0)
{
// This may happen if a desktop Mac is running headless
return _glfw_strdup("Display");
}
while ((service = IOIteratorNext(it)) != 0)
{
info = IODisplayCreateInfoDictionary(service,
kIODisplayOnlyPreferredName);
CFNumberRef vendorIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayVendorID));
CFNumberRef productIDRef =
CFDictionaryGetValue(info, CFSTR(kDisplayProductID));
if (!vendorIDRef || !productIDRef)
{
CFRelease(info);
continue;
}
unsigned int vendorID, productID;
CFNumberGetValue(vendorIDRef, kCFNumberIntType, &vendorID);
CFNumberGetValue(productIDRef, kCFNumberIntType, &productID);
if (CGDisplayVendorNumber(displayID) == vendorID &&
CGDisplayModelNumber(displayID) == productID)
{
// Info dictionary is used and freed below
break;
}
CFRelease(info);
}
IOObjectRelease(it);
if (!service)
return _glfw_strdup("Display");
CFDictionaryRef names =
CFDictionaryGetValue(info, CFSTR(kDisplayProductName));
CFStringRef nameRef;
if (!names || !CFDictionaryGetValueIfPresent(names, CFSTR("en_US"),
(const void**) &nameRef))
{
// This may happen if a desktop Mac is running headless
CFRelease(info);
return _glfw_strdup("Display");
}
const CFIndex size =
CFStringGetMaximumSizeForEncoding(CFStringGetLength(nameRef),
kCFStringEncodingUTF8);
char* name = _glfw_calloc(size + 1, 1);
CFStringGetCString(nameRef, name, size, kCFStringEncodingUTF8);
CFRelease(info);
return name;
}
// Check whether the display mode should be included in enumeration
//
static GLFWbool modeIsGood(CGDisplayModeRef mode)
{
uint32_t flags = CGDisplayModeGetIOFlags(mode);
if (!(flags & kDisplayModeValidFlag) || !(flags & kDisplayModeSafeFlag))
return GLFW_FALSE;
if (flags & kDisplayModeInterlacedFlag)
return GLFW_FALSE;
if (flags & kDisplayModeStretchedFlag)
return GLFW_FALSE;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) &&
CFStringCompare(format, CFSTR(IO32BitDirectPixels), 0))
{
CFRelease(format);
return GLFW_FALSE;
}
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return GLFW_TRUE;
}
// Convert Core Graphics display mode to GLFW video mode
//
static GLFWvidmode vidmodeFromCGDisplayMode(CGDisplayModeRef mode,
double fallbackRefreshRate)
{
GLFWvidmode result;
result.width = (int) CGDisplayModeGetWidth(mode);
result.height = (int) CGDisplayModeGetHeight(mode);
result.refreshRate = (int) round(CGDisplayModeGetRefreshRate(mode));
if (result.refreshRate == 0)
result.refreshRate = (int) round(fallbackRefreshRate);
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFStringRef format = CGDisplayModeCopyPixelEncoding(mode);
if (CFStringCompare(format, CFSTR(IO16BitDirectPixels), 0) == 0)
{
result.redBits = 5;
result.greenBits = 5;
result.blueBits = 5;
}
else
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
{
result.redBits = 8;
result.greenBits = 8;
result.blueBits = 8;
}
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101100
CFRelease(format);
#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
return result;
}
// Starts reservation for display fading
//
static CGDisplayFadeReservationToken beginFadeReservation(void)
{
CGDisplayFadeReservationToken token = kCGDisplayFadeReservationInvalidToken;
if (CGAcquireDisplayFadeReservation(5, &token) == kCGErrorSuccess)
{
CGDisplayFade(token, 0.3,
kCGDisplayBlendNormal,
kCGDisplayBlendSolidColor,
0.0, 0.0, 0.0,
TRUE);
}
return token;
}
// Ends reservation for display fading
//
static void endFadeReservation(CGDisplayFadeReservationToken token)
{
if (token != kCGDisplayFadeReservationInvalidToken)
{
CGDisplayFade(token, 0.5,
kCGDisplayBlendSolidColor,
kCGDisplayBlendNormal,
0.0, 0.0, 0.0,
FALSE);
CGReleaseDisplayFadeReservation(token);
}
}
// Returns the display refresh rate queried from the I/O registry
//
static double getFallbackRefreshRate(CGDirectDisplayID displayID)
{
double refreshRate = 60.0;
io_iterator_t it;
io_service_t service;
if (IOServiceGetMatchingServices(MACH_PORT_NULL,
IOServiceMatching("IOFramebuffer"),
&it) != 0)
{
return refreshRate;
}
while ((service = IOIteratorNext(it)) != 0)
{
const CFNumberRef indexRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFramebufferOpenGLIndex"),
kCFAllocatorDefault,
kNilOptions);
if (!indexRef)
continue;
uint32_t index = 0;
CFNumberGetValue(indexRef, kCFNumberIntType, &index);
CFRelease(indexRef);
if (CGOpenGLDisplayMaskToDisplayID(1 << index) != displayID)
continue;
const CFNumberRef clockRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFBCurrentPixelClock"),
kCFAllocatorDefault,
kNilOptions);
const CFNumberRef countRef =
IORegistryEntryCreateCFProperty(service,
CFSTR("IOFBCurrentPixelCount"),
kCFAllocatorDefault,
kNilOptions);
uint32_t clock = 0, count = 0;
if (clockRef)
{
CFNumberGetValue(clockRef, kCFNumberIntType, &clock);
CFRelease(clockRef);
}
if (countRef)
{
CFNumberGetValue(countRef, kCFNumberIntType, &count);
CFRelease(countRef);
}
if (clock > 0 && count > 0)
refreshRate = clock / (double) count;
break;
}
IOObjectRelease(it);
return refreshRate;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsCocoa(void)
{
uint32_t displayCount;
CGGetOnlineDisplayList(0, NULL, &displayCount);
CGDirectDisplayID* displays = _glfw_calloc(displayCount, sizeof(CGDirectDisplayID));
CGGetOnlineDisplayList(displayCount, displays, &displayCount);
for (int i = 0; i < _glfw.monitorCount; i++)
_glfw.monitors[i]->ns.screen = nil;
_GLFWmonitor** disconnected = NULL;
uint32_t disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (uint32_t i = 0; i < displayCount; i++)
{
if (CGDisplayIsAsleep(displays[i]))
continue;
const uint32_t unitNumber = CGDisplayUnitNumber(displays[i]);
NSScreen* screen = nil;
for (screen in [NSScreen screens])
{
NSNumber* screenNumber = [screen deviceDescription][@"NSScreenNumber"];
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
if (CGDisplayUnitNumber([screenNumber unsignedIntValue]) == unitNumber)
break;
}
// HACK: Compare unit numbers instead of display IDs to work around
// display replacement on machines with automatic graphics
// switching
uint32_t j;
for (j = 0; j < disconnectedCount; j++)
{
if (disconnected[j] && disconnected[j]->ns.unitNumber == unitNumber)
{
disconnected[j]->ns.screen = screen;
disconnected[j] = NULL;
break;
}
}
if (j < disconnectedCount)
continue;
const CGSize size = CGDisplayScreenSize(displays[i]);
char* name = getMonitorName(displays[i], screen);
if (!name)
continue;
_GLFWmonitor* monitor = _glfwAllocMonitor(name, size.width, size.height);
monitor->ns.displayID = displays[i];
monitor->ns.unitNumber = unitNumber;
monitor->ns.screen = screen;
_glfw_free(name);
CGDisplayModeRef mode = CGDisplayCopyDisplayMode(displays[i]);
if (CGDisplayModeGetRefreshRate(mode) == 0.0)
monitor->ns.fallbackRefreshRate = getFallbackRefreshRate(displays[i]);
CGDisplayModeRelease(mode);
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
for (uint32_t i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
_glfw_free(disconnected);
_glfw_free(displays);
}
// Change the current video mode
//
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
GLFWvidmode current;
_glfwGetVideoModeCocoa(monitor, &current);
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex count = CFArrayGetCount(modes);
CGDisplayModeRef native = NULL;
for (CFIndex i = 0; i < count; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
if (_glfwCompareVideoModes(best, &mode) == 0)
{
native = dm;
break;
}
}
if (native)
{
if (monitor->ns.previousMode == NULL)
monitor->ns.previousMode = CGDisplayCopyDisplayMode(monitor->ns.displayID);
CGDisplayFadeReservationToken token = beginFadeReservation();
CGDisplaySetDisplayMode(monitor->ns.displayID, native, NULL);
endFadeReservation(token);
}
CFRelease(modes);
}
// Restore the previously saved (original) video mode
//
void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor)
{
if (monitor->ns.previousMode)
{
CGDisplayFadeReservationToken token = beginFadeReservation();
CGDisplaySetDisplayMode(monitor->ns.displayID,
monitor->ns.previousMode, NULL);
endFadeReservation(token);
CGDisplayModeRelease(monitor->ns.previousMode);
monitor->ns.previousMode = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor)
{
}
void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
@autoreleasepool {
const CGRect bounds = CGDisplayBounds(monitor->ns.displayID);
if (xpos)
*xpos = (int) bounds.origin.x;
if (ypos)
*ypos = (int) bounds.origin.y;
} // autoreleasepool
}
void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
@autoreleasepool {
if (!monitor->ns.screen)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query content scale without screen");
}
const NSRect points = [monitor->ns.screen frame];
const NSRect pixels = [monitor->ns.screen convertRectToBacking:points];
if (xscale)
*xscale = (float) (pixels.size.width / points.size.width);
if (yscale)
*yscale = (float) (pixels.size.height / points.size.height);
} // autoreleasepool
}
void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
@autoreleasepool {
if (!monitor->ns.screen)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Cocoa: Cannot query workarea without screen");
}
const NSRect frameRect = [monitor->ns.screen visibleFrame];
if (xpos)
*xpos = frameRect.origin.x;
if (ypos)
*ypos = _glfwTransformYCocoa(frameRect.origin.y + frameRect.size.height - 1);
if (width)
*width = frameRect.size.width;
if (height)
*height = frameRect.size.height;
} // autoreleasepool
}
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count)
{
@autoreleasepool {
*count = 0;
CFArrayRef modes = CGDisplayCopyAllDisplayModes(monitor->ns.displayID, NULL);
const CFIndex found = CFArrayGetCount(modes);
GLFWvidmode* result = _glfw_calloc(found, sizeof(GLFWvidmode));
for (CFIndex i = 0; i < found; i++)
{
CGDisplayModeRef dm = (CGDisplayModeRef) CFArrayGetValueAtIndex(modes, i);
if (!modeIsGood(dm))
continue;
const GLFWvidmode mode =
vidmodeFromCGDisplayMode(dm, monitor->ns.fallbackRefreshRate);
CFIndex j;
for (j = 0; j < *count; j++)
{
if (_glfwCompareVideoModes(result + j, &mode) == 0)
break;
}
// Skip duplicate modes
if (j < *count)
continue;
(*count)++;
result[*count - 1] = mode;
}
CFRelease(modes);
return result;
} // autoreleasepool
}
GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode *mode)
{
@autoreleasepool {
CGDisplayModeRef native = CGDisplayCopyDisplayMode(monitor->ns.displayID);
if (!native)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Cocoa: Failed to query display mode");
return GLFW_FALSE;
}
*mode = vidmodeFromCGDisplayMode(native, monitor->ns.fallbackRefreshRate);
CGDisplayModeRelease(native);
return GLFW_TRUE;
} // autoreleasepool
}
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
@autoreleasepool {
uint32_t size = CGDisplayGammaTableCapacity(monitor->ns.displayID);
CGGammaValue* values = _glfw_calloc(size * 3, sizeof(CGGammaValue));
CGGetDisplayTransferByTable(monitor->ns.displayID,
size,
values,
values + size,
values + size * 2,
&size);
_glfwAllocGammaArrays(ramp, size);
for (uint32_t i = 0; i < size; i++)
{
ramp->red[i] = (unsigned short) (values[i] * 65535);
ramp->green[i] = (unsigned short) (values[i + size] * 65535);
ramp->blue[i] = (unsigned short) (values[i + size * 2] * 65535);
}
_glfw_free(values);
return GLFW_TRUE;
} // autoreleasepool
}
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
@autoreleasepool {
CGGammaValue* values = _glfw_calloc(ramp->size * 3, sizeof(CGGammaValue));
for (unsigned int i = 0; i < ramp->size; i++)
{
values[i] = ramp->red[i] / 65535.f;
values[i + ramp->size] = ramp->green[i] / 65535.f;
values[i + ramp->size * 2] = ramp->blue[i] / 65535.f;
}
CGSetDisplayTransferByTable(monitor->ns.displayID,
ramp->size,
values,
values + ramp->size,
values + ramp->size * 2);
_glfw_free(values);
} // autoreleasepool
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(kCGNullDirectDisplay);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Cocoa: Platform not initialized");
return kCGNullDirectDisplay;
}
return monitor->ns.displayID;
}
#endif // _GLFW_COCOA

View File

@@ -0,0 +1,302 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <stdint.h>
#include <Carbon/Carbon.h>
#include <IOKit/hid/IOHIDLib.h>
// NOTE: All of NSGL was deprecated in the 10.14 SDK
// This disables the pointless warnings for every symbol we use
#ifndef GL_SILENCE_DEPRECATION
#define GL_SILENCE_DEPRECATION
#endif
#if defined(__OBJC__)
#import <Cocoa/Cocoa.h>
#else
typedef void* id;
#endif
// NOTE: Many Cocoa enum values have been renamed and we need to build across
// SDK versions where one is unavailable or deprecated.
// We use the newer names in code and replace them with the older names if
// the base SDK does not provide the newer names.
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101400
#define NSOpenGLContextParameterSwapInterval NSOpenGLCPSwapInterval
#define NSOpenGLContextParameterSurfaceOpacity NSOpenGLCPSurfaceOpacity
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
#define NSBitmapFormatAlphaNonpremultiplied NSAlphaNonpremultipliedBitmapFormat
#define NSEventMaskAny NSAnyEventMask
#define NSEventMaskKeyUp NSKeyUpMask
#define NSEventModifierFlagCapsLock NSAlphaShiftKeyMask
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagControl NSControlKeyMask
#define NSEventModifierFlagDeviceIndependentFlagsMask NSDeviceIndependentModifierFlagsMask
#define NSEventModifierFlagOption NSAlternateKeyMask
#define NSEventModifierFlagShift NSShiftKeyMask
#define NSEventTypeApplicationDefined NSApplicationDefined
#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
#define NSWindowStyleMaskClosable NSClosableWindowMask
#define NSWindowStyleMaskMiniaturizable NSMiniaturizableWindowMask
#define NSWindowStyleMaskResizable NSResizableWindowMask
#define NSWindowStyleMaskTitled NSTitledWindowMask
#endif
// NOTE: Many Cocoa dynamically linked constants have been renamed and we need
// to build across SDK versions where one is unavailable or deprecated.
// We use the newer names in code and replace them with the older names if
// the deployment target is older than the newer names.
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101300
#define NSPasteboardTypeURL NSURLPboardType
#endif
typedef VkFlags VkMacOSSurfaceCreateFlagsMVK;
typedef VkFlags VkMetalSurfaceCreateFlagsEXT;
typedef struct VkMacOSSurfaceCreateInfoMVK
{
VkStructureType sType;
const void* pNext;
VkMacOSSurfaceCreateFlagsMVK flags;
const void* pView;
} VkMacOSSurfaceCreateInfoMVK;
typedef struct VkMetalSurfaceCreateInfoEXT
{
VkStructureType sType;
const void* pNext;
VkMetalSurfaceCreateFlagsEXT flags;
const void* pLayer;
} VkMetalSurfaceCreateInfoEXT;
typedef VkResult (APIENTRY *PFN_vkCreateMacOSSurfaceMVK)(VkInstance,const VkMacOSSurfaceCreateInfoMVK*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkResult (APIENTRY *PFN_vkCreateMetalSurfaceEXT)(VkInstance,const VkMetalSurfaceCreateInfoEXT*,const VkAllocationCallbacks*,VkSurfaceKHR*);
#define GLFW_COCOA_WINDOW_STATE _GLFWwindowNS ns;
#define GLFW_COCOA_LIBRARY_WINDOW_STATE _GLFWlibraryNS ns;
#define GLFW_COCOA_MONITOR_STATE _GLFWmonitorNS ns;
#define GLFW_COCOA_CURSOR_STATE _GLFWcursorNS ns;
#define GLFW_NSGL_CONTEXT_STATE _GLFWcontextNSGL nsgl;
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE _GLFWlibraryNSGL nsgl;
// HIToolbox.framework pointer typedefs
#define kTISPropertyUnicodeKeyLayoutData _glfw.ns.tis.kPropertyUnicodeKeyLayoutData
typedef TISInputSourceRef (*PFN_TISCopyCurrentKeyboardLayoutInputSource)(void);
#define TISCopyCurrentKeyboardLayoutInputSource _glfw.ns.tis.CopyCurrentKeyboardLayoutInputSource
typedef void* (*PFN_TISGetInputSourceProperty)(TISInputSourceRef,CFStringRef);
#define TISGetInputSourceProperty _glfw.ns.tis.GetInputSourceProperty
typedef UInt8 (*PFN_LMGetKbdType)(void);
#define LMGetKbdType _glfw.ns.tis.GetKbdType
// NSGL-specific per-context data
//
typedef struct _GLFWcontextNSGL
{
id pixelFormat;
id object;
} _GLFWcontextNSGL;
// NSGL-specific global data
//
typedef struct _GLFWlibraryNSGL
{
// dlopen handle for OpenGL.framework (for glfwGetProcAddress)
CFBundleRef framework;
} _GLFWlibraryNSGL;
// Cocoa-specific per-window data
//
typedef struct _GLFWwindowNS
{
id object;
id delegate;
id view;
id layer;
GLFWbool maximized;
GLFWbool occluded;
GLFWbool scaleFramebuffer;
// Cached window properties to filter out duplicate events
int width, height;
int fbWidth, fbHeight;
float xscale, yscale;
// The total sum of the distances the cursor has been warped
// since the last cursor motion event was processed
// This is kept to counteract Cocoa doing the same internally
double cursorWarpDeltaX, cursorWarpDeltaY;
} _GLFWwindowNS;
// Cocoa-specific global data
//
typedef struct _GLFWlibraryNS
{
CGEventSourceRef eventSource;
id delegate;
GLFWbool cursorHidden;
TISInputSourceRef inputSource;
IOHIDManagerRef hidManager;
id unicodeData;
id helper;
id keyUpMonitor;
id nibObjects;
char keynames[GLFW_KEY_LAST + 1][17];
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char* clipboardString;
CGPoint cascadePoint;
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
struct {
CFBundleRef bundle;
PFN_TISCopyCurrentKeyboardLayoutInputSource CopyCurrentKeyboardLayoutInputSource;
PFN_TISGetInputSourceProperty GetInputSourceProperty;
PFN_LMGetKbdType GetKbdType;
CFStringRef kPropertyUnicodeKeyLayoutData;
} tis;
} _GLFWlibraryNS;
// Cocoa-specific per-monitor data
//
typedef struct _GLFWmonitorNS
{
CGDirectDisplayID displayID;
CGDisplayModeRef previousMode;
uint32_t unitNumber;
id screen;
double fallbackRefreshRate;
} _GLFWmonitorNS;
// Cocoa-specific per-cursor data
//
typedef struct _GLFWcursorNS
{
id object;
} _GLFWcursorNS;
GLFWbool _glfwConnectCocoa(int platformID, _GLFWplatform* platform);
int _glfwInitCocoa(void);
void _glfwTerminateCocoa(void);
GLFWbool _glfwCreateWindowCocoa(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowTitleCocoa(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconCocoa(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosCocoa(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosCocoa(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeCocoa(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsCocoa(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioCocoa(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeCocoa(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeCocoa(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleCocoa(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowCocoa(_GLFWwindow* window);
void _glfwRestoreWindowCocoa(_GLFWwindow* window);
void _glfwMaximizeWindowCocoa(_GLFWwindow* window);
void _glfwShowWindowCocoa(_GLFWwindow* window);
void _glfwHideWindowCocoa(_GLFWwindow* window);
void _glfwRequestWindowAttentionCocoa(_GLFWwindow* window);
void _glfwFocusWindowCocoa(_GLFWwindow* window);
void _glfwSetWindowMonitorCocoa(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedCocoa(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredCocoa(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentCocoa(_GLFWwindow* window);
void _glfwSetWindowResizableCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingCocoa(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityCocoa(_GLFWwindow* window);
void _glfwSetWindowOpacityCocoa(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughCocoa(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionCocoa(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedCocoa(void);
void _glfwPollEventsCocoa(void);
void _glfwWaitEventsCocoa(void);
void _glfwWaitEventsTimeoutCocoa(double timeout);
void _glfwPostEmptyEventCocoa(void);
void _glfwGetCursorPosCocoa(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosCocoa(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeCocoa(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameCocoa(int scancode);
int _glfwGetKeyScancodeCocoa(int key);
GLFWbool _glfwCreateCursorCocoa(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorCocoa(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorCocoa(_GLFWcursor* cursor);
void _glfwSetCursorCocoa(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringCocoa(const char* string);
const char* _glfwGetClipboardStringCocoa(void);
EGLenum _glfwGetEGLPlatformCocoa(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayCocoa(void);
EGLNativeWindowType _glfwGetEGLNativeWindowCocoa(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsCocoa(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportCocoa(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceCocoa(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorCocoa(_GLFWmonitor* monitor);
void _glfwGetMonitorPosCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleCocoa(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaCocoa(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesCocoa(_GLFWmonitor* monitor, int* count);
GLFWbool _glfwGetVideoModeCocoa(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampCocoa(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampCocoa(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwPollMonitorsCocoa(void);
void _glfwSetVideoModeCocoa(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeCocoa(_GLFWmonitor* monitor);
float _glfwTransformYCocoa(float y);
void* _glfwLoadLocalVulkanLoaderCocoa(void);
GLFWbool _glfwInitNSGL(void);
void _glfwTerminateNSGL(void);
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
void _glfwDestroyContextNSGL(_GLFWwindow* window);

57
raylib/external/glfw/src/cocoa_time.c vendored Normal file
View File

@@ -0,0 +1,57 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_COCOA_TIMER)
#include <mach/mach_time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
_glfw.timer.ns.frequency = (info.denom * 1e9) / info.numer;
}
uint64_t _glfwPlatformGetTimerValue(void)
{
return mach_absolute_time();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.ns.frequency;
}
#endif // GLFW_BUILD_COCOA_TIMER

35
raylib/external/glfw/src/cocoa_time.h vendored Normal file
View File

@@ -0,0 +1,35 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_COCOA_LIBRARY_TIMER_STATE _GLFWtimerNS ns;
// Cocoa-specific global timer data
//
typedef struct _GLFWtimerNS
{
uint64_t frequency;
} _GLFWtimerNS;

2072
raylib/external/glfw/src/cocoa_window.m vendored Normal file

File diff suppressed because it is too large Load Diff

765
raylib/external/glfw/src/context.c vendored Normal file
View File

@@ -0,0 +1,765 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2016 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Checks whether the desired context attributes are valid
//
// This function checks things like whether the specified client API version
// exists and whether all relevant options have supported and non-conflicting
// values
//
GLFWbool _glfwIsValidContextConfig(const _GLFWctxconfig* ctxconfig)
{
if (ctxconfig->source != GLFW_NATIVE_CONTEXT_API &&
ctxconfig->source != GLFW_EGL_CONTEXT_API &&
ctxconfig->source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context creation API 0x%08X",
ctxconfig->source);
return GLFW_FALSE;
}
if (ctxconfig->client != GLFW_NO_API &&
ctxconfig->client != GLFW_OPENGL_API &&
ctxconfig->client != GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid client API 0x%08X",
ctxconfig->client);
return GLFW_FALSE;
}
if (ctxconfig->share)
{
if (ctxconfig->client == GLFW_NO_API ||
ctxconfig->share->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (ctxconfig->source != ctxconfig->share->context.source)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Context creation APIs do not match between contexts");
return GLFW_FALSE;
}
}
if (ctxconfig->client == GLFW_OPENGL_API)
{
if ((ctxconfig->major < 1 || ctxconfig->minor < 0) ||
(ctxconfig->major == 1 && ctxconfig->minor > 5) ||
(ctxconfig->major == 2 && ctxconfig->minor > 1) ||
(ctxconfig->major == 3 && ctxconfig->minor > 3))
{
// OpenGL 1.0 is the smallest valid version
// OpenGL 1.x series ended with version 1.5
// OpenGL 2.x series ended with version 2.1
// OpenGL 3.x series ended with version 3.3
// For now, let everything else through
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
}
if (ctxconfig->profile)
{
if (ctxconfig->profile != GLFW_OPENGL_CORE_PROFILE &&
ctxconfig->profile != GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid OpenGL profile 0x%08X",
ctxconfig->profile);
return GLFW_FALSE;
}
if (ctxconfig->major <= 2 ||
(ctxconfig->major == 3 && ctxconfig->minor < 2))
{
// Desktop OpenGL context profiles are only defined for version 3.2
// and above
_glfwInputError(GLFW_INVALID_VALUE,
"Context profiles are only defined for OpenGL version 3.2 and above");
return GLFW_FALSE;
}
}
if (ctxconfig->forward && ctxconfig->major <= 2)
{
// Forward-compatible contexts are only defined for OpenGL version 3.0 and above
_glfwInputError(GLFW_INVALID_VALUE,
"Forward-compatibility is only defined for OpenGL version 3.0 and above");
return GLFW_FALSE;
}
}
else if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major < 1 || ctxconfig->minor < 0 ||
(ctxconfig->major == 1 && ctxconfig->minor > 1) ||
(ctxconfig->major == 2 && ctxconfig->minor > 0))
{
// OpenGL ES 1.0 is the smallest valid version
// OpenGL ES 1.x series ended with version 1.1
// OpenGL ES 2.x series ended with version 2.0
// For now, let everything else through
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid OpenGL ES version %i.%i",
ctxconfig->major, ctxconfig->minor);
return GLFW_FALSE;
}
}
if (ctxconfig->robustness)
{
if (ctxconfig->robustness != GLFW_NO_RESET_NOTIFICATION &&
ctxconfig->robustness != GLFW_LOSE_CONTEXT_ON_RESET)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context robustness mode 0x%08X",
ctxconfig->robustness);
return GLFW_FALSE;
}
}
if (ctxconfig->release)
{
if (ctxconfig->release != GLFW_RELEASE_BEHAVIOR_NONE &&
ctxconfig->release != GLFW_RELEASE_BEHAVIOR_FLUSH)
{
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid context release behavior 0x%08X",
ctxconfig->release);
return GLFW_FALSE;
}
}
return GLFW_TRUE;
}
// Chooses the framebuffer config that best matches the desired one
//
const _GLFWfbconfig* _glfwChooseFBConfig(const _GLFWfbconfig* desired,
const _GLFWfbconfig* alternatives,
unsigned int count)
{
unsigned int i;
unsigned int missing, leastMissing = UINT_MAX;
unsigned int colorDiff, leastColorDiff = UINT_MAX;
unsigned int extraDiff, leastExtraDiff = UINT_MAX;
const _GLFWfbconfig* current;
const _GLFWfbconfig* closest = NULL;
for (i = 0; i < count; i++)
{
current = alternatives + i;
if (desired->stereo > 0 && current->stereo == 0)
{
// Stereo is a hard constraint
continue;
}
// Count number of missing buffers
{
missing = 0;
if (desired->alphaBits > 0 && current->alphaBits == 0)
missing++;
if (desired->depthBits > 0 && current->depthBits == 0)
missing++;
if (desired->stencilBits > 0 && current->stencilBits == 0)
missing++;
if (desired->auxBuffers > 0 &&
current->auxBuffers < desired->auxBuffers)
{
missing += desired->auxBuffers - current->auxBuffers;
}
if (desired->samples > 0 && current->samples == 0)
{
// Technically, several multisampling buffers could be
// involved, but that's a lower level implementation detail and
// not important to us here, so we count them as one
missing++;
}
if (desired->transparent != current->transparent)
missing++;
}
// These polynomials make many small channel size differences matter
// less than one large channel size difference
// Calculate color channel size difference value
{
colorDiff = 0;
if (desired->redBits != GLFW_DONT_CARE)
{
colorDiff += (desired->redBits - current->redBits) *
(desired->redBits - current->redBits);
}
if (desired->greenBits != GLFW_DONT_CARE)
{
colorDiff += (desired->greenBits - current->greenBits) *
(desired->greenBits - current->greenBits);
}
if (desired->blueBits != GLFW_DONT_CARE)
{
colorDiff += (desired->blueBits - current->blueBits) *
(desired->blueBits - current->blueBits);
}
}
// Calculate non-color channel size difference value
{
extraDiff = 0;
if (desired->alphaBits != GLFW_DONT_CARE)
{
extraDiff += (desired->alphaBits - current->alphaBits) *
(desired->alphaBits - current->alphaBits);
}
if (desired->depthBits != GLFW_DONT_CARE)
{
extraDiff += (desired->depthBits - current->depthBits) *
(desired->depthBits - current->depthBits);
}
if (desired->stencilBits != GLFW_DONT_CARE)
{
extraDiff += (desired->stencilBits - current->stencilBits) *
(desired->stencilBits - current->stencilBits);
}
if (desired->accumRedBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumRedBits - current->accumRedBits) *
(desired->accumRedBits - current->accumRedBits);
}
if (desired->accumGreenBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumGreenBits - current->accumGreenBits) *
(desired->accumGreenBits - current->accumGreenBits);
}
if (desired->accumBlueBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumBlueBits - current->accumBlueBits) *
(desired->accumBlueBits - current->accumBlueBits);
}
if (desired->accumAlphaBits != GLFW_DONT_CARE)
{
extraDiff += (desired->accumAlphaBits - current->accumAlphaBits) *
(desired->accumAlphaBits - current->accumAlphaBits);
}
if (desired->samples != GLFW_DONT_CARE)
{
extraDiff += (desired->samples - current->samples) *
(desired->samples - current->samples);
}
if (desired->sRGB && !current->sRGB)
extraDiff++;
}
// Figure out if the current one is better than the best one found so far
// Least number of missing buffers is the most important heuristic,
// then color buffer size match and lastly size match for other buffers
if (missing < leastMissing)
closest = current;
else if (missing == leastMissing)
{
if ((colorDiff < leastColorDiff) ||
(colorDiff == leastColorDiff && extraDiff < leastExtraDiff))
{
closest = current;
}
}
if (current == closest)
{
leastMissing = missing;
leastColorDiff = colorDiff;
leastExtraDiff = extraDiff;
}
}
return closest;
}
// Retrieves the attributes of the current context
//
GLFWbool _glfwRefreshContextAttribs(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig)
{
int i;
_GLFWwindow* previous;
const char* version;
const char* prefixes[] =
{
"OpenGL ES-CM ",
"OpenGL ES-CL ",
"OpenGL ES ",
NULL
};
window->context.source = ctxconfig->source;
window->context.client = GLFW_OPENGL_API;
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
glfwMakeContextCurrent((GLFWwindow*) window);
if (_glfwPlatformGetTls(&_glfw.contextSlot) != window)
return GLFW_FALSE;
window->context.GetIntegerv = (PFNGLGETINTEGERVPROC)
window->context.getProcAddress("glGetIntegerv");
window->context.GetString = (PFNGLGETSTRINGPROC)
window->context.getProcAddress("glGetString");
if (!window->context.GetIntegerv || !window->context.GetString)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
version = (const char*) window->context.GetString(GL_VERSION);
if (!version)
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL version string retrieval is broken");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OpenGL ES version string retrieval is broken");
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
for (i = 0; prefixes[i]; i++)
{
const size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0)
{
version += length;
window->context.client = GLFW_OPENGL_ES_API;
break;
}
}
if (!sscanf(version, "%d.%d.%d",
&window->context.major,
&window->context.minor,
&window->context.revision))
{
if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL version string");
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"No version found in OpenGL ES version string");
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
if (window->context.major < ctxconfig->major ||
(window->context.major == ctxconfig->major &&
window->context.minor < ctxconfig->minor))
{
// The desired OpenGL version is greater than the actual version
// This only happens if the machine lacks {GLX|WGL}_ARB_create_context
// /and/ the user has requested an OpenGL version greater than 1.0
// For API consistency, we emulate the behavior of the
// {GLX|WGL}_ARB_create_context extension and fail here
if (window->context.client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested OpenGL version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"Requested OpenGL ES version %i.%i, got version %i.%i",
ctxconfig->major, ctxconfig->minor,
window->context.major, window->context.minor);
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
if (window->context.major >= 3)
{
// OpenGL 3.0+ uses a different function for extension string retrieval
// We cache it here instead of in glfwExtensionSupported mostly to alert
// users as early as possible that their build may be broken
window->context.GetStringi = (PFNGLGETSTRINGIPROC)
window->context.getProcAddress("glGetStringi");
if (!window->context.GetStringi)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Entry point retrieval is broken");
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_FALSE;
}
}
if (window->context.client == GLFW_OPENGL_API)
{
// Read back context flags (OpenGL 3.0 and above)
if (window->context.major >= 3)
{
GLint flags;
window->context.GetIntegerv(GL_CONTEXT_FLAGS, &flags);
if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT)
window->context.forward = GLFW_TRUE;
if (flags & GL_CONTEXT_FLAG_DEBUG_BIT)
window->context.debug = GLFW_TRUE;
else if (glfwExtensionSupported("GL_ARB_debug_output") &&
ctxconfig->debug)
{
// HACK: This is a workaround for older drivers (pre KHR_debug)
// not setting the debug bit in the context flags for
// debug contexts
window->context.debug = GLFW_TRUE;
}
if (flags & GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR)
window->context.noerror = GLFW_TRUE;
}
// Read back OpenGL context profile (OpenGL 3.2 and above)
if (window->context.major >= 4 ||
(window->context.major == 3 && window->context.minor >= 2))
{
GLint mask;
window->context.GetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
if (mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT)
window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
else if (mask & GL_CONTEXT_CORE_PROFILE_BIT)
window->context.profile = GLFW_OPENGL_CORE_PROFILE;
else if (glfwExtensionSupported("GL_ARB_compatibility"))
{
// HACK: This is a workaround for the compatibility profile bit
// not being set in the context flags if an OpenGL 3.2+
// context was created without having requested a specific
// version
window->context.profile = GLFW_OPENGL_COMPAT_PROFILE;
}
}
// Read back robustness strategy
if (glfwExtensionSupported("GL_ARB_robustness"))
{
// NOTE: We avoid using the context flags for detection, as they are
// only present from 3.0 while the extension applies from 1.1
GLint strategy;
window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
&strategy);
if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
}
}
else
{
// Read back robustness strategy
if (glfwExtensionSupported("GL_EXT_robustness"))
{
// NOTE: The values of these constants match those of the OpenGL ARB
// one, so we can reuse them here
GLint strategy;
window->context.GetIntegerv(GL_RESET_NOTIFICATION_STRATEGY_ARB,
&strategy);
if (strategy == GL_LOSE_CONTEXT_ON_RESET_ARB)
window->context.robustness = GLFW_LOSE_CONTEXT_ON_RESET;
else if (strategy == GL_NO_RESET_NOTIFICATION_ARB)
window->context.robustness = GLFW_NO_RESET_NOTIFICATION;
}
}
if (glfwExtensionSupported("GL_KHR_context_flush_control"))
{
GLint behavior;
window->context.GetIntegerv(GL_CONTEXT_RELEASE_BEHAVIOR, &behavior);
if (behavior == GL_NONE)
window->context.release = GLFW_RELEASE_BEHAVIOR_NONE;
else if (behavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH)
window->context.release = GLFW_RELEASE_BEHAVIOR_FLUSH;
}
// Clearing the front buffer to black to avoid garbage pixels left over from
// previous uses of our bit of VRAM
{
PFNGLCLEARPROC glClear = (PFNGLCLEARPROC)
window->context.getProcAddress("glClear");
glClear(GL_COLOR_BUFFER_BIT);
if (window->doublebuffer)
window->context.swapBuffers(window);
}
glfwMakeContextCurrent((GLFWwindow*) previous);
return GLFW_TRUE;
}
// Searches an extension string for the specified extension
//
GLFWbool _glfwStringInExtensionString(const char* string, const char* extensions)
{
const char* start = extensions;
for (;;)
{
const char* where;
const char* terminator;
where = strstr(start, string);
if (!where)
return GLFW_FALSE;
terminator = where + strlen(string);
if (where == start || *(where - 1) == ' ')
{
if (*terminator == ' ' || *terminator == '\0')
break;
}
start = terminator;
}
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFWwindow* previous;
_GLFW_REQUIRE_INIT();
previous = _glfwPlatformGetTls(&_glfw.contextSlot);
if (window && window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot make current with a window that has no OpenGL or OpenGL ES context");
return;
}
if (previous)
{
if (!window || window->context.source != previous->context.source)
previous->context.makeCurrent(NULL);
}
if (window)
window->context.makeCurrent(window);
}
GLFWAPI GLFWwindow* glfwGetCurrentContext(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return _glfwPlatformGetTls(&_glfw.contextSlot);
}
GLFWAPI void glfwSwapBuffers(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT();
if (window->context.client == GLFW_NO_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT,
"Cannot swap buffers of a window that has no OpenGL or OpenGL ES context");
return;
}
window->context.swapBuffers(window);
}
GLFWAPI void glfwSwapInterval(int interval)
{
_GLFWwindow* window;
_GLFW_REQUIRE_INIT();
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot set swap interval without a current OpenGL or OpenGL ES context");
return;
}
window->context.swapInterval(interval);
}
GLFWAPI int glfwExtensionSupported(const char* extension)
{
_GLFWwindow* window;
assert(extension != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot query extension without a current OpenGL or OpenGL ES context");
return GLFW_FALSE;
}
if (*extension == '\0')
{
_glfwInputError(GLFW_INVALID_VALUE, "Extension name cannot be an empty string");
return GLFW_FALSE;
}
if (window->context.major >= 3)
{
int i;
GLint count;
// Check if extension is in the modern OpenGL extensions string list
window->context.GetIntegerv(GL_NUM_EXTENSIONS, &count);
for (i = 0; i < count; i++)
{
const char* en = (const char*)
window->context.GetStringi(GL_EXTENSIONS, i);
if (!en)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
}
if (strcmp(en, extension) == 0)
return GLFW_TRUE;
}
}
else
{
// Check if extension is in the old style OpenGL extensions string
const char* extensions = (const char*)
window->context.GetString(GL_EXTENSIONS);
if (!extensions)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Extension string retrieval is broken");
return GLFW_FALSE;
}
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
// Check if extension is in the platform-specific string
return window->context.extensionSupported(extension);
}
GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
{
_GLFWwindow* window;
assert(procname != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
window = _glfwPlatformGetTls(&_glfw.contextSlot);
if (!window)
{
_glfwInputError(GLFW_NO_CURRENT_CONTEXT,
"Cannot query entry point without a current OpenGL or OpenGL ES context");
return NULL;
}
return window->context.getProcAddress(procname);
}

911
raylib/external/glfw/src/egl_context.c vendored Normal file
View File

@@ -0,0 +1,911 @@
//========================================================================
// GLFW 3.4 EGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
// Return a description of the specified EGL error
//
static const char* getEGLErrorString(EGLint error)
{
switch (error)
{
case EGL_SUCCESS:
return "Success";
case EGL_NOT_INITIALIZED:
return "EGL is not or could not be initialized";
case EGL_BAD_ACCESS:
return "EGL cannot access a requested resource";
case EGL_BAD_ALLOC:
return "EGL failed to allocate resources for the requested operation";
case EGL_BAD_ATTRIBUTE:
return "An unrecognized attribute or attribute value was passed in the attribute list";
case EGL_BAD_CONTEXT:
return "An EGLContext argument does not name a valid EGL rendering context";
case EGL_BAD_CONFIG:
return "An EGLConfig argument does not name a valid EGL frame buffer configuration";
case EGL_BAD_CURRENT_SURFACE:
return "The current surface of the calling thread is a window, pixel buffer or pixmap that is no longer valid";
case EGL_BAD_DISPLAY:
return "An EGLDisplay argument does not name a valid EGL display connection";
case EGL_BAD_SURFACE:
return "An EGLSurface argument does not name a valid surface configured for GL rendering";
case EGL_BAD_MATCH:
return "Arguments are inconsistent";
case EGL_BAD_PARAMETER:
return "One or more argument values are invalid";
case EGL_BAD_NATIVE_PIXMAP:
return "A NativePixmapType argument does not refer to a valid native pixmap";
case EGL_BAD_NATIVE_WINDOW:
return "A NativeWindowType argument does not refer to a valid native window";
case EGL_CONTEXT_LOST:
return "The application must destroy all contexts and reinitialise";
default:
return "ERROR: UNKNOWN EGL ERROR";
}
}
// Returns the specified attribute of the specified EGLConfig
//
static int getEGLConfigAttrib(EGLConfig config, int attrib)
{
int value;
eglGetConfigAttrib(_glfw.egl.display, config, attrib, &value);
return value;
}
// Return the EGLConfig most closely matching the specified hints
//
static GLFWbool chooseEGLConfig(const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
EGLConfig* result)
{
EGLConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, nativeCount, usableCount, apiBit;
GLFWbool wrongApiAvailable = GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
apiBit = EGL_OPENGL_ES_BIT;
else
apiBit = EGL_OPENGL_ES2_BIT;
}
else
apiBit = EGL_OPENGL_BIT;
if (fbconfig->stereo)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE, "EGL: Stereo rendering not supported");
return GLFW_FALSE;
}
eglGetConfigs(_glfw.egl.display, NULL, 0, &nativeCount);
if (!nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: No EGLConfigs returned");
return GLFW_FALSE;
}
nativeConfigs = _glfw_calloc(nativeCount, sizeof(EGLConfig));
eglGetConfigs(_glfw.egl.display, nativeConfigs, nativeCount, &nativeCount);
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (i = 0; i < nativeCount; i++)
{
const EGLConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGB(A) EGLConfigs
if (getEGLConfigAttrib(n, EGL_COLOR_BUFFER_TYPE) != EGL_RGB_BUFFER)
continue;
// Only consider window EGLConfigs
if (!(getEGLConfigAttrib(n, EGL_SURFACE_TYPE) & EGL_WINDOW_BIT))
continue;
#if defined(_GLFW_X11)
if (_glfw.platform.platformID == GLFW_PLATFORM_X11)
{
XVisualInfo vi = {0};
// Only consider EGLConfigs with associated Visuals
vi.visualid = getEGLConfigAttrib(n, EGL_NATIVE_VISUAL_ID);
if (!vi.visualid)
continue;
if (fbconfig->transparent)
{
int count;
XVisualInfo* vis =
XGetVisualInfo(_glfw.x11.display, VisualIDMask, &vi, &count);
if (vis)
{
u->transparent = _glfwIsVisualTransparentX11(vis[0].visual);
XFree(vis);
}
}
}
#endif // _GLFW_X11
if (!(getEGLConfigAttrib(n, EGL_RENDERABLE_TYPE) & apiBit))
{
wrongApiAvailable = GLFW_TRUE;
continue;
}
u->redBits = getEGLConfigAttrib(n, EGL_RED_SIZE);
u->greenBits = getEGLConfigAttrib(n, EGL_GREEN_SIZE);
u->blueBits = getEGLConfigAttrib(n, EGL_BLUE_SIZE);
u->alphaBits = getEGLConfigAttrib(n, EGL_ALPHA_SIZE);
u->depthBits = getEGLConfigAttrib(n, EGL_DEPTH_SIZE);
u->stencilBits = getEGLConfigAttrib(n, EGL_STENCIL_SIZE);
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: The wl_surface opaque region is no guarantee that its buffer
// is presented as opaque, if it also has an alpha channel
// HACK: If EGL_EXT_present_opaque is unavailable, ignore any config
// with an alpha channel to ensure the buffer is opaque
if (!_glfw.egl.EXT_present_opaque)
{
if (!fbconfig->transparent && u->alphaBits > 0)
continue;
}
}
#endif // _GLFW_WAYLAND
u->samples = getEGLConfigAttrib(n, EGL_SAMPLES);
u->doublebuffer = fbconfig->doublebuffer;
u->handle = (uintptr_t) n;
usableCount++;
}
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (closest)
*result = (EGLConfig) closest->handle;
else
{
if (wrongApiAvailable)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 1.x");
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL ES 2 or later");
}
}
else
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to find support for OpenGL");
}
}
else
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"EGL: Failed to find a suitable EGLConfig");
}
}
_glfw_free(nativeConfigs);
_glfw_free(usableConfigs);
return closest != NULL;
}
static void makeContextCurrentEGL(_GLFWwindow* window)
{
if (window)
{
if (!eglMakeCurrent(_glfw.egl.display,
window->context.egl.surface,
window->context.egl.surface,
window->context.egl.handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to make context current: %s",
getEGLErrorString(eglGetError()));
return;
}
}
else
{
if (!eglMakeCurrent(_glfw.egl.display,
EGL_NO_SURFACE,
EGL_NO_SURFACE,
EGL_NO_CONTEXT))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to clear current context: %s",
getEGLErrorString(eglGetError()));
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static void swapBuffersEGL(_GLFWwindow* window)
{
if (window != _glfwPlatformGetTls(&_glfw.contextSlot))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: The context must be current on the calling thread when swapping buffers");
return;
}
#if defined(_GLFW_WAYLAND)
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
// NOTE: Swapping buffers on a hidden window on Wayland makes it visible
if (!window->wl.visible)
return;
}
#endif
eglSwapBuffers(_glfw.egl.display, window->context.egl.surface);
}
static void swapIntervalEGL(int interval)
{
eglSwapInterval(_glfw.egl.display, interval);
}
static int extensionSupportedEGL(const char* extension)
{
const char* extensions = eglQueryString(_glfw.egl.display, EGL_EXTENSIONS);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
return GLFW_FALSE;
}
static GLFWglproc getProcAddressEGL(const char* procname)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (window->context.egl.client)
{
GLFWglproc proc = (GLFWglproc)
_glfwPlatformGetModuleSymbol(window->context.egl.client, procname);
if (proc)
return proc;
}
return eglGetProcAddress(procname);
}
static void destroyContextEGL(_GLFWwindow* window)
{
// NOTE: Do not unload libGL.so.1 while the X11 display is still open,
// as it will make XCloseDisplay segfault
if (_glfw.platform.platformID != GLFW_PLATFORM_X11 ||
window->context.client != GLFW_OPENGL_API)
{
if (window->context.egl.client)
{
_glfwPlatformFreeModule(window->context.egl.client);
window->context.egl.client = NULL;
}
}
if (window->context.egl.surface)
{
eglDestroySurface(_glfw.egl.display, window->context.egl.surface);
window->context.egl.surface = EGL_NO_SURFACE;
}
if (window->context.egl.handle)
{
eglDestroyContext(_glfw.egl.display, window->context.egl.handle);
window->context.egl.handle = EGL_NO_CONTEXT;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize EGL
//
GLFWbool _glfwInitEGL(void)
{
int i;
EGLint* attribs = NULL;
const char* extensions;
const char* sonames[] =
{
#if defined(_GLFW_EGL_LIBRARY)
_GLFW_EGL_LIBRARY,
#elif defined(_GLFW_WIN32)
"libEGL.dll",
"EGL.dll",
#elif defined(_GLFW_COCOA)
"libEGL.dylib",
#elif defined(__CYGWIN__)
"libEGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libEGL.so",
#else
"libEGL.so.1",
#endif
NULL
};
if (_glfw.egl.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++)
{
_glfw.egl.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.egl.handle)
break;
}
if (!_glfw.egl.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: Library not found");
return GLFW_FALSE;
}
_glfw.egl.prefix = (strncmp(sonames[i], "lib", 3) == 0);
_glfw.egl.GetConfigAttrib = (PFN_eglGetConfigAttrib)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigAttrib");
_glfw.egl.GetConfigs = (PFN_eglGetConfigs)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetConfigs");
_glfw.egl.GetDisplay = (PFN_eglGetDisplay)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetDisplay");
_glfw.egl.GetError = (PFN_eglGetError)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetError");
_glfw.egl.Initialize = (PFN_eglInitialize)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglInitialize");
_glfw.egl.Terminate = (PFN_eglTerminate)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglTerminate");
_glfw.egl.BindAPI = (PFN_eglBindAPI)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglBindAPI");
_glfw.egl.CreateContext = (PFN_eglCreateContext)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateContext");
_glfw.egl.DestroySurface = (PFN_eglDestroySurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroySurface");
_glfw.egl.DestroyContext = (PFN_eglDestroyContext)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglDestroyContext");
_glfw.egl.CreateWindowSurface = (PFN_eglCreateWindowSurface)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglCreateWindowSurface");
_glfw.egl.MakeCurrent = (PFN_eglMakeCurrent)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglMakeCurrent");
_glfw.egl.SwapBuffers = (PFN_eglSwapBuffers)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapBuffers");
_glfw.egl.SwapInterval = (PFN_eglSwapInterval)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglSwapInterval");
_glfw.egl.QueryString = (PFN_eglQueryString)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglQueryString");
_glfw.egl.GetProcAddress = (PFN_eglGetProcAddress)
_glfwPlatformGetModuleSymbol(_glfw.egl.handle, "eglGetProcAddress");
if (!_glfw.egl.GetConfigAttrib ||
!_glfw.egl.GetConfigs ||
!_glfw.egl.GetDisplay ||
!_glfw.egl.GetError ||
!_glfw.egl.Initialize ||
!_glfw.egl.Terminate ||
!_glfw.egl.BindAPI ||
!_glfw.egl.CreateContext ||
!_glfw.egl.DestroySurface ||
!_glfw.egl.DestroyContext ||
!_glfw.egl.CreateWindowSurface ||
!_glfw.egl.MakeCurrent ||
!_glfw.egl.SwapBuffers ||
!_glfw.egl.SwapInterval ||
!_glfw.egl.QueryString ||
!_glfw.egl.GetProcAddress)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to load required entry points");
_glfwTerminateEGL();
return GLFW_FALSE;
}
extensions = eglQueryString(EGL_NO_DISPLAY, EGL_EXTENSIONS);
if (extensions && eglGetError() == EGL_SUCCESS)
_glfw.egl.EXT_client_extensions = GLFW_TRUE;
if (_glfw.egl.EXT_client_extensions)
{
_glfw.egl.EXT_platform_base =
_glfwStringInExtensionString("EGL_EXT_platform_base", extensions);
_glfw.egl.EXT_platform_x11 =
_glfwStringInExtensionString("EGL_EXT_platform_x11", extensions);
_glfw.egl.EXT_platform_wayland =
_glfwStringInExtensionString("EGL_EXT_platform_wayland", extensions);
_glfw.egl.ANGLE_platform_angle =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle", extensions);
_glfw.egl.ANGLE_platform_angle_opengl =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_opengl", extensions);
_glfw.egl.ANGLE_platform_angle_d3d =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_d3d", extensions);
_glfw.egl.ANGLE_platform_angle_vulkan =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_vulkan", extensions);
_glfw.egl.ANGLE_platform_angle_metal =
_glfwStringInExtensionString("EGL_ANGLE_platform_angle_metal", extensions);
}
if (_glfw.egl.EXT_platform_base)
{
_glfw.egl.GetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)
eglGetProcAddress("eglGetPlatformDisplayEXT");
_glfw.egl.CreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)
eglGetProcAddress("eglCreatePlatformWindowSurfaceEXT");
}
_glfw.egl.platform = _glfw.platform.getEGLPlatform(&attribs);
if (_glfw.egl.platform)
{
_glfw.egl.display =
eglGetPlatformDisplayEXT(_glfw.egl.platform,
_glfw.platform.getEGLNativeDisplay(),
attribs);
}
else
_glfw.egl.display = eglGetDisplay(_glfw.platform.getEGLNativeDisplay());
_glfw_free(attribs);
if (_glfw.egl.display == EGL_NO_DISPLAY)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to get EGL display: %s",
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
}
if (!eglInitialize(_glfw.egl.display, &_glfw.egl.major, &_glfw.egl.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to initialize EGL: %s",
getEGLErrorString(eglGetError()));
_glfwTerminateEGL();
return GLFW_FALSE;
}
_glfw.egl.KHR_create_context =
extensionSupportedEGL("EGL_KHR_create_context");
_glfw.egl.KHR_create_context_no_error =
extensionSupportedEGL("EGL_KHR_create_context_no_error");
_glfw.egl.KHR_gl_colorspace =
extensionSupportedEGL("EGL_KHR_gl_colorspace");
_glfw.egl.KHR_get_all_proc_addresses =
extensionSupportedEGL("EGL_KHR_get_all_proc_addresses");
_glfw.egl.KHR_context_flush_control =
extensionSupportedEGL("EGL_KHR_context_flush_control");
_glfw.egl.EXT_present_opaque =
extensionSupportedEGL("EGL_EXT_present_opaque");
return GLFW_TRUE;
}
// Terminate EGL
//
void _glfwTerminateEGL(void)
{
if (_glfw.egl.display)
{
eglTerminate(_glfw.egl.display);
_glfw.egl.display = EGL_NO_DISPLAY;
}
if (_glfw.egl.handle)
{
_glfwPlatformFreeModule(_glfw.egl.handle);
_glfw.egl.handle = NULL;
}
}
#define SET_ATTRIB(a, v) \
{ \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextEGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
EGLint attribs[40];
EGLConfig config;
EGLContext share = NULL;
EGLNativeWindowType native;
int index = 0;
if (!_glfw.egl.display)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "EGL: API not available");
return GLFW_FALSE;
}
if (ctxconfig->share)
share = ctxconfig->share->context.egl.handle;
if (!chooseEGLConfig(ctxconfig, fbconfig, &config))
return GLFW_FALSE;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (!eglBindAPI(EGL_OPENGL_ES_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL ES: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
}
else
{
if (!eglBindAPI(EGL_OPENGL_API))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to bind OpenGL: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
}
if (_glfw.egl.KHR_create_context)
{
int mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= EGL_CONTEXT_OPENGL_FORWARD_COMPATIBLE_BIT_KHR;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT_KHR;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= EGL_CONTEXT_OPENGL_COMPATIBILITY_PROFILE_BIT_KHR;
}
if (ctxconfig->debug)
flags |= EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR;
if (ctxconfig->robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_NO_RESET_NOTIFICATION_KHR);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
SET_ATTRIB(EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_KHR,
EGL_LOSE_CONTEXT_ON_RESET_KHR);
}
flags |= EGL_CONTEXT_OPENGL_ROBUST_ACCESS_BIT_KHR;
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
SET_ATTRIB(EGL_CONTEXT_MAJOR_VERSION_KHR, ctxconfig->major);
SET_ATTRIB(EGL_CONTEXT_MINOR_VERSION_KHR, ctxconfig->minor);
}
if (ctxconfig->noerror)
{
if (_glfw.egl.KHR_create_context_no_error)
SET_ATTRIB(EGL_CONTEXT_OPENGL_NO_ERROR_KHR, GLFW_TRUE);
}
if (mask)
SET_ATTRIB(EGL_CONTEXT_OPENGL_PROFILE_MASK_KHR, mask);
if (flags)
SET_ATTRIB(EGL_CONTEXT_FLAGS_KHR, flags);
}
else
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
SET_ATTRIB(EGL_CONTEXT_CLIENT_VERSION, ctxconfig->major);
}
if (_glfw.egl.KHR_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_NONE_KHR);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
SET_ATTRIB(EGL_CONTEXT_RELEASE_BEHAVIOR_KHR,
EGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR);
}
}
SET_ATTRIB(EGL_NONE, EGL_NONE);
window->context.egl.handle = eglCreateContext(_glfw.egl.display,
config, share, attribs);
if (window->context.egl.handle == EGL_NO_CONTEXT)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"EGL: Failed to create context: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
// Set up attributes for surface creation
index = 0;
if (fbconfig->sRGB)
{
if (_glfw.egl.KHR_gl_colorspace)
SET_ATTRIB(EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR);
}
if (!fbconfig->doublebuffer)
SET_ATTRIB(EGL_RENDER_BUFFER, EGL_SINGLE_BUFFER);
if (_glfw.platform.platformID == GLFW_PLATFORM_WAYLAND)
{
if (_glfw.egl.EXT_present_opaque)
SET_ATTRIB(EGL_PRESENT_OPAQUE_EXT, !fbconfig->transparent);
}
SET_ATTRIB(EGL_NONE, EGL_NONE);
native = _glfw.platform.getEGLNativeWindow(window);
// HACK: ANGLE does not implement eglCreatePlatformWindowSurfaceEXT
// despite reporting EGL_EXT_platform_base
if (_glfw.egl.platform && _glfw.egl.platform != EGL_PLATFORM_ANGLE_ANGLE)
{
window->context.egl.surface =
eglCreatePlatformWindowSurfaceEXT(_glfw.egl.display, config, native, attribs);
}
else
{
window->context.egl.surface =
eglCreateWindowSurface(_glfw.egl.display, config, native, attribs);
}
if (window->context.egl.surface == EGL_NO_SURFACE)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to create window surface: %s",
getEGLErrorString(eglGetError()));
return GLFW_FALSE;
}
window->context.egl.config = config;
// Load the appropriate client library
if (!_glfw.egl.KHR_get_all_proc_addresses)
{
int i;
const char** sonames;
const char* es1sonames[] =
{
#if defined(_GLFW_GLESV1_LIBRARY)
_GLFW_GLESV1_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv1_CM.dll",
"libGLES_CM.dll",
#elif defined(_GLFW_COCOA)
"libGLESv1_CM.dylib",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv1_CM.so",
#else
"libGLESv1_CM.so.1",
"libGLES_CM.so.1",
#endif
NULL
};
const char* es2sonames[] =
{
#if defined(_GLFW_GLESV2_LIBRARY)
_GLFW_GLESV2_LIBRARY,
#elif defined(_GLFW_WIN32)
"GLESv2.dll",
"libGLESv2.dll",
#elif defined(_GLFW_COCOA)
"libGLESv2.dylib",
#elif defined(__CYGWIN__)
"libGLESv2-2.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGLESv2.so",
#else
"libGLESv2.so.2",
#endif
NULL
};
const char* glsonames[] =
{
#if defined(_GLFW_OPENGL_LIBRARY)
_GLFW_OPENGL_LIBRARY,
#elif defined(_GLFW_WIN32)
#elif defined(_GLFW_COCOA)
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else
"libOpenGL.so.0",
"libGL.so.1",
#endif
NULL
};
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (ctxconfig->major == 1)
sonames = es1sonames;
else
sonames = es2sonames;
}
else
sonames = glsonames;
for (i = 0; sonames[i]; i++)
{
// HACK: Match presence of lib prefix to increase chance of finding
// a matching pair in the jungle that is Win32 EGL/GLES
if (_glfw.egl.prefix != (strncmp(sonames[i], "lib", 3) == 0))
continue;
window->context.egl.client = _glfwPlatformLoadModule(sonames[i]);
if (window->context.egl.client)
break;
}
if (!window->context.egl.client)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"EGL: Failed to load client library");
return GLFW_FALSE;
}
}
window->context.makeCurrent = makeContextCurrentEGL;
window->context.swapBuffers = swapBuffersEGL;
window->context.swapInterval = swapIntervalEGL;
window->context.extensionSupported = extensionSupportedEGL;
window->context.getProcAddress = getProcAddressEGL;
window->context.destroy = destroyContextEGL;
return GLFW_TRUE;
}
#undef SET_ATTRIB
// Returns the Visual and depth of the chosen EGLConfig
//
#if defined(_GLFW_X11)
GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
XVisualInfo* result;
XVisualInfo desired;
EGLConfig native;
EGLint visualID = 0, count = 0;
const long vimask = VisualScreenMask | VisualIDMask;
if (!chooseEGLConfig(ctxconfig, fbconfig, &native))
return GLFW_FALSE;
eglGetConfigAttrib(_glfw.egl.display, native,
EGL_NATIVE_VISUAL_ID, &visualID);
desired.screen = _glfw.x11.screen;
desired.visualid = visualID;
result = XGetVisualInfo(_glfw.x11.display, vimask, &desired, &count);
if (!result)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"EGL: Failed to retrieve Visual for EGLConfig");
return GLFW_FALSE;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
}
#endif // _GLFW_X11
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI EGLDisplay glfwGetEGLDisplay(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_DISPLAY);
return _glfw.egl.display;
}
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_CONTEXT);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT;
}
return window->context.egl.handle;
}
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(EGL_NO_SURFACE);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_SURFACE;
}
return window->context.egl.surface;
}

30
raylib/external/glfw/src/glfw.rc.in vendored Normal file
View File

@@ -0,0 +1,30 @@
#include <winver.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
PRODUCTVERSION @GLFW_VERSION_MAJOR@,@GLFW_VERSION_MINOR@,@GLFW_VERSION_PATCH@,0
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_DLL
FILESUBTYPE 0
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "CompanyName", "GLFW"
VALUE "FileDescription", "GLFW @GLFW_VERSION@ DLL"
VALUE "FileVersion", "@GLFW_VERSION@"
VALUE "OriginalFilename", "glfw3.dll"
VALUE "ProductName", "GLFW"
VALUE "ProductVersion", "@GLFW_VERSION@"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x409, 1200
}
}

719
raylib/external/glfw/src/glx_context.c vendored Normal file
View File

@@ -0,0 +1,719 @@
//========================================================================
// GLFW 3.4 GLX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_X11)
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#ifndef GLXBadProfileARB
#define GLXBadProfileARB 13
#endif
// Returns the specified attribute of the specified GLXFBConfig
//
static int getGLXFBConfigAttrib(GLXFBConfig fbconfig, int attrib)
{
int value;
glXGetFBConfigAttrib(_glfw.x11.display, fbconfig, attrib, &value);
return value;
}
// Return the GLXFBConfig most closely matching the specified hints
//
static GLFWbool chooseGLXFBConfig(const _GLFWfbconfig* desired,
GLXFBConfig* result)
{
GLXFBConfig* nativeConfigs;
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int nativeCount, usableCount;
const char* vendor;
GLFWbool trustWindowBit = GLFW_TRUE;
// HACK: This is a (hopefully temporary) workaround for Chromium
// (VirtualBox GL) not setting the window bit on any GLXFBConfigs
vendor = glXGetClientString(_glfw.x11.display, GLX_VENDOR);
if (vendor && strcmp(vendor, "Chromium") == 0)
trustWindowBit = GLFW_FALSE;
nativeConfigs =
glXGetFBConfigs(_glfw.x11.display, _glfw.x11.screen, &nativeCount);
if (!nativeConfigs || !nativeCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: No GLXFBConfigs returned");
return GLFW_FALSE;
}
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
usableCount = 0;
for (int i = 0; i < nativeCount; i++)
{
const GLXFBConfig n = nativeConfigs[i];
_GLFWfbconfig* u = usableConfigs + usableCount;
// Only consider RGBA GLXFBConfigs
if (!(getGLXFBConfigAttrib(n, GLX_RENDER_TYPE) & GLX_RGBA_BIT))
continue;
// Only consider window GLXFBConfigs
if (!(getGLXFBConfigAttrib(n, GLX_DRAWABLE_TYPE) & GLX_WINDOW_BIT))
{
if (trustWindowBit)
continue;
}
if (getGLXFBConfigAttrib(n, GLX_DOUBLEBUFFER) != desired->doublebuffer)
continue;
if (desired->transparent)
{
XVisualInfo* vi = glXGetVisualFromFBConfig(_glfw.x11.display, n);
if (vi)
{
u->transparent = _glfwIsVisualTransparentX11(vi->visual);
XFree(vi);
}
}
u->redBits = getGLXFBConfigAttrib(n, GLX_RED_SIZE);
u->greenBits = getGLXFBConfigAttrib(n, GLX_GREEN_SIZE);
u->blueBits = getGLXFBConfigAttrib(n, GLX_BLUE_SIZE);
u->alphaBits = getGLXFBConfigAttrib(n, GLX_ALPHA_SIZE);
u->depthBits = getGLXFBConfigAttrib(n, GLX_DEPTH_SIZE);
u->stencilBits = getGLXFBConfigAttrib(n, GLX_STENCIL_SIZE);
u->accumRedBits = getGLXFBConfigAttrib(n, GLX_ACCUM_RED_SIZE);
u->accumGreenBits = getGLXFBConfigAttrib(n, GLX_ACCUM_GREEN_SIZE);
u->accumBlueBits = getGLXFBConfigAttrib(n, GLX_ACCUM_BLUE_SIZE);
u->accumAlphaBits = getGLXFBConfigAttrib(n, GLX_ACCUM_ALPHA_SIZE);
u->auxBuffers = getGLXFBConfigAttrib(n, GLX_AUX_BUFFERS);
if (getGLXFBConfigAttrib(n, GLX_STEREO))
u->stereo = GLFW_TRUE;
if (_glfw.glx.ARB_multisample)
u->samples = getGLXFBConfigAttrib(n, GLX_SAMPLES);
if (_glfw.glx.ARB_framebuffer_sRGB || _glfw.glx.EXT_framebuffer_sRGB)
u->sRGB = getGLXFBConfigAttrib(n, GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB);
u->handle = (uintptr_t) n;
usableCount++;
}
closest = _glfwChooseFBConfig(desired, usableConfigs, usableCount);
if (closest)
*result = (GLXFBConfig) closest->handle;
XFree(nativeConfigs);
_glfw_free(usableConfigs);
return closest != NULL;
}
// Create the OpenGL context using legacy API
//
static GLXContext createLegacyContextGLX(_GLFWwindow* window,
GLXFBConfig fbconfig,
GLXContext share)
{
return glXCreateNewContext(_glfw.x11.display,
fbconfig,
GLX_RGBA_TYPE,
share,
True);
}
static void makeContextCurrentGLX(_GLFWwindow* window)
{
if (window)
{
if (!glXMakeCurrent(_glfw.x11.display,
window->context.glx.window,
window->context.glx.handle))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to make context current");
return;
}
}
else
{
if (!glXMakeCurrent(_glfw.x11.display, None, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to clear current context");
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static void swapBuffersGLX(_GLFWwindow* window)
{
glXSwapBuffers(_glfw.x11.display, window->context.glx.window);
}
static void swapIntervalGLX(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
if (_glfw.glx.EXT_swap_control)
{
_glfw.glx.SwapIntervalEXT(_glfw.x11.display,
window->context.glx.window,
interval);
}
else if (_glfw.glx.MESA_swap_control)
_glfw.glx.SwapIntervalMESA(interval);
else if (_glfw.glx.SGI_swap_control)
{
if (interval > 0)
_glfw.glx.SwapIntervalSGI(interval);
}
}
static int extensionSupportedGLX(const char* extension)
{
const char* extensions =
glXQueryExtensionsString(_glfw.x11.display, _glfw.x11.screen);
if (extensions)
{
if (_glfwStringInExtensionString(extension, extensions))
return GLFW_TRUE;
}
return GLFW_FALSE;
}
static GLFWglproc getProcAddressGLX(const char* procname)
{
if (_glfw.glx.GetProcAddress)
return _glfw.glx.GetProcAddress((const GLubyte*) procname);
else if (_glfw.glx.GetProcAddressARB)
return _glfw.glx.GetProcAddressARB((const GLubyte*) procname);
else
{
// NOTE: glvnd provides GLX 1.4, so this can only happen with libGL
return _glfwPlatformGetModuleSymbol(_glfw.glx.handle, procname);
}
}
static void destroyContextGLX(_GLFWwindow* window)
{
if (window->context.glx.window)
{
glXDestroyWindow(_glfw.x11.display, window->context.glx.window);
window->context.glx.window = None;
}
if (window->context.glx.handle)
{
glXDestroyContext(_glfw.x11.display, window->context.glx.handle);
window->context.glx.handle = NULL;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize GLX
//
GLFWbool _glfwInitGLX(void)
{
const char* sonames[] =
{
#if defined(_GLFW_GLX_LIBRARY)
_GLFW_GLX_LIBRARY,
#elif defined(__CYGWIN__)
"libGL-1.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libGL.so",
#else
"libGLX.so.0",
"libGL.so.1",
"libGL.so",
#endif
NULL
};
if (_glfw.glx.handle)
return GLFW_TRUE;
for (int i = 0; sonames[i]; i++)
{
_glfw.glx.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.glx.handle)
break;
}
if (!_glfw.glx.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: Failed to load GLX");
return GLFW_FALSE;
}
_glfw.glx.GetFBConfigs = (PFNGLXGETFBCONFIGSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigs");
_glfw.glx.GetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetFBConfigAttrib");
_glfw.glx.GetClientString = (PFNGLXGETCLIENTSTRINGPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetClientString");
_glfw.glx.QueryExtension = (PFNGLXQUERYEXTENSIONPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtension");
_glfw.glx.QueryVersion = (PFNGLXQUERYVERSIONPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryVersion");
_glfw.glx.DestroyContext = (PFNGLXDESTROYCONTEXTPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyContext");
_glfw.glx.MakeCurrent = (PFNGLXMAKECURRENTPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXMakeCurrent");
_glfw.glx.SwapBuffers = (PFNGLXSWAPBUFFERSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXSwapBuffers");
_glfw.glx.QueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXQueryExtensionsString");
_glfw.glx.CreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateNewContext");
_glfw.glx.CreateWindow = (PFNGLXCREATEWINDOWPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXCreateWindow");
_glfw.glx.DestroyWindow = (PFNGLXDESTROYWINDOWPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXDestroyWindow");
_glfw.glx.GetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetVisualFromFBConfig");
if (!_glfw.glx.GetFBConfigs ||
!_glfw.glx.GetFBConfigAttrib ||
!_glfw.glx.GetClientString ||
!_glfw.glx.QueryExtension ||
!_glfw.glx.QueryVersion ||
!_glfw.glx.DestroyContext ||
!_glfw.glx.MakeCurrent ||
!_glfw.glx.SwapBuffers ||
!_glfw.glx.QueryExtensionsString ||
!_glfw.glx.CreateNewContext ||
!_glfw.glx.CreateWindow ||
!_glfw.glx.DestroyWindow ||
!_glfw.glx.GetVisualFromFBConfig)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to load required entry points");
return GLFW_FALSE;
}
// NOTE: Unlike GLX 1.3 entry points these are not required to be present
_glfw.glx.GetProcAddress = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddress");
_glfw.glx.GetProcAddressARB = (PFNGLXGETPROCADDRESSPROC)
_glfwPlatformGetModuleSymbol(_glfw.glx.handle, "glXGetProcAddressARB");
if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase,
&_glfw.glx.eventBase))
{
_glfwInputError(GLFW_API_UNAVAILABLE, "GLX: GLX extension not found");
return GLFW_FALSE;
}
if (!glXQueryVersion(_glfw.x11.display, &_glfw.glx.major, &_glfw.glx.minor))
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: Failed to query GLX version");
return GLFW_FALSE;
}
if (_glfw.glx.major == 1 && _glfw.glx.minor < 3)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: GLX version 1.3 is required");
return GLFW_FALSE;
}
if (extensionSupportedGLX("GLX_EXT_swap_control"))
{
_glfw.glx.SwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)
getProcAddressGLX("glXSwapIntervalEXT");
if (_glfw.glx.SwapIntervalEXT)
_glfw.glx.EXT_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_SGI_swap_control"))
{
_glfw.glx.SwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)
getProcAddressGLX("glXSwapIntervalSGI");
if (_glfw.glx.SwapIntervalSGI)
_glfw.glx.SGI_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_MESA_swap_control"))
{
_glfw.glx.SwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)
getProcAddressGLX("glXSwapIntervalMESA");
if (_glfw.glx.SwapIntervalMESA)
_glfw.glx.MESA_swap_control = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_ARB_multisample"))
_glfw.glx.ARB_multisample = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_framebuffer_sRGB"))
_glfw.glx.ARB_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_framebuffer_sRGB"))
_glfw.glx.EXT_framebuffer_sRGB = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context"))
{
_glfw.glx.CreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
getProcAddressGLX("glXCreateContextAttribsARB");
if (_glfw.glx.CreateContextAttribsARB)
_glfw.glx.ARB_create_context = GLFW_TRUE;
}
if (extensionSupportedGLX("GLX_ARB_create_context_robustness"))
_glfw.glx.ARB_create_context_robustness = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_profile"))
_glfw.glx.ARB_create_context_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_EXT_create_context_es2_profile"))
_glfw.glx.EXT_create_context_es2_profile = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_create_context_no_error"))
_glfw.glx.ARB_create_context_no_error = GLFW_TRUE;
if (extensionSupportedGLX("GLX_ARB_context_flush_control"))
_glfw.glx.ARB_context_flush_control = GLFW_TRUE;
return GLFW_TRUE;
}
// Terminate GLX
//
void _glfwTerminateGLX(void)
{
// NOTE: This function must not call any X11 functions, as it is called
// after XCloseDisplay (see _glfwTerminateX11 for details)
if (_glfw.glx.handle)
{
_glfwPlatformFreeModule(_glfw.glx.handle);
_glfw.glx.handle = NULL;
}
}
#define SET_ATTRIB(a, v) \
{ \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int attribs[40];
GLXFBConfig native = NULL;
GLXContext share = NULL;
if (ctxconfig->share)
share = ctxconfig->share->context.glx.handle;
if (!chooseGLXFBConfig(fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
if (!_glfw.glx.ARB_create_context ||
!_glfw.glx.ARB_create_context_profile ||
!_glfw.glx.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"GLX: OpenGL ES requested but GLX_EXT_create_context_es2_profile is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->forward)
{
if (!_glfw.glx.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: Forward compatibility requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->profile)
{
if (!_glfw.glx.ARB_create_context ||
!_glfw.glx.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"GLX: An OpenGL profile requested but GLX_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
_glfwGrabErrorHandlerX11();
if (_glfw.glx.ARB_create_context)
{
int index = 0, mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
}
else
mask |= GLX_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= GLX_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (_glfw.glx.ARB_create_context_robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
SET_ATTRIB(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
GLX_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB;
}
}
if (ctxconfig->release)
{
if (_glfw.glx.ARB_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
SET_ATTRIB(GLX_CONTEXT_RELEASE_BEHAVIOR_ARB,
GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
}
}
}
if (ctxconfig->noerror)
{
if (_glfw.glx.ARB_create_context_no_error)
SET_ATTRIB(GLX_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
}
// NOTE: Only request an explicitly versioned context when necessary, as
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
SET_ATTRIB(GLX_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
SET_ATTRIB(GLX_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (mask)
SET_ATTRIB(GLX_CONTEXT_PROFILE_MASK_ARB, mask);
if (flags)
SET_ATTRIB(GLX_CONTEXT_FLAGS_ARB, flags);
SET_ATTRIB(None, None);
window->context.glx.handle =
_glfw.glx.CreateContextAttribsARB(_glfw.x11.display,
native,
share,
True,
attribs);
// HACK: This is a fallback for broken versions of the Mesa
// implementation of GLX_ARB_create_context_profile that fail
// default 1.0 context creation with a GLXBadProfileARB error in
// violation of the extension spec
if (!window->context.glx.handle)
{
if (_glfw.x11.errorCode == _glfw.glx.errorBase + GLXBadProfileARB &&
ctxconfig->client == GLFW_OPENGL_API &&
ctxconfig->profile == GLFW_OPENGL_ANY_PROFILE &&
ctxconfig->forward == GLFW_FALSE)
{
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
}
}
}
else
{
window->context.glx.handle =
createLegacyContextGLX(window, native, share);
}
_glfwReleaseErrorHandlerX11();
if (!window->context.glx.handle)
{
_glfwInputErrorX11(GLFW_VERSION_UNAVAILABLE, "GLX: Failed to create context");
return GLFW_FALSE;
}
window->context.glx.window =
glXCreateWindow(_glfw.x11.display, native, window->x11.handle, NULL);
if (!window->context.glx.window)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "GLX: Failed to create window");
return GLFW_FALSE;
}
window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapIntervalGLX;
window->context.extensionSupported = extensionSupportedGLX;
window->context.getProcAddress = getProcAddressGLX;
window->context.destroy = destroyContextGLX;
return GLFW_TRUE;
}
#undef SET_ATTRIB
// Returns the Visual and depth of the chosen GLXFBConfig
//
GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig,
Visual** visual, int* depth)
{
GLXFBConfig native;
XVisualInfo* result;
if (!chooseGLXFBConfig(fbconfig, &native))
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"GLX: Failed to find a suitable GLXFBConfig");
return GLFW_FALSE;
}
result = glXGetVisualFromFBConfig(_glfw.x11.display, native);
if (!result)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to retrieve Visual for GLXFBConfig");
return GLFW_FALSE;
}
*visual = result->visual;
*depth = result->depth;
XFree(result);
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return NULL;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.glx.handle;
}
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return None;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return None;
}
return window->context.glx.window;
}
#endif // _GLFW_X11

528
raylib/external/glfw/src/init.c vendored Normal file
View File

@@ -0,0 +1,528 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <assert.h>
// NOTE: The global variables below comprise all mutable global data in GLFW
// Any other mutable global variable is a bug
// This contains all mutable state shared between compilation units of GLFW
//
_GLFWlibrary _glfw = { GLFW_FALSE };
// These are outside of _glfw so they can be used before initialization and
// after termination without special handling when _glfw is cleared to zero
//
static _GLFWerror _glfwMainThreadError;
static GLFWerrorfun _glfwErrorCallback;
static GLFWallocator _glfwInitAllocator;
static _GLFWinitconfig _glfwInitHints =
{
.hatButtons = GLFW_TRUE,
.angleType = GLFW_ANGLE_PLATFORM_TYPE_NONE,
.platformID = GLFW_ANY_PLATFORM,
.vulkanLoader = NULL,
.ns =
{
.menubar = GLFW_TRUE,
.chdir = GLFW_TRUE
},
.x11 =
{
.xcbVulkanSurface = GLFW_TRUE,
},
.wl =
{
.libdecorMode = GLFW_WAYLAND_PREFER_LIBDECOR
},
};
// The allocation function used when no custom allocator is set
//
static void* defaultAllocate(size_t size, void* user)
{
return malloc(size);
}
// The deallocation function used when no custom allocator is set
//
static void defaultDeallocate(void* block, void* user)
{
free(block);
}
// The reallocation function used when no custom allocator is set
//
static void* defaultReallocate(void* block, size_t size, void* user)
{
return realloc(block, size);
}
// Terminate the library
//
static void terminate(void)
{
int i;
memset(&_glfw.callbacks, 0, sizeof(_glfw.callbacks));
while (_glfw.windowListHead)
glfwDestroyWindow((GLFWwindow*) _glfw.windowListHead);
while (_glfw.cursorListHead)
glfwDestroyCursor((GLFWcursor*) _glfw.cursorListHead);
for (i = 0; i < _glfw.monitorCount; i++)
{
_GLFWmonitor* monitor = _glfw.monitors[i];
if (monitor->originalRamp.size)
_glfw.platform.setGammaRamp(monitor, &monitor->originalRamp);
_glfwFreeMonitor(monitor);
}
_glfw_free(_glfw.monitors);
_glfw.monitors = NULL;
_glfw.monitorCount = 0;
_glfw_free(_glfw.mappings);
_glfw.mappings = NULL;
_glfw.mappingCount = 0;
_glfwTerminateVulkan();
_glfw.platform.terminateJoysticks();
_glfw.platform.terminate();
_glfw.initialized = GLFW_FALSE;
while (_glfw.errorListHead)
{
_GLFWerror* error = _glfw.errorListHead;
_glfw.errorListHead = error->next;
_glfw_free(error);
}
_glfwPlatformDestroyTls(&_glfw.contextSlot);
_glfwPlatformDestroyTls(&_glfw.errorSlot);
_glfwPlatformDestroyMutex(&_glfw.errorLock);
memset(&_glfw, 0, sizeof(_glfw));
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Encode a Unicode code point to a UTF-8 stream
// Based on cutef8 by Jeff Bezanson (Public Domain)
//
size_t _glfwEncodeUTF8(char* s, uint32_t codepoint)
{
size_t count = 0;
if (codepoint < 0x80)
s[count++] = (char) codepoint;
else if (codepoint < 0x800)
{
s[count++] = (codepoint >> 6) | 0xc0;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x10000)
{
s[count++] = (codepoint >> 12) | 0xe0;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
else if (codepoint < 0x110000)
{
s[count++] = (codepoint >> 18) | 0xf0;
s[count++] = ((codepoint >> 12) & 0x3f) | 0x80;
s[count++] = ((codepoint >> 6) & 0x3f) | 0x80;
s[count++] = (codepoint & 0x3f) | 0x80;
}
return count;
}
// Splits and translates a text/uri-list into separate file paths
// NOTE: This function destroys the provided string
//
char** _glfwParseUriList(char* text, int* count)
{
const char* prefix = "file://";
char** paths = NULL;
char* line;
*count = 0;
while ((line = strtok(text, "\r\n")))
{
char* path;
text = NULL;
if (line[0] == '#')
continue;
if (strncmp(line, prefix, strlen(prefix)) == 0)
{
line += strlen(prefix);
// TODO: Validate hostname
while (*line != '/')
line++;
}
(*count)++;
path = _glfw_calloc(strlen(line) + 1, 1);
paths = _glfw_realloc(paths, *count * sizeof(char*));
paths[*count - 1] = path;
while (*line)
{
if (line[0] == '%' && line[1] && line[2])
{
const char digits[3] = { line[1], line[2], '\0' };
*path = (char) strtol(digits, NULL, 16);
line += 2;
}
else
*path = *line;
path++;
line++;
}
}
return paths;
}
char* _glfw_strdup(const char* source)
{
const size_t length = strlen(source);
char* result = _glfw_calloc(length + 1, 1);
strcpy(result, source);
return result;
}
int _glfw_min(int a, int b)
{
return a < b ? a : b;
}
int _glfw_max(int a, int b)
{
return a > b ? a : b;
}
void* _glfw_calloc(size_t count, size_t size)
{
if (count && size)
{
void* block;
if (count > SIZE_MAX / size)
{
_glfwInputError(GLFW_INVALID_VALUE, "Allocation size overflow");
return NULL;
}
block = _glfw.allocator.allocate(count * size, _glfw.allocator.user);
if (block)
return memset(block, 0, count * size);
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else
return NULL;
}
void* _glfw_realloc(void* block, size_t size)
{
if (block && size)
{
void* resized = _glfw.allocator.reallocate(block, size, _glfw.allocator.user);
if (resized)
return resized;
else
{
_glfwInputError(GLFW_OUT_OF_MEMORY, NULL);
return NULL;
}
}
else if (block)
{
_glfw_free(block);
return NULL;
}
else
return _glfw_calloc(1, size);
}
void _glfw_free(void* block)
{
if (block)
_glfw.allocator.deallocate(block, _glfw.allocator.user);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of an error
//
void _glfwInputError(int code, const char* format, ...)
{
_GLFWerror* error;
char description[_GLFW_MESSAGE_SIZE];
if (format)
{
va_list vl;
va_start(vl, format);
vsnprintf(description, sizeof(description), format, vl);
va_end(vl);
description[sizeof(description) - 1] = '\0';
}
else
{
if (code == GLFW_NOT_INITIALIZED)
strcpy(description, "The GLFW library is not initialized");
else if (code == GLFW_NO_CURRENT_CONTEXT)
strcpy(description, "There is no current context");
else if (code == GLFW_INVALID_ENUM)
strcpy(description, "Invalid argument for enum parameter");
else if (code == GLFW_INVALID_VALUE)
strcpy(description, "Invalid value for parameter");
else if (code == GLFW_OUT_OF_MEMORY)
strcpy(description, "Out of memory");
else if (code == GLFW_API_UNAVAILABLE)
strcpy(description, "The requested API is unavailable");
else if (code == GLFW_VERSION_UNAVAILABLE)
strcpy(description, "The requested API version is unavailable");
else if (code == GLFW_PLATFORM_ERROR)
strcpy(description, "A platform-specific error occurred");
else if (code == GLFW_FORMAT_UNAVAILABLE)
strcpy(description, "The requested format is unavailable");
else if (code == GLFW_NO_WINDOW_CONTEXT)
strcpy(description, "The specified window has no context");
else if (code == GLFW_CURSOR_UNAVAILABLE)
strcpy(description, "The specified cursor shape is unavailable");
else if (code == GLFW_FEATURE_UNAVAILABLE)
strcpy(description, "The requested feature cannot be implemented for this platform");
else if (code == GLFW_FEATURE_UNIMPLEMENTED)
strcpy(description, "The requested feature has not yet been implemented for this platform");
else if (code == GLFW_PLATFORM_UNAVAILABLE)
strcpy(description, "The requested platform is unavailable");
else
strcpy(description, "ERROR: UNKNOWN GLFW ERROR");
}
if (_glfw.initialized)
{
error = _glfwPlatformGetTls(&_glfw.errorSlot);
if (!error)
{
error = _glfw_calloc(1, sizeof(_GLFWerror));
_glfwPlatformSetTls(&_glfw.errorSlot, error);
_glfwPlatformLockMutex(&_glfw.errorLock);
error->next = _glfw.errorListHead;
_glfw.errorListHead = error;
_glfwPlatformUnlockMutex(&_glfw.errorLock);
}
}
else
error = &_glfwMainThreadError;
error->code = code;
strcpy(error->description, description);
if (_glfwErrorCallback)
_glfwErrorCallback(code, description);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwInit(void)
{
if (_glfw.initialized)
return GLFW_TRUE;
memset(&_glfw, 0, sizeof(_glfw));
_glfw.hints.init = _glfwInitHints;
_glfw.allocator = _glfwInitAllocator;
if (!_glfw.allocator.allocate)
{
_glfw.allocator.allocate = defaultAllocate;
_glfw.allocator.reallocate = defaultReallocate;
_glfw.allocator.deallocate = defaultDeallocate;
}
if (!_glfwSelectPlatform(_glfw.hints.init.platformID, &_glfw.platform))
return GLFW_FALSE;
if (!_glfw.platform.init())
{
terminate();
return GLFW_FALSE;
}
if (!_glfwPlatformCreateMutex(&_glfw.errorLock) ||
!_glfwPlatformCreateTls(&_glfw.errorSlot) ||
!_glfwPlatformCreateTls(&_glfw.contextSlot))
{
terminate();
return GLFW_FALSE;
}
_glfwPlatformSetTls(&_glfw.errorSlot, &_glfwMainThreadError);
_glfwInitGamepadMappings();
_glfwPlatformInitTimer();
_glfw.timer.offset = _glfwPlatformGetTimerValue();
_glfw.initialized = GLFW_TRUE;
glfwDefaultWindowHints();
return GLFW_TRUE;
}
GLFWAPI void glfwTerminate(void)
{
if (!_glfw.initialized)
return;
terminate();
}
GLFWAPI void glfwInitHint(int hint, int value)
{
switch (hint)
{
case GLFW_JOYSTICK_HAT_BUTTONS:
_glfwInitHints.hatButtons = value;
return;
case GLFW_ANGLE_PLATFORM_TYPE:
_glfwInitHints.angleType = value;
return;
case GLFW_PLATFORM:
_glfwInitHints.platformID = value;
return;
case GLFW_COCOA_CHDIR_RESOURCES:
_glfwInitHints.ns.chdir = value;
return;
case GLFW_COCOA_MENUBAR:
_glfwInitHints.ns.menubar = value;
return;
case GLFW_X11_XCB_VULKAN_SURFACE:
_glfwInitHints.x11.xcbVulkanSurface = value;
return;
case GLFW_WAYLAND_LIBDECOR:
_glfwInitHints.wl.libdecorMode = value;
return;
}
_glfwInputError(GLFW_INVALID_ENUM,
"Invalid init hint 0x%08X", hint);
}
GLFWAPI void glfwInitAllocator(const GLFWallocator* allocator)
{
if (allocator)
{
if (allocator->allocate && allocator->reallocate && allocator->deallocate)
_glfwInitAllocator = *allocator;
else
_glfwInputError(GLFW_INVALID_VALUE, "Missing function in allocator");
}
else
memset(&_glfwInitAllocator, 0, sizeof(GLFWallocator));
}
GLFWAPI void glfwInitVulkanLoader(PFN_vkGetInstanceProcAddr loader)
{
_glfwInitHints.vulkanLoader = loader;
}
GLFWAPI void glfwGetVersion(int* major, int* minor, int* rev)
{
if (major != NULL)
*major = GLFW_VERSION_MAJOR;
if (minor != NULL)
*minor = GLFW_VERSION_MINOR;
if (rev != NULL)
*rev = GLFW_VERSION_REVISION;
}
GLFWAPI int glfwGetError(const char** description)
{
_GLFWerror* error;
int code = GLFW_NO_ERROR;
if (description)
*description = NULL;
if (_glfw.initialized)
error = _glfwPlatformGetTls(&_glfw.errorSlot);
else
error = &_glfwMainThreadError;
if (error)
{
code = error->code;
error->code = GLFW_NO_ERROR;
if (description && code)
*description = error->description;
}
return code;
}
GLFWAPI GLFWerrorfun glfwSetErrorCallback(GLFWerrorfun cbfun)
{
_GLFW_SWAP(GLFWerrorfun, _glfwErrorCallback, cbfun);
return cbfun;
}

1505
raylib/external/glfw/src/input.c vendored Normal file

File diff suppressed because it is too large Load Diff

1009
raylib/external/glfw/src/internal.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,436 @@
//========================================================================
// GLFW 3.4 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
#include <fcntl.h>
#include <errno.h>
#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifndef SYN_DROPPED // < v2.6.39 kernel headers
// Workaround for CentOS-6, which is supported till 2020-11-30, but still on v2.6.32
#define SYN_DROPPED 3
#endif
// Apply an EV_KEY event to the specified joystick
//
static void handleKeyEvent(_GLFWjoystick* js, int code, int value)
{
_glfwInputJoystickButton(js,
js->linjs.keyMap[code - BTN_MISC],
value ? GLFW_PRESS : GLFW_RELEASE);
}
// Apply an EV_ABS event to the specified joystick
//
static void handleAbsEvent(_GLFWjoystick* js, int code, int value)
{
const int index = js->linjs.absMap[code];
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
static const char stateMap[3][3] =
{
{ GLFW_HAT_CENTERED, GLFW_HAT_UP, GLFW_HAT_DOWN },
{ GLFW_HAT_LEFT, GLFW_HAT_LEFT_UP, GLFW_HAT_LEFT_DOWN },
{ GLFW_HAT_RIGHT, GLFW_HAT_RIGHT_UP, GLFW_HAT_RIGHT_DOWN },
};
const int hat = (code - ABS_HAT0X) / 2;
const int axis = (code - ABS_HAT0X) % 2;
int* state = js->linjs.hats[hat];
// NOTE: Looking at several input drivers, it seems all hat events use
// -1 for left / up, 0 for centered and 1 for right / down
if (value == 0)
state[axis] = 0;
else if (value < 0)
state[axis] = 1;
else if (value > 0)
state[axis] = 2;
_glfwInputJoystickHat(js, index, stateMap[state[0]][state[1]]);
}
else
{
const struct input_absinfo* info = &js->linjs.absInfo[code];
float normalized = value;
const int range = info->maximum - info->minimum;
if (range)
{
// Normalize to 0.0 -> 1.0
normalized = (normalized - info->minimum) / range;
// Normalize to -1.0 -> 1.0
normalized = normalized * 2.0f - 1.0f;
}
_glfwInputJoystickAxis(js, index, normalized);
}
}
// Poll state of absolute axes
//
static void pollAbsState(_GLFWjoystick* js)
{
for (int code = 0; code < ABS_CNT; code++)
{
if (js->linjs.absMap[code] < 0)
continue;
struct input_absinfo* info = &js->linjs.absInfo[code];
if (ioctl(js->linjs.fd, EVIOCGABS(code), info) < 0)
continue;
handleAbsEvent(js, code, info->value);
}
}
#define isBitSet(bit, arr) (arr[(bit) / 8] & (1 << ((bit) % 8)))
// Attempt to open the specified joystick device
//
static GLFWbool openJoystickDevice(const char* path)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (!_glfw.joysticks[jid].connected)
continue;
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
return GLFW_FALSE;
}
_GLFWjoystickLinux linjs = {0};
linjs.fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
if (linjs.fd == -1)
return GLFW_FALSE;
char evBits[(EV_CNT + 7) / 8] = {0};
char keyBits[(KEY_CNT + 7) / 8] = {0};
char absBits[(ABS_CNT + 7) / 8] = {0};
struct input_id id;
if (ioctl(linjs.fd, EVIOCGBIT(0, sizeof(evBits)), evBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_KEY, sizeof(keyBits)), keyBits) < 0 ||
ioctl(linjs.fd, EVIOCGBIT(EV_ABS, sizeof(absBits)), absBits) < 0 ||
ioctl(linjs.fd, EVIOCGID, &id) < 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Linux: Failed to query input device: %s",
strerror(errno));
close(linjs.fd);
return GLFW_FALSE;
}
// Ensure this device supports the events expected of a joystick
if (!isBitSet(EV_ABS, evBits))
{
close(linjs.fd);
return GLFW_FALSE;
}
char name[256] = "";
if (ioctl(linjs.fd, EVIOCGNAME(sizeof(name)), name) < 0)
strncpy(name, "Unknown", sizeof(name));
char guid[33] = "";
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (id.vendor && id.product && id.version)
{
sprintf(guid, "%02x%02x0000%02x%02x0000%02x%02x0000%02x%02x0000",
id.bustype & 0xff, id.bustype >> 8,
id.vendor & 0xff, id.vendor >> 8,
id.product & 0xff, id.product >> 8,
id.version & 0xff, id.version >> 8);
}
else
{
sprintf(guid, "%02x%02x0000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
id.bustype & 0xff, id.bustype >> 8,
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
int axisCount = 0, buttonCount = 0, hatCount = 0;
for (int code = BTN_MISC; code < KEY_CNT; code++)
{
if (!isBitSet(code, keyBits))
continue;
linjs.keyMap[code - BTN_MISC] = buttonCount;
buttonCount++;
}
for (int code = 0; code < ABS_CNT; code++)
{
linjs.absMap[code] = -1;
if (!isBitSet(code, absBits))
continue;
if (code >= ABS_HAT0X && code <= ABS_HAT3Y)
{
linjs.absMap[code] = hatCount;
hatCount++;
// Skip the Y axis
code++;
}
else
{
if (ioctl(linjs.fd, EVIOCGABS(code), &linjs.absInfo[code]) < 0)
continue;
linjs.absMap[code] = axisCount;
axisCount++;
}
}
_GLFWjoystick* js =
_glfwAllocJoystick(name, guid, axisCount, buttonCount, hatCount);
if (!js)
{
close(linjs.fd);
return GLFW_FALSE;
}
strncpy(linjs.path, path, sizeof(linjs.path) - 1);
memcpy(&js->linjs, &linjs, sizeof(linjs));
pollAbsState(js);
_glfwInputJoystick(js, GLFW_CONNECTED);
return GLFW_TRUE;
}
#undef isBitSet
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
_glfwInputJoystick(js, GLFW_DISCONNECTED);
close(js->linjs.fd);
_glfwFreeJoystick(js);
}
// Lexically compare joysticks by name; used by qsort
//
static int compareJoysticks(const void* fp, const void* sp)
{
const _GLFWjoystick* fj = fp;
const _GLFWjoystick* sj = sp;
return strcmp(fj->linjs.path, sj->linjs.path);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwDetectJoystickConnectionLinux(void)
{
if (_glfw.linjs.inotify <= 0)
return;
ssize_t offset = 0;
char buffer[16384];
const ssize_t size = read(_glfw.linjs.inotify, buffer, sizeof(buffer));
while (size > offset)
{
regmatch_t match;
const struct inotify_event* e = (struct inotify_event*) (buffer + offset);
offset += sizeof(struct inotify_event) + e->len;
if (regexec(&_glfw.linjs.regex, e->name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "/dev/input/%s", e->name);
if (e->mask & (IN_CREATE | IN_ATTRIB))
openJoystickDevice(path);
else if (e->mask & IN_DELETE)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (strcmp(_glfw.joysticks[jid].linjs.path, path) == 0)
{
closeJoystick(_glfw.joysticks + jid);
break;
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksLinux(void)
{
const char* dirname = "/dev/input";
_glfw.linjs.inotify = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (_glfw.linjs.inotify > 0)
{
// HACK: Register for IN_ATTRIB to get notified when udev is done
// This works well in practice but the true way is libudev
_glfw.linjs.watch = inotify_add_watch(_glfw.linjs.inotify,
dirname,
IN_CREATE | IN_ATTRIB | IN_DELETE);
}
// Continue without device connection notifications if inotify fails
_glfw.linjs.regexCompiled = (regcomp(&_glfw.linjs.regex, "^event[0-9]\\+$", 0) == 0);
if (!_glfw.linjs.regexCompiled)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Linux: Failed to compile regex");
return GLFW_FALSE;
}
int count = 0;
DIR* dir = opendir(dirname);
if (dir)
{
struct dirent* entry;
while ((entry = readdir(dir)))
{
regmatch_t match;
if (regexec(&_glfw.linjs.regex, entry->d_name, 1, &match, 0) != 0)
continue;
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/%s", dirname, entry->d_name);
if (openJoystickDevice(path))
count++;
}
closedir(dir);
}
// Continue with no joysticks if enumeration fails
qsort(_glfw.joysticks, count, sizeof(_GLFWjoystick), compareJoysticks);
return GLFW_TRUE;
}
void _glfwTerminateJoysticksLinux(void)
{
for (int jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->connected)
closeJoystick(js);
}
if (_glfw.linjs.inotify > 0)
{
if (_glfw.linjs.watch > 0)
inotify_rm_watch(_glfw.linjs.inotify, _glfw.linjs.watch);
close(_glfw.linjs.inotify);
}
if (_glfw.linjs.regexCompiled)
regfree(&_glfw.linjs.regex);
}
GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode)
{
// Read all queued events (non-blocking)
for (;;)
{
struct input_event e;
errno = 0;
if (read(js->linjs.fd, &e, sizeof(e)) < 0)
{
// Reset the joystick slot if the device was disconnected
if (errno == ENODEV)
closeJoystick(js);
break;
}
if (e.type == EV_SYN)
{
if (e.code == SYN_DROPPED)
_glfw.linjs.dropped = GLFW_TRUE;
else if (e.code == SYN_REPORT)
{
_glfw.linjs.dropped = GLFW_FALSE;
pollAbsState(js);
}
}
if (_glfw.linjs.dropped)
continue;
if (e.type == EV_KEY)
handleKeyEvent(js, e.code, e.value);
else if (e.type == EV_ABS)
handleAbsEvent(js, e.code, e.value);
}
return js->connected;
}
const char* _glfwGetMappingNameLinux(void)
{
return "Linux";
}
void _glfwUpdateGamepadGUIDLinux(char* guid)
{
}
#endif // GLFW_BUILD_LINUX_JOYSTICK

View File

@@ -0,0 +1,64 @@
//========================================================================
// GLFW 3.4 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <linux/input.h>
#include <linux/limits.h>
#include <regex.h>
#define GLFW_LINUX_JOYSTICK_STATE _GLFWjoystickLinux linjs;
#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE _GLFWlibraryLinux linjs;
// Linux-specific joystick data
//
typedef struct _GLFWjoystickLinux
{
int fd;
char path[PATH_MAX];
int keyMap[KEY_CNT - BTN_MISC];
int absMap[ABS_CNT];
struct input_absinfo absInfo[ABS_CNT];
int hats[4][2];
} _GLFWjoystickLinux;
// Linux-specific joystick API data
//
typedef struct _GLFWlibraryLinux
{
int inotify;
int watch;
regex_t regex;
GLFWbool regexCompiled;
GLFWbool dropped;
} _GLFWlibraryLinux;
void _glfwDetectJoystickConnectionLinux(void);
GLFWbool _glfwInitJoysticksLinux(void);
void _glfwTerminateJoysticksLinux(void);
GLFWbool _glfwPollJoystickLinux(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameLinux(void);
void _glfwUpdateGamepadGUIDLinux(char* guid);

1002
raylib/external/glfw/src/mappings.h vendored Normal file

File diff suppressed because it is too large Load Diff

82
raylib/external/glfw/src/mappings.h.in vendored Normal file
View File

@@ -0,0 +1,82 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// As mappings.h.in, this file is used by CMake to produce the mappings.h
// header file. If you are adding a GLFW specific gamepad mapping, this is
// where to put it.
//========================================================================
// As mappings.h, this provides all pre-defined gamepad mappings, including
// all available in SDL_GameControllerDB. Do not edit this file. Any gamepad
// mappings not specific to GLFW should be submitted to SDL_GameControllerDB.
// This file can be re-generated from mappings.h.in and the upstream
// gamecontrollerdb.txt with the 'update_mappings' CMake target.
//========================================================================
// All gamepad mappings not labeled GLFW are copied from the
// SDL_GameControllerDB project under the following license:
//
// Simple DirectMedia Layer
// Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not be
// misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
const char* _glfwDefaultMappings[] =
{
#if defined(_GLFW_WIN32)
@GLFW_WIN32_MAPPINGS@
"78696e70757401000000000000000000,XInput Gamepad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757402000000000000000000,XInput Wheel (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757403000000000000000000,XInput Arcade Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757404000000000000000000,XInput Flight Stick (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757405000000000000000000,XInput Dance Pad (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757406000000000000000000,XInput Guitar (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
"78696e70757408000000000000000000,XInput Drum Kit (GLFW),platform:Windows,a:b0,b:b1,x:b2,y:b3,leftshoulder:b4,rightshoulder:b5,back:b6,start:b7,leftstick:b8,rightstick:b9,leftx:a0,lefty:a1,rightx:a2,righty:a3,lefttrigger:a4,righttrigger:a5,dpup:h0.1,dpright:h0.2,dpdown:h0.4,dpleft:h0.8,",
#endif // _GLFW_WIN32
#if defined(_GLFW_COCOA)
@GLFW_COCOA_MAPPINGS@
#endif // _GLFW_COCOA
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
@GLFW_LINUX_MAPPINGS@
#endif // GLFW_BUILD_LINUX_JOYSTICK
};

548
raylib/external/glfw/src/monitor.c vendored Normal file
View File

@@ -0,0 +1,548 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <assert.h>
#include <math.h>
#include <float.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
// Lexically compare video modes, used by qsort
//
static int compareVideoModes(const void* fp, const void* sp)
{
const GLFWvidmode* fm = fp;
const GLFWvidmode* sm = sp;
const int fbpp = fm->redBits + fm->greenBits + fm->blueBits;
const int sbpp = sm->redBits + sm->greenBits + sm->blueBits;
const int farea = fm->width * fm->height;
const int sarea = sm->width * sm->height;
// First sort on color bits per pixel
if (fbpp != sbpp)
return fbpp - sbpp;
// Then sort on screen area
if (farea != sarea)
return farea - sarea;
// Then sort on width
if (fm->width != sm->width)
return fm->width - sm->width;
// Lastly sort on refresh rate
return fm->refreshRate - sm->refreshRate;
}
// Retrieves the available modes for the specified monitor
//
static GLFWbool refreshVideoModes(_GLFWmonitor* monitor)
{
int modeCount;
GLFWvidmode* modes;
if (monitor->modes)
return GLFW_TRUE;
modes = _glfw.platform.getVideoModes(monitor, &modeCount);
if (!modes)
return GLFW_FALSE;
qsort(modes, modeCount, sizeof(GLFWvidmode), compareVideoModes);
_glfw_free(monitor->modes);
monitor->modes = modes;
monitor->modeCount = modeCount;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW event API //////
//////////////////////////////////////////////////////////////////////////
// Notifies shared code of a monitor connection or disconnection
//
void _glfwInputMonitor(_GLFWmonitor* monitor, int action, int placement)
{
assert(monitor != NULL);
assert(action == GLFW_CONNECTED || action == GLFW_DISCONNECTED);
assert(placement == _GLFW_INSERT_FIRST || placement == _GLFW_INSERT_LAST);
if (action == GLFW_CONNECTED)
{
_glfw.monitorCount++;
_glfw.monitors =
_glfw_realloc(_glfw.monitors,
sizeof(_GLFWmonitor*) * _glfw.monitorCount);
if (placement == _GLFW_INSERT_FIRST)
{
memmove(_glfw.monitors + 1,
_glfw.monitors,
((size_t) _glfw.monitorCount - 1) * sizeof(_GLFWmonitor*));
_glfw.monitors[0] = monitor;
}
else
_glfw.monitors[_glfw.monitorCount - 1] = monitor;
}
else if (action == GLFW_DISCONNECTED)
{
int i;
_GLFWwindow* window;
for (window = _glfw.windowListHead; window; window = window->next)
{
if (window->monitor == monitor)
{
int width, height, xoff, yoff;
_glfw.platform.getWindowSize(window, &width, &height);
_glfw.platform.setWindowMonitor(window, NULL, 0, 0, width, height, 0);
_glfw.platform.getWindowFrameSize(window, &xoff, &yoff, NULL, NULL);
_glfw.platform.setWindowPos(window, xoff, yoff);
}
}
for (i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
{
_glfw.monitorCount--;
memmove(_glfw.monitors + i,
_glfw.monitors + i + 1,
((size_t) _glfw.monitorCount - i) * sizeof(_GLFWmonitor*));
break;
}
}
}
if (_glfw.callbacks.monitor)
_glfw.callbacks.monitor((GLFWmonitor*) monitor, action);
if (action == GLFW_DISCONNECTED)
_glfwFreeMonitor(monitor);
}
// Notifies shared code that a full screen window has acquired or released
// a monitor
//
void _glfwInputMonitorWindow(_GLFWmonitor* monitor, _GLFWwindow* window)
{
assert(monitor != NULL);
monitor->window = window;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Allocates and returns a monitor object with the specified name and dimensions
//
_GLFWmonitor* _glfwAllocMonitor(const char* name, int widthMM, int heightMM)
{
_GLFWmonitor* monitor = _glfw_calloc(1, sizeof(_GLFWmonitor));
monitor->widthMM = widthMM;
monitor->heightMM = heightMM;
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
return monitor;
}
// Frees a monitor object and any data associated with it
//
void _glfwFreeMonitor(_GLFWmonitor* monitor)
{
if (monitor == NULL)
return;
_glfw.platform.freeMonitor(monitor);
_glfwFreeGammaArrays(&monitor->originalRamp);
_glfwFreeGammaArrays(&monitor->currentRamp);
_glfw_free(monitor->modes);
_glfw_free(monitor);
}
// Allocates red, green and blue value arrays of the specified size
//
void _glfwAllocGammaArrays(GLFWgammaramp* ramp, unsigned int size)
{
ramp->red = _glfw_calloc(size, sizeof(unsigned short));
ramp->green = _glfw_calloc(size, sizeof(unsigned short));
ramp->blue = _glfw_calloc(size, sizeof(unsigned short));
ramp->size = size;
}
// Frees the red, green and blue value arrays and clears the struct
//
void _glfwFreeGammaArrays(GLFWgammaramp* ramp)
{
_glfw_free(ramp->red);
_glfw_free(ramp->green);
_glfw_free(ramp->blue);
memset(ramp, 0, sizeof(GLFWgammaramp));
}
// Chooses the video mode most closely matching the desired one
//
const GLFWvidmode* _glfwChooseVideoMode(_GLFWmonitor* monitor,
const GLFWvidmode* desired)
{
int i;
unsigned int sizeDiff, leastSizeDiff = UINT_MAX;
unsigned int rateDiff, leastRateDiff = UINT_MAX;
unsigned int colorDiff, leastColorDiff = UINT_MAX;
const GLFWvidmode* current;
const GLFWvidmode* closest = NULL;
if (!refreshVideoModes(monitor))
return NULL;
for (i = 0; i < monitor->modeCount; i++)
{
current = monitor->modes + i;
colorDiff = 0;
if (desired->redBits != GLFW_DONT_CARE)
colorDiff += abs(current->redBits - desired->redBits);
if (desired->greenBits != GLFW_DONT_CARE)
colorDiff += abs(current->greenBits - desired->greenBits);
if (desired->blueBits != GLFW_DONT_CARE)
colorDiff += abs(current->blueBits - desired->blueBits);
sizeDiff = abs((current->width - desired->width) *
(current->width - desired->width) +
(current->height - desired->height) *
(current->height - desired->height));
if (desired->refreshRate != GLFW_DONT_CARE)
rateDiff = abs(current->refreshRate - desired->refreshRate);
else
rateDiff = UINT_MAX - current->refreshRate;
if ((colorDiff < leastColorDiff) ||
(colorDiff == leastColorDiff && sizeDiff < leastSizeDiff) ||
(colorDiff == leastColorDiff && sizeDiff == leastSizeDiff && rateDiff < leastRateDiff))
{
closest = current;
leastSizeDiff = sizeDiff;
leastRateDiff = rateDiff;
leastColorDiff = colorDiff;
}
}
return closest;
}
// Performs lexical comparison between two @ref GLFWvidmode structures
//
int _glfwCompareVideoModes(const GLFWvidmode* fm, const GLFWvidmode* sm)
{
return compareVideoModes(fm, sm);
}
// Splits a color depth into red, green and blue bit depths
//
void _glfwSplitBPP(int bpp, int* red, int* green, int* blue)
{
int delta;
// We assume that by 32 the user really meant 24
if (bpp == 32)
bpp = 24;
// Convert "bits per pixel" to red, green & blue sizes
*red = *green = *blue = bpp / 3;
delta = bpp - (*red * 3);
if (delta >= 1)
*green = *green + 1;
if (delta == 2)
*red = *red + 1;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI GLFWmonitor** glfwGetMonitors(int* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
*count = _glfw.monitorCount;
return (GLFWmonitor**) _glfw.monitors;
}
GLFWAPI GLFWmonitor* glfwGetPrimaryMonitor(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.monitorCount)
return NULL;
return (GLFWmonitor*) _glfw.monitors[0];
}
GLFWAPI void glfwGetMonitorPos(GLFWmonitor* handle, int* xpos, int* ypos)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
_GLFW_REQUIRE_INIT();
_glfw.platform.getMonitorPos(monitor, xpos, ypos);
}
GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* handle,
int* xpos, int* ypos,
int* width, int* height)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
if (width)
*width = 0;
if (height)
*height = 0;
_GLFW_REQUIRE_INIT();
_glfw.platform.getMonitorWorkarea(monitor, xpos, ypos, width, height);
}
GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* handle, int* widthMM, int* heightMM)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (widthMM)
*widthMM = 0;
if (heightMM)
*heightMM = 0;
_GLFW_REQUIRE_INIT();
if (widthMM)
*widthMM = monitor->widthMM;
if (heightMM)
*heightMM = monitor->heightMM;
}
GLFWAPI void glfwGetMonitorContentScale(GLFWmonitor* handle,
float* xscale, float* yscale)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
_GLFW_REQUIRE_INIT();
_glfw.platform.getMonitorContentScale(monitor, xscale, yscale);
}
GLFWAPI const char* glfwGetMonitorName(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->name;
}
GLFWAPI void glfwSetMonitorUserPointer(GLFWmonitor* handle, void* pointer)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT();
monitor->userPointer = pointer;
}
GLFWAPI void* glfwGetMonitorUserPointer(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
return monitor->userPointer;
}
GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun cbfun)
{
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_GLFW_SWAP(GLFWmonitorfun, _glfw.callbacks.monitor, cbfun);
return cbfun;
}
GLFWAPI const GLFWvidmode* glfwGetVideoModes(GLFWmonitor* handle, int* count)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!refreshVideoModes(monitor))
return NULL;
*count = monitor->modeCount;
return monitor->modes;
}
GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfw.platform.getVideoMode(monitor, &monitor->currentMode))
return NULL;
return &monitor->currentMode;
}
GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma)
{
unsigned int i;
unsigned short* values;
GLFWgammaramp ramp;
const GLFWgammaramp* original;
assert(handle != NULL);
assert(gamma > 0.f);
assert(gamma <= FLT_MAX);
_GLFW_REQUIRE_INIT();
if (gamma != gamma || gamma <= 0.f || gamma > FLT_MAX)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid gamma value %f", gamma);
return;
}
original = glfwGetGammaRamp(handle);
if (!original)
return;
values = _glfw_calloc(original->size, sizeof(unsigned short));
for (i = 0; i < original->size; i++)
{
float value;
// Calculate intensity
value = i / (float) (original->size - 1);
// Apply gamma curve
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp to value range
value = fminf(value, 65535.f);
values[i] = (unsigned short) value;
}
ramp.red = values;
ramp.green = values;
ramp.blue = values;
ramp.size = original->size;
glfwSetGammaRamp(handle, &ramp);
_glfw_free(values);
}
GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
_glfwFreeGammaArrays(&monitor->currentRamp);
if (!_glfw.platform.getGammaRamp(monitor, &monitor->currentRamp))
return NULL;
return &monitor->currentRamp;
}
GLFWAPI void glfwSetGammaRamp(GLFWmonitor* handle, const GLFWgammaramp* ramp)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
assert(monitor != NULL);
assert(ramp != NULL);
assert(ramp->size > 0);
assert(ramp->red != NULL);
assert(ramp->green != NULL);
assert(ramp->blue != NULL);
_GLFW_REQUIRE_INIT();
if (ramp->size <= 0)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Invalid gamma ramp size %i",
ramp->size);
return;
}
if (!monitor->originalRamp.size)
{
if (!_glfw.platform.getGammaRamp(monitor, &monitor->originalRamp))
return;
}
_glfw.platform.setGammaRamp(monitor, ramp);
}

384
raylib/external/glfw/src/nsgl_context.m vendored Normal file
View File

@@ -0,0 +1,384 @@
//========================================================================
// GLFW 3.4 macOS - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2009-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_COCOA)
#include <unistd.h>
#include <math.h>
static void makeContextCurrentNSGL(_GLFWwindow* window)
{
@autoreleasepool {
if (window)
[window->context.nsgl.object makeCurrentContext];
else
[NSOpenGLContext clearCurrentContext];
_glfwPlatformSetTls(&_glfw.contextSlot, window);
} // autoreleasepool
}
static void swapBuffersNSGL(_GLFWwindow* window)
{
@autoreleasepool {
// HACK: Simulate vsync with usleep as NSGL swap interval does not apply to
// windows with a non-visible occlusion state
if (window->ns.occluded)
{
int interval = 0;
[window->context.nsgl.object getValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
if (interval > 0)
{
const double framerate = 60.0;
const uint64_t frequency = _glfwPlatformGetTimerFrequency();
const uint64_t value = _glfwPlatformGetTimerValue();
const double elapsed = value / (double) frequency;
const double period = 1.0 / framerate;
const double delay = period - fmod(elapsed, period);
usleep(floorl(delay * 1e6));
}
}
[window->context.nsgl.object flushBuffer];
} // autoreleasepool
}
static void swapIntervalNSGL(int interval)
{
@autoreleasepool {
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
[window->context.nsgl.object setValues:&interval
forParameter:NSOpenGLContextParameterSwapInterval];
} // autoreleasepool
}
static int extensionSupportedNSGL(const char* extension)
{
// There are no NSGL extensions
return GLFW_FALSE;
}
static GLFWglproc getProcAddressNSGL(const char* procname)
{
CFStringRef symbolName = CFStringCreateWithCString(kCFAllocatorDefault,
procname,
kCFStringEncodingASCII);
GLFWglproc symbol = CFBundleGetFunctionPointerForName(_glfw.nsgl.framework,
symbolName);
CFRelease(symbolName);
return symbol;
}
static void destroyContextNSGL(_GLFWwindow* window)
{
@autoreleasepool {
[window->context.nsgl.pixelFormat release];
window->context.nsgl.pixelFormat = nil;
[window->context.nsgl.object release];
window->context.nsgl.object = nil;
} // autoreleasepool
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Initialize OpenGL support
//
GLFWbool _glfwInitNSGL(void)
{
if (_glfw.nsgl.framework)
return GLFW_TRUE;
_glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
if (_glfw.nsgl.framework == NULL)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: Failed to locate OpenGL framework");
return GLFW_FALSE;
}
return GLFW_TRUE;
}
// Terminate OpenGL support
//
void _glfwTerminateNSGL(void)
{
}
// Create the OpenGL context
//
GLFWbool _glfwCreateContextNSGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"NSGL: OpenGL ES is not available via NSGL");
return GLFW_FALSE;
}
if (ctxconfig->major > 2)
{
if (ctxconfig->major == 3 && ctxconfig->minor < 2)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The targeted version of macOS does not support OpenGL 3.0 or 3.1 but may support 3.2 and above");
return GLFW_FALSE;
}
}
if (ctxconfig->major >= 3 && ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: The compatibility profile is not available on macOS");
return GLFW_FALSE;
}
// Context robustness modes (GL_KHR_robustness) are not yet supported by
// macOS but are not a hard constraint, so ignore and continue
// Context release behaviors (GL_KHR_context_flush_control) are not yet
// supported by macOS but are not a hard constraint, so ignore and continue
// Debug contexts (GL_KHR_debug) are not yet supported by macOS but are not
// a hard constraint, so ignore and continue
// No-error contexts (GL_KHR_no_error) are not yet supported by macOS but
// are not a hard constraint, so ignore and continue
#define ADD_ATTRIB(a) \
{ \
assert((size_t) index < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
}
#define SET_ATTRIB(a, v) { ADD_ATTRIB(a); ADD_ATTRIB(v); }
NSOpenGLPixelFormatAttribute attribs[40];
int index = 0;
ADD_ATTRIB(NSOpenGLPFAAccelerated);
ADD_ATTRIB(NSOpenGLPFAClosestPolicy);
if (ctxconfig->nsgl.offline)
{
ADD_ATTRIB(NSOpenGLPFAAllowOfflineRenderers);
// NOTE: This replaces the NSSupportsAutomaticGraphicsSwitching key in
// Info.plist for unbundled applications
// HACK: This assumes that NSOpenGLPixelFormat will remain
// a straightforward wrapper of its CGL counterpart
ADD_ATTRIB(kCGLPFASupportsAutomaticGraphicsSwitching);
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101000
if (ctxconfig->major >= 4)
{
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion4_1Core);
}
else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
if (ctxconfig->major >= 3)
{
SET_ATTRIB(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
if (ctxconfig->major <= 2)
{
if (fbconfig->auxBuffers != GLFW_DONT_CARE)
SET_ATTRIB(NSOpenGLPFAAuxBuffers, fbconfig->auxBuffers);
if (fbconfig->accumRedBits != GLFW_DONT_CARE &&
fbconfig->accumGreenBits != GLFW_DONT_CARE &&
fbconfig->accumBlueBits != GLFW_DONT_CARE &&
fbconfig->accumAlphaBits != GLFW_DONT_CARE)
{
const int accumBits = fbconfig->accumRedBits +
fbconfig->accumGreenBits +
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
SET_ATTRIB(NSOpenGLPFAAccumSize, accumBits);
}
}
if (fbconfig->redBits != GLFW_DONT_CARE &&
fbconfig->greenBits != GLFW_DONT_CARE &&
fbconfig->blueBits != GLFW_DONT_CARE)
{
int colorBits = fbconfig->redBits +
fbconfig->greenBits +
fbconfig->blueBits;
// macOS needs non-zero color size, so set reasonable values
if (colorBits == 0)
colorBits = 24;
else if (colorBits < 15)
colorBits = 15;
SET_ATTRIB(NSOpenGLPFAColorSize, colorBits);
}
if (fbconfig->alphaBits != GLFW_DONT_CARE)
SET_ATTRIB(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
if (fbconfig->depthBits != GLFW_DONT_CARE)
SET_ATTRIB(NSOpenGLPFADepthSize, fbconfig->depthBits);
if (fbconfig->stencilBits != GLFW_DONT_CARE)
SET_ATTRIB(NSOpenGLPFAStencilSize, fbconfig->stencilBits);
if (fbconfig->stereo)
{
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Stereo rendering is deprecated");
return GLFW_FALSE;
#else
ADD_ATTRIB(NSOpenGLPFAStereo);
#endif
}
if (fbconfig->doublebuffer)
ADD_ATTRIB(NSOpenGLPFADoubleBuffer);
if (fbconfig->samples != GLFW_DONT_CARE)
{
if (fbconfig->samples == 0)
{
SET_ATTRIB(NSOpenGLPFASampleBuffers, 0);
}
else
{
SET_ATTRIB(NSOpenGLPFASampleBuffers, 1);
SET_ATTRIB(NSOpenGLPFASamples, fbconfig->samples);
}
}
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// framebuffer, so there's no need (and no way) to request it
ADD_ATTRIB(0);
#undef ADD_ATTRIB
#undef SET_ATTRIB
window->context.nsgl.pixelFormat =
[[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
if (window->context.nsgl.pixelFormat == nil)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"NSGL: Failed to find a suitable pixel format");
return GLFW_FALSE;
}
NSOpenGLContext* share = nil;
if (ctxconfig->share)
share = ctxconfig->share->context.nsgl.object;
window->context.nsgl.object =
[[NSOpenGLContext alloc] initWithFormat:window->context.nsgl.pixelFormat
shareContext:share];
if (window->context.nsgl.object == nil)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"NSGL: Failed to create OpenGL context");
return GLFW_FALSE;
}
if (fbconfig->transparent)
{
GLint opaque = 0;
[window->context.nsgl.object setValues:&opaque
forParameter:NSOpenGLContextParameterSurfaceOpacity];
}
[window->ns.view setWantsBestResolutionOpenGLSurface:window->ns.scaleFramebuffer];
[window->context.nsgl.object setView:window->ns.view];
window->context.makeCurrent = makeContextCurrentNSGL;
window->context.swapBuffers = swapBuffersNSGL;
window->context.swapInterval = swapIntervalNSGL;
window->context.extensionSupported = extensionSupportedNSGL;
window->context.getProcAddress = getProcAddressNSGL;
window->context.destroy = destroyContextNSGL;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI id glfwGetNSGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(nil);
if (_glfw.platform.platformID != GLFW_PLATFORM_COCOA)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"NSGL: Platform not initialized");
return nil;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return nil;
}
return window->context.nsgl.object;
}
#endif // _GLFW_COCOA

264
raylib/external/glfw/src/null_init.c vendored Normal file
View File

@@ -0,0 +1,264 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform null =
{
.platformID = GLFW_PLATFORM_NULL,
.init = _glfwInitNull,
.terminate = _glfwTerminateNull,
.getCursorPos = _glfwGetCursorPosNull,
.setCursorPos = _glfwSetCursorPosNull,
.setCursorMode = _glfwSetCursorModeNull,
.setRawMouseMotion = _glfwSetRawMouseMotionNull,
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedNull,
.createCursor = _glfwCreateCursorNull,
.createStandardCursor = _glfwCreateStandardCursorNull,
.destroyCursor = _glfwDestroyCursorNull,
.setCursor = _glfwSetCursorNull,
.getScancodeName = _glfwGetScancodeNameNull,
.getKeyScancode = _glfwGetKeyScancodeNull,
.setClipboardString = _glfwSetClipboardStringNull,
.getClipboardString = _glfwGetClipboardStringNull,
.initJoysticks = _glfwInitJoysticksNull,
.terminateJoysticks = _glfwTerminateJoysticksNull,
.pollJoystick = _glfwPollJoystickNull,
.getMappingName = _glfwGetMappingNameNull,
.updateGamepadGUID = _glfwUpdateGamepadGUIDNull,
.freeMonitor = _glfwFreeMonitorNull,
.getMonitorPos = _glfwGetMonitorPosNull,
.getMonitorContentScale = _glfwGetMonitorContentScaleNull,
.getMonitorWorkarea = _glfwGetMonitorWorkareaNull,
.getVideoModes = _glfwGetVideoModesNull,
.getVideoMode = _glfwGetVideoModeNull,
.getGammaRamp = _glfwGetGammaRampNull,
.setGammaRamp = _glfwSetGammaRampNull,
.createWindow = _glfwCreateWindowNull,
.destroyWindow = _glfwDestroyWindowNull,
.setWindowTitle = _glfwSetWindowTitleNull,
.setWindowIcon = _glfwSetWindowIconNull,
.getWindowPos = _glfwGetWindowPosNull,
.setWindowPos = _glfwSetWindowPosNull,
.getWindowSize = _glfwGetWindowSizeNull,
.setWindowSize = _glfwSetWindowSizeNull,
.setWindowSizeLimits = _glfwSetWindowSizeLimitsNull,
.setWindowAspectRatio = _glfwSetWindowAspectRatioNull,
.getFramebufferSize = _glfwGetFramebufferSizeNull,
.getWindowFrameSize = _glfwGetWindowFrameSizeNull,
.getWindowContentScale = _glfwGetWindowContentScaleNull,
.iconifyWindow = _glfwIconifyWindowNull,
.restoreWindow = _glfwRestoreWindowNull,
.maximizeWindow = _glfwMaximizeWindowNull,
.showWindow = _glfwShowWindowNull,
.hideWindow = _glfwHideWindowNull,
.requestWindowAttention = _glfwRequestWindowAttentionNull,
.focusWindow = _glfwFocusWindowNull,
.setWindowMonitor = _glfwSetWindowMonitorNull,
.windowFocused = _glfwWindowFocusedNull,
.windowIconified = _glfwWindowIconifiedNull,
.windowVisible = _glfwWindowVisibleNull,
.windowMaximized = _glfwWindowMaximizedNull,
.windowHovered = _glfwWindowHoveredNull,
.framebufferTransparent = _glfwFramebufferTransparentNull,
.getWindowOpacity = _glfwGetWindowOpacityNull,
.setWindowResizable = _glfwSetWindowResizableNull,
.setWindowDecorated = _glfwSetWindowDecoratedNull,
.setWindowFloating = _glfwSetWindowFloatingNull,
.setWindowOpacity = _glfwSetWindowOpacityNull,
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughNull,
.pollEvents = _glfwPollEventsNull,
.waitEvents = _glfwWaitEventsNull,
.waitEventsTimeout = _glfwWaitEventsTimeoutNull,
.postEmptyEvent = _glfwPostEmptyEventNull,
.getEGLPlatform = _glfwGetEGLPlatformNull,
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayNull,
.getEGLNativeWindow = _glfwGetEGLNativeWindowNull,
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsNull,
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportNull,
.createWindowSurface = _glfwCreateWindowSurfaceNull
};
*platform = null;
return GLFW_TRUE;
}
int _glfwInitNull(void)
{
int scancode;
memset(_glfw.null.keycodes, -1, sizeof(_glfw.null.keycodes));
memset(_glfw.null.scancodes, -1, sizeof(_glfw.null.scancodes));
_glfw.null.keycodes[GLFW_NULL_SC_SPACE] = GLFW_KEY_SPACE;
_glfw.null.keycodes[GLFW_NULL_SC_APOSTROPHE] = GLFW_KEY_APOSTROPHE;
_glfw.null.keycodes[GLFW_NULL_SC_COMMA] = GLFW_KEY_COMMA;
_glfw.null.keycodes[GLFW_NULL_SC_MINUS] = GLFW_KEY_MINUS;
_glfw.null.keycodes[GLFW_NULL_SC_PERIOD] = GLFW_KEY_PERIOD;
_glfw.null.keycodes[GLFW_NULL_SC_SLASH] = GLFW_KEY_SLASH;
_glfw.null.keycodes[GLFW_NULL_SC_0] = GLFW_KEY_0;
_glfw.null.keycodes[GLFW_NULL_SC_1] = GLFW_KEY_1;
_glfw.null.keycodes[GLFW_NULL_SC_2] = GLFW_KEY_2;
_glfw.null.keycodes[GLFW_NULL_SC_3] = GLFW_KEY_3;
_glfw.null.keycodes[GLFW_NULL_SC_4] = GLFW_KEY_4;
_glfw.null.keycodes[GLFW_NULL_SC_5] = GLFW_KEY_5;
_glfw.null.keycodes[GLFW_NULL_SC_6] = GLFW_KEY_6;
_glfw.null.keycodes[GLFW_NULL_SC_7] = GLFW_KEY_7;
_glfw.null.keycodes[GLFW_NULL_SC_8] = GLFW_KEY_8;
_glfw.null.keycodes[GLFW_NULL_SC_9] = GLFW_KEY_9;
_glfw.null.keycodes[GLFW_NULL_SC_SEMICOLON] = GLFW_KEY_SEMICOLON;
_glfw.null.keycodes[GLFW_NULL_SC_EQUAL] = GLFW_KEY_EQUAL;
_glfw.null.keycodes[GLFW_NULL_SC_A] = GLFW_KEY_A;
_glfw.null.keycodes[GLFW_NULL_SC_B] = GLFW_KEY_B;
_glfw.null.keycodes[GLFW_NULL_SC_C] = GLFW_KEY_C;
_glfw.null.keycodes[GLFW_NULL_SC_D] = GLFW_KEY_D;
_glfw.null.keycodes[GLFW_NULL_SC_E] = GLFW_KEY_E;
_glfw.null.keycodes[GLFW_NULL_SC_F] = GLFW_KEY_F;
_glfw.null.keycodes[GLFW_NULL_SC_G] = GLFW_KEY_G;
_glfw.null.keycodes[GLFW_NULL_SC_H] = GLFW_KEY_H;
_glfw.null.keycodes[GLFW_NULL_SC_I] = GLFW_KEY_I;
_glfw.null.keycodes[GLFW_NULL_SC_J] = GLFW_KEY_J;
_glfw.null.keycodes[GLFW_NULL_SC_K] = GLFW_KEY_K;
_glfw.null.keycodes[GLFW_NULL_SC_L] = GLFW_KEY_L;
_glfw.null.keycodes[GLFW_NULL_SC_M] = GLFW_KEY_M;
_glfw.null.keycodes[GLFW_NULL_SC_N] = GLFW_KEY_N;
_glfw.null.keycodes[GLFW_NULL_SC_O] = GLFW_KEY_O;
_glfw.null.keycodes[GLFW_NULL_SC_P] = GLFW_KEY_P;
_glfw.null.keycodes[GLFW_NULL_SC_Q] = GLFW_KEY_Q;
_glfw.null.keycodes[GLFW_NULL_SC_R] = GLFW_KEY_R;
_glfw.null.keycodes[GLFW_NULL_SC_S] = GLFW_KEY_S;
_glfw.null.keycodes[GLFW_NULL_SC_T] = GLFW_KEY_T;
_glfw.null.keycodes[GLFW_NULL_SC_U] = GLFW_KEY_U;
_glfw.null.keycodes[GLFW_NULL_SC_V] = GLFW_KEY_V;
_glfw.null.keycodes[GLFW_NULL_SC_W] = GLFW_KEY_W;
_glfw.null.keycodes[GLFW_NULL_SC_X] = GLFW_KEY_X;
_glfw.null.keycodes[GLFW_NULL_SC_Y] = GLFW_KEY_Y;
_glfw.null.keycodes[GLFW_NULL_SC_Z] = GLFW_KEY_Z;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_BRACKET] = GLFW_KEY_LEFT_BRACKET;
_glfw.null.keycodes[GLFW_NULL_SC_BACKSLASH] = GLFW_KEY_BACKSLASH;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_BRACKET] = GLFW_KEY_RIGHT_BRACKET;
_glfw.null.keycodes[GLFW_NULL_SC_GRAVE_ACCENT] = GLFW_KEY_GRAVE_ACCENT;
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_1] = GLFW_KEY_WORLD_1;
_glfw.null.keycodes[GLFW_NULL_SC_WORLD_2] = GLFW_KEY_WORLD_2;
_glfw.null.keycodes[GLFW_NULL_SC_ESCAPE] = GLFW_KEY_ESCAPE;
_glfw.null.keycodes[GLFW_NULL_SC_ENTER] = GLFW_KEY_ENTER;
_glfw.null.keycodes[GLFW_NULL_SC_TAB] = GLFW_KEY_TAB;
_glfw.null.keycodes[GLFW_NULL_SC_BACKSPACE] = GLFW_KEY_BACKSPACE;
_glfw.null.keycodes[GLFW_NULL_SC_INSERT] = GLFW_KEY_INSERT;
_glfw.null.keycodes[GLFW_NULL_SC_DELETE] = GLFW_KEY_DELETE;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT] = GLFW_KEY_RIGHT;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT] = GLFW_KEY_LEFT;
_glfw.null.keycodes[GLFW_NULL_SC_DOWN] = GLFW_KEY_DOWN;
_glfw.null.keycodes[GLFW_NULL_SC_UP] = GLFW_KEY_UP;
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_UP] = GLFW_KEY_PAGE_UP;
_glfw.null.keycodes[GLFW_NULL_SC_PAGE_DOWN] = GLFW_KEY_PAGE_DOWN;
_glfw.null.keycodes[GLFW_NULL_SC_HOME] = GLFW_KEY_HOME;
_glfw.null.keycodes[GLFW_NULL_SC_END] = GLFW_KEY_END;
_glfw.null.keycodes[GLFW_NULL_SC_CAPS_LOCK] = GLFW_KEY_CAPS_LOCK;
_glfw.null.keycodes[GLFW_NULL_SC_SCROLL_LOCK] = GLFW_KEY_SCROLL_LOCK;
_glfw.null.keycodes[GLFW_NULL_SC_NUM_LOCK] = GLFW_KEY_NUM_LOCK;
_glfw.null.keycodes[GLFW_NULL_SC_PRINT_SCREEN] = GLFW_KEY_PRINT_SCREEN;
_glfw.null.keycodes[GLFW_NULL_SC_PAUSE] = GLFW_KEY_PAUSE;
_glfw.null.keycodes[GLFW_NULL_SC_F1] = GLFW_KEY_F1;
_glfw.null.keycodes[GLFW_NULL_SC_F2] = GLFW_KEY_F2;
_glfw.null.keycodes[GLFW_NULL_SC_F3] = GLFW_KEY_F3;
_glfw.null.keycodes[GLFW_NULL_SC_F4] = GLFW_KEY_F4;
_glfw.null.keycodes[GLFW_NULL_SC_F5] = GLFW_KEY_F5;
_glfw.null.keycodes[GLFW_NULL_SC_F6] = GLFW_KEY_F6;
_glfw.null.keycodes[GLFW_NULL_SC_F7] = GLFW_KEY_F7;
_glfw.null.keycodes[GLFW_NULL_SC_F8] = GLFW_KEY_F8;
_glfw.null.keycodes[GLFW_NULL_SC_F9] = GLFW_KEY_F9;
_glfw.null.keycodes[GLFW_NULL_SC_F10] = GLFW_KEY_F10;
_glfw.null.keycodes[GLFW_NULL_SC_F11] = GLFW_KEY_F11;
_glfw.null.keycodes[GLFW_NULL_SC_F12] = GLFW_KEY_F12;
_glfw.null.keycodes[GLFW_NULL_SC_F13] = GLFW_KEY_F13;
_glfw.null.keycodes[GLFW_NULL_SC_F14] = GLFW_KEY_F14;
_glfw.null.keycodes[GLFW_NULL_SC_F15] = GLFW_KEY_F15;
_glfw.null.keycodes[GLFW_NULL_SC_F16] = GLFW_KEY_F16;
_glfw.null.keycodes[GLFW_NULL_SC_F17] = GLFW_KEY_F17;
_glfw.null.keycodes[GLFW_NULL_SC_F18] = GLFW_KEY_F18;
_glfw.null.keycodes[GLFW_NULL_SC_F19] = GLFW_KEY_F19;
_glfw.null.keycodes[GLFW_NULL_SC_F20] = GLFW_KEY_F20;
_glfw.null.keycodes[GLFW_NULL_SC_F21] = GLFW_KEY_F21;
_glfw.null.keycodes[GLFW_NULL_SC_F22] = GLFW_KEY_F22;
_glfw.null.keycodes[GLFW_NULL_SC_F23] = GLFW_KEY_F23;
_glfw.null.keycodes[GLFW_NULL_SC_F24] = GLFW_KEY_F24;
_glfw.null.keycodes[GLFW_NULL_SC_F25] = GLFW_KEY_F25;
_glfw.null.keycodes[GLFW_NULL_SC_KP_0] = GLFW_KEY_KP_0;
_glfw.null.keycodes[GLFW_NULL_SC_KP_1] = GLFW_KEY_KP_1;
_glfw.null.keycodes[GLFW_NULL_SC_KP_2] = GLFW_KEY_KP_2;
_glfw.null.keycodes[GLFW_NULL_SC_KP_3] = GLFW_KEY_KP_3;
_glfw.null.keycodes[GLFW_NULL_SC_KP_4] = GLFW_KEY_KP_4;
_glfw.null.keycodes[GLFW_NULL_SC_KP_5] = GLFW_KEY_KP_5;
_glfw.null.keycodes[GLFW_NULL_SC_KP_6] = GLFW_KEY_KP_6;
_glfw.null.keycodes[GLFW_NULL_SC_KP_7] = GLFW_KEY_KP_7;
_glfw.null.keycodes[GLFW_NULL_SC_KP_8] = GLFW_KEY_KP_8;
_glfw.null.keycodes[GLFW_NULL_SC_KP_9] = GLFW_KEY_KP_9;
_glfw.null.keycodes[GLFW_NULL_SC_KP_DECIMAL] = GLFW_KEY_KP_DECIMAL;
_glfw.null.keycodes[GLFW_NULL_SC_KP_DIVIDE] = GLFW_KEY_KP_DIVIDE;
_glfw.null.keycodes[GLFW_NULL_SC_KP_MULTIPLY] = GLFW_KEY_KP_MULTIPLY;
_glfw.null.keycodes[GLFW_NULL_SC_KP_SUBTRACT] = GLFW_KEY_KP_SUBTRACT;
_glfw.null.keycodes[GLFW_NULL_SC_KP_ADD] = GLFW_KEY_KP_ADD;
_glfw.null.keycodes[GLFW_NULL_SC_KP_ENTER] = GLFW_KEY_KP_ENTER;
_glfw.null.keycodes[GLFW_NULL_SC_KP_EQUAL] = GLFW_KEY_KP_EQUAL;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SHIFT] = GLFW_KEY_LEFT_SHIFT;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_CONTROL] = GLFW_KEY_LEFT_CONTROL;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_ALT] = GLFW_KEY_LEFT_ALT;
_glfw.null.keycodes[GLFW_NULL_SC_LEFT_SUPER] = GLFW_KEY_LEFT_SUPER;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SHIFT] = GLFW_KEY_RIGHT_SHIFT;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_CONTROL] = GLFW_KEY_RIGHT_CONTROL;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_ALT] = GLFW_KEY_RIGHT_ALT;
_glfw.null.keycodes[GLFW_NULL_SC_RIGHT_SUPER] = GLFW_KEY_RIGHT_SUPER;
_glfw.null.keycodes[GLFW_NULL_SC_MENU] = GLFW_KEY_MENU;
for (scancode = GLFW_NULL_SC_FIRST; scancode < GLFW_NULL_SC_LAST; scancode++)
{
if (_glfw.null.keycodes[scancode] > 0)
_glfw.null.scancodes[_glfw.null.keycodes[scancode]] = scancode;
}
_glfwPollMonitorsNull();
return GLFW_TRUE;
}
void _glfwTerminateNull(void)
{
free(_glfw.null.clipboardString);
_glfwTerminateOSMesa();
_glfwTerminateEGL();
}

View File

@@ -0,0 +1,56 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksNull(void)
{
return GLFW_TRUE;
}
void _glfwTerminateJoysticksNull(void)
{
}
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode)
{
return GLFW_FALSE;
}
const char* _glfwGetMappingNameNull(void)
{
return "";
}
void _glfwUpdateGamepadGUIDNull(char* guid)
{
}

View File

@@ -0,0 +1,32 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
GLFWbool _glfwInitJoysticksNull(void);
void _glfwTerminateJoysticksNull(void);
GLFWbool _glfwPollJoystickNull(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameNull(void);
void _glfwUpdateGamepadGUIDNull(char* guid);

160
raylib/external/glfw/src/null_monitor.c vendored Normal file
View File

@@ -0,0 +1,160 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <string.h>
#include <math.h>
// The the sole (fake) video mode of our (sole) fake monitor
//
static GLFWvidmode getVideoMode(void)
{
GLFWvidmode mode;
mode.width = 1920;
mode.height = 1080;
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = 60;
return mode;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPollMonitorsNull(void)
{
const float dpi = 141.f;
const GLFWvidmode mode = getVideoMode();
_GLFWmonitor* monitor = _glfwAllocMonitor("Null SuperNoop 0",
(int) (mode.width * 25.4f / dpi),
(int) (mode.height * 25.4f / dpi));
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorNull(_GLFWmonitor* monitor)
{
_glfwFreeGammaArrays(&monitor->null.ramp);
}
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
}
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.f;
if (yscale)
*yscale = 1.f;
}
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
const GLFWvidmode mode = getVideoMode();
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 10;
if (width)
*width = mode.width;
if (height)
*height = mode.height - 10;
}
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found)
{
GLFWvidmode* mode = _glfw_calloc(1, sizeof(GLFWvidmode));
*mode = getVideoMode();
*found = 1;
return mode;
}
GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
*mode = getVideoMode();
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
if (!monitor->null.ramp.size)
{
unsigned int i;
_glfwAllocGammaArrays(&monitor->null.ramp, 256);
for (i = 0; i < monitor->null.ramp.size; i++)
{
const float gamma = 2.2f;
float value;
value = i / (float) (monitor->null.ramp.size - 1);
value = powf(value, 1.f / gamma) * 65535.f + 0.5f;
value = fminf(value, 65535.f);
monitor->null.ramp.red[i] = (unsigned short) value;
monitor->null.ramp.green[i] = (unsigned short) value;
monitor->null.ramp.blue[i] = (unsigned short) value;
}
}
_glfwAllocGammaArrays(ramp, monitor->null.ramp.size);
memcpy(ramp->red, monitor->null.ramp.red, sizeof(short) * ramp->size);
memcpy(ramp->green, monitor->null.ramp.green, sizeof(short) * ramp->size);
memcpy(ramp->blue, monitor->null.ramp.blue, sizeof(short) * ramp->size);
return GLFW_TRUE;
}
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (monitor->null.ramp.size != ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Null: Gamma ramp size must match current ramp size");
return;
}
memcpy(monitor->null.ramp.red, ramp->red, sizeof(short) * ramp->size);
memcpy(monitor->null.ramp.green, ramp->green, sizeof(short) * ramp->size);
memcpy(monitor->null.ramp.blue, ramp->blue, sizeof(short) * ramp->size);
}

271
raylib/external/glfw/src/null_platform.h vendored Normal file
View File

@@ -0,0 +1,271 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_NULL_WINDOW_STATE _GLFWwindowNull null;
#define GLFW_NULL_LIBRARY_WINDOW_STATE _GLFWlibraryNull null;
#define GLFW_NULL_MONITOR_STATE _GLFWmonitorNull null;
#define GLFW_NULL_CONTEXT_STATE
#define GLFW_NULL_CURSOR_STATE
#define GLFW_NULL_LIBRARY_CONTEXT_STATE
#define GLFW_NULL_SC_FIRST GLFW_NULL_SC_SPACE
#define GLFW_NULL_SC_SPACE 1
#define GLFW_NULL_SC_APOSTROPHE 2
#define GLFW_NULL_SC_COMMA 3
#define GLFW_NULL_SC_MINUS 4
#define GLFW_NULL_SC_PERIOD 5
#define GLFW_NULL_SC_SLASH 6
#define GLFW_NULL_SC_0 7
#define GLFW_NULL_SC_1 8
#define GLFW_NULL_SC_2 9
#define GLFW_NULL_SC_3 10
#define GLFW_NULL_SC_4 11
#define GLFW_NULL_SC_5 12
#define GLFW_NULL_SC_6 13
#define GLFW_NULL_SC_7 14
#define GLFW_NULL_SC_8 15
#define GLFW_NULL_SC_9 16
#define GLFW_NULL_SC_SEMICOLON 17
#define GLFW_NULL_SC_EQUAL 18
#define GLFW_NULL_SC_LEFT_BRACKET 19
#define GLFW_NULL_SC_BACKSLASH 20
#define GLFW_NULL_SC_RIGHT_BRACKET 21
#define GLFW_NULL_SC_GRAVE_ACCENT 22
#define GLFW_NULL_SC_WORLD_1 23
#define GLFW_NULL_SC_WORLD_2 24
#define GLFW_NULL_SC_ESCAPE 25
#define GLFW_NULL_SC_ENTER 26
#define GLFW_NULL_SC_TAB 27
#define GLFW_NULL_SC_BACKSPACE 28
#define GLFW_NULL_SC_INSERT 29
#define GLFW_NULL_SC_DELETE 30
#define GLFW_NULL_SC_RIGHT 31
#define GLFW_NULL_SC_LEFT 32
#define GLFW_NULL_SC_DOWN 33
#define GLFW_NULL_SC_UP 34
#define GLFW_NULL_SC_PAGE_UP 35
#define GLFW_NULL_SC_PAGE_DOWN 36
#define GLFW_NULL_SC_HOME 37
#define GLFW_NULL_SC_END 38
#define GLFW_NULL_SC_CAPS_LOCK 39
#define GLFW_NULL_SC_SCROLL_LOCK 40
#define GLFW_NULL_SC_NUM_LOCK 41
#define GLFW_NULL_SC_PRINT_SCREEN 42
#define GLFW_NULL_SC_PAUSE 43
#define GLFW_NULL_SC_A 44
#define GLFW_NULL_SC_B 45
#define GLFW_NULL_SC_C 46
#define GLFW_NULL_SC_D 47
#define GLFW_NULL_SC_E 48
#define GLFW_NULL_SC_F 49
#define GLFW_NULL_SC_G 50
#define GLFW_NULL_SC_H 51
#define GLFW_NULL_SC_I 52
#define GLFW_NULL_SC_J 53
#define GLFW_NULL_SC_K 54
#define GLFW_NULL_SC_L 55
#define GLFW_NULL_SC_M 56
#define GLFW_NULL_SC_N 57
#define GLFW_NULL_SC_O 58
#define GLFW_NULL_SC_P 59
#define GLFW_NULL_SC_Q 60
#define GLFW_NULL_SC_R 61
#define GLFW_NULL_SC_S 62
#define GLFW_NULL_SC_T 63
#define GLFW_NULL_SC_U 64
#define GLFW_NULL_SC_V 65
#define GLFW_NULL_SC_W 66
#define GLFW_NULL_SC_X 67
#define GLFW_NULL_SC_Y 68
#define GLFW_NULL_SC_Z 69
#define GLFW_NULL_SC_F1 70
#define GLFW_NULL_SC_F2 71
#define GLFW_NULL_SC_F3 72
#define GLFW_NULL_SC_F4 73
#define GLFW_NULL_SC_F5 74
#define GLFW_NULL_SC_F6 75
#define GLFW_NULL_SC_F7 76
#define GLFW_NULL_SC_F8 77
#define GLFW_NULL_SC_F9 78
#define GLFW_NULL_SC_F10 79
#define GLFW_NULL_SC_F11 80
#define GLFW_NULL_SC_F12 81
#define GLFW_NULL_SC_F13 82
#define GLFW_NULL_SC_F14 83
#define GLFW_NULL_SC_F15 84
#define GLFW_NULL_SC_F16 85
#define GLFW_NULL_SC_F17 86
#define GLFW_NULL_SC_F18 87
#define GLFW_NULL_SC_F19 88
#define GLFW_NULL_SC_F20 89
#define GLFW_NULL_SC_F21 90
#define GLFW_NULL_SC_F22 91
#define GLFW_NULL_SC_F23 92
#define GLFW_NULL_SC_F24 93
#define GLFW_NULL_SC_F25 94
#define GLFW_NULL_SC_KP_0 95
#define GLFW_NULL_SC_KP_1 96
#define GLFW_NULL_SC_KP_2 97
#define GLFW_NULL_SC_KP_3 98
#define GLFW_NULL_SC_KP_4 99
#define GLFW_NULL_SC_KP_5 100
#define GLFW_NULL_SC_KP_6 101
#define GLFW_NULL_SC_KP_7 102
#define GLFW_NULL_SC_KP_8 103
#define GLFW_NULL_SC_KP_9 104
#define GLFW_NULL_SC_KP_DECIMAL 105
#define GLFW_NULL_SC_KP_DIVIDE 106
#define GLFW_NULL_SC_KP_MULTIPLY 107
#define GLFW_NULL_SC_KP_SUBTRACT 108
#define GLFW_NULL_SC_KP_ADD 109
#define GLFW_NULL_SC_KP_ENTER 110
#define GLFW_NULL_SC_KP_EQUAL 111
#define GLFW_NULL_SC_LEFT_SHIFT 112
#define GLFW_NULL_SC_LEFT_CONTROL 113
#define GLFW_NULL_SC_LEFT_ALT 114
#define GLFW_NULL_SC_LEFT_SUPER 115
#define GLFW_NULL_SC_RIGHT_SHIFT 116
#define GLFW_NULL_SC_RIGHT_CONTROL 117
#define GLFW_NULL_SC_RIGHT_ALT 118
#define GLFW_NULL_SC_RIGHT_SUPER 119
#define GLFW_NULL_SC_MENU 120
#define GLFW_NULL_SC_LAST GLFW_NULL_SC_MENU
// Null-specific per-window data
//
typedef struct _GLFWwindowNull
{
int xpos;
int ypos;
int width;
int height;
GLFWbool visible;
GLFWbool iconified;
GLFWbool maximized;
GLFWbool resizable;
GLFWbool decorated;
GLFWbool floating;
GLFWbool transparent;
float opacity;
} _GLFWwindowNull;
// Null-specific per-monitor data
//
typedef struct _GLFWmonitorNull
{
GLFWgammaramp ramp;
} _GLFWmonitorNull;
// Null-specific global data
//
typedef struct _GLFWlibraryNull
{
int xcursor;
int ycursor;
char* clipboardString;
_GLFWwindow* focusedWindow;
uint16_t keycodes[GLFW_NULL_SC_LAST + 1];
uint8_t scancodes[GLFW_KEY_LAST + 1];
} _GLFWlibraryNull;
void _glfwPollMonitorsNull(void);
GLFWbool _glfwConnectNull(int platformID, _GLFWplatform* platform);
int _glfwInitNull(void);
void _glfwTerminateNull(void);
void _glfwFreeMonitorNull(_GLFWmonitor* monitor);
void _glfwGetMonitorPosNull(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleNull(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaNull(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesNull(_GLFWmonitor* monitor, int* found);
GLFWbool _glfwGetVideoModeNull(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampNull(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampNull(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowNull(_GLFWwindow* window);
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwSetWindowMonitorNull(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d);
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowNull(_GLFWwindow* window);
void _glfwRestoreWindowNull(_GLFWwindow* window);
void _glfwMaximizeWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window);
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityNull(_GLFWwindow* window);
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity);
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedNull(void);
void _glfwShowWindowNull(_GLFWwindow* window);
void _glfwRequestWindowAttentionNull(_GLFWwindow* window);
void _glfwHideWindowNull(_GLFWwindow* window);
void _glfwFocusWindowNull(_GLFWwindow* window);
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window);
void _glfwPollEventsNull(void);
void _glfwWaitEventsNull(void);
void _glfwWaitEventsTimeoutNull(double timeout);
void _glfwPostEmptyEventNull(void);
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y);
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode);
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorNull(_GLFWcursor* cursor);
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringNull(const char* string);
const char* _glfwGetClipboardStringNull(void);
const char* _glfwGetScancodeNameNull(int scancode);
int _glfwGetKeyScancodeNull(int key);
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void);
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsNull(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwPollMonitorsNull(void);

720
raylib/external/glfw/src/null_window.c vendored Normal file
View File

@@ -0,0 +1,720 @@
//========================================================================
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
static void applySizeLimits(_GLFWwindow* window, int* width, int* height)
{
if (window->numer != GLFW_DONT_CARE && window->denom != GLFW_DONT_CARE)
{
const float ratio = (float) window->numer / (float) window->denom;
*height = (int) (*width / ratio);
}
if (window->minwidth != GLFW_DONT_CARE)
*width = _glfw_max(*width, window->minwidth);
else if (window->maxwidth != GLFW_DONT_CARE)
*width = _glfw_min(*width, window->maxwidth);
if (window->minheight != GLFW_DONT_CARE)
*height = _glfw_min(*height, window->minheight);
else if (window->maxheight != GLFW_DONT_CARE)
*height = _glfw_max(*height, window->maxheight);
}
static void fitToMonitor(_GLFWwindow* window)
{
GLFWvidmode mode;
_glfwGetVideoModeNull(window->monitor, &mode);
_glfwGetMonitorPosNull(window->monitor,
&window->null.xpos,
&window->null.ypos);
window->null.width = mode.width;
window->null.height = mode.height;
}
static void acquireMonitorNull(_GLFWwindow* window)
{
_glfwInputMonitorWindow(window->monitor, window);
}
static void releaseMonitorNull(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
_glfwInputMonitorWindow(window->monitor, NULL);
}
static int createNativeWindow(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWfbconfig* fbconfig)
{
if (window->monitor)
fitToMonitor(window);
else
{
if (wndconfig->xpos == GLFW_ANY_POSITION && wndconfig->ypos == GLFW_ANY_POSITION)
{
window->null.xpos = 17;
window->null.ypos = 17;
}
else
{
window->null.xpos = wndconfig->xpos;
window->null.ypos = wndconfig->ypos;
}
window->null.width = wndconfig->width;
window->null.height = wndconfig->height;
}
window->null.visible = wndconfig->visible;
window->null.decorated = wndconfig->decorated;
window->null.maximized = wndconfig->maximized;
window->null.floating = wndconfig->floating;
window->null.transparent = fbconfig->transparent;
window->null.opacity = 1.f;
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateWindowNull(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (!createNativeWindow(window, wndconfig, fbconfig))
return GLFW_FALSE;
if (ctxconfig->client != GLFW_NO_API)
{
if (ctxconfig->source == GLFW_NATIVE_CONTEXT_API ||
ctxconfig->source == GLFW_OSMESA_CONTEXT_API)
{
if (!_glfwInitOSMesa())
return GLFW_FALSE;
if (!_glfwCreateContextOSMesa(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
else if (ctxconfig->source == GLFW_EGL_CONTEXT_API)
{
if (!_glfwInitEGL())
return GLFW_FALSE;
if (!_glfwCreateContextEGL(window, ctxconfig, fbconfig))
return GLFW_FALSE;
}
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
}
if (wndconfig->mousePassthrough)
_glfwSetWindowMousePassthroughNull(window, GLFW_TRUE);
if (window->monitor)
{
_glfwShowWindowNull(window);
_glfwFocusWindowNull(window);
acquireMonitorNull(window);
if (wndconfig->centerCursor)
_glfwCenterCursorInContentArea(window);
}
else
{
if (wndconfig->visible)
{
_glfwShowWindowNull(window);
if (wndconfig->focused)
_glfwFocusWindowNull(window);
}
}
return GLFW_TRUE;
}
void _glfwDestroyWindowNull(_GLFWwindow* window)
{
if (window->monitor)
releaseMonitorNull(window);
if (_glfw.null.focusedWindow == window)
_glfw.null.focusedWindow = NULL;
if (window->context.destroy)
window->context.destroy(window);
}
void _glfwSetWindowTitleNull(_GLFWwindow* window, const char* title)
{
}
void _glfwSetWindowIconNull(_GLFWwindow* window, int count, const GLFWimage* images)
{
}
void _glfwSetWindowMonitorNull(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
if (window->monitor == monitor)
{
if (!monitor)
{
_glfwSetWindowPosNull(window, xpos, ypos);
_glfwSetWindowSizeNull(window, width, height);
}
return;
}
if (window->monitor)
releaseMonitorNull(window);
_glfwInputWindowMonitor(window, monitor);
if (window->monitor)
{
window->null.visible = GLFW_TRUE;
acquireMonitorNull(window);
fitToMonitor(window);
}
else
{
_glfwSetWindowPosNull(window, xpos, ypos);
_glfwSetWindowSizeNull(window, width, height);
}
}
void _glfwGetWindowPosNull(_GLFWwindow* window, int* xpos, int* ypos)
{
if (xpos)
*xpos = window->null.xpos;
if (ypos)
*ypos = window->null.ypos;
}
void _glfwSetWindowPosNull(_GLFWwindow* window, int xpos, int ypos)
{
if (window->monitor)
return;
if (window->null.xpos != xpos || window->null.ypos != ypos)
{
window->null.xpos = xpos;
window->null.ypos = ypos;
_glfwInputWindowPos(window, xpos, ypos);
}
}
void _glfwGetWindowSizeNull(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
if (height)
*height = window->null.height;
}
void _glfwSetWindowSizeNull(_GLFWwindow* window, int width, int height)
{
if (window->monitor)
return;
if (window->null.width != width || window->null.height != height)
{
window->null.width = width;
window->null.height = height;
_glfwInputFramebufferSize(window, width, height);
_glfwInputWindowDamage(window);
_glfwInputWindowSize(window, width, height);
}
}
void _glfwSetWindowSizeLimitsNull(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
int width = window->null.width;
int height = window->null.height;
applySizeLimits(window, &width, &height);
_glfwSetWindowSizeNull(window, width, height);
}
void _glfwSetWindowAspectRatioNull(_GLFWwindow* window, int n, int d)
{
int width = window->null.width;
int height = window->null.height;
applySizeLimits(window, &width, &height);
_glfwSetWindowSizeNull(window, width, height);
}
void _glfwGetFramebufferSizeNull(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->null.width;
if (height)
*height = window->null.height;
}
void _glfwGetWindowFrameSizeNull(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
if (window->null.decorated && !window->monitor)
{
if (left)
*left = 1;
if (top)
*top = 10;
if (right)
*right = 1;
if (bottom)
*bottom = 1;
}
else
{
if (left)
*left = 0;
if (top)
*top = 0;
if (right)
*right = 0;
if (bottom)
*bottom = 0;
}
}
void _glfwGetWindowContentScaleNull(_GLFWwindow* window, float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.f;
if (yscale)
*yscale = 1.f;
}
void _glfwIconifyWindowNull(_GLFWwindow* window)
{
if (_glfw.null.focusedWindow == window)
{
_glfw.null.focusedWindow = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
}
if (!window->null.iconified)
{
window->null.iconified = GLFW_TRUE;
_glfwInputWindowIconify(window, GLFW_TRUE);
if (window->monitor)
releaseMonitorNull(window);
}
}
void _glfwRestoreWindowNull(_GLFWwindow* window)
{
if (window->null.iconified)
{
window->null.iconified = GLFW_FALSE;
_glfwInputWindowIconify(window, GLFW_FALSE);
if (window->monitor)
acquireMonitorNull(window);
}
else if (window->null.maximized)
{
window->null.maximized = GLFW_FALSE;
_glfwInputWindowMaximize(window, GLFW_FALSE);
}
}
void _glfwMaximizeWindowNull(_GLFWwindow* window)
{
if (!window->null.maximized)
{
window->null.maximized = GLFW_TRUE;
_glfwInputWindowMaximize(window, GLFW_TRUE);
}
}
GLFWbool _glfwWindowMaximizedNull(_GLFWwindow* window)
{
return window->null.maximized;
}
GLFWbool _glfwWindowHoveredNull(_GLFWwindow* window)
{
return _glfw.null.xcursor >= window->null.xpos &&
_glfw.null.ycursor >= window->null.ypos &&
_glfw.null.xcursor <= window->null.xpos + window->null.width - 1 &&
_glfw.null.ycursor <= window->null.ypos + window->null.height - 1;
}
GLFWbool _glfwFramebufferTransparentNull(_GLFWwindow* window)
{
return window->null.transparent;
}
void _glfwSetWindowResizableNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.resizable = enabled;
}
void _glfwSetWindowDecoratedNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.decorated = enabled;
}
void _glfwSetWindowFloatingNull(_GLFWwindow* window, GLFWbool enabled)
{
window->null.floating = enabled;
}
void _glfwSetWindowMousePassthroughNull(_GLFWwindow* window, GLFWbool enabled)
{
}
float _glfwGetWindowOpacityNull(_GLFWwindow* window)
{
return window->null.opacity;
}
void _glfwSetWindowOpacityNull(_GLFWwindow* window, float opacity)
{
window->null.opacity = opacity;
}
void _glfwSetRawMouseMotionNull(_GLFWwindow *window, GLFWbool enabled)
{
}
GLFWbool _glfwRawMouseMotionSupportedNull(void)
{
return GLFW_TRUE;
}
void _glfwShowWindowNull(_GLFWwindow* window)
{
window->null.visible = GLFW_TRUE;
}
void _glfwRequestWindowAttentionNull(_GLFWwindow* window)
{
}
void _glfwHideWindowNull(_GLFWwindow* window)
{
if (_glfw.null.focusedWindow == window)
{
_glfw.null.focusedWindow = NULL;
_glfwInputWindowFocus(window, GLFW_FALSE);
}
window->null.visible = GLFW_FALSE;
}
void _glfwFocusWindowNull(_GLFWwindow* window)
{
_GLFWwindow* previous;
if (_glfw.null.focusedWindow == window)
return;
if (!window->null.visible)
return;
previous = _glfw.null.focusedWindow;
_glfw.null.focusedWindow = window;
if (previous)
{
_glfwInputWindowFocus(previous, GLFW_FALSE);
if (previous->monitor && previous->autoIconify)
_glfwIconifyWindowNull(previous);
}
_glfwInputWindowFocus(window, GLFW_TRUE);
}
GLFWbool _glfwWindowFocusedNull(_GLFWwindow* window)
{
return _glfw.null.focusedWindow == window;
}
GLFWbool _glfwWindowIconifiedNull(_GLFWwindow* window)
{
return window->null.iconified;
}
GLFWbool _glfwWindowVisibleNull(_GLFWwindow* window)
{
return window->null.visible;
}
void _glfwPollEventsNull(void)
{
}
void _glfwWaitEventsNull(void)
{
}
void _glfwWaitEventsTimeoutNull(double timeout)
{
}
void _glfwPostEmptyEventNull(void)
{
}
void _glfwGetCursorPosNull(_GLFWwindow* window, double* xpos, double* ypos)
{
if (xpos)
*xpos = _glfw.null.xcursor - window->null.xpos;
if (ypos)
*ypos = _glfw.null.ycursor - window->null.ypos;
}
void _glfwSetCursorPosNull(_GLFWwindow* window, double x, double y)
{
_glfw.null.xcursor = window->null.xpos + (int) x;
_glfw.null.ycursor = window->null.ypos + (int) y;
}
void _glfwSetCursorModeNull(_GLFWwindow* window, int mode)
{
}
GLFWbool _glfwCreateCursorNull(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{
return GLFW_TRUE;
}
GLFWbool _glfwCreateStandardCursorNull(_GLFWcursor* cursor, int shape)
{
return GLFW_TRUE;
}
void _glfwDestroyCursorNull(_GLFWcursor* cursor)
{
}
void _glfwSetCursorNull(_GLFWwindow* window, _GLFWcursor* cursor)
{
}
void _glfwSetClipboardStringNull(const char* string)
{
char* copy = _glfw_strdup(string);
_glfw_free(_glfw.null.clipboardString);
_glfw.null.clipboardString = copy;
}
const char* _glfwGetClipboardStringNull(void)
{
return _glfw.null.clipboardString;
}
EGLenum _glfwGetEGLPlatformNull(EGLint** attribs)
{
return 0;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayNull(void)
{
return 0;
}
EGLNativeWindowType _glfwGetEGLNativeWindowNull(_GLFWwindow* window)
{
return 0;
}
const char* _glfwGetScancodeNameNull(int scancode)
{
if (scancode < GLFW_NULL_SC_FIRST || scancode > GLFW_NULL_SC_LAST)
{
_glfwInputError(GLFW_INVALID_VALUE, "Invalid scancode %i", scancode);
return NULL;
}
switch (scancode)
{
case GLFW_NULL_SC_APOSTROPHE:
return "'";
case GLFW_NULL_SC_COMMA:
return ",";
case GLFW_NULL_SC_MINUS:
case GLFW_NULL_SC_KP_SUBTRACT:
return "-";
case GLFW_NULL_SC_PERIOD:
case GLFW_NULL_SC_KP_DECIMAL:
return ".";
case GLFW_NULL_SC_SLASH:
case GLFW_NULL_SC_KP_DIVIDE:
return "/";
case GLFW_NULL_SC_SEMICOLON:
return ";";
case GLFW_NULL_SC_EQUAL:
case GLFW_NULL_SC_KP_EQUAL:
return "=";
case GLFW_NULL_SC_LEFT_BRACKET:
return "[";
case GLFW_NULL_SC_RIGHT_BRACKET:
return "]";
case GLFW_NULL_SC_KP_MULTIPLY:
return "*";
case GLFW_NULL_SC_KP_ADD:
return "+";
case GLFW_NULL_SC_BACKSLASH:
case GLFW_NULL_SC_WORLD_1:
case GLFW_NULL_SC_WORLD_2:
return "\\";
case GLFW_NULL_SC_0:
case GLFW_NULL_SC_KP_0:
return "0";
case GLFW_NULL_SC_1:
case GLFW_NULL_SC_KP_1:
return "1";
case GLFW_NULL_SC_2:
case GLFW_NULL_SC_KP_2:
return "2";
case GLFW_NULL_SC_3:
case GLFW_NULL_SC_KP_3:
return "3";
case GLFW_NULL_SC_4:
case GLFW_NULL_SC_KP_4:
return "4";
case GLFW_NULL_SC_5:
case GLFW_NULL_SC_KP_5:
return "5";
case GLFW_NULL_SC_6:
case GLFW_NULL_SC_KP_6:
return "6";
case GLFW_NULL_SC_7:
case GLFW_NULL_SC_KP_7:
return "7";
case GLFW_NULL_SC_8:
case GLFW_NULL_SC_KP_8:
return "8";
case GLFW_NULL_SC_9:
case GLFW_NULL_SC_KP_9:
return "9";
case GLFW_NULL_SC_A:
return "a";
case GLFW_NULL_SC_B:
return "b";
case GLFW_NULL_SC_C:
return "c";
case GLFW_NULL_SC_D:
return "d";
case GLFW_NULL_SC_E:
return "e";
case GLFW_NULL_SC_F:
return "f";
case GLFW_NULL_SC_G:
return "g";
case GLFW_NULL_SC_H:
return "h";
case GLFW_NULL_SC_I:
return "i";
case GLFW_NULL_SC_J:
return "j";
case GLFW_NULL_SC_K:
return "k";
case GLFW_NULL_SC_L:
return "l";
case GLFW_NULL_SC_M:
return "m";
case GLFW_NULL_SC_N:
return "n";
case GLFW_NULL_SC_O:
return "o";
case GLFW_NULL_SC_P:
return "p";
case GLFW_NULL_SC_Q:
return "q";
case GLFW_NULL_SC_R:
return "r";
case GLFW_NULL_SC_S:
return "s";
case GLFW_NULL_SC_T:
return "t";
case GLFW_NULL_SC_U:
return "u";
case GLFW_NULL_SC_V:
return "v";
case GLFW_NULL_SC_W:
return "w";
case GLFW_NULL_SC_X:
return "x";
case GLFW_NULL_SC_Y:
return "y";
case GLFW_NULL_SC_Z:
return "z";
}
return NULL;
}
int _glfwGetKeyScancodeNull(int key)
{
return _glfw.null.scancodes[key];
}
void _glfwGetRequiredInstanceExtensionsNull(char** extensions)
{
}
GLFWbool _glfwGetPhysicalDevicePresentationSupportNull(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
}
VkResult _glfwCreateWindowSurfaceNull(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
// This seems like the most appropriate error to return here
return VK_ERROR_EXTENSION_NOT_PRESENT;
}

View File

@@ -0,0 +1,383 @@
//========================================================================
// GLFW 3.4 OSMesa - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2016 Google Inc.
// Copyright (c) 2016-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static void makeContextCurrentOSMesa(_GLFWwindow* window)
{
if (window)
{
int width, height;
_glfw.platform.getFramebufferSize(window, &width, &height);
// Check to see if we need to allocate a new buffer
if ((window->context.osmesa.buffer == NULL) ||
(width != window->context.osmesa.width) ||
(height != window->context.osmesa.height))
{
_glfw_free(window->context.osmesa.buffer);
// Allocate the new buffer (width * height * 8-bit RGBA)
window->context.osmesa.buffer = _glfw_calloc(4, (size_t) width * height);
window->context.osmesa.width = width;
window->context.osmesa.height = height;
}
if (!OSMesaMakeCurrent(window->context.osmesa.handle,
window->context.osmesa.buffer,
GL_UNSIGNED_BYTE,
width, height))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to make context current");
return;
}
}
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static GLFWglproc getProcAddressOSMesa(const char* procname)
{
return (GLFWglproc) OSMesaGetProcAddress(procname);
}
static void destroyContextOSMesa(_GLFWwindow* window)
{
if (window->context.osmesa.handle)
{
OSMesaDestroyContext(window->context.osmesa.handle);
window->context.osmesa.handle = NULL;
}
if (window->context.osmesa.buffer)
{
_glfw_free(window->context.osmesa.buffer);
window->context.osmesa.width = 0;
window->context.osmesa.height = 0;
}
}
static void swapBuffersOSMesa(_GLFWwindow* window)
{
// No double buffering on OSMesa
}
static void swapIntervalOSMesa(int interval)
{
// No swap interval on OSMesa
}
static int extensionSupportedOSMesa(const char* extension)
{
// OSMesa does not have extensions
return GLFW_FALSE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitOSMesa(void)
{
int i;
const char* sonames[] =
{
#if defined(_GLFW_OSMESA_LIBRARY)
_GLFW_OSMESA_LIBRARY,
#elif defined(_WIN32)
"libOSMesa.dll",
"OSMesa.dll",
#elif defined(__APPLE__)
"libOSMesa.8.dylib",
#elif defined(__CYGWIN__)
"libOSMesa-8.so",
#elif defined(__OpenBSD__) || defined(__NetBSD__)
"libOSMesa.so",
#else
"libOSMesa.so.8",
"libOSMesa.so.6",
#endif
NULL
};
if (_glfw.osmesa.handle)
return GLFW_TRUE;
for (i = 0; sonames[i]; i++)
{
_glfw.osmesa.handle = _glfwPlatformLoadModule(sonames[i]);
if (_glfw.osmesa.handle)
break;
}
if (!_glfw.osmesa.handle)
{
_glfwInputError(GLFW_API_UNAVAILABLE, "OSMesa: Library not found");
return GLFW_FALSE;
}
_glfw.osmesa.CreateContextExt = (PFN_OSMesaCreateContextExt)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextExt");
_glfw.osmesa.CreateContextAttribs = (PFN_OSMesaCreateContextAttribs)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaCreateContextAttribs");
_glfw.osmesa.DestroyContext = (PFN_OSMesaDestroyContext)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaDestroyContext");
_glfw.osmesa.MakeCurrent = (PFN_OSMesaMakeCurrent)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaMakeCurrent");
_glfw.osmesa.GetColorBuffer = (PFN_OSMesaGetColorBuffer)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetColorBuffer");
_glfw.osmesa.GetDepthBuffer = (PFN_OSMesaGetDepthBuffer)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetDepthBuffer");
_glfw.osmesa.GetProcAddress = (PFN_OSMesaGetProcAddress)
_glfwPlatformGetModuleSymbol(_glfw.osmesa.handle, "OSMesaGetProcAddress");
if (!_glfw.osmesa.CreateContextExt ||
!_glfw.osmesa.DestroyContext ||
!_glfw.osmesa.MakeCurrent ||
!_glfw.osmesa.GetColorBuffer ||
!_glfw.osmesa.GetDepthBuffer ||
!_glfw.osmesa.GetProcAddress)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to load required entry points");
_glfwTerminateOSMesa();
return GLFW_FALSE;
}
return GLFW_TRUE;
}
void _glfwTerminateOSMesa(void)
{
if (_glfw.osmesa.handle)
{
_glfwPlatformFreeModule(_glfw.osmesa.handle);
_glfw.osmesa.handle = NULL;
}
}
#define SET_ATTRIB(a, v) \
{ \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
OSMesaContext share = NULL;
const int accumBits = fbconfig->accumRedBits +
fbconfig->accumGreenBits +
fbconfig->accumBlueBits +
fbconfig->accumAlphaBits;
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"OSMesa: OpenGL ES is not available on OSMesa");
return GLFW_FALSE;
}
if (ctxconfig->share)
share = ctxconfig->share->context.osmesa.handle;
if (OSMesaCreateContextAttribs)
{
int index = 0, attribs[40];
SET_ATTRIB(OSMESA_FORMAT, OSMESA_RGBA);
SET_ATTRIB(OSMESA_DEPTH_BITS, fbconfig->depthBits);
SET_ATTRIB(OSMESA_STENCIL_BITS, fbconfig->stencilBits);
SET_ATTRIB(OSMESA_ACCUM_BITS, accumBits);
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
{
SET_ATTRIB(OSMESA_PROFILE, OSMESA_CORE_PROFILE);
}
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
{
SET_ATTRIB(OSMESA_PROFILE, OSMESA_COMPAT_PROFILE);
}
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
SET_ATTRIB(OSMESA_CONTEXT_MAJOR_VERSION, ctxconfig->major);
SET_ATTRIB(OSMESA_CONTEXT_MINOR_VERSION, ctxconfig->minor);
}
if (ctxconfig->forward)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Forward-compatible contexts not supported");
return GLFW_FALSE;
}
SET_ATTRIB(0, 0);
window->context.osmesa.handle =
OSMesaCreateContextAttribs(attribs, share);
}
else
{
if (ctxconfig->profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: OpenGL profiles unavailable");
return GLFW_FALSE;
}
window->context.osmesa.handle =
OSMesaCreateContextExt(OSMESA_RGBA,
fbconfig->depthBits,
fbconfig->stencilBits,
accumBits,
share);
}
if (window->context.osmesa.handle == NULL)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"OSMesa: Failed to create context");
return GLFW_FALSE;
}
window->context.makeCurrent = makeContextCurrentOSMesa;
window->context.swapBuffers = swapBuffersOSMesa;
window->context.swapInterval = swapIntervalOSMesa;
window->context.extensionSupported = extensionSupportedOSMesa;
window->context.getProcAddress = getProcAddressOSMesa;
window->context.destroy = destroyContextOSMesa;
return GLFW_TRUE;
}
#undef SET_ATTRIB
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwGetOSMesaColorBuffer(GLFWwindow* handle, int* width,
int* height, int* format, void** buffer)
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaFormat;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetColorBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
&mesaFormat, &mesaBuffer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve color buffer");
return GLFW_FALSE;
}
if (width)
*width = mesaWidth;
if (height)
*height = mesaHeight;
if (format)
*format = mesaFormat;
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
}
GLFWAPI int glfwGetOSMesaDepthBuffer(GLFWwindow* handle,
int* width, int* height,
int* bytesPerValue,
void** buffer)
{
void* mesaBuffer;
GLint mesaWidth, mesaHeight, mesaBytes;
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
if (!OSMesaGetDepthBuffer(window->context.osmesa.handle,
&mesaWidth, &mesaHeight,
&mesaBytes, &mesaBuffer))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"OSMesa: Failed to retrieve depth buffer");
return GLFW_FALSE;
}
if (width)
*width = mesaWidth;
if (height)
*height = mesaHeight;
if (bytesPerValue)
*bytesPerValue = mesaBytes;
if (buffer)
*buffer = mesaBuffer;
return GLFW_TRUE;
}
GLFWAPI OSMesaContext glfwGetOSMesaContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (window->context.source != GLFW_OSMESA_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.osmesa.handle;
}

204
raylib/external/glfw/src/platform.c vendored Normal file
View File

@@ -0,0 +1,204 @@
//========================================================================
// GLFW 3.4 (modified for raylib) - www.glfw.org; www.raylib.com
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <string.h>
#include <stdlib.h>
// These construct a string literal from individual numeric constants
#define _GLFW_CONCAT_VERSION(m, n, r) #m "." #n "." #r
#define _GLFW_MAKE_VERSION(m, n, r) _GLFW_CONCAT_VERSION(m, n, r)
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
static const struct
{
int ID;
GLFWbool (*connect)(int,_GLFWplatform*);
} supportedPlatforms[] =
{
#if defined(_GLFW_WIN32)
{ GLFW_PLATFORM_WIN32, _glfwConnectWin32 },
#endif
#if defined(_GLFW_COCOA)
{ GLFW_PLATFORM_COCOA, _glfwConnectCocoa },
#endif
#if defined(_GLFW_WAYLAND)
{ GLFW_PLATFORM_WAYLAND, _glfwConnectWayland },
#endif
#if defined(_GLFW_X11)
{ GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif
};
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (desiredID != GLFW_ANY_PLATFORM &&
desiredID != GLFW_PLATFORM_WIN32 &&
desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);
return GLFW_FALSE;
}
#if defined(_GLFW_WAYLAND) && defined(_GLFW_X11)
if (desiredID == GLFW_ANY_PLATFORM)
{
const char* const session = getenv("XDG_SESSION_TYPE");
if (session)
{
// Only follow XDG_SESSION_TYPE if it is set correctly and the
// environment looks plausble; otherwise fall back to detection
if (strcmp(session, "wayland") == 0 && getenv("WAYLAND_DISPLAY"))
desiredID = GLFW_PLATFORM_WAYLAND;
else if (strcmp(session, "x11") == 0 && getenv("DISPLAY"))
desiredID = GLFW_PLATFORM_X11;
}
}
#endif
if (desiredID == GLFW_ANY_PLATFORM)
{
// If there is exactly one platform available for auto-selection, let it emit the
// error on failure as the platform-specific error description may be more helpful
if (count == 1)
return supportedPlatforms[0].connect(supportedPlatforms[0].ID, platform);
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].connect(desiredID, platform))
return GLFW_TRUE;
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Failed to detect any supported platform");
}
else
{
for (i = 0; i < count; i++)
{
if (supportedPlatforms[i].ID == desiredID)
return supportedPlatforms[i].connect(desiredID, platform);
}
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "The requested platform is not supported");
}
return GLFW_FALSE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwGetPlatform(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(0);
return _glfw.platform.platformID;
}
GLFWAPI int glfwPlatformSupported(int platformID)
{
const size_t count = sizeof(supportedPlatforms) / sizeof(supportedPlatforms[0]);
size_t i;
if (platformID != GLFW_PLATFORM_WIN32 &&
platformID != GLFW_PLATFORM_COCOA &&
platformID != GLFW_PLATFORM_WAYLAND &&
platformID != GLFW_PLATFORM_X11 &&
platformID != GLFW_PLATFORM_NULL)
{
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", platformID);
return GLFW_FALSE;
}
if (platformID == GLFW_PLATFORM_NULL)
return GLFW_TRUE;
for (i = 0; i < count; i++)
{
if (platformID == supportedPlatforms[i].ID)
return GLFW_TRUE;
}
return GLFW_FALSE;
}
GLFWAPI const char* glfwGetVersionString(void)
{
return _GLFW_MAKE_VERSION(GLFW_VERSION_MAJOR,
GLFW_VERSION_MINOR,
GLFW_VERSION_REVISION)
#if defined(_GLFW_WIN32)
" Win32 WGL"
#endif
#if defined(_GLFW_COCOA)
" Cocoa NSGL"
#endif
#if defined(_GLFW_WAYLAND)
" Wayland"
#endif
#if defined(_GLFW_X11)
" X11 GLX"
#endif
" Null"
" EGL"
" OSMesa"
#if defined(__MINGW64_VERSION_MAJOR)
" MinGW-w64"
#elif defined(__MINGW32__)
" MinGW"
#elif defined(_MSC_VER)
" VisualC"
#endif
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
" hybrid-GPU"
#endif
#if defined(_POSIX_MONOTONIC_CLOCK)
" monotonic"
#endif
#if defined(_GLFW_BUILD_DLL)
#if defined(_WIN32)
" DLL"
#elif defined(__APPLE__)
" dynamic"
#else
" shared"
#endif
#endif
;
}

212
raylib/external/glfw/src/platform.h vendored Normal file
View File

@@ -0,0 +1,212 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#if defined(GLFW_BUILD_WIN32_TIMER) || \
defined(GLFW_BUILD_WIN32_MODULE) || \
defined(GLFW_BUILD_WIN32_THREAD) || \
defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \
defined(GLFW_BUILD_POSIX_POLL) || \
defined(GLFW_BUILD_LINUX_JOYSTICK)
#error "You must not define these; define zero or more _GLFW_<platform> macros instead"
#endif
#include "null_platform.h"
#define GLFW_EXPOSE_NATIVE_EGL
#define GLFW_EXPOSE_NATIVE_OSMESA
#if defined(_GLFW_WIN32)
#include "win32_platform.h"
#define GLFW_EXPOSE_NATIVE_WIN32
#define GLFW_EXPOSE_NATIVE_WGL
#else
#define GLFW_WIN32_WINDOW_STATE
#define GLFW_WIN32_MONITOR_STATE
#define GLFW_WIN32_CURSOR_STATE
#define GLFW_WIN32_LIBRARY_WINDOW_STATE
#define GLFW_WGL_CONTEXT_STATE
#define GLFW_WGL_LIBRARY_CONTEXT_STATE
#endif
#if defined(_GLFW_COCOA)
#include "cocoa_platform.h"
#define GLFW_EXPOSE_NATIVE_COCOA
#define GLFW_EXPOSE_NATIVE_NSGL
#else
#define GLFW_COCOA_WINDOW_STATE
#define GLFW_COCOA_MONITOR_STATE
#define GLFW_COCOA_CURSOR_STATE
#define GLFW_COCOA_LIBRARY_WINDOW_STATE
#define GLFW_NSGL_CONTEXT_STATE
#define GLFW_NSGL_LIBRARY_CONTEXT_STATE
#endif
#if defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#define GLFW_EXPOSE_NATIVE_WAYLAND
#else
#define GLFW_WAYLAND_WINDOW_STATE
#define GLFW_WAYLAND_MONITOR_STATE
#define GLFW_WAYLAND_CURSOR_STATE
#define GLFW_WAYLAND_LIBRARY_WINDOW_STATE
#endif
#if defined(_GLFW_X11)
#include "x11_platform.h"
#define GLFW_EXPOSE_NATIVE_X11
#define GLFW_EXPOSE_NATIVE_GLX
#else
#define GLFW_X11_WINDOW_STATE
#define GLFW_X11_MONITOR_STATE
#define GLFW_X11_CURSOR_STATE
#define GLFW_X11_LIBRARY_WINDOW_STATE
#define GLFW_GLX_CONTEXT_STATE
#define GLFW_GLX_LIBRARY_CONTEXT_STATE
#endif
#include "null_joystick.h"
#if defined(_GLFW_WIN32)
#include "win32_joystick.h"
#else
#define GLFW_WIN32_JOYSTICK_STATE
#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
#endif
#if defined(_GLFW_COCOA)
#include "cocoa_joystick.h"
#else
#define GLFW_COCOA_JOYSTICK_STATE
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#endif
#if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)
#define GLFW_BUILD_LINUX_JOYSTICK
#endif
#if defined(GLFW_BUILD_LINUX_JOYSTICK)
#include "linux_joystick.h"
#else
#define GLFW_LINUX_JOYSTICK_STATE
#define GLFW_LINUX_LIBRARY_JOYSTICK_STATE
#endif
#define GLFW_PLATFORM_WINDOW_STATE \
GLFW_WIN32_WINDOW_STATE \
GLFW_COCOA_WINDOW_STATE \
GLFW_WAYLAND_WINDOW_STATE \
GLFW_X11_WINDOW_STATE \
GLFW_NULL_WINDOW_STATE \
#define GLFW_PLATFORM_MONITOR_STATE \
GLFW_WIN32_MONITOR_STATE \
GLFW_COCOA_MONITOR_STATE \
GLFW_WAYLAND_MONITOR_STATE \
GLFW_X11_MONITOR_STATE \
GLFW_NULL_MONITOR_STATE \
#define GLFW_PLATFORM_CURSOR_STATE \
GLFW_WIN32_CURSOR_STATE \
GLFW_COCOA_CURSOR_STATE \
GLFW_WAYLAND_CURSOR_STATE \
GLFW_X11_CURSOR_STATE \
GLFW_NULL_CURSOR_STATE \
#define GLFW_PLATFORM_JOYSTICK_STATE \
GLFW_WIN32_JOYSTICK_STATE \
GLFW_COCOA_JOYSTICK_STATE \
GLFW_LINUX_JOYSTICK_STATE
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
GLFW_WIN32_LIBRARY_WINDOW_STATE \
GLFW_COCOA_LIBRARY_WINDOW_STATE \
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
GLFW_X11_LIBRARY_WINDOW_STATE \
GLFW_NULL_LIBRARY_WINDOW_STATE \
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
GLFW_WIN32_LIBRARY_JOYSTICK_STATE \
GLFW_COCOA_LIBRARY_JOYSTICK_STATE \
GLFW_LINUX_LIBRARY_JOYSTICK_STATE
#define GLFW_PLATFORM_CONTEXT_STATE \
GLFW_WGL_CONTEXT_STATE \
GLFW_NSGL_CONTEXT_STATE \
GLFW_GLX_CONTEXT_STATE
#define GLFW_PLATFORM_LIBRARY_CONTEXT_STATE \
GLFW_WGL_LIBRARY_CONTEXT_STATE \
GLFW_NSGL_LIBRARY_CONTEXT_STATE \
GLFW_GLX_LIBRARY_CONTEXT_STATE
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_THREAD
#else
#define GLFW_BUILD_POSIX_THREAD
#endif
#if defined(GLFW_BUILD_WIN32_THREAD)
#include "win32_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_WIN32_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_WIN32_MUTEX_STATE
#elif defined(GLFW_BUILD_POSIX_THREAD)
#include "posix_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE
#endif
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__)
#define GLFW_BUILD_COCOA_TIMER
#else
#define GLFW_BUILD_POSIX_TIMER
#endif
#if defined(GLFW_BUILD_WIN32_TIMER)
#include "win32_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_WIN32_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_COCOA_TIMER)
#include "cocoa_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_COCOA_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
#endif
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_MODULE
#else
#define GLFW_BUILD_POSIX_MODULE
#endif
#if defined(_GLFW_WAYLAND) || defined(_GLFW_X11)
#define GLFW_BUILD_POSIX_POLL
#endif

53
raylib/external/glfw/src/posix_module.c vendored Normal file
View File

@@ -0,0 +1,53 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_POSIX_MODULE)
#include <dlfcn.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return dlopen(path, RTLD_LAZY | RTLD_LOCAL);
}
void _glfwPlatformFreeModule(void* module)
{
dlclose(module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return dlsym(module, name);
}
#endif // GLFW_BUILD_POSIX_MODULE

83
raylib/external/glfw/src/posix_poll.c vendored Normal file
View File

@@ -0,0 +1,83 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define _GNU_SOURCE
#include "internal.h"
#if defined(GLFW_BUILD_POSIX_POLL)
#include <signal.h>
#include <time.h>
#include <errno.h>
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout)
{
for (;;)
{
if (timeout)
{
const uint64_t base = _glfwPlatformGetTimerValue();
#if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__)
const time_t seconds = (time_t) *timeout;
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
const struct timespec ts = { seconds, nanoseconds };
const int result = ppoll(fds, count, &ts, NULL);
#elif defined(__NetBSD__)
const time_t seconds = (time_t) *timeout;
const long nanoseconds = (long) ((*timeout - seconds) * 1e9);
const struct timespec ts = { seconds, nanoseconds };
const int result = pollts(fds, count, &ts, NULL);
#else
const int milliseconds = (int) (*timeout * 1e3);
const int result = poll(fds, count, milliseconds);
#endif
const int error = errno; // clock_gettime may overwrite our error
*timeout -= (_glfwPlatformGetTimerValue() - base) /
(double) _glfwPlatformGetTimerFrequency();
if (result > 0)
return GLFW_TRUE;
else if (result == -1 && error != EINTR && error != EAGAIN)
return GLFW_FALSE;
else if (*timeout <= 0.0)
return GLFW_FALSE;
}
else
{
const int result = poll(fds, count, -1);
if (result > 0)
return GLFW_TRUE;
else if (result == -1 && errno != EINTR && errno != EAGAIN)
return GLFW_FALSE;
}
}
}
#endif // GLFW_BUILD_POSIX_POLL

30
raylib/external/glfw/src/posix_poll.h vendored Normal file
View File

@@ -0,0 +1,30 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2022 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <poll.h>
GLFWbool _glfwPollPOSIX(struct pollfd* fds, nfds_t count, double* timeout);

107
raylib/external/glfw/src/posix_thread.c vendored Normal file
View File

@@ -0,0 +1,107 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_POSIX_THREAD)
#include <assert.h>
#include <string.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_FALSE);
if (pthread_key_create(&tls->posix.key, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"POSIX: Failed to create context TLS");
return GLFW_FALSE;
}
tls->posix.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->posix.allocated)
pthread_key_delete(tls->posix.key);
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->posix.allocated == GLFW_TRUE);
return pthread_getspecific(tls->posix.key);
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->posix.allocated == GLFW_TRUE);
pthread_setspecific(tls->posix.key, value);
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_FALSE);
if (pthread_mutex_init(&mutex->posix.handle, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "POSIX: Failed to create mutex");
return GLFW_FALSE;
}
return mutex->posix.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->posix.allocated)
pthread_mutex_destroy(&mutex->posix.handle);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
pthread_mutex_lock(&mutex->posix.handle);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->posix.allocated == GLFW_TRUE);
pthread_mutex_unlock(&mutex->posix.handle);
}
#endif // GLFW_BUILD_POSIX_THREAD

49
raylib/external/glfw/src/posix_thread.h vendored Normal file
View File

@@ -0,0 +1,49 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <pthread.h>
#define GLFW_POSIX_TLS_STATE _GLFWtlsPOSIX posix;
#define GLFW_POSIX_MUTEX_STATE _GLFWmutexPOSIX posix;
// POSIX-specific thread local storage data
//
typedef struct _GLFWtlsPOSIX
{
GLFWbool allocated;
pthread_key_t key;
} _GLFWtlsPOSIX;
// POSIX-specific mutex data
//
typedef struct _GLFWmutexPOSIX
{
GLFWbool allocated;
pthread_mutex_t handle;
} _GLFWmutexPOSIX;

65
raylib/external/glfw/src/posix_time.c vendored Normal file
View File

@@ -0,0 +1,65 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_POSIX_TIMER)
#include <unistd.h>
#include <sys/time.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
_glfw.timer.posix.clock = CLOCK_REALTIME;
_glfw.timer.posix.frequency = 1000000000;
#if defined(_POSIX_MONOTONIC_CLOCK)
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0)
_glfw.timer.posix.clock = CLOCK_MONOTONIC;
#endif
}
uint64_t _glfwPlatformGetTimerValue(void)
{
struct timespec ts;
clock_gettime(_glfw.timer.posix.clock, &ts);
return (uint64_t) ts.tv_sec * _glfw.timer.posix.frequency + (uint64_t) ts.tv_nsec;
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.posix.frequency;
}
#endif // GLFW_BUILD_POSIX_TIMER

41
raylib/external/glfw/src/posix_time.h vendored Normal file
View File

@@ -0,0 +1,41 @@
//========================================================================
// GLFW 3.4 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_POSIX_LIBRARY_TIMER_STATE _GLFWtimerPOSIX posix;
#include <stdint.h>
#include <time.h>
// POSIX-specific global timer data
//
typedef struct _GLFWtimerPOSIX
{
clockid_t clock;
uint64_t frequency;
} _GLFWtimerPOSIX;

328
raylib/external/glfw/src/vulkan.c vendored Normal file
View File

@@ -0,0 +1,328 @@
//========================================================================
// GLFW 3.4 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2018 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define _GLFW_FIND_LOADER 1
#define _GLFW_REQUIRE_LOADER 2
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitVulkan(int mode)
{
VkResult err;
VkExtensionProperties* ep;
PFN_vkEnumerateInstanceExtensionProperties vkEnumerateInstanceExtensionProperties;
uint32_t i, count;
if (_glfw.vk.available)
return GLFW_TRUE;
if (_glfw.hints.init.vulkanLoader)
_glfw.vk.GetInstanceProcAddr = _glfw.hints.init.vulkanLoader;
else
{
#if defined(_GLFW_VULKAN_LIBRARY)
_glfw.vk.handle = _glfwPlatformLoadModule(_GLFW_VULKAN_LIBRARY);
#elif defined(_GLFW_WIN32)
_glfw.vk.handle = _glfwPlatformLoadModule("vulkan-1.dll");
#elif defined(_GLFW_COCOA)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.1.dylib");
if (!_glfw.vk.handle)
_glfw.vk.handle = _glfwLoadLocalVulkanLoaderCocoa();
#elif defined(__OpenBSD__) || defined(__NetBSD__)
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so");
#else
_glfw.vk.handle = _glfwPlatformLoadModule("libvulkan.so.1");
#endif
if (!_glfw.vk.handle)
{
if (mode == _GLFW_REQUIRE_LOADER)
_glfwInputError(GLFW_API_UNAVAILABLE, "Vulkan: Loader not found");
return GLFW_FALSE;
}
_glfw.vk.GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)
_glfwPlatformGetModuleSymbol(_glfw.vk.handle, "vkGetInstanceProcAddr");
if (!_glfw.vk.GetInstanceProcAddr)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Loader does not export vkGetInstanceProcAddr");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
}
vkEnumerateInstanceExtensionProperties = (PFN_vkEnumerateInstanceExtensionProperties)
vkGetInstanceProcAddr(NULL, "vkEnumerateInstanceExtensionProperties");
if (!vkEnumerateInstanceExtensionProperties)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to retrieve vkEnumerateInstanceExtensionProperties");
_glfwTerminateVulkan();
return GLFW_FALSE;
}
err = vkEnumerateInstanceExtensionProperties(NULL, &count, NULL);
if (err)
{
// NOTE: This happens on systems with a loader but without any Vulkan ICD
if (mode == _GLFW_REQUIRE_LOADER)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to query instance extension count: %s",
_glfwGetVulkanResultString(err));
}
_glfwTerminateVulkan();
return GLFW_FALSE;
}
ep = _glfw_calloc(count, sizeof(VkExtensionProperties));
err = vkEnumerateInstanceExtensionProperties(NULL, &count, ep);
if (err)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Failed to query instance extensions: %s",
_glfwGetVulkanResultString(err));
_glfw_free(ep);
_glfwTerminateVulkan();
return GLFW_FALSE;
}
for (i = 0; i < count; i++)
{
if (strcmp(ep[i].extensionName, "VK_KHR_surface") == 0)
_glfw.vk.KHR_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_win32_surface") == 0)
_glfw.vk.KHR_win32_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_MVK_macos_surface") == 0)
_glfw.vk.MVK_macos_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_EXT_metal_surface") == 0)
_glfw.vk.EXT_metal_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xlib_surface") == 0)
_glfw.vk.KHR_xlib_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_xcb_surface") == 0)
_glfw.vk.KHR_xcb_surface = GLFW_TRUE;
else if (strcmp(ep[i].extensionName, "VK_KHR_wayland_surface") == 0)
_glfw.vk.KHR_wayland_surface = GLFW_TRUE;
}
_glfw_free(ep);
_glfw.vk.available = GLFW_TRUE;
_glfw.platform.getRequiredInstanceExtensions(_glfw.vk.extensions);
return GLFW_TRUE;
}
void _glfwTerminateVulkan(void)
{
if (_glfw.vk.handle)
_glfwPlatformFreeModule(_glfw.vk.handle);
}
const char* _glfwGetVulkanResultString(VkResult result)
{
switch (result)
{
case VK_SUCCESS:
return "Success";
case VK_NOT_READY:
return "A fence or query has not yet completed";
case VK_TIMEOUT:
return "A wait operation has not completed in the specified time";
case VK_EVENT_SET:
return "An event is signaled";
case VK_EVENT_RESET:
return "An event is unsignaled";
case VK_INCOMPLETE:
return "A return array was too small for the result";
case VK_ERROR_OUT_OF_HOST_MEMORY:
return "A host memory allocation has failed";
case VK_ERROR_OUT_OF_DEVICE_MEMORY:
return "A device memory allocation has failed";
case VK_ERROR_INITIALIZATION_FAILED:
return "Initialization of an object could not be completed for implementation-specific reasons";
case VK_ERROR_DEVICE_LOST:
return "The logical or physical device has been lost";
case VK_ERROR_MEMORY_MAP_FAILED:
return "Mapping of a memory object has failed";
case VK_ERROR_LAYER_NOT_PRESENT:
return "A requested layer is not present or could not be loaded";
case VK_ERROR_EXTENSION_NOT_PRESENT:
return "A requested extension is not supported";
case VK_ERROR_FEATURE_NOT_PRESENT:
return "A requested feature is not supported";
case VK_ERROR_INCOMPATIBLE_DRIVER:
return "The requested version of Vulkan is not supported by the driver or is otherwise incompatible";
case VK_ERROR_TOO_MANY_OBJECTS:
return "Too many objects of the type have already been created";
case VK_ERROR_FORMAT_NOT_SUPPORTED:
return "A requested format is not supported on this device";
case VK_ERROR_SURFACE_LOST_KHR:
return "A surface is no longer available";
case VK_SUBOPTIMAL_KHR:
return "A swapchain no longer matches the surface properties exactly, but can still be used";
case VK_ERROR_OUT_OF_DATE_KHR:
return "A surface has changed in such a way that it is no longer compatible with the swapchain";
case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR:
return "The display used by a swapchain does not use the same presentable image layout";
case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR:
return "The requested window is already connected to a VkSurfaceKHR, or to some other non-Vulkan API";
case VK_ERROR_VALIDATION_FAILED_EXT:
return "A validation layer found an error";
default:
return "ERROR: UNKNOWN VULKAN ERROR";
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW public API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI int glfwVulkanSupported(void)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
return _glfwInitVulkan(_GLFW_FIND_LOADER);
}
GLFWAPI const char** glfwGetRequiredInstanceExtensions(uint32_t* count)
{
assert(count != NULL);
*count = 0;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL;
if (!_glfw.vk.extensions[0])
return NULL;
*count = 2;
return (const char**) _glfw.vk.extensions;
}
GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance,
const char* procname)
{
GLFWvkproc proc;
assert(procname != NULL);
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return NULL;
// NOTE: Vulkan 1.0 and 1.1 vkGetInstanceProcAddr cannot return itself
if (strcmp(procname, "vkGetInstanceProcAddr") == 0)
return (GLFWvkproc) vkGetInstanceProcAddr;
proc = (GLFWvkproc) vkGetInstanceProcAddr(instance, procname);
if (!proc)
{
if (_glfw.vk.handle)
proc = (GLFWvkproc) _glfwPlatformGetModuleSymbol(_glfw.vk.handle, procname);
}
return proc;
}
GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
assert(instance != VK_NULL_HANDLE);
assert(device != VK_NULL_HANDLE);
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return GLFW_FALSE;
if (!_glfw.vk.extensions[0])
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return GLFW_FALSE;
}
return _glfw.platform.getPhysicalDevicePresentationSupport(instance,
device,
queuefamily);
}
GLFWAPI VkResult glfwCreateWindowSurface(VkInstance instance,
GLFWwindow* handle,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(instance != VK_NULL_HANDLE);
assert(window != NULL);
assert(surface != NULL);
*surface = VK_NULL_HANDLE;
_GLFW_REQUIRE_INIT_OR_RETURN(VK_ERROR_INITIALIZATION_FAILED);
if (!_glfwInitVulkan(_GLFW_REQUIRE_LOADER))
return VK_ERROR_INITIALIZATION_FAILED;
if (!_glfw.vk.extensions[0])
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Vulkan: Window surface creation extensions not found");
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
if (window->context.client != GLFW_NO_API)
{
_glfwInputError(GLFW_INVALID_VALUE,
"Vulkan: Window surface creation requires the window to have the client API set to GLFW_NO_API");
return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
}
return _glfw.platform.createWindowSurface(instance, window, allocator, surface);
}

798
raylib/external/glfw/src/wgl_context.c vendored Normal file
View File

@@ -0,0 +1,798 @@
//========================================================================
// GLFW 3.4 WGL - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_WIN32)
#include <stdlib.h>
#include <assert.h>
// Return the value corresponding to the specified attribute
//
static int findPixelFormatAttribValueWGL(const int* attribs,
int attribCount,
const int* values,
int attrib)
{
int i;
for (i = 0; i < attribCount; i++)
{
if (attribs[i] == attrib)
return values[i];
}
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Unknown pixel format attribute requested");
return 0;
}
#define ADD_ATTRIB(a) \
{ \
assert((size_t) attribCount < sizeof(attribs) / sizeof(attribs[0])); \
attribs[attribCount++] = a; \
}
#define FIND_ATTRIB_VALUE(a) \
findPixelFormatAttribValueWGL(attribs, attribCount, values, a)
// Return a list of available and usable framebuffer configs
//
static int choosePixelFormatWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
_GLFWfbconfig* usableConfigs;
const _GLFWfbconfig* closest;
int i, pixelFormat, nativeCount, usableCount = 0, attribCount = 0;
int attribs[40];
int values[sizeof(attribs) / sizeof(attribs[0])];
nativeCount = DescribePixelFormat(window->context.wgl.dc,
1,
sizeof(PIXELFORMATDESCRIPTOR),
NULL);
if (_glfw.wgl.ARB_pixel_format)
{
ADD_ATTRIB(WGL_SUPPORT_OPENGL_ARB);
ADD_ATTRIB(WGL_DRAW_TO_WINDOW_ARB);
ADD_ATTRIB(WGL_PIXEL_TYPE_ARB);
ADD_ATTRIB(WGL_ACCELERATION_ARB);
ADD_ATTRIB(WGL_RED_BITS_ARB);
ADD_ATTRIB(WGL_RED_SHIFT_ARB);
ADD_ATTRIB(WGL_GREEN_BITS_ARB);
ADD_ATTRIB(WGL_GREEN_SHIFT_ARB);
ADD_ATTRIB(WGL_BLUE_BITS_ARB);
ADD_ATTRIB(WGL_BLUE_SHIFT_ARB);
ADD_ATTRIB(WGL_ALPHA_BITS_ARB);
ADD_ATTRIB(WGL_ALPHA_SHIFT_ARB);
ADD_ATTRIB(WGL_DEPTH_BITS_ARB);
ADD_ATTRIB(WGL_STENCIL_BITS_ARB);
ADD_ATTRIB(WGL_ACCUM_BITS_ARB);
ADD_ATTRIB(WGL_ACCUM_RED_BITS_ARB);
ADD_ATTRIB(WGL_ACCUM_GREEN_BITS_ARB);
ADD_ATTRIB(WGL_ACCUM_BLUE_BITS_ARB);
ADD_ATTRIB(WGL_ACCUM_ALPHA_BITS_ARB);
ADD_ATTRIB(WGL_AUX_BUFFERS_ARB);
ADD_ATTRIB(WGL_STEREO_ARB);
ADD_ATTRIB(WGL_DOUBLE_BUFFER_ARB);
if (_glfw.wgl.ARB_multisample)
ADD_ATTRIB(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB || _glfw.wgl.EXT_framebuffer_sRGB)
ADD_ATTRIB(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB);
}
else
{
if (_glfw.wgl.EXT_colorspace)
ADD_ATTRIB(WGL_COLORSPACE_EXT);
}
// NOTE: In a Parallels VM WGL_ARB_pixel_format returns fewer pixel formats than
// DescribePixelFormat, violating the guarantees of the extension spec
// HACK: Iterate through the minimum of both counts
const int attrib = WGL_NUMBER_PIXEL_FORMATS_ARB;
int extensionCount;
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
1, 0, 1, &attrib, &extensionCount))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attribute");
return 0;
}
nativeCount = _glfw_min(nativeCount, extensionCount);
}
usableConfigs = _glfw_calloc(nativeCount, sizeof(_GLFWfbconfig));
for (i = 0; i < nativeCount; i++)
{
_GLFWfbconfig* u = usableConfigs + usableCount;
pixelFormat = i + 1;
if (_glfw.wgl.ARB_pixel_format)
{
// Get pixel format attributes through "modern" extension
if (!wglGetPixelFormatAttribivARB(window->context.wgl.dc,
pixelFormat, 0,
attribCount,
attribs, values))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve pixel format attributes");
_glfw_free(usableConfigs);
return 0;
}
if (!FIND_ATTRIB_VALUE(WGL_SUPPORT_OPENGL_ARB) ||
!FIND_ATTRIB_VALUE(WGL_DRAW_TO_WINDOW_ARB))
{
continue;
}
if (FIND_ATTRIB_VALUE(WGL_PIXEL_TYPE_ARB) != WGL_TYPE_RGBA_ARB)
continue;
if (FIND_ATTRIB_VALUE(WGL_ACCELERATION_ARB) == WGL_NO_ACCELERATION_ARB)
continue;
if (FIND_ATTRIB_VALUE(WGL_DOUBLE_BUFFER_ARB) != fbconfig->doublebuffer)
continue;
u->redBits = FIND_ATTRIB_VALUE(WGL_RED_BITS_ARB);
u->greenBits = FIND_ATTRIB_VALUE(WGL_GREEN_BITS_ARB);
u->blueBits = FIND_ATTRIB_VALUE(WGL_BLUE_BITS_ARB);
u->alphaBits = FIND_ATTRIB_VALUE(WGL_ALPHA_BITS_ARB);
u->depthBits = FIND_ATTRIB_VALUE(WGL_DEPTH_BITS_ARB);
u->stencilBits = FIND_ATTRIB_VALUE(WGL_STENCIL_BITS_ARB);
u->accumRedBits = FIND_ATTRIB_VALUE(WGL_ACCUM_RED_BITS_ARB);
u->accumGreenBits = FIND_ATTRIB_VALUE(WGL_ACCUM_GREEN_BITS_ARB);
u->accumBlueBits = FIND_ATTRIB_VALUE(WGL_ACCUM_BLUE_BITS_ARB);
u->accumAlphaBits = FIND_ATTRIB_VALUE(WGL_ACCUM_ALPHA_BITS_ARB);
u->auxBuffers = FIND_ATTRIB_VALUE(WGL_AUX_BUFFERS_ARB);
if (FIND_ATTRIB_VALUE(WGL_STEREO_ARB))
u->stereo = GLFW_TRUE;
if (_glfw.wgl.ARB_multisample)
u->samples = FIND_ATTRIB_VALUE(WGL_SAMPLES_ARB);
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (_glfw.wgl.ARB_framebuffer_sRGB ||
_glfw.wgl.EXT_framebuffer_sRGB)
{
if (FIND_ATTRIB_VALUE(WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB))
u->sRGB = GLFW_TRUE;
}
}
else
{
if (_glfw.wgl.EXT_colorspace)
{
if (FIND_ATTRIB_VALUE(WGL_COLORSPACE_EXT) == WGL_COLORSPACE_SRGB_EXT)
u->sRGB = GLFW_TRUE;
}
}
}
else
{
// Get pixel format attributes through legacy PFDs
PIXELFORMATDESCRIPTOR pfd;
if (!DescribePixelFormat(window->context.wgl.dc,
pixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),
&pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to describe pixel format");
_glfw_free(usableConfigs);
return 0;
}
if (!(pfd.dwFlags & PFD_DRAW_TO_WINDOW) ||
!(pfd.dwFlags & PFD_SUPPORT_OPENGL))
{
continue;
}
if (!(pfd.dwFlags & PFD_GENERIC_ACCELERATED) &&
(pfd.dwFlags & PFD_GENERIC_FORMAT))
{
continue;
}
if (pfd.iPixelType != PFD_TYPE_RGBA)
continue;
if (!!(pfd.dwFlags & PFD_DOUBLEBUFFER) != fbconfig->doublebuffer)
continue;
u->redBits = pfd.cRedBits;
u->greenBits = pfd.cGreenBits;
u->blueBits = pfd.cBlueBits;
u->alphaBits = pfd.cAlphaBits;
u->depthBits = pfd.cDepthBits;
u->stencilBits = pfd.cStencilBits;
u->accumRedBits = pfd.cAccumRedBits;
u->accumGreenBits = pfd.cAccumGreenBits;
u->accumBlueBits = pfd.cAccumBlueBits;
u->accumAlphaBits = pfd.cAccumAlphaBits;
u->auxBuffers = pfd.cAuxBuffers;
if (pfd.dwFlags & PFD_STEREO)
u->stereo = GLFW_TRUE;
}
u->handle = pixelFormat;
usableCount++;
}
if (!usableCount)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: The driver does not appear to support OpenGL");
_glfw_free(usableConfigs);
return 0;
}
closest = _glfwChooseFBConfig(fbconfig, usableConfigs, usableCount);
if (!closest)
{
_glfwInputError(GLFW_FORMAT_UNAVAILABLE,
"WGL: Failed to find a suitable pixel format");
_glfw_free(usableConfigs);
return 0;
}
pixelFormat = (int) closest->handle;
_glfw_free(usableConfigs);
return pixelFormat;
}
#undef ADD_ATTRIB
#undef FIND_ATTRIB_VALUE
static void makeContextCurrentWGL(_GLFWwindow* window)
{
if (window)
{
if (wglMakeCurrent(window->context.wgl.dc, window->context.wgl.handle))
_glfwPlatformSetTls(&_glfw.contextSlot, window);
else
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make context current");
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
}
}
else
{
if (!wglMakeCurrent(NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to clear current context");
}
_glfwPlatformSetTls(&_glfw.contextSlot, NULL);
}
}
static void swapBuffersWGL(_GLFWwindow* window)
{
if (!window->monitor)
{
// HACK: Use DwmFlush when desktop composition is enabled on Windows Vista and 7
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
{
BOOL enabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
{
int count = abs(window->context.wgl.interval);
while (count--)
DwmFlush();
}
}
}
SwapBuffers(window->context.wgl.dc);
}
static void swapIntervalWGL(int interval)
{
_GLFWwindow* window = _glfwPlatformGetTls(&_glfw.contextSlot);
assert(window != NULL);
window->context.wgl.interval = interval;
if (!window->monitor)
{
// HACK: Disable WGL swap interval when desktop composition is enabled on Windows
// Vista and 7 to avoid interfering with DWM vsync
if (!IsWindows8OrGreater() && IsWindowsVistaOrGreater())
{
BOOL enabled = FALSE;
if (SUCCEEDED(DwmIsCompositionEnabled(&enabled)) && enabled)
interval = 0;
}
}
if (_glfw.wgl.EXT_swap_control)
wglSwapIntervalEXT(interval);
}
static int extensionSupportedWGL(const char* extension)
{
const char* extensions = NULL;
if (_glfw.wgl.GetExtensionsStringARB)
extensions = wglGetExtensionsStringARB(wglGetCurrentDC());
else if (_glfw.wgl.GetExtensionsStringEXT)
extensions = wglGetExtensionsStringEXT();
if (!extensions)
return GLFW_FALSE;
return _glfwStringInExtensionString(extension, extensions);
}
static GLFWglproc getProcAddressWGL(const char* procname)
{
const GLFWglproc proc = (GLFWglproc) wglGetProcAddress(procname);
if (proc)
return proc;
return (GLFWglproc) _glfwPlatformGetModuleSymbol(_glfw.wgl.instance, procname);
}
static void destroyContextWGL(_GLFWwindow* window)
{
if (window->context.wgl.handle)
{
wglDeleteContext(window->context.wgl.handle);
window->context.wgl.handle = NULL;
}
}
// Initialize WGL
//
GLFWbool _glfwInitWGL(void)
{
PIXELFORMATDESCRIPTOR pfd;
HGLRC prc, rc;
HDC pdc, dc;
if (_glfw.wgl.instance)
return GLFW_TRUE;
_glfw.wgl.instance = _glfwPlatformLoadModule("opengl32.dll");
if (!_glfw.wgl.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to load opengl32.dll");
return GLFW_FALSE;
}
_glfw.wgl.CreateContext = (PFN_wglCreateContext)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglCreateContext");
_glfw.wgl.DeleteContext = (PFN_wglDeleteContext)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglDeleteContext");
_glfw.wgl.GetProcAddress = (PFN_wglGetProcAddress)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetProcAddress");
_glfw.wgl.GetCurrentDC = (PFN_wglGetCurrentDC)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentDC");
_glfw.wgl.GetCurrentContext = (PFN_wglGetCurrentContext)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglGetCurrentContext");
_glfw.wgl.MakeCurrent = (PFN_wglMakeCurrent)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglMakeCurrent");
_glfw.wgl.ShareLists = (PFN_wglShareLists)
_glfwPlatformGetModuleSymbol(_glfw.wgl.instance, "wglShareLists");
// NOTE: A dummy context has to be created for opengl32.dll to load the
// OpenGL ICD, from which we can then query WGL extensions
// NOTE: This code will accept the Microsoft GDI ICD; accelerated context
// creation failure occurs during manual pixel format enumeration
dc = GetDC(_glfw.win32.helperWindowHandle);
ZeroMemory(&pfd, sizeof(pfd));
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
if (!SetPixelFormat(dc, ChoosePixelFormat(dc, &pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set pixel format for dummy context");
return GLFW_FALSE;
}
rc = wglCreateContext(dc);
if (!rc)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to create dummy context");
return GLFW_FALSE;
}
pdc = wglGetCurrentDC();
prc = wglGetCurrentContext();
if (!wglMakeCurrent(dc, rc))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to make dummy context current");
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_FALSE;
}
// NOTE: Functions must be loaded first as they're needed to retrieve the
// extension string that tells us whether the functions are supported
_glfw.wgl.GetExtensionsStringEXT = (PFNWGLGETEXTENSIONSSTRINGEXTPROC)
wglGetProcAddress("wglGetExtensionsStringEXT");
_glfw.wgl.GetExtensionsStringARB = (PFNWGLGETEXTENSIONSSTRINGARBPROC)
wglGetProcAddress("wglGetExtensionsStringARB");
_glfw.wgl.CreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)
wglGetProcAddress("wglCreateContextAttribsARB");
_glfw.wgl.SwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)
wglGetProcAddress("wglSwapIntervalEXT");
_glfw.wgl.GetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
wglGetProcAddress("wglGetPixelFormatAttribivARB");
// NOTE: WGL_ARB_extensions_string and WGL_EXT_extensions_string are not
// checked below as we are already using them
_glfw.wgl.ARB_multisample =
extensionSupportedWGL("WGL_ARB_multisample");
_glfw.wgl.ARB_framebuffer_sRGB =
extensionSupportedWGL("WGL_ARB_framebuffer_sRGB");
_glfw.wgl.EXT_framebuffer_sRGB =
extensionSupportedWGL("WGL_EXT_framebuffer_sRGB");
_glfw.wgl.ARB_create_context =
extensionSupportedWGL("WGL_ARB_create_context");
_glfw.wgl.ARB_create_context_profile =
extensionSupportedWGL("WGL_ARB_create_context_profile");
_glfw.wgl.EXT_create_context_es2_profile =
extensionSupportedWGL("WGL_EXT_create_context_es2_profile");
_glfw.wgl.ARB_create_context_robustness =
extensionSupportedWGL("WGL_ARB_create_context_robustness");
_glfw.wgl.ARB_create_context_no_error =
extensionSupportedWGL("WGL_ARB_create_context_no_error");
_glfw.wgl.EXT_swap_control =
extensionSupportedWGL("WGL_EXT_swap_control");
_glfw.wgl.EXT_colorspace =
extensionSupportedWGL("WGL_EXT_colorspace");
_glfw.wgl.ARB_pixel_format =
extensionSupportedWGL("WGL_ARB_pixel_format");
_glfw.wgl.ARB_context_flush_control =
extensionSupportedWGL("WGL_ARB_context_flush_control");
wglMakeCurrent(pdc, prc);
wglDeleteContext(rc);
return GLFW_TRUE;
}
// Terminate WGL
//
void _glfwTerminateWGL(void)
{
if (_glfw.wgl.instance)
_glfwPlatformFreeModule(_glfw.wgl.instance);
}
#define SET_ATTRIB(a, v) \
{ \
assert(((size_t) index + 1) < sizeof(attribs) / sizeof(attribs[0])); \
attribs[index++] = a; \
attribs[index++] = v; \
}
// Create the OpenGL or OpenGL ES context
//
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
int attribs[40];
int pixelFormat;
PIXELFORMATDESCRIPTOR pfd;
HGLRC share = NULL;
if (ctxconfig->share)
share = ctxconfig->share->context.wgl.handle;
window->context.wgl.dc = GetDC(window->win32.handle);
if (!window->context.wgl.dc)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve DC for window");
return GLFW_FALSE;
}
pixelFormat = choosePixelFormatWGL(window, ctxconfig, fbconfig);
if (!pixelFormat)
return GLFW_FALSE;
if (!DescribePixelFormat(window->context.wgl.dc,
pixelFormat, sizeof(pfd), &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to retrieve PFD for selected pixel format");
return GLFW_FALSE;
}
if (!SetPixelFormat(window->context.wgl.dc, pixelFormat, &pfd))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to set selected pixel format");
return GLFW_FALSE;
}
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
{
if (!_glfw.wgl.ARB_create_context)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: A forward compatible OpenGL context requested but WGL_ARB_create_context is unavailable");
return GLFW_FALSE;
}
}
if (ctxconfig->profile)
{
if (!_glfw.wgl.ARB_create_context_profile)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: OpenGL profile requested but WGL_ARB_create_context_profile is unavailable");
return GLFW_FALSE;
}
}
}
else
{
if (!_glfw.wgl.ARB_create_context ||
!_glfw.wgl.ARB_create_context_profile ||
!_glfw.wgl.EXT_create_context_es2_profile)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"WGL: OpenGL ES requested but WGL_ARB_create_context_es2_profile is unavailable");
return GLFW_FALSE;
}
}
if (_glfw.wgl.ARB_create_context)
{
int index = 0, mask = 0, flags = 0;
if (ctxconfig->client == GLFW_OPENGL_API)
{
if (ctxconfig->forward)
flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
if (ctxconfig->profile == GLFW_OPENGL_CORE_PROFILE)
mask |= WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
else if (ctxconfig->profile == GLFW_OPENGL_COMPAT_PROFILE)
mask |= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB;
}
else
mask |= WGL_CONTEXT_ES2_PROFILE_BIT_EXT;
if (ctxconfig->debug)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (ctxconfig->robustness)
{
if (_glfw.wgl.ARB_create_context_robustness)
{
if (ctxconfig->robustness == GLFW_NO_RESET_NOTIFICATION)
{
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_NO_RESET_NOTIFICATION_ARB);
}
else if (ctxconfig->robustness == GLFW_LOSE_CONTEXT_ON_RESET)
{
SET_ATTRIB(WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB,
WGL_LOSE_CONTEXT_ON_RESET_ARB);
}
flags |= WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB;
}
}
if (ctxconfig->release)
{
if (_glfw.wgl.ARB_context_flush_control)
{
if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_NONE)
{
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB);
}
else if (ctxconfig->release == GLFW_RELEASE_BEHAVIOR_FLUSH)
{
SET_ATTRIB(WGL_CONTEXT_RELEASE_BEHAVIOR_ARB,
WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB);
}
}
}
if (ctxconfig->noerror)
{
if (_glfw.wgl.ARB_create_context_no_error)
SET_ATTRIB(WGL_CONTEXT_OPENGL_NO_ERROR_ARB, GLFW_TRUE);
}
// NOTE: Only request an explicitly versioned context when necessary, as
// explicitly requesting version 1.0 does not always return the
// highest version supported by the driver
if (ctxconfig->major != 1 || ctxconfig->minor != 0)
{
SET_ATTRIB(WGL_CONTEXT_MAJOR_VERSION_ARB, ctxconfig->major);
SET_ATTRIB(WGL_CONTEXT_MINOR_VERSION_ARB, ctxconfig->minor);
}
if (flags)
SET_ATTRIB(WGL_CONTEXT_FLAGS_ARB, flags);
if (mask)
SET_ATTRIB(WGL_CONTEXT_PROFILE_MASK_ARB, mask);
SET_ATTRIB(0, 0);
window->context.wgl.handle =
wglCreateContextAttribsARB(window->context.wgl.dc, share, attribs);
if (!window->context.wgl.handle)
{
const DWORD error = GetLastError();
if (error == (0xc0070000 | ERROR_INVALID_VERSION_ARB))
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support OpenGL ES version %i.%i",
ctxconfig->major,
ctxconfig->minor);
}
}
else if (error == (0xc0070000 | ERROR_INVALID_PROFILE_ARB))
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Driver does not support the requested OpenGL profile");
}
else if (error == (0xc0070000 | ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB))
{
_glfwInputError(GLFW_INVALID_VALUE,
"WGL: The share context is not compatible with the requested context");
}
else
{
if (ctxconfig->client == GLFW_OPENGL_API)
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
}
else
{
_glfwInputError(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL ES context");
}
}
return GLFW_FALSE;
}
}
else
{
window->context.wgl.handle = wglCreateContext(window->context.wgl.dc);
if (!window->context.wgl.handle)
{
_glfwInputErrorWin32(GLFW_VERSION_UNAVAILABLE,
"WGL: Failed to create OpenGL context");
return GLFW_FALSE;
}
if (share)
{
if (!wglShareLists(share, window->context.wgl.handle))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"WGL: Failed to enable sharing with specified OpenGL context");
return GLFW_FALSE;
}
}
}
window->context.makeCurrent = makeContextCurrentWGL;
window->context.swapBuffers = swapBuffersWGL;
window->context.swapInterval = swapIntervalWGL;
window->context.extensionSupported = extensionSupportedWGL;
window->context.getProcAddress = getProcAddressWGL;
window->context.destroy = destroyContextWGL;
return GLFW_TRUE;
}
#undef SET_ATTRIB
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* handle)
{
_GLFWwindow* window = (_GLFWwindow*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE,
"WGL: Platform not initialized");
return NULL;
}
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return NULL;
}
return window->context.wgl.handle;
}
#endif // _GLFW_WIN32

732
raylib/external/glfw/src/win32_init.c vendored Normal file
View File

@@ -0,0 +1,732 @@
//========================================================================
// GLFW 3.4 Win32 (modified for raylib) - www.glfw.org; www.raylib.com
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
// Copyright (c) 2024 M374LX <wilsalx@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_WIN32)
#include <stdlib.h>
static const GUID _glfw_GUID_DEVINTERFACE_HID =
{0x4d1e55b2,0xf16f,0x11cf,{0x88,0xcb,0x00,0x11,0x11,0x00,0x00,0x30}};
#define GUID_DEVINTERFACE_HID _glfw_GUID_DEVINTERFACE_HID
#if defined(_GLFW_USE_HYBRID_HPG) || defined(_GLFW_USE_OPTIMUS_HPG)
#if defined(_GLFW_BUILD_DLL)
#pragma message("These symbols must be exported by the executable and have no effect in a DLL")
#endif
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on Nvidia Optimus systems
// with up-to-date drivers
//
__declspec(dllexport) DWORD NvOptimusEnablement = 1;
// Executables (but not DLLs) exporting this symbol with this value will be
// automatically directed to the high-performance GPU on AMD PowerXpress systems
// with up-to-date drivers
//
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
#endif // _GLFW_USE_HYBRID_HPG
#if defined(_GLFW_BUILD_DLL)
// GLFW DLL entry point
//
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
return TRUE;
}
#endif // _GLFW_BUILD_DLL
// Load necessary libraries (DLLs)
//
static GLFWbool loadLibraries(void)
{
if (!GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
(const WCHAR*) &_glfw,
(HMODULE*) &_glfw.win32.instance))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to retrieve own module handle");
return GLFW_FALSE;
}
_glfw.win32.user32.instance = _glfwPlatformLoadModule("user32.dll");
if (!_glfw.win32.user32.instance)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to load user32.dll");
return GLFW_FALSE;
}
_glfw.win32.user32.SetProcessDPIAware_ = (PFN_SetProcessDPIAware)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDPIAware");
_glfw.win32.user32.ChangeWindowMessageFilterEx_ = (PFN_ChangeWindowMessageFilterEx)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "ChangeWindowMessageFilterEx");
_glfw.win32.user32.EnableNonClientDpiScaling_ = (PFN_EnableNonClientDpiScaling)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "EnableNonClientDpiScaling");
_glfw.win32.user32.SetProcessDpiAwarenessContext_ = (PFN_SetProcessDpiAwarenessContext)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "SetProcessDpiAwarenessContext");
_glfw.win32.user32.GetDpiForWindow_ = (PFN_GetDpiForWindow)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetDpiForWindow");
_glfw.win32.user32.AdjustWindowRectExForDpi_ = (PFN_AdjustWindowRectExForDpi)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "AdjustWindowRectExForDpi");
_glfw.win32.user32.GetSystemMetricsForDpi_ = (PFN_GetSystemMetricsForDpi)
_glfwPlatformGetModuleSymbol(_glfw.win32.user32.instance, "GetSystemMetricsForDpi");
_glfw.win32.dinput8.instance = _glfwPlatformLoadModule("dinput8.dll");
if (_glfw.win32.dinput8.instance)
{
_glfw.win32.dinput8.Create = (PFN_DirectInput8Create)
_glfwPlatformGetModuleSymbol(_glfw.win32.dinput8.instance, "DirectInput8Create");
}
{
int i;
const char* names[] =
{
"xinput1_4.dll",
"xinput1_3.dll",
"xinput9_1_0.dll",
"xinput1_2.dll",
"xinput1_1.dll",
NULL
};
for (i = 0; names[i]; i++)
{
_glfw.win32.xinput.instance = _glfwPlatformLoadModule(names[i]);
if (_glfw.win32.xinput.instance)
{
_glfw.win32.xinput.GetCapabilities = (PFN_XInputGetCapabilities)
_glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetCapabilities");
_glfw.win32.xinput.GetState = (PFN_XInputGetState)
_glfwPlatformGetModuleSymbol(_glfw.win32.xinput.instance, "XInputGetState");
break;
}
}
}
_glfw.win32.dwmapi.instance = _glfwPlatformLoadModule("dwmapi.dll");
if (_glfw.win32.dwmapi.instance)
{
_glfw.win32.dwmapi.IsCompositionEnabled = (PFN_DwmIsCompositionEnabled)
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmIsCompositionEnabled");
_glfw.win32.dwmapi.Flush = (PFN_DwmFlush)
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmFlush");
_glfw.win32.dwmapi.EnableBlurBehindWindow = (PFN_DwmEnableBlurBehindWindow)
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmEnableBlurBehindWindow");
_glfw.win32.dwmapi.GetColorizationColor = (PFN_DwmGetColorizationColor)
_glfwPlatformGetModuleSymbol(_glfw.win32.dwmapi.instance, "DwmGetColorizationColor");
}
_glfw.win32.shcore.instance = _glfwPlatformLoadModule("shcore.dll");
if (_glfw.win32.shcore.instance)
{
_glfw.win32.shcore.SetProcessDpiAwareness_ = (PFN_SetProcessDpiAwareness)
_glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "SetProcessDpiAwareness");
_glfw.win32.shcore.GetDpiForMonitor_ = (PFN_GetDpiForMonitor)
_glfwPlatformGetModuleSymbol(_glfw.win32.shcore.instance, "GetDpiForMonitor");
}
_glfw.win32.ntdll.instance = _glfwPlatformLoadModule("ntdll.dll");
if (_glfw.win32.ntdll.instance)
{
_glfw.win32.ntdll.RtlVerifyVersionInfo_ = (PFN_RtlVerifyVersionInfo)
_glfwPlatformGetModuleSymbol(_glfw.win32.ntdll.instance, "RtlVerifyVersionInfo");
}
return GLFW_TRUE;
}
// Unload used libraries (DLLs)
//
static void freeLibraries(void)
{
if (_glfw.win32.xinput.instance)
_glfwPlatformFreeModule(_glfw.win32.xinput.instance);
if (_glfw.win32.dinput8.instance)
_glfwPlatformFreeModule(_glfw.win32.dinput8.instance);
if (_glfw.win32.user32.instance)
_glfwPlatformFreeModule(_glfw.win32.user32.instance);
if (_glfw.win32.dwmapi.instance)
_glfwPlatformFreeModule(_glfw.win32.dwmapi.instance);
if (_glfw.win32.shcore.instance)
_glfwPlatformFreeModule(_glfw.win32.shcore.instance);
if (_glfw.win32.ntdll.instance)
_glfwPlatformFreeModule(_glfw.win32.ntdll.instance);
}
// Create key code translation tables
//
static void createKeyTablesWin32(void)
{
int scancode;
memset(_glfw.win32.keycodes, -1, sizeof(_glfw.win32.keycodes));
memset(_glfw.win32.scancodes, -1, sizeof(_glfw.win32.scancodes));
_glfw.win32.keycodes[0x00B] = GLFW_KEY_0;
_glfw.win32.keycodes[0x002] = GLFW_KEY_1;
_glfw.win32.keycodes[0x003] = GLFW_KEY_2;
_glfw.win32.keycodes[0x004] = GLFW_KEY_3;
_glfw.win32.keycodes[0x005] = GLFW_KEY_4;
_glfw.win32.keycodes[0x006] = GLFW_KEY_5;
_glfw.win32.keycodes[0x007] = GLFW_KEY_6;
_glfw.win32.keycodes[0x008] = GLFW_KEY_7;
_glfw.win32.keycodes[0x009] = GLFW_KEY_8;
_glfw.win32.keycodes[0x00A] = GLFW_KEY_9;
_glfw.win32.keycodes[0x01E] = GLFW_KEY_A;
_glfw.win32.keycodes[0x030] = GLFW_KEY_B;
_glfw.win32.keycodes[0x02E] = GLFW_KEY_C;
_glfw.win32.keycodes[0x020] = GLFW_KEY_D;
_glfw.win32.keycodes[0x012] = GLFW_KEY_E;
_glfw.win32.keycodes[0x021] = GLFW_KEY_F;
_glfw.win32.keycodes[0x022] = GLFW_KEY_G;
_glfw.win32.keycodes[0x023] = GLFW_KEY_H;
_glfw.win32.keycodes[0x017] = GLFW_KEY_I;
_glfw.win32.keycodes[0x024] = GLFW_KEY_J;
_glfw.win32.keycodes[0x025] = GLFW_KEY_K;
_glfw.win32.keycodes[0x026] = GLFW_KEY_L;
_glfw.win32.keycodes[0x032] = GLFW_KEY_M;
_glfw.win32.keycodes[0x031] = GLFW_KEY_N;
_glfw.win32.keycodes[0x018] = GLFW_KEY_O;
_glfw.win32.keycodes[0x019] = GLFW_KEY_P;
_glfw.win32.keycodes[0x010] = GLFW_KEY_Q;
_glfw.win32.keycodes[0x013] = GLFW_KEY_R;
_glfw.win32.keycodes[0x01F] = GLFW_KEY_S;
_glfw.win32.keycodes[0x014] = GLFW_KEY_T;
_glfw.win32.keycodes[0x016] = GLFW_KEY_U;
_glfw.win32.keycodes[0x02F] = GLFW_KEY_V;
_glfw.win32.keycodes[0x011] = GLFW_KEY_W;
_glfw.win32.keycodes[0x02D] = GLFW_KEY_X;
_glfw.win32.keycodes[0x015] = GLFW_KEY_Y;
_glfw.win32.keycodes[0x02C] = GLFW_KEY_Z;
_glfw.win32.keycodes[0x028] = GLFW_KEY_APOSTROPHE;
_glfw.win32.keycodes[0x02B] = GLFW_KEY_BACKSLASH;
_glfw.win32.keycodes[0x033] = GLFW_KEY_COMMA;
_glfw.win32.keycodes[0x00D] = GLFW_KEY_EQUAL;
_glfw.win32.keycodes[0x029] = GLFW_KEY_GRAVE_ACCENT;
_glfw.win32.keycodes[0x01A] = GLFW_KEY_LEFT_BRACKET;
_glfw.win32.keycodes[0x00C] = GLFW_KEY_MINUS;
_glfw.win32.keycodes[0x034] = GLFW_KEY_PERIOD;
_glfw.win32.keycodes[0x01B] = GLFW_KEY_RIGHT_BRACKET;
_glfw.win32.keycodes[0x027] = GLFW_KEY_SEMICOLON;
_glfw.win32.keycodes[0x035] = GLFW_KEY_SLASH;
_glfw.win32.keycodes[0x056] = GLFW_KEY_WORLD_2;
_glfw.win32.keycodes[0x00E] = GLFW_KEY_BACKSPACE;
_glfw.win32.keycodes[0x153] = GLFW_KEY_DELETE;
_glfw.win32.keycodes[0x14F] = GLFW_KEY_END;
_glfw.win32.keycodes[0x01C] = GLFW_KEY_ENTER;
_glfw.win32.keycodes[0x001] = GLFW_KEY_ESCAPE;
_glfw.win32.keycodes[0x147] = GLFW_KEY_HOME;
_glfw.win32.keycodes[0x152] = GLFW_KEY_INSERT;
_glfw.win32.keycodes[0x15D] = GLFW_KEY_MENU;
_glfw.win32.keycodes[0x151] = GLFW_KEY_PAGE_DOWN;
_glfw.win32.keycodes[0x149] = GLFW_KEY_PAGE_UP;
_glfw.win32.keycodes[0x045] = GLFW_KEY_PAUSE;
_glfw.win32.keycodes[0x039] = GLFW_KEY_SPACE;
_glfw.win32.keycodes[0x00F] = GLFW_KEY_TAB;
_glfw.win32.keycodes[0x03A] = GLFW_KEY_CAPS_LOCK;
_glfw.win32.keycodes[0x145] = GLFW_KEY_NUM_LOCK;
_glfw.win32.keycodes[0x046] = GLFW_KEY_SCROLL_LOCK;
_glfw.win32.keycodes[0x03B] = GLFW_KEY_F1;
_glfw.win32.keycodes[0x03C] = GLFW_KEY_F2;
_glfw.win32.keycodes[0x03D] = GLFW_KEY_F3;
_glfw.win32.keycodes[0x03E] = GLFW_KEY_F4;
_glfw.win32.keycodes[0x03F] = GLFW_KEY_F5;
_glfw.win32.keycodes[0x040] = GLFW_KEY_F6;
_glfw.win32.keycodes[0x041] = GLFW_KEY_F7;
_glfw.win32.keycodes[0x042] = GLFW_KEY_F8;
_glfw.win32.keycodes[0x043] = GLFW_KEY_F9;
_glfw.win32.keycodes[0x044] = GLFW_KEY_F10;
_glfw.win32.keycodes[0x057] = GLFW_KEY_F11;
_glfw.win32.keycodes[0x058] = GLFW_KEY_F12;
_glfw.win32.keycodes[0x064] = GLFW_KEY_F13;
_glfw.win32.keycodes[0x065] = GLFW_KEY_F14;
_glfw.win32.keycodes[0x066] = GLFW_KEY_F15;
_glfw.win32.keycodes[0x067] = GLFW_KEY_F16;
_glfw.win32.keycodes[0x068] = GLFW_KEY_F17;
_glfw.win32.keycodes[0x069] = GLFW_KEY_F18;
_glfw.win32.keycodes[0x06A] = GLFW_KEY_F19;
_glfw.win32.keycodes[0x06B] = GLFW_KEY_F20;
_glfw.win32.keycodes[0x06C] = GLFW_KEY_F21;
_glfw.win32.keycodes[0x06D] = GLFW_KEY_F22;
_glfw.win32.keycodes[0x06E] = GLFW_KEY_F23;
_glfw.win32.keycodes[0x076] = GLFW_KEY_F24;
_glfw.win32.keycodes[0x038] = GLFW_KEY_LEFT_ALT;
_glfw.win32.keycodes[0x01D] = GLFW_KEY_LEFT_CONTROL;
_glfw.win32.keycodes[0x02A] = GLFW_KEY_LEFT_SHIFT;
_glfw.win32.keycodes[0x15B] = GLFW_KEY_LEFT_SUPER;
_glfw.win32.keycodes[0x137] = GLFW_KEY_PRINT_SCREEN;
_glfw.win32.keycodes[0x138] = GLFW_KEY_RIGHT_ALT;
_glfw.win32.keycodes[0x11D] = GLFW_KEY_RIGHT_CONTROL;
_glfw.win32.keycodes[0x036] = GLFW_KEY_RIGHT_SHIFT;
_glfw.win32.keycodes[0x15C] = GLFW_KEY_RIGHT_SUPER;
_glfw.win32.keycodes[0x150] = GLFW_KEY_DOWN;
_glfw.win32.keycodes[0x14B] = GLFW_KEY_LEFT;
_glfw.win32.keycodes[0x14D] = GLFW_KEY_RIGHT;
_glfw.win32.keycodes[0x148] = GLFW_KEY_UP;
_glfw.win32.keycodes[0x052] = GLFW_KEY_KP_0;
_glfw.win32.keycodes[0x04F] = GLFW_KEY_KP_1;
_glfw.win32.keycodes[0x050] = GLFW_KEY_KP_2;
_glfw.win32.keycodes[0x051] = GLFW_KEY_KP_3;
_glfw.win32.keycodes[0x04B] = GLFW_KEY_KP_4;
_glfw.win32.keycodes[0x04C] = GLFW_KEY_KP_5;
_glfw.win32.keycodes[0x04D] = GLFW_KEY_KP_6;
_glfw.win32.keycodes[0x047] = GLFW_KEY_KP_7;
_glfw.win32.keycodes[0x048] = GLFW_KEY_KP_8;
_glfw.win32.keycodes[0x049] = GLFW_KEY_KP_9;
_glfw.win32.keycodes[0x04E] = GLFW_KEY_KP_ADD;
_glfw.win32.keycodes[0x053] = GLFW_KEY_KP_DECIMAL;
_glfw.win32.keycodes[0x135] = GLFW_KEY_KP_DIVIDE;
_glfw.win32.keycodes[0x11C] = GLFW_KEY_KP_ENTER;
_glfw.win32.keycodes[0x059] = GLFW_KEY_KP_EQUAL;
_glfw.win32.keycodes[0x037] = GLFW_KEY_KP_MULTIPLY;
_glfw.win32.keycodes[0x04A] = GLFW_KEY_KP_SUBTRACT;
for (scancode = 0; scancode < 512; scancode++)
{
if (_glfw.win32.keycodes[scancode] > 0)
_glfw.win32.scancodes[_glfw.win32.keycodes[scancode]] = scancode;
}
}
// Window procedure for the hidden helper window
//
static LRESULT CALLBACK helperWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_DISPLAYCHANGE:
_glfwPollMonitorsWin32();
break;
case WM_DEVICECHANGE:
{
if (!_glfw.joysticksInitialized)
break;
if (wParam == DBT_DEVICEARRIVAL)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickConnectionWin32();
}
else if (wParam == DBT_DEVICEREMOVECOMPLETE)
{
DEV_BROADCAST_HDR* dbh = (DEV_BROADCAST_HDR*) lParam;
if (dbh && dbh->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE)
_glfwDetectJoystickDisconnectionWin32();
}
break;
}
}
return DefWindowProcW(hWnd, uMsg, wParam, lParam);
}
// Creates a dummy window for behind-the-scenes work
//
static GLFWbool createHelperWindow(void)
{
MSG msg;
WNDCLASSEXW wc = { sizeof(wc) };
wc.style = CS_OWNDC;
wc.lpfnWndProc = (WNDPROC) helperWindowProc;
wc.hInstance = _glfw.win32.instance;
wc.lpszClassName = L"GLFW3 Helper";
_glfw.win32.helperWindowClass = RegisterClassExW(&wc);
if (!_glfw.win32.helperWindowClass)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to register helper window class");
return GLFW_FALSE;
}
_glfw.win32.helperWindowHandle =
CreateWindowExW(WS_EX_OVERLAPPEDWINDOW,
MAKEINTATOM(_glfw.win32.helperWindowClass),
L"GLFW message window",
WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
0, 0, 1, 1,
NULL, NULL,
_glfw.win32.instance,
NULL);
if (!_glfw.win32.helperWindowHandle)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to create helper window");
return GLFW_FALSE;
}
// HACK: The command to the first ShowWindow call is ignored if the parent
// process passed along a STARTUPINFO, so clear that with a no-op call
ShowWindow(_glfw.win32.helperWindowHandle, SW_HIDE);
// Register for HID device notifications
{
DEV_BROADCAST_DEVICEINTERFACE_W dbi;
ZeroMemory(&dbi, sizeof(dbi));
dbi.dbcc_size = sizeof(dbi);
dbi.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
dbi.dbcc_classguid = GUID_DEVINTERFACE_HID;
_glfw.win32.deviceNotificationHandle =
RegisterDeviceNotificationW(_glfw.win32.helperWindowHandle,
(DEV_BROADCAST_HDR*) &dbi,
DEVICE_NOTIFY_WINDOW_HANDLE);
}
while (PeekMessageW(&msg, _glfw.win32.helperWindowHandle, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Returns a wide string version of the specified UTF-8 string
//
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source)
{
WCHAR* target;
int count;
count = MultiByteToWideChar(CP_UTF8, 0, source, -1, NULL, 0);
if (!count)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
return NULL;
}
target = _glfw_calloc(count, sizeof(WCHAR));
if (!MultiByteToWideChar(CP_UTF8, 0, source, -1, target, count))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string from UTF-8");
_glfw_free(target);
return NULL;
}
return target;
}
// Returns a UTF-8 string version of the specified wide string
//
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source)
{
char* target;
int size;
size = WideCharToMultiByte(CP_UTF8, 0, source, -1, NULL, 0, NULL, NULL);
if (!size)
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
return NULL;
}
target = _glfw_calloc(size, 1);
if (!WideCharToMultiByte(CP_UTF8, 0, source, -1, target, size, NULL, NULL))
{
_glfwInputErrorWin32(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert string to UTF-8");
_glfw_free(target);
return NULL;
}
return target;
}
// Reports the specified error, appending information about the last Win32 error
//
void _glfwInputErrorWin32(int error, const char* description)
{
WCHAR buffer[_GLFW_MESSAGE_SIZE] = L"";
char message[_GLFW_MESSAGE_SIZE] = "";
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL,
GetLastError() & 0xffff,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
buffer,
sizeof(buffer) / sizeof(WCHAR),
NULL);
WideCharToMultiByte(CP_UTF8, 0, buffer, -1, message, sizeof(message), NULL, NULL);
_glfwInputError(error, "%s: %s", description, message);
}
// Updates key names according to the current keyboard layout
//
void _glfwUpdateKeyNamesWin32(void)
{
int key;
BYTE state[256] = {0};
memset(_glfw.win32.keynames, 0, sizeof(_glfw.win32.keynames));
for (key = GLFW_KEY_SPACE; key <= GLFW_KEY_LAST; key++)
{
UINT vk;
int scancode, length;
WCHAR chars[16];
scancode = _glfw.win32.scancodes[key];
if (scancode == -1)
continue;
if (key >= GLFW_KEY_KP_0 && key <= GLFW_KEY_KP_ADD)
{
const UINT vks[] = {
VK_NUMPAD0, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3,
VK_NUMPAD4, VK_NUMPAD5, VK_NUMPAD6, VK_NUMPAD7,
VK_NUMPAD8, VK_NUMPAD9, VK_DECIMAL, VK_DIVIDE,
VK_MULTIPLY, VK_SUBTRACT, VK_ADD
};
vk = vks[key - GLFW_KEY_KP_0];
}
else
vk = MapVirtualKeyW(scancode, MAPVK_VSC_TO_VK);
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
if (length == -1)
{
// This is a dead key, so we need a second simulated key press
// to make it output its own character (usually a diacritic)
length = ToUnicode(vk, scancode, state,
chars, sizeof(chars) / sizeof(WCHAR),
0);
}
if (length < 1)
continue;
WideCharToMultiByte(CP_UTF8, 0, chars, 1,
_glfw.win32.keynames[key],
sizeof(_glfw.win32.keynames[key]),
NULL, NULL);
}
}
// Replacement for IsWindowsVersionOrGreater, as we cannot rely on the
// application having a correct embedded manifest
//
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, {0}, sp };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embed a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
// Checks whether we are on at least the specified build of Windows 10
//
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build)
{
OSVERSIONINFOEXW osvi = { sizeof(osvi), 10, 0, build };
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER;
ULONGLONG cond = VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
cond = VerSetConditionMask(cond, VER_BUILDNUMBER, VER_GREATER_EQUAL);
// HACK: Use RtlVerifyVersionInfo instead of VerifyVersionInfoW as the
// latter lies unless the user knew to embed a non-default manifest
// announcing support for Windows 10 via supportedOS GUID
return RtlVerifyVersionInfo(&osvi, mask, cond) == 0;
}
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform win32 =
{
.platformID = GLFW_PLATFORM_WIN32,
.init = _glfwInitWin32,
.terminate = _glfwTerminateWin32,
.getCursorPos = _glfwGetCursorPosWin32,
.setCursorPos = _glfwSetCursorPosWin32,
.setCursorMode = _glfwSetCursorModeWin32,
.setRawMouseMotion = _glfwSetRawMouseMotionWin32,
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedWin32,
.createCursor = _glfwCreateCursorWin32,
.createStandardCursor = _glfwCreateStandardCursorWin32,
.destroyCursor = _glfwDestroyCursorWin32,
.setCursor = _glfwSetCursorWin32,
.getScancodeName = _glfwGetScancodeNameWin32,
.getKeyScancode = _glfwGetKeyScancodeWin32,
.setClipboardString = _glfwSetClipboardStringWin32,
.getClipboardString = _glfwGetClipboardStringWin32,
.initJoysticks = _glfwInitJoysticksWin32,
.terminateJoysticks = _glfwTerminateJoysticksWin32,
.pollJoystick = _glfwPollJoystickWin32,
.getMappingName = _glfwGetMappingNameWin32,
.updateGamepadGUID = _glfwUpdateGamepadGUIDWin32,
.freeMonitor = _glfwFreeMonitorWin32,
.getMonitorPos = _glfwGetMonitorPosWin32,
.getMonitorContentScale = _glfwGetMonitorContentScaleWin32,
.getMonitorWorkarea = _glfwGetMonitorWorkareaWin32,
.getVideoModes = _glfwGetVideoModesWin32,
.getVideoMode = _glfwGetVideoModeWin32,
.getGammaRamp = _glfwGetGammaRampWin32,
.setGammaRamp = _glfwSetGammaRampWin32,
.createWindow = _glfwCreateWindowWin32,
.destroyWindow = _glfwDestroyWindowWin32,
.setWindowTitle = _glfwSetWindowTitleWin32,
.setWindowIcon = _glfwSetWindowIconWin32,
.getWindowPos = _glfwGetWindowPosWin32,
.setWindowPos = _glfwSetWindowPosWin32,
.getWindowSize = _glfwGetWindowSizeWin32,
.setWindowSize = _glfwSetWindowSizeWin32,
.setWindowSizeLimits = _glfwSetWindowSizeLimitsWin32,
.setWindowAspectRatio = _glfwSetWindowAspectRatioWin32,
.getFramebufferSize = _glfwGetFramebufferSizeWin32,
.getWindowFrameSize = _glfwGetWindowFrameSizeWin32,
.getWindowContentScale = _glfwGetWindowContentScaleWin32,
.iconifyWindow = _glfwIconifyWindowWin32,
.restoreWindow = _glfwRestoreWindowWin32,
.maximizeWindow = _glfwMaximizeWindowWin32,
.showWindow = _glfwShowWindowWin32,
.hideWindow = _glfwHideWindowWin32,
.requestWindowAttention = _glfwRequestWindowAttentionWin32,
.focusWindow = _glfwFocusWindowWin32,
.setWindowMonitor = _glfwSetWindowMonitorWin32,
.windowFocused = _glfwWindowFocusedWin32,
.windowIconified = _glfwWindowIconifiedWin32,
.windowVisible = _glfwWindowVisibleWin32,
.windowMaximized = _glfwWindowMaximizedWin32,
.windowHovered = _glfwWindowHoveredWin32,
.framebufferTransparent = _glfwFramebufferTransparentWin32,
.getWindowOpacity = _glfwGetWindowOpacityWin32,
.setWindowResizable = _glfwSetWindowResizableWin32,
.setWindowDecorated = _glfwSetWindowDecoratedWin32,
.setWindowFloating = _glfwSetWindowFloatingWin32,
.setWindowOpacity = _glfwSetWindowOpacityWin32,
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughWin32,
.pollEvents = _glfwPollEventsWin32,
.waitEvents = _glfwWaitEventsWin32,
.waitEventsTimeout = _glfwWaitEventsTimeoutWin32,
.postEmptyEvent = _glfwPostEmptyEventWin32,
.getEGLPlatform = _glfwGetEGLPlatformWin32,
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayWin32,
.getEGLNativeWindow = _glfwGetEGLNativeWindowWin32,
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsWin32,
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportWin32,
.createWindowSurface = _glfwCreateWindowSurfaceWin32
};
*platform = win32;
return GLFW_TRUE;
}
int _glfwInitWin32(void)
{
if (!loadLibraries())
return GLFW_FALSE;
createKeyTablesWin32();
_glfwUpdateKeyNamesWin32();
if (_glfwIsWindows10Version1703OrGreaterWin32())
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
else if (IsWindows8Point1OrGreater())
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
else if (IsWindowsVistaOrGreater())
SetProcessDPIAware();
if (!createHelperWindow())
return GLFW_FALSE;
_glfwPollMonitorsWin32();
return GLFW_TRUE;
}
void _glfwTerminateWin32(void)
{
if (_glfw.win32.blankCursor)
DestroyIcon((HICON) _glfw.win32.blankCursor);
if (_glfw.win32.deviceNotificationHandle)
UnregisterDeviceNotification(_glfw.win32.deviceNotificationHandle);
if (_glfw.win32.helperWindowHandle)
DestroyWindow(_glfw.win32.helperWindowHandle);
if (_glfw.win32.helperWindowClass)
UnregisterClassW(MAKEINTATOM(_glfw.win32.helperWindowClass), _glfw.win32.instance);
if (_glfw.win32.mainWindowClass)
UnregisterClassW(MAKEINTATOM(_glfw.win32.mainWindowClass), _glfw.win32.instance);
_glfw_free(_glfw.win32.clipboardString);
_glfw_free(_glfw.win32.rawInput);
_glfwTerminateWGL();
_glfwTerminateEGL();
_glfwTerminateOSMesa();
freeLibraries();
}
#endif // _GLFW_WIN32

View File

@@ -0,0 +1,767 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_WIN32)
#include <stdio.h>
#include <math.h>
#define _GLFW_TYPE_AXIS 0
#define _GLFW_TYPE_SLIDER 1
#define _GLFW_TYPE_BUTTON 2
#define _GLFW_TYPE_POV 3
// Data produced with DirectInput device object enumeration
//
typedef struct _GLFWobjenumWin32
{
IDirectInputDevice8W* device;
_GLFWjoyobjectWin32* objects;
int objectCount;
int axisCount;
int sliderCount;
int buttonCount;
int povCount;
} _GLFWobjenumWin32;
// Define local copies of the necessary GUIDs
//
static const GUID _glfw_IID_IDirectInput8W =
{0xbf798031,0x483a,0x4da2,{0xaa,0x99,0x5d,0x64,0xed,0x36,0x97,0x00}};
static const GUID _glfw_GUID_XAxis =
{0xa36d02e0,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_YAxis =
{0xa36d02e1,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_ZAxis =
{0xa36d02e2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RxAxis =
{0xa36d02f4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RyAxis =
{0xa36d02f5,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_RzAxis =
{0xa36d02e3,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_Slider =
{0xa36d02e4,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
static const GUID _glfw_GUID_POV =
{0xa36d02f2,0xc9f3,0x11cf,{0xbf,0xc7,0x44,0x45,0x53,0x54,0x00,0x00}};
#define IID_IDirectInput8W _glfw_IID_IDirectInput8W
#define GUID_XAxis _glfw_GUID_XAxis
#define GUID_YAxis _glfw_GUID_YAxis
#define GUID_ZAxis _glfw_GUID_ZAxis
#define GUID_RxAxis _glfw_GUID_RxAxis
#define GUID_RyAxis _glfw_GUID_RyAxis
#define GUID_RzAxis _glfw_GUID_RzAxis
#define GUID_Slider _glfw_GUID_Slider
#define GUID_POV _glfw_GUID_POV
// Object data array for our clone of c_dfDIJoystick
// Generated with https://github.com/elmindreda/c_dfDIJoystick2
//
static DIOBJECTDATAFORMAT _glfwObjectDataFormats[] =
{
{ &GUID_XAxis,DIJOFS_X,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_YAxis,DIJOFS_Y,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_ZAxis,DIJOFS_Z,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RxAxis,DIJOFS_RX,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RyAxis,DIJOFS_RY,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_RzAxis,DIJOFS_RZ,DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_AXIS|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,DIDOI_ASPECTPOSITION },
{ &GUID_POV,DIJOFS_POV(0),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(1),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(2),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ &GUID_POV,DIJOFS_POV(3),DIDFT_POV|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(0),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(1),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(2),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(3),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(4),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(5),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(6),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(7),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(8),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(9),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(10),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(11),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(12),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(13),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(14),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(15),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(16),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(17),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(18),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(19),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(20),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(21),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(22),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(23),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(24),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(25),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(26),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(27),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(28),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(29),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(30),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
{ NULL,DIJOFS_BUTTON(31),DIDFT_BUTTON|DIDFT_OPTIONAL|DIDFT_ANYINSTANCE,0 },
};
// Our clone of c_dfDIJoystick
//
static const DIDATAFORMAT _glfwDataFormat =
{
sizeof(DIDATAFORMAT),
sizeof(DIOBJECTDATAFORMAT),
DIDFT_ABSAXIS,
sizeof(DIJOYSTATE),
sizeof(_glfwObjectDataFormats) / sizeof(DIOBJECTDATAFORMAT),
_glfwObjectDataFormats
};
// Returns a description fitting the specified XInput capabilities
//
static const char* getDeviceDescription(const XINPUT_CAPABILITIES* xic)
{
switch (xic->SubType)
{
case XINPUT_DEVSUBTYPE_WHEEL:
return "XInput Wheel";
case XINPUT_DEVSUBTYPE_ARCADE_STICK:
return "XInput Arcade Stick";
case XINPUT_DEVSUBTYPE_FLIGHT_STICK:
return "XInput Flight Stick";
case XINPUT_DEVSUBTYPE_DANCE_PAD:
return "XInput Dance Pad";
case XINPUT_DEVSUBTYPE_GUITAR:
return "XInput Guitar";
case XINPUT_DEVSUBTYPE_DRUM_KIT:
return "XInput Drum Kit";
case XINPUT_DEVSUBTYPE_GAMEPAD:
{
if (xic->Flags & XINPUT_CAPS_WIRELESS)
return "Wireless Xbox Controller";
else
return "Xbox Controller";
}
}
return "Unknown XInput Device";
}
// Lexically compare device objects
//
static int compareJoystickObjects(const void* first, const void* second)
{
const _GLFWjoyobjectWin32* fo = first;
const _GLFWjoyobjectWin32* so = second;
if (fo->type != so->type)
return fo->type - so->type;
return fo->offset - so->offset;
}
// Checks whether the specified device supports XInput
// Technique from FDInputJoystickManager::IsXInputDeviceFast in ZDoom
//
static GLFWbool supportsXInput(const GUID* guid)
{
UINT i, count = 0;
RAWINPUTDEVICELIST* ridl;
GLFWbool result = GLFW_FALSE;
if (GetRawInputDeviceList(NULL, &count, sizeof(RAWINPUTDEVICELIST)) != 0)
return GLFW_FALSE;
ridl = _glfw_calloc(count, sizeof(RAWINPUTDEVICELIST));
if (GetRawInputDeviceList(ridl, &count, sizeof(RAWINPUTDEVICELIST)) == (UINT) -1)
{
_glfw_free(ridl);
return GLFW_FALSE;
}
for (i = 0; i < count; i++)
{
RID_DEVICE_INFO rdi;
char name[256];
UINT size;
if (ridl[i].dwType != RIM_TYPEHID)
continue;
ZeroMemory(&rdi, sizeof(rdi));
rdi.cbSize = sizeof(rdi);
size = sizeof(rdi);
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICEINFO,
&rdi, &size) == -1)
{
continue;
}
if (MAKELONG(rdi.hid.dwVendorId, rdi.hid.dwProductId) != (LONG) guid->Data1)
continue;
memset(name, 0, sizeof(name));
size = sizeof(name);
if ((INT) GetRawInputDeviceInfoA(ridl[i].hDevice,
RIDI_DEVICENAME,
name, &size) == -1)
{
break;
}
name[sizeof(name) - 1] = '\0';
if (strstr(name, "IG_"))
{
result = GLFW_TRUE;
break;
}
}
_glfw_free(ridl);
return result;
}
// Frees all resources associated with the specified joystick
//
static void closeJoystick(_GLFWjoystick* js)
{
_glfwInputJoystick(js, GLFW_DISCONNECTED);
if (js->win32.device)
{
IDirectInputDevice8_Unacquire(js->win32.device);
IDirectInputDevice8_Release(js->win32.device);
}
_glfw_free(js->win32.objects);
_glfwFreeJoystick(js);
}
// DirectInput device object enumeration callback
// Insights gleaned from SDL
//
static BOOL CALLBACK deviceObjectCallback(const DIDEVICEOBJECTINSTANCEW* doi,
void* user)
{
_GLFWobjenumWin32* data = user;
_GLFWjoyobjectWin32* object = data->objects + data->objectCount;
if (DIDFT_GETTYPE(doi->dwType) & DIDFT_AXIS)
{
DIPROPRANGE dipr;
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
object->offset = DIJOFS_SLIDER(data->sliderCount);
else if (memcmp(&doi->guidType, &GUID_XAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_X;
else if (memcmp(&doi->guidType, &GUID_YAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Y;
else if (memcmp(&doi->guidType, &GUID_ZAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_Z;
else if (memcmp(&doi->guidType, &GUID_RxAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RX;
else if (memcmp(&doi->guidType, &GUID_RyAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RY;
else if (memcmp(&doi->guidType, &GUID_RzAxis, sizeof(GUID)) == 0)
object->offset = DIJOFS_RZ;
else
return DIENUM_CONTINUE;
ZeroMemory(&dipr, sizeof(dipr));
dipr.diph.dwSize = sizeof(dipr);
dipr.diph.dwHeaderSize = sizeof(dipr.diph);
dipr.diph.dwObj = doi->dwType;
dipr.diph.dwHow = DIPH_BYID;
dipr.lMin = -32768;
dipr.lMax = 32767;
if (FAILED(IDirectInputDevice8_SetProperty(data->device,
DIPROP_RANGE,
&dipr.diph)))
{
return DIENUM_CONTINUE;
}
if (memcmp(&doi->guidType, &GUID_Slider, sizeof(GUID)) == 0)
{
object->type = _GLFW_TYPE_SLIDER;
data->sliderCount++;
}
else
{
object->type = _GLFW_TYPE_AXIS;
data->axisCount++;
}
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_BUTTON)
{
object->offset = DIJOFS_BUTTON(data->buttonCount);
object->type = _GLFW_TYPE_BUTTON;
data->buttonCount++;
}
else if (DIDFT_GETTYPE(doi->dwType) & DIDFT_POV)
{
object->offset = DIJOFS_POV(data->povCount);
object->type = _GLFW_TYPE_POV;
data->povCount++;
}
data->objectCount++;
return DIENUM_CONTINUE;
}
// DirectInput device enumeration callback
//
static BOOL CALLBACK deviceCallback(const DIDEVICEINSTANCE* di, void* user)
{
int jid = 0;
DIDEVCAPS dc;
DIPROPDWORD dipd;
IDirectInputDevice8* device;
_GLFWobjenumWin32 data;
_GLFWjoystick* js;
char guid[33];
char name[256];
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
js = _glfw.joysticks + jid;
if (js->connected)
{
if (memcmp(&js->win32.guid, &di->guidInstance, sizeof(GUID)) == 0)
return DIENUM_CONTINUE;
}
}
if (supportsXInput(&di->guidProduct))
return DIENUM_CONTINUE;
if (FAILED(IDirectInput8_CreateDevice(_glfw.win32.dinput8.api,
&di->guidInstance,
&device,
NULL)))
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to create device");
return DIENUM_CONTINUE;
}
if (FAILED(IDirectInputDevice8_SetDataFormat(device, &_glfwDataFormat)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set device data format");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dc, sizeof(dc));
dc.dwSize = sizeof(dc);
if (FAILED(IDirectInputDevice8_GetCapabilities(device, &dc)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to query device capabilities");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
ZeroMemory(&dipd, sizeof(dipd));
dipd.diph.dwSize = sizeof(dipd);
dipd.diph.dwHeaderSize = sizeof(dipd.diph);
dipd.diph.dwHow = DIPH_DEVICE;
dipd.dwData = DIPROPAXISMODE_ABS;
if (FAILED(IDirectInputDevice8_SetProperty(device,
DIPROP_AXISMODE,
&dipd.diph)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set device axis mode");
IDirectInputDevice8_Release(device);
return DIENUM_CONTINUE;
}
memset(&data, 0, sizeof(data));
data.device = device;
data.objects = _glfw_calloc(dc.dwAxes + (size_t) dc.dwButtons + dc.dwPOVs,
sizeof(_GLFWjoyobjectWin32));
if (FAILED(IDirectInputDevice8_EnumObjects(device,
deviceObjectCallback,
&data,
DIDFT_AXIS | DIDFT_BUTTON | DIDFT_POV)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to enumerate device objects");
IDirectInputDevice8_Release(device);
_glfw_free(data.objects);
return DIENUM_CONTINUE;
}
qsort(data.objects, data.objectCount,
sizeof(_GLFWjoyobjectWin32),
compareJoystickObjects);
if (!WideCharToMultiByte(CP_UTF8, 0,
di->tszInstanceName, -1,
name, sizeof(name),
NULL, NULL))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to convert joystick name to UTF-8");
IDirectInputDevice8_Release(device);
_glfw_free(data.objects);
return DIENUM_STOP;
}
// Generate a joystick GUID that matches the SDL 2.0.5+ one
if (memcmp(&di->guidProduct.Data4[2], "PIDVID", 6) == 0)
{
sprintf(guid, "03000000%02x%02x0000%02x%02x000000000000",
(uint8_t) di->guidProduct.Data1,
(uint8_t) (di->guidProduct.Data1 >> 8),
(uint8_t) (di->guidProduct.Data1 >> 16),
(uint8_t) (di->guidProduct.Data1 >> 24));
}
else
{
sprintf(guid, "05000000%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x00",
name[0], name[1], name[2], name[3],
name[4], name[5], name[6], name[7],
name[8], name[9], name[10]);
}
js = _glfwAllocJoystick(name, guid,
data.axisCount + data.sliderCount,
data.buttonCount,
data.povCount);
if (!js)
{
IDirectInputDevice8_Release(device);
_glfw_free(data.objects);
return DIENUM_STOP;
}
js->win32.device = device;
js->win32.guid = di->guidInstance;
js->win32.objects = data.objects;
js->win32.objectCount = data.objectCount;
_glfwInputJoystick(js, GLFW_CONNECTED);
return DIENUM_CONTINUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Checks for new joysticks after DBT_DEVICEARRIVAL
//
void _glfwDetectJoystickConnectionWin32(void)
{
if (_glfw.win32.xinput.instance)
{
DWORD index;
for (index = 0; index < XUSER_MAX_COUNT; index++)
{
int jid;
char guid[33];
XINPUT_CAPABILITIES xic;
_GLFWjoystick* js;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
if (_glfw.joysticks[jid].connected &&
_glfw.joysticks[jid].win32.device == NULL &&
_glfw.joysticks[jid].win32.index == index)
{
break;
}
}
if (jid <= GLFW_JOYSTICK_LAST)
continue;
if (XInputGetCapabilities(index, 0, &xic) != ERROR_SUCCESS)
continue;
// Generate a joystick GUID that matches the SDL 2.0.5+ one
sprintf(guid, "78696e707574%02x000000000000000000",
xic.SubType & 0xff);
js = _glfwAllocJoystick(getDeviceDescription(&xic), guid, 6, 10, 1);
if (!js)
continue;
js->win32.index = index;
_glfwInputJoystick(js, GLFW_CONNECTED);
}
}
if (_glfw.win32.dinput8.api)
{
if (FAILED(IDirectInput8_EnumDevices(_glfw.win32.dinput8.api,
DI8DEVCLASS_GAMECTRL,
deviceCallback,
NULL,
DIEDFL_ALLDEVICES)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Failed to enumerate DirectInput8 devices");
return;
}
}
}
// Checks for joystick disconnection after DBT_DEVICEREMOVECOMPLETE
//
void _glfwDetectJoystickDisconnectionWin32(void)
{
int jid;
for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
{
_GLFWjoystick* js = _glfw.joysticks + jid;
if (js->connected)
_glfwPollJoystickWin32(js, _GLFW_POLL_PRESENCE);
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksWin32(void)
{
if (_glfw.win32.dinput8.instance)
{
if (FAILED(DirectInput8Create(_glfw.win32.instance,
DIRECTINPUT_VERSION,
&IID_IDirectInput8W,
(void**) &_glfw.win32.dinput8.api,
NULL)))
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to create interface");
return GLFW_FALSE;
}
}
_glfwDetectJoystickConnectionWin32();
return GLFW_TRUE;
}
void _glfwTerminateJoysticksWin32(void)
{
int jid;
for (jid = GLFW_JOYSTICK_1; jid <= GLFW_JOYSTICK_LAST; jid++)
closeJoystick(_glfw.joysticks + jid);
if (_glfw.win32.dinput8.api)
IDirectInput8_Release(_glfw.win32.dinput8.api);
}
GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode)
{
if (js->win32.device)
{
int i, ai = 0, bi = 0, pi = 0;
HRESULT result;
DIJOYSTATE state = {0};
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
if (result == DIERR_NOTACQUIRED || result == DIERR_INPUTLOST)
{
IDirectInputDevice8_Acquire(js->win32.device);
IDirectInputDevice8_Poll(js->win32.device);
result = IDirectInputDevice8_GetDeviceState(js->win32.device,
sizeof(state),
&state);
}
if (FAILED(result))
{
closeJoystick(js);
return GLFW_FALSE;
}
if (mode == _GLFW_POLL_PRESENCE)
return GLFW_TRUE;
for (i = 0; i < js->win32.objectCount; i++)
{
const void* data = (char*) &state + js->win32.objects[i].offset;
switch (js->win32.objects[i].type)
{
case _GLFW_TYPE_AXIS:
case _GLFW_TYPE_SLIDER:
{
const float value = (*((LONG*) data) + 0.5f) / 32767.5f;
_glfwInputJoystickAxis(js, ai, value);
ai++;
break;
}
case _GLFW_TYPE_BUTTON:
{
const char value = (*((BYTE*) data) & 0x80) != 0;
_glfwInputJoystickButton(js, bi, value);
bi++;
break;
}
case _GLFW_TYPE_POV:
{
const int states[9] =
{
GLFW_HAT_UP,
GLFW_HAT_RIGHT_UP,
GLFW_HAT_RIGHT,
GLFW_HAT_RIGHT_DOWN,
GLFW_HAT_DOWN,
GLFW_HAT_LEFT_DOWN,
GLFW_HAT_LEFT,
GLFW_HAT_LEFT_UP,
GLFW_HAT_CENTERED
};
// Screams of horror are appropriate at this point
int stateIndex = LOWORD(*(DWORD*) data) / (45 * DI_DEGREES);
if (stateIndex < 0 || stateIndex > 8)
stateIndex = 8;
_glfwInputJoystickHat(js, pi, states[stateIndex]);
pi++;
break;
}
}
}
}
else
{
int i, dpad = 0;
DWORD result;
XINPUT_STATE xis;
const WORD buttons[10] =
{
XINPUT_GAMEPAD_A,
XINPUT_GAMEPAD_B,
XINPUT_GAMEPAD_X,
XINPUT_GAMEPAD_Y,
XINPUT_GAMEPAD_LEFT_SHOULDER,
XINPUT_GAMEPAD_RIGHT_SHOULDER,
XINPUT_GAMEPAD_BACK,
XINPUT_GAMEPAD_START,
XINPUT_GAMEPAD_LEFT_THUMB,
XINPUT_GAMEPAD_RIGHT_THUMB
};
result = XInputGetState(js->win32.index, &xis);
if (result != ERROR_SUCCESS)
{
if (result == ERROR_DEVICE_NOT_CONNECTED)
closeJoystick(js);
return GLFW_FALSE;
}
if (mode == _GLFW_POLL_PRESENCE)
return GLFW_TRUE;
_glfwInputJoystickAxis(js, 0, (xis.Gamepad.sThumbLX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 1, -(xis.Gamepad.sThumbLY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 2, (xis.Gamepad.sThumbRX + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 3, -(xis.Gamepad.sThumbRY + 0.5f) / 32767.5f);
_glfwInputJoystickAxis(js, 4, xis.Gamepad.bLeftTrigger / 127.5f - 1.f);
_glfwInputJoystickAxis(js, 5, xis.Gamepad.bRightTrigger / 127.5f - 1.f);
for (i = 0; i < 10; i++)
{
const char value = (xis.Gamepad.wButtons & buttons[i]) ? 1 : 0;
_glfwInputJoystickButton(js, i, value);
}
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_UP)
dpad |= GLFW_HAT_UP;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT)
dpad |= GLFW_HAT_RIGHT;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_DOWN)
dpad |= GLFW_HAT_DOWN;
if (xis.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT)
dpad |= GLFW_HAT_LEFT;
// Treat invalid combinations as neither being pressed
// while preserving what data can be preserved
if ((dpad & GLFW_HAT_RIGHT) && (dpad & GLFW_HAT_LEFT))
dpad &= ~(GLFW_HAT_RIGHT | GLFW_HAT_LEFT);
if ((dpad & GLFW_HAT_UP) && (dpad & GLFW_HAT_DOWN))
dpad &= ~(GLFW_HAT_UP | GLFW_HAT_DOWN);
_glfwInputJoystickHat(js, 0, dpad);
}
return GLFW_TRUE;
}
const char* _glfwGetMappingNameWin32(void)
{
return "Windows";
}
void _glfwUpdateGamepadGUIDWin32(char* guid)
{
if (strcmp(guid + 20, "504944564944") == 0)
{
char original[33];
strncpy(original, guid, sizeof(original) - 1);
sprintf(guid, "03000000%.4s0000%.4s000000000000",
original, original + 4);
}
}
#endif // _GLFW_WIN32

View File

@@ -0,0 +1,51 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_WIN32_JOYSTICK_STATE _GLFWjoystickWin32 win32;
#define GLFW_WIN32_LIBRARY_JOYSTICK_STATE
// Joystick element (axis, button or slider)
//
typedef struct _GLFWjoyobjectWin32
{
int offset;
int type;
} _GLFWjoyobjectWin32;
// Win32-specific per-joystick data
//
typedef struct _GLFWjoystickWin32
{
_GLFWjoyobjectWin32* objects;
int objectCount;
IDirectInputDevice8W* device;
DWORD index;
GUID guid;
} _GLFWjoystickWin32;
void _glfwDetectJoystickConnectionWin32(void);
void _glfwDetectJoystickDisconnectionWin32(void);

51
raylib/external/glfw/src/win32_module.c vendored Normal file
View File

@@ -0,0 +1,51 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2021 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_WIN32_MODULE)
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return LoadLibraryA(path);
}
void _glfwPlatformFreeModule(void* module)
{
FreeLibrary((HMODULE) module);
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return (GLFWproc) GetProcAddress((HMODULE) module, name);
}
#endif // GLFW_BUILD_WIN32_MODULE

569
raylib/external/glfw/src/win32_monitor.c vendored Normal file
View File

@@ -0,0 +1,569 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_WIN32)
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <wchar.h>
// Callback for EnumDisplayMonitors in createMonitor
//
static BOOL CALLBACK monitorCallback(HMONITOR handle,
HDC dc,
RECT* rect,
LPARAM data)
{
MONITORINFOEXW mi;
ZeroMemory(&mi, sizeof(mi));
mi.cbSize = sizeof(mi);
if (GetMonitorInfoW(handle, (MONITORINFO*) &mi))
{
_GLFWmonitor* monitor = (_GLFWmonitor*) data;
if (wcscmp(mi.szDevice, monitor->win32.adapterName) == 0)
monitor->win32.handle = handle;
}
return TRUE;
}
// Create monitor from an adapter and (optionally) a display
//
static _GLFWmonitor* createMonitor(DISPLAY_DEVICEW* adapter,
DISPLAY_DEVICEW* display)
{
_GLFWmonitor* monitor;
int widthMM, heightMM;
char* name;
HDC dc;
DEVMODEW dm;
RECT rect;
if (display)
name = _glfwCreateUTF8FromWideStringWin32(display->DeviceString);
else
name = _glfwCreateUTF8FromWideStringWin32(adapter->DeviceString);
if (!name)
return NULL;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsW(adapter->DeviceName, ENUM_CURRENT_SETTINGS, &dm);
dc = CreateDCW(L"DISPLAY", adapter->DeviceName, NULL, NULL);
if (IsWindows8Point1OrGreater())
{
widthMM = GetDeviceCaps(dc, HORZSIZE);
heightMM = GetDeviceCaps(dc, VERTSIZE);
}
else
{
widthMM = (int) (dm.dmPelsWidth * 25.4f / GetDeviceCaps(dc, LOGPIXELSX));
heightMM = (int) (dm.dmPelsHeight * 25.4f / GetDeviceCaps(dc, LOGPIXELSY));
}
DeleteDC(dc);
monitor = _glfwAllocMonitor(name, widthMM, heightMM);
_glfw_free(name);
if (adapter->StateFlags & DISPLAY_DEVICE_MODESPRUNED)
monitor->win32.modesPruned = GLFW_TRUE;
wcscpy(monitor->win32.adapterName, adapter->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
adapter->DeviceName, -1,
monitor->win32.publicAdapterName,
sizeof(monitor->win32.publicAdapterName),
NULL, NULL);
if (display)
{
wcscpy(monitor->win32.displayName, display->DeviceName);
WideCharToMultiByte(CP_UTF8, 0,
display->DeviceName, -1,
monitor->win32.publicDisplayName,
sizeof(monitor->win32.publicDisplayName),
NULL, NULL);
}
rect.left = dm.dmPosition.x;
rect.top = dm.dmPosition.y;
rect.right = dm.dmPosition.x + dm.dmPelsWidth;
rect.bottom = dm.dmPosition.y + dm.dmPelsHeight;
EnumDisplayMonitors(NULL, &rect, monitorCallback, (LPARAM) monitor);
return monitor;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsWin32(void)
{
int i, disconnectedCount;
_GLFWmonitor** disconnected = NULL;
DWORD adapterIndex, displayIndex;
DISPLAY_DEVICEW adapter, display;
_GLFWmonitor* monitor;
disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (adapterIndex = 0; ; adapterIndex++)
{
int type = _GLFW_INSERT_LAST;
ZeroMemory(&adapter, sizeof(adapter));
adapter.cb = sizeof(adapter);
if (!EnumDisplayDevicesW(NULL, adapterIndex, &adapter, 0))
break;
if (!(adapter.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
if (adapter.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
type = _GLFW_INSERT_FIRST;
for (displayIndex = 0; ; displayIndex++)
{
ZeroMemory(&display, sizeof(display));
display.cb = sizeof(display);
if (!EnumDisplayDevicesW(adapter.DeviceName, displayIndex, &display, 0))
break;
if (!(display.StateFlags & DISPLAY_DEVICE_ACTIVE))
continue;
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.displayName,
display.DeviceName) == 0)
{
disconnected[i] = NULL;
// handle may have changed, update
EnumDisplayMonitors(NULL, NULL, monitorCallback, (LPARAM) _glfw.monitors[i]);
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, &display);
if (!monitor)
{
_glfw_free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
type = _GLFW_INSERT_LAST;
}
// HACK: If an active adapter does not have any display devices
// (as sometimes happens), add it directly as a monitor
if (displayIndex == 0)
{
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i] &&
wcscmp(disconnected[i]->win32.adapterName,
adapter.DeviceName) == 0)
{
disconnected[i] = NULL;
break;
}
}
if (i < disconnectedCount)
continue;
monitor = createMonitor(&adapter, NULL);
if (!monitor)
{
_glfw_free(disconnected);
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
}
}
for (i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
_glfw_free(disconnected);
}
// Change the current video mode
//
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
GLFWvidmode current;
const GLFWvidmode* best;
DEVMODEW dm;
LONG result;
best = _glfwChooseVideoMode(monitor, desired);
_glfwGetVideoModeWin32(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL |
DM_DISPLAYFREQUENCY;
dm.dmPelsWidth = best->width;
dm.dmPelsHeight = best->height;
dm.dmBitsPerPel = best->redBits + best->greenBits + best->blueBits;
dm.dmDisplayFrequency = best->refreshRate;
if (dm.dmBitsPerPel < 15 || dm.dmBitsPerPel >= 24)
dm.dmBitsPerPel = 32;
result = ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_FULLSCREEN,
NULL);
if (result == DISP_CHANGE_SUCCESSFUL)
monitor->win32.modeChanged = GLFW_TRUE;
else
{
const char* description = "Unknown error";
if (result == DISP_CHANGE_BADDUALVIEW)
description = "The system uses DualView";
else if (result == DISP_CHANGE_BADFLAGS)
description = "Invalid flags";
else if (result == DISP_CHANGE_BADMODE)
description = "Graphics mode not supported";
else if (result == DISP_CHANGE_BADPARAM)
description = "Invalid parameter";
else if (result == DISP_CHANGE_FAILED)
description = "Graphics mode failed";
else if (result == DISP_CHANGE_NOTUPDATED)
description = "Failed to write to registry";
else if (result == DISP_CHANGE_RESTART)
description = "Computer restart required";
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to set video mode: %s",
description);
}
}
// Restore the previously saved (original) video mode
//
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor)
{
if (monitor->win32.modeChanged)
{
ChangeDisplaySettingsExW(monitor->win32.adapterName,
NULL, NULL, CDS_FULLSCREEN, NULL);
monitor->win32.modeChanged = GLFW_FALSE;
}
}
void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale)
{
UINT xdpi, ydpi;
if (xscale)
*xscale = 0.f;
if (yscale)
*yscale = 0.f;
if (IsWindows8Point1OrGreater())
{
if (GetDpiForMonitor(handle, MDT_EFFECTIVE_DPI, &xdpi, &ydpi) != S_OK)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query monitor DPI");
return;
}
}
else
{
const HDC dc = GetDC(NULL);
xdpi = GetDeviceCaps(dc, LOGPIXELSX);
ydpi = GetDeviceCaps(dc, LOGPIXELSY);
ReleaseDC(NULL, dc);
}
if (xscale)
*xscale = xdpi / (float) USER_DEFAULT_SCREEN_DPI;
if (yscale)
*yscale = ydpi / (float) USER_DEFAULT_SCREEN_DPI;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorWin32(_GLFWmonitor* monitor)
{
}
void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
EnumDisplaySettingsExW(monitor->win32.adapterName,
ENUM_CURRENT_SETTINGS,
&dm,
EDS_ROTATEDMODE);
if (xpos)
*xpos = dm.dmPosition.x;
if (ypos)
*ypos = dm.dmPosition.y;
}
void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
_glfwGetHMONITORContentScaleWin32(monitor->win32.handle, xscale, yscale);
}
void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
MONITORINFO mi = { sizeof(mi) };
GetMonitorInfoW(monitor->win32.handle, &mi);
if (xpos)
*xpos = mi.rcWork.left;
if (ypos)
*ypos = mi.rcWork.top;
if (width)
*width = mi.rcWork.right - mi.rcWork.left;
if (height)
*height = mi.rcWork.bottom - mi.rcWork.top;
}
GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count)
{
int modeIndex = 0, size = 0;
GLFWvidmode* result = NULL;
*count = 0;
for (;;)
{
int i;
GLFWvidmode mode;
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, modeIndex, &dm))
break;
modeIndex++;
// Skip modes with less than 15 BPP
if (dm.dmBitsPerPel < 15)
continue;
mode.width = dm.dmPelsWidth;
mode.height = dm.dmPelsHeight;
mode.refreshRate = dm.dmDisplayFrequency;
_glfwSplitBPP(dm.dmBitsPerPel,
&mode.redBits,
&mode.greenBits,
&mode.blueBits);
for (i = 0; i < *count; i++)
{
if (_glfwCompareVideoModes(result + i, &mode) == 0)
break;
}
// Skip duplicate modes
if (i < *count)
continue;
if (monitor->win32.modesPruned)
{
// Skip modes not supported by the connected displays
if (ChangeDisplaySettingsExW(monitor->win32.adapterName,
&dm,
NULL,
CDS_TEST,
NULL) != DISP_CHANGE_SUCCESSFUL)
{
continue;
}
}
if (*count == size)
{
size += 128;
result = (GLFWvidmode*) _glfw_realloc(result, size * sizeof(GLFWvidmode));
}
(*count)++;
result[*count - 1] = mode;
}
if (!*count)
{
// HACK: Report the current mode if no valid modes were found
result = _glfw_calloc(1, sizeof(GLFWvidmode));
_glfwGetVideoModeWin32(monitor, result);
*count = 1;
}
return result;
}
GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
DEVMODEW dm;
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (!EnumDisplaySettingsW(monitor->win32.adapterName, ENUM_CURRENT_SETTINGS, &dm))
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to query display settings");
return GLFW_FALSE;
}
mode->width = dm.dmPelsWidth;
mode->height = dm.dmPelsHeight;
mode->refreshRate = dm.dmDisplayFrequency;
_glfwSplitBPP(dm.dmBitsPerPel,
&mode->redBits,
&mode->greenBits,
&mode->blueBits);
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
HDC dc;
WORD values[3][256];
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
GetDeviceGammaRamp(dc, values);
DeleteDC(dc);
_glfwAllocGammaArrays(ramp, 256);
memcpy(ramp->red, values[0], sizeof(values[0]));
memcpy(ramp->green, values[1], sizeof(values[1]));
memcpy(ramp->blue, values[2], sizeof(values[2]));
return GLFW_TRUE;
}
void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
HDC dc;
WORD values[3][256];
if (ramp->size != 256)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Gamma ramp size must be 256");
return;
}
memcpy(values[0], ramp->red, sizeof(values[0]));
memcpy(values[1], ramp->green, sizeof(values[1]));
memcpy(values[2], ramp->blue, sizeof(values[2]));
dc = CreateDCW(L"DISPLAY", monitor->win32.adapterName, NULL, NULL);
SetDeviceGammaRamp(dc, values);
DeleteDC(dc);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");
return NULL;
}
return monitor->win32.publicAdapterName;
}
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WIN32)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Win32: Platform not initialized");
return NULL;
}
return monitor->win32.publicDisplayName;
}
#endif // _GLFW_WIN32

View File

@@ -0,0 +1,627 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// We don't need all the fancy stuff
#ifndef NOMINMAX
#define NOMINMAX
#endif
#ifndef VC_EXTRALEAN
#define VC_EXTRALEAN
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does
#undef APIENTRY
// GLFW on Windows is Unicode only and does not work in MBCS mode
#ifndef UNICODE
#define UNICODE
#endif
// GLFW requires Windows XP or later
#if WINVER < 0x0501
#undef WINVER
#define WINVER 0x0501
#endif
#if _WIN32_WINNT < 0x0501
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
// GLFW uses DirectInput8 interfaces
#define DIRECTINPUT_VERSION 0x0800
// GLFW uses OEM cursor resources
#define OEMRESOURCE
#include <wctype.h>
#include <windows.h>
#include <dinput.h>
#include <xinput.h>
#include <dbt.h>
// HACK: Define macros that some windows.h variants don't
#ifndef WM_MOUSEHWHEEL
#define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WM_DWMCOMPOSITIONCHANGED
#define WM_DWMCOMPOSITIONCHANGED 0x031E
#endif
#ifndef WM_DWMCOLORIZATIONCOLORCHANGED
#define WM_DWMCOLORIZATIONCOLORCHANGED 0x0320
#endif
#ifndef WM_COPYGLOBALDATA
#define WM_COPYGLOBALDATA 0x0049
#endif
#ifndef WM_UNICHAR
#define WM_UNICHAR 0x0109
#endif
#ifndef UNICODE_NOCHAR
#define UNICODE_NOCHAR 0xFFFF
#endif
#ifndef WM_DPICHANGED
#define WM_DPICHANGED 0x02E0
#endif
#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(w) (HIWORD(w))
#endif
#ifndef EDS_ROTATEDMODE
#define EDS_ROTATEDMODE 0x00000004
#endif
#ifndef DISPLAY_DEVICE_ACTIVE
#define DISPLAY_DEVICE_ACTIVE 0x00000001
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0603
#endif
#ifndef _WIN32_WINNT_WIN8
#define _WIN32_WINNT_WIN8 0x0602
#endif
#ifndef WM_GETDPISCALEDSIZE
#define WM_GETDPISCALEDSIZE 0x02e4
#endif
#ifndef USER_DEFAULT_SCREEN_DPI
#define USER_DEFAULT_SCREEN_DPI 96
#endif
#ifndef OCR_HAND
#define OCR_HAND 32649
#endif
#if WINVER < 0x0601
typedef struct
{
DWORD cbSize;
DWORD ExtStatus;
} CHANGEFILTERSTRUCT;
#ifndef MSGFLT_ALLOW
#define MSGFLT_ALLOW 1
#endif
#endif /*Windows 7*/
#if WINVER < 0x0600
#define DWM_BB_ENABLE 0x00000001
#define DWM_BB_BLURREGION 0x00000002
typedef struct
{
DWORD dwFlags;
BOOL fEnable;
HRGN hRgnBlur;
BOOL fTransitionOnMaximized;
} DWM_BLURBEHIND;
#else
#include <dwmapi.h>
#endif /*Windows Vista*/
#ifndef DPI_ENUMS_DECLARED
typedef enum
{
PROCESS_DPI_UNAWARE = 0,
PROCESS_SYSTEM_DPI_AWARE = 1,
PROCESS_PER_MONITOR_DPI_AWARE = 2
} PROCESS_DPI_AWARENESS;
typedef enum
{
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
#endif /*DPI_ENUMS_DECLARED*/
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 ((HANDLE) -4)
#endif /*DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2*/
// Replacement for versionhelpers.h macros, as we cannot rely on the
// application having a correct embedded manifest
//
#define IsWindowsVistaOrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_VISTA), \
LOBYTE(_WIN32_WINNT_VISTA), 0)
#define IsWindows7OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN7), \
LOBYTE(_WIN32_WINNT_WIN7), 0)
#define IsWindows8OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WIN8), \
LOBYTE(_WIN32_WINNT_WIN8), 0)
#define IsWindows8Point1OrGreater() \
_glfwIsWindowsVersionOrGreaterWin32(HIBYTE(_WIN32_WINNT_WINBLUE), \
LOBYTE(_WIN32_WINNT_WINBLUE), 0)
// Windows 10 Anniversary Update
#define _glfwIsWindows10Version1607OrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(14393)
// Windows 10 Creators Update
#define _glfwIsWindows10Version1703OrGreaterWin32() \
_glfwIsWindows10BuildOrGreaterWin32(15063)
// HACK: Define macros that some xinput.h variants don't
#ifndef XINPUT_CAPS_WIRELESS
#define XINPUT_CAPS_WIRELESS 0x0002
#endif
#ifndef XINPUT_DEVSUBTYPE_WHEEL
#define XINPUT_DEVSUBTYPE_WHEEL 0x02
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_STICK
#define XINPUT_DEVSUBTYPE_ARCADE_STICK 0x03
#endif
#ifndef XINPUT_DEVSUBTYPE_FLIGHT_STICK
#define XINPUT_DEVSUBTYPE_FLIGHT_STICK 0x04
#endif
#ifndef XINPUT_DEVSUBTYPE_DANCE_PAD
#define XINPUT_DEVSUBTYPE_DANCE_PAD 0x05
#endif
#ifndef XINPUT_DEVSUBTYPE_GUITAR
#define XINPUT_DEVSUBTYPE_GUITAR 0x06
#endif
#ifndef XINPUT_DEVSUBTYPE_DRUM_KIT
#define XINPUT_DEVSUBTYPE_DRUM_KIT 0x08
#endif
#ifndef XINPUT_DEVSUBTYPE_ARCADE_PAD
#define XINPUT_DEVSUBTYPE_ARCADE_PAD 0x13
#endif
#ifndef XUSER_MAX_COUNT
#define XUSER_MAX_COUNT 4
#endif
// HACK: Define macros that some dinput.h variants don't
#ifndef DIDFT_OPTIONAL
#define DIDFT_OPTIONAL 0x80000000
#endif
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_PIXEL_TYPE_ARB 0x2013
#define WGL_TYPE_RGBA_ARB 0x202b
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_NO_ACCELERATION_ARB 0x2025
#define WGL_RED_BITS_ARB 0x2015
#define WGL_RED_SHIFT_ARB 0x2016
#define WGL_GREEN_BITS_ARB 0x2017
#define WGL_GREEN_SHIFT_ARB 0x2018
#define WGL_BLUE_BITS_ARB 0x2019
#define WGL_BLUE_SHIFT_ARB 0x201a
#define WGL_ALPHA_BITS_ARB 0x201b
#define WGL_ALPHA_SHIFT_ARB 0x201c
#define WGL_ACCUM_BITS_ARB 0x201d
#define WGL_ACCUM_RED_BITS_ARB 0x201e
#define WGL_ACCUM_GREEN_BITS_ARB 0x201f
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_AUX_BUFFERS_ARB 0x2024
#define WGL_STEREO_ARB 0x2012
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_SAMPLES_ARB 0x2042
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20a9
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_FLAGS_ARB 0x2094
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
#define WGL_CONTEXT_OPENGL_NO_ERROR_ARB 0x31b3
#define WGL_COLORSPACE_EXT 0x309d
#define WGL_COLORSPACE_SRGB_EXT 0x3089
#define ERROR_INVALID_VERSION_ARB 0x2095
#define ERROR_INVALID_PROFILE_ARB 0x2096
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
// xinput.dll function pointer typedefs
typedef DWORD (WINAPI * PFN_XInputGetCapabilities)(DWORD,DWORD,XINPUT_CAPABILITIES*);
typedef DWORD (WINAPI * PFN_XInputGetState)(DWORD,XINPUT_STATE*);
#define XInputGetCapabilities _glfw.win32.xinput.GetCapabilities
#define XInputGetState _glfw.win32.xinput.GetState
// dinput8.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DirectInput8Create)(HINSTANCE,DWORD,REFIID,LPVOID*,LPUNKNOWN);
#define DirectInput8Create _glfw.win32.dinput8.Create
// user32.dll function pointer typedefs
typedef BOOL (WINAPI * PFN_SetProcessDPIAware)(void);
typedef BOOL (WINAPI * PFN_ChangeWindowMessageFilterEx)(HWND,UINT,DWORD,CHANGEFILTERSTRUCT*);
typedef BOOL (WINAPI * PFN_EnableNonClientDpiScaling)(HWND);
typedef BOOL (WINAPI * PFN_SetProcessDpiAwarenessContext)(HANDLE);
typedef UINT (WINAPI * PFN_GetDpiForWindow)(HWND);
typedef BOOL (WINAPI * PFN_AdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
typedef int (WINAPI * PFN_GetSystemMetricsForDpi)(int,UINT);
#define SetProcessDPIAware _glfw.win32.user32.SetProcessDPIAware_
#define ChangeWindowMessageFilterEx _glfw.win32.user32.ChangeWindowMessageFilterEx_
#define EnableNonClientDpiScaling _glfw.win32.user32.EnableNonClientDpiScaling_
#define SetProcessDpiAwarenessContext _glfw.win32.user32.SetProcessDpiAwarenessContext_
#define GetDpiForWindow _glfw.win32.user32.GetDpiForWindow_
#define AdjustWindowRectExForDpi _glfw.win32.user32.AdjustWindowRectExForDpi_
#define GetSystemMetricsForDpi _glfw.win32.user32.GetSystemMetricsForDpi_
// dwmapi.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_DwmIsCompositionEnabled)(BOOL*);
typedef HRESULT (WINAPI * PFN_DwmFlush)(VOID);
typedef HRESULT(WINAPI * PFN_DwmEnableBlurBehindWindow)(HWND,const DWM_BLURBEHIND*);
typedef HRESULT (WINAPI * PFN_DwmGetColorizationColor)(DWORD*,BOOL*);
#define DwmIsCompositionEnabled _glfw.win32.dwmapi.IsCompositionEnabled
#define DwmFlush _glfw.win32.dwmapi.Flush
#define DwmEnableBlurBehindWindow _glfw.win32.dwmapi.EnableBlurBehindWindow
#define DwmGetColorizationColor _glfw.win32.dwmapi.GetColorizationColor
// shcore.dll function pointer typedefs
typedef HRESULT (WINAPI * PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS);
typedef HRESULT (WINAPI * PFN_GetDpiForMonitor)(HMONITOR,MONITOR_DPI_TYPE,UINT*,UINT*);
#define SetProcessDpiAwareness _glfw.win32.shcore.SetProcessDpiAwareness_
#define GetDpiForMonitor _glfw.win32.shcore.GetDpiForMonitor_
// ntdll.dll function pointer typedefs
typedef LONG (WINAPI * PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*,ULONG,ULONGLONG);
#define RtlVerifyVersionInfo _glfw.win32.ntdll.RtlVerifyVersionInfo_
// WGL extension pointer typedefs
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC)(int);
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC)(HDC,int,int,UINT,const int*,int*);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC)(void);
typedef const char* (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC)(HDC);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC,HGLRC,const int*);
#define wglSwapIntervalEXT _glfw.wgl.SwapIntervalEXT
#define wglGetPixelFormatAttribivARB _glfw.wgl.GetPixelFormatAttribivARB
#define wglGetExtensionsStringEXT _glfw.wgl.GetExtensionsStringEXT
#define wglGetExtensionsStringARB _glfw.wgl.GetExtensionsStringARB
#define wglCreateContextAttribsARB _glfw.wgl.CreateContextAttribsARB
// opengl32.dll function pointer typedefs
typedef HGLRC (WINAPI * PFN_wglCreateContext)(HDC);
typedef BOOL (WINAPI * PFN_wglDeleteContext)(HGLRC);
typedef PROC (WINAPI * PFN_wglGetProcAddress)(LPCSTR);
typedef HDC (WINAPI * PFN_wglGetCurrentDC)(void);
typedef HGLRC (WINAPI * PFN_wglGetCurrentContext)(void);
typedef BOOL (WINAPI * PFN_wglMakeCurrent)(HDC,HGLRC);
typedef BOOL (WINAPI * PFN_wglShareLists)(HGLRC,HGLRC);
#define wglCreateContext _glfw.wgl.CreateContext
#define wglDeleteContext _glfw.wgl.DeleteContext
#define wglGetProcAddress _glfw.wgl.GetProcAddress
#define wglGetCurrentDC _glfw.wgl.GetCurrentDC
#define wglGetCurrentContext _glfw.wgl.GetCurrentContext
#define wglMakeCurrent _glfw.wgl.MakeCurrent
#define wglShareLists _glfw.wgl.ShareLists
typedef VkFlags VkWin32SurfaceCreateFlagsKHR;
typedef struct VkWin32SurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWin32SurfaceCreateFlagsKHR flags;
HINSTANCE hinstance;
HWND hwnd;
} VkWin32SurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWin32SurfaceKHR)(VkInstance,const VkWin32SurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice,uint32_t);
#define GLFW_WIN32_WINDOW_STATE _GLFWwindowWin32 win32;
#define GLFW_WIN32_LIBRARY_WINDOW_STATE _GLFWlibraryWin32 win32;
#define GLFW_WIN32_MONITOR_STATE _GLFWmonitorWin32 win32;
#define GLFW_WIN32_CURSOR_STATE _GLFWcursorWin32 win32;
#define GLFW_WGL_CONTEXT_STATE _GLFWcontextWGL wgl;
#define GLFW_WGL_LIBRARY_CONTEXT_STATE _GLFWlibraryWGL wgl;
// WGL-specific per-context data
//
typedef struct _GLFWcontextWGL
{
HDC dc;
HGLRC handle;
int interval;
} _GLFWcontextWGL;
// WGL-specific global data
//
typedef struct _GLFWlibraryWGL
{
HINSTANCE instance;
PFN_wglCreateContext CreateContext;
PFN_wglDeleteContext DeleteContext;
PFN_wglGetProcAddress GetProcAddress;
PFN_wglGetCurrentDC GetCurrentDC;
PFN_wglGetCurrentContext GetCurrentContext;
PFN_wglMakeCurrent MakeCurrent;
PFN_wglShareLists ShareLists;
PFNWGLSWAPINTERVALEXTPROC SwapIntervalEXT;
PFNWGLGETPIXELFORMATATTRIBIVARBPROC GetPixelFormatAttribivARB;
PFNWGLGETEXTENSIONSSTRINGEXTPROC GetExtensionsStringEXT;
PFNWGLGETEXTENSIONSSTRINGARBPROC GetExtensionsStringARB;
PFNWGLCREATECONTEXTATTRIBSARBPROC CreateContextAttribsARB;
GLFWbool EXT_swap_control;
GLFWbool EXT_colorspace;
GLFWbool ARB_multisample;
GLFWbool ARB_framebuffer_sRGB;
GLFWbool EXT_framebuffer_sRGB;
GLFWbool ARB_pixel_format;
GLFWbool ARB_create_context;
GLFWbool ARB_create_context_profile;
GLFWbool EXT_create_context_es2_profile;
GLFWbool ARB_create_context_robustness;
GLFWbool ARB_create_context_no_error;
GLFWbool ARB_context_flush_control;
} _GLFWlibraryWGL;
// Win32-specific per-window data
//
typedef struct _GLFWwindowWin32
{
HWND handle;
HICON bigIcon;
HICON smallIcon;
GLFWbool cursorTracked;
GLFWbool frameAction;
GLFWbool iconified;
GLFWbool maximized;
// Whether to enable framebuffer transparency on DWM
GLFWbool transparent;
GLFWbool scaleToMonitor;
GLFWbool keymenu;
GLFWbool showDefault;
// Cached size used to filter out duplicate events
int width, height;
// The last received cursor position, regardless of source
int lastCursorPosX, lastCursorPosY;
// The last received high surrogate when decoding pairs of UTF-16 messages
WCHAR highSurrogate;
} _GLFWwindowWin32;
// Win32-specific global data
//
typedef struct _GLFWlibraryWin32
{
HINSTANCE instance;
HWND helperWindowHandle;
ATOM helperWindowClass;
ATOM mainWindowClass;
HDEVNOTIFY deviceNotificationHandle;
int acquiredMonitorCount;
char* clipboardString;
short int keycodes[512];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
// Where to place the cursor when re-enabled
double restoreCursorPosX, restoreCursorPosY;
// The window whose disabled cursor mode is active
_GLFWwindow* disabledCursorWindow;
// The window the cursor is captured in
_GLFWwindow* capturedCursorWindow;
RAWINPUT* rawInput;
int rawInputSize;
UINT mouseTrailSize;
// The cursor handle to use to hide the cursor (NULL or a transparent cursor)
HCURSOR blankCursor;
struct {
HINSTANCE instance;
PFN_DirectInput8Create Create;
IDirectInput8W* api;
} dinput8;
struct {
HINSTANCE instance;
PFN_XInputGetCapabilities GetCapabilities;
PFN_XInputGetState GetState;
} xinput;
struct {
HINSTANCE instance;
PFN_SetProcessDPIAware SetProcessDPIAware_;
PFN_ChangeWindowMessageFilterEx ChangeWindowMessageFilterEx_;
PFN_EnableNonClientDpiScaling EnableNonClientDpiScaling_;
PFN_SetProcessDpiAwarenessContext SetProcessDpiAwarenessContext_;
PFN_GetDpiForWindow GetDpiForWindow_;
PFN_AdjustWindowRectExForDpi AdjustWindowRectExForDpi_;
PFN_GetSystemMetricsForDpi GetSystemMetricsForDpi_;
} user32;
struct {
HINSTANCE instance;
PFN_DwmIsCompositionEnabled IsCompositionEnabled;
PFN_DwmFlush Flush;
PFN_DwmEnableBlurBehindWindow EnableBlurBehindWindow;
PFN_DwmGetColorizationColor GetColorizationColor;
} dwmapi;
struct {
HINSTANCE instance;
PFN_SetProcessDpiAwareness SetProcessDpiAwareness_;
PFN_GetDpiForMonitor GetDpiForMonitor_;
} shcore;
struct {
HINSTANCE instance;
PFN_RtlVerifyVersionInfo RtlVerifyVersionInfo_;
} ntdll;
} _GLFWlibraryWin32;
// Win32-specific per-monitor data
//
typedef struct _GLFWmonitorWin32
{
HMONITOR handle;
// This size matches the static size of DISPLAY_DEVICE.DeviceName
WCHAR adapterName[32];
WCHAR displayName[32];
char publicAdapterName[32];
char publicDisplayName[32];
GLFWbool modesPruned;
GLFWbool modeChanged;
} _GLFWmonitorWin32;
// Win32-specific per-cursor data
//
typedef struct _GLFWcursorWin32
{
HCURSOR handle;
} _GLFWcursorWin32;
GLFWbool _glfwConnectWin32(int platformID, _GLFWplatform* platform);
int _glfwInitWin32(void);
void _glfwTerminateWin32(void);
WCHAR* _glfwCreateWideStringFromUTF8Win32(const char* source);
char* _glfwCreateUTF8FromWideStringWin32(const WCHAR* source);
BOOL _glfwIsWindowsVersionOrGreaterWin32(WORD major, WORD minor, WORD sp);
BOOL _glfwIsWindows10BuildOrGreaterWin32(WORD build);
void _glfwInputErrorWin32(int error, const char* description);
void _glfwUpdateKeyNamesWin32(void);
void _glfwPollMonitorsWin32(void);
void _glfwSetVideoModeWin32(_GLFWmonitor* monitor, const GLFWvidmode* desired);
void _glfwRestoreVideoModeWin32(_GLFWmonitor* monitor);
void _glfwGetHMONITORContentScaleWin32(HMONITOR handle, float* xscale, float* yscale);
GLFWbool _glfwCreateWindowWin32(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowWin32(_GLFWwindow* window);
void _glfwSetWindowTitleWin32(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWin32(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosWin32(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWin32(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWin32(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeWin32(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsWin32(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioWin32(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeWin32(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeWin32(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleWin32(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowWin32(_GLFWwindow* window);
void _glfwRestoreWindowWin32(_GLFWwindow* window);
void _glfwMaximizeWindowWin32(_GLFWwindow* window);
void _glfwShowWindowWin32(_GLFWwindow* window);
void _glfwHideWindowWin32(_GLFWwindow* window);
void _glfwRequestWindowAttentionWin32(_GLFWwindow* window);
void _glfwFocusWindowWin32(_GLFWwindow* window);
void _glfwSetWindowMonitorWin32(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleWin32(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedWin32(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredWin32(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentWin32(_GLFWwindow* window);
void _glfwSetWindowResizableWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingWin32(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowMousePassthroughWin32(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityWin32(_GLFWwindow* window);
void _glfwSetWindowOpacityWin32(_GLFWwindow* window, float opacity);
void _glfwSetRawMouseMotionWin32(_GLFWwindow *window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedWin32(void);
void _glfwPollEventsWin32(void);
void _glfwWaitEventsWin32(void);
void _glfwWaitEventsTimeoutWin32(double timeout);
void _glfwPostEmptyEventWin32(void);
void _glfwGetCursorPosWin32(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWin32(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWin32(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWin32(int scancode);
int _glfwGetKeyScancodeWin32(int key);
GLFWbool _glfwCreateCursorWin32(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWin32(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorWin32(_GLFWcursor* cursor);
void _glfwSetCursorWin32(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWin32(const char* string);
const char* _glfwGetClipboardStringWin32(void);
EGLenum _glfwGetEGLPlatformWin32(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWin32(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWin32(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWin32(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWin32(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWin32(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorWin32(_GLFWmonitor* monitor);
void _glfwGetMonitorPosWin32(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleWin32(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaWin32(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesWin32(_GLFWmonitor* monitor, int* count);
GLFWbool _glfwGetVideoModeWin32(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampWin32(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampWin32(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
GLFWbool _glfwInitJoysticksWin32(void);
void _glfwTerminateJoysticksWin32(void);
GLFWbool _glfwPollJoystickWin32(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameWin32(void);
void _glfwUpdateGamepadGUIDWin32(char* guid);
GLFWbool _glfwInitWGL(void);
void _glfwTerminateWGL(void);
GLFWbool _glfwCreateContextWGL(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);

100
raylib/external/glfw/src/win32_thread.c vendored Normal file
View File

@@ -0,0 +1,100 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_WIN32_THREAD)
#include <assert.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->win32.allocated == GLFW_FALSE);
tls->win32.index = TlsAlloc();
if (tls->win32.index == TLS_OUT_OF_INDEXES)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "Win32: Failed to allocate TLS index");
return GLFW_FALSE;
}
tls->win32.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->win32.allocated)
TlsFree(tls->win32.index);
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->win32.allocated == GLFW_TRUE);
return TlsGetValue(tls->win32.index);
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->win32.allocated == GLFW_TRUE);
TlsSetValue(tls->win32.index, value);
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_FALSE);
InitializeCriticalSection(&mutex->win32.section);
return mutex->win32.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->win32.allocated)
DeleteCriticalSection(&mutex->win32.section);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_TRUE);
EnterCriticalSection(&mutex->win32.section);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->win32.allocated == GLFW_TRUE);
LeaveCriticalSection(&mutex->win32.section);
}
#endif // GLFW_BUILD_WIN32_THREAD

53
raylib/external/glfw/src/win32_thread.h vendored Normal file
View File

@@ -0,0 +1,53 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does
#undef APIENTRY
#include <windows.h>
#define GLFW_WIN32_TLS_STATE _GLFWtlsWin32 win32;
#define GLFW_WIN32_MUTEX_STATE _GLFWmutexWin32 win32;
// Win32-specific thread local storage data
//
typedef struct _GLFWtlsWin32
{
GLFWbool allocated;
DWORD index;
} _GLFWtlsWin32;
// Win32-specific mutex data
//
typedef struct _GLFWmutexWin32
{
GLFWbool allocated;
CRITICAL_SECTION section;
} _GLFWmutexWin32;

54
raylib/external/glfw/src/win32_time.c vendored Normal file
View File

@@ -0,0 +1,54 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(GLFW_BUILD_WIN32_TIMER)
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
QueryPerformanceFrequency((LARGE_INTEGER*) &_glfw.timer.win32.frequency);
}
uint64_t _glfwPlatformGetTimerValue(void)
{
uint64_t value;
QueryPerformanceCounter((LARGE_INTEGER*) &value);
return value;
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return _glfw.timer.win32.frequency;
}
#endif // GLFW_BUILD_WIN32_TIMER

43
raylib/external/glfw/src/win32_time.h vendored Normal file
View File

@@ -0,0 +1,43 @@
//========================================================================
// GLFW 3.4 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
// example to allow applications to correctly declare a GL_KHR_debug callback)
// but windows.h assumes no one will define APIENTRY before it does
#undef APIENTRY
#include <windows.h>
#define GLFW_WIN32_LIBRARY_TIMER_STATE _GLFWtimerWin32 win32;
// Win32-specific global timer data
//
typedef struct _GLFWtimerWin32
{
uint64_t frequency;
} _GLFWtimerWin32;

2594
raylib/external/glfw/src/win32_window.c vendored Normal file

File diff suppressed because it is too large Load Diff

1172
raylib/external/glfw/src/window.c vendored Normal file

File diff suppressed because it is too large Load Diff

1004
raylib/external/glfw/src/wl_init.c vendored Normal file

File diff suppressed because it is too large Load Diff

274
raylib/external/glfw/src/wl_monitor.c vendored Normal file
View File

@@ -0,0 +1,274 @@
//========================================================================
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_WAYLAND)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include "wayland-client-protocol.h"
static void outputHandleGeometry(void* userData,
struct wl_output* output,
int32_t x,
int32_t y,
int32_t physicalWidth,
int32_t physicalHeight,
int32_t subpixel,
const char* make,
const char* model,
int32_t transform)
{
struct _GLFWmonitor* monitor = userData;
monitor->wl.x = x;
monitor->wl.y = y;
monitor->widthMM = physicalWidth;
monitor->heightMM = physicalHeight;
if (strlen(monitor->name) == 0)
snprintf(monitor->name, sizeof(monitor->name), "%s %s", make, model);
}
static void outputHandleMode(void* userData,
struct wl_output* output,
uint32_t flags,
int32_t width,
int32_t height,
int32_t refresh)
{
struct _GLFWmonitor* monitor = userData;
GLFWvidmode mode;
mode.width = width;
mode.height = height;
mode.redBits = 8;
mode.greenBits = 8;
mode.blueBits = 8;
mode.refreshRate = (int) round(refresh / 1000.0);
monitor->modeCount++;
monitor->modes =
_glfw_realloc(monitor->modes, monitor->modeCount * sizeof(GLFWvidmode));
monitor->modes[monitor->modeCount - 1] = mode;
if (flags & WL_OUTPUT_MODE_CURRENT)
monitor->wl.currentMode = monitor->modeCount - 1;
}
static void outputHandleDone(void* userData, struct wl_output* output)
{
struct _GLFWmonitor* monitor = userData;
if (monitor->widthMM <= 0 || monitor->heightMM <= 0)
{
// If Wayland does not provide a physical size, assume the default 96 DPI
const GLFWvidmode* mode = &monitor->modes[monitor->wl.currentMode];
monitor->widthMM = (int) (mode->width * 25.4f / 96.f);
monitor->heightMM = (int) (mode->height * 25.4f / 96.f);
}
for (int i = 0; i < _glfw.monitorCount; i++)
{
if (_glfw.monitors[i] == monitor)
return;
}
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_LAST);
}
static void outputHandleScale(void* userData,
struct wl_output* output,
int32_t factor)
{
struct _GLFWmonitor* monitor = userData;
monitor->wl.scale = factor;
for (_GLFWwindow* window = _glfw.windowListHead; window; window = window->next)
{
for (size_t i = 0; i < window->wl.outputScaleCount; i++)
{
if (window->wl.outputScales[i].output == monitor->wl.output)
{
window->wl.outputScales[i].factor = monitor->wl.scale;
_glfwUpdateBufferScaleFromOutputsWayland(window);
break;
}
}
}
}
void outputHandleName(void* userData, struct wl_output* wl_output, const char* name)
{
struct _GLFWmonitor* monitor = userData;
strncpy(monitor->name, name, sizeof(monitor->name) - 1);
}
void outputHandleDescription(void* userData,
struct wl_output* wl_output,
const char* description)
{
}
static const struct wl_output_listener outputListener =
{
outputHandleGeometry,
outputHandleMode,
outputHandleDone,
outputHandleScale,
outputHandleName,
outputHandleDescription,
};
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwAddOutputWayland(uint32_t name, uint32_t version)
{
if (version < 2)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Wayland: Unsupported output interface version");
return;
}
version = _glfw_min(version, WL_OUTPUT_NAME_SINCE_VERSION);
struct wl_output* output = wl_registry_bind(_glfw.wl.registry,
name,
&wl_output_interface,
version);
if (!output)
return;
// The actual name of this output will be set in the geometry handler
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
monitor->wl.scale = 1;
monitor->wl.output = output;
monitor->wl.name = name;
wl_proxy_set_tag((struct wl_proxy*) output, &_glfw.wl.tag);
wl_output_add_listener(output, &outputListener, monitor);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorWayland(_GLFWmonitor* monitor)
{
if (monitor->wl.output)
wl_output_destroy(monitor->wl.output);
}
void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (xpos)
*xpos = monitor->wl.x;
if (ypos)
*ypos = monitor->wl.y;
}
void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = (float) monitor->wl.scale;
if (yscale)
*yscale = (float) monitor->wl.scale;
}
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = monitor->wl.x;
if (ypos)
*ypos = monitor->wl.y;
if (width)
*width = monitor->modes[monitor->wl.currentMode].width;
if (height)
*height = monitor->modes[monitor->wl.currentMode].height;
}
GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* found)
{
*found = monitor->modeCount;
return monitor->modes;
}
GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
*mode = monitor->modes[monitor->wl.currentMode];
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available");
return GLFW_FALSE;
}
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE,
"Wayland: Gamma ramp access is not available");
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI struct wl_output* glfwGetWaylandMonitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(NULL);
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "Wayland: Platform not initialized");
return NULL;
}
return monitor->wl.output;
}
#endif // _GLFW_WAYLAND

691
raylib/external/glfw/src/wl_platform.h vendored Normal file
View File

@@ -0,0 +1,691 @@
//========================================================================
// GLFW 3.4 Wayland - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include <wayland-client-core.h>
#include <xkbcommon/xkbcommon.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <stdbool.h>
typedef VkFlags VkWaylandSurfaceCreateFlagsKHR;
typedef struct VkWaylandSurfaceCreateInfoKHR
{
VkStructureType sType;
const void* pNext;
VkWaylandSurfaceCreateFlagsKHR flags;
struct wl_display* display;
struct wl_surface* surface;
} VkWaylandSurfaceCreateInfoKHR;
typedef VkResult (APIENTRY *PFN_vkCreateWaylandSurfaceKHR)(VkInstance,const VkWaylandSurfaceCreateInfoKHR*,const VkAllocationCallbacks*,VkSurfaceKHR*);
typedef VkBool32 (APIENTRY *PFN_vkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice,uint32_t,struct wl_display*);
#include "xkb_unicode.h"
#include "posix_poll.h"
typedef int (* PFN_wl_display_flush)(struct wl_display* display);
typedef void (* PFN_wl_display_cancel_read)(struct wl_display* display);
typedef int (* PFN_wl_display_dispatch_pending)(struct wl_display* display);
typedef int (* PFN_wl_display_read_events)(struct wl_display* display);
typedef struct wl_display* (* PFN_wl_display_connect)(const char*);
typedef void (* PFN_wl_display_disconnect)(struct wl_display*);
typedef int (* PFN_wl_display_roundtrip)(struct wl_display*);
typedef int (* PFN_wl_display_get_fd)(struct wl_display*);
typedef int (* PFN_wl_display_prepare_read)(struct wl_display*);
typedef void (* PFN_wl_proxy_marshal)(struct wl_proxy*,uint32_t,...);
typedef int (* PFN_wl_proxy_add_listener)(struct wl_proxy*,void(**)(void),void*);
typedef void (* PFN_wl_proxy_destroy)(struct wl_proxy*);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor)(struct wl_proxy*,uint32_t,const struct wl_interface*,...);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_constructor_versioned)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,...);
typedef void* (* PFN_wl_proxy_get_user_data)(struct wl_proxy*);
typedef void (* PFN_wl_proxy_set_user_data)(struct wl_proxy*,void*);
typedef void (* PFN_wl_proxy_set_tag)(struct wl_proxy*,const char*const*);
typedef const char* const* (* PFN_wl_proxy_get_tag)(struct wl_proxy*);
typedef uint32_t (* PFN_wl_proxy_get_version)(struct wl_proxy*);
typedef struct wl_proxy* (* PFN_wl_proxy_marshal_flags)(struct wl_proxy*,uint32_t,const struct wl_interface*,uint32_t,uint32_t,...);
#define wl_display_flush _glfw.wl.client.display_flush
#define wl_display_cancel_read _glfw.wl.client.display_cancel_read
#define wl_display_dispatch_pending _glfw.wl.client.display_dispatch_pending
#define wl_display_read_events _glfw.wl.client.display_read_events
#define wl_display_disconnect _glfw.wl.client.display_disconnect
#define wl_display_roundtrip _glfw.wl.client.display_roundtrip
#define wl_display_get_fd _glfw.wl.client.display_get_fd
#define wl_display_prepare_read _glfw.wl.client.display_prepare_read
#define wl_proxy_marshal _glfw.wl.client.proxy_marshal
#define wl_proxy_add_listener _glfw.wl.client.proxy_add_listener
#define wl_proxy_destroy _glfw.wl.client.proxy_destroy
#define wl_proxy_marshal_constructor _glfw.wl.client.proxy_marshal_constructor
#define wl_proxy_marshal_constructor_versioned _glfw.wl.client.proxy_marshal_constructor_versioned
#define wl_proxy_get_user_data _glfw.wl.client.proxy_get_user_data
#define wl_proxy_set_user_data _glfw.wl.client.proxy_set_user_data
#define wl_proxy_get_tag _glfw.wl.client.proxy_get_tag
#define wl_proxy_set_tag _glfw.wl.client.proxy_set_tag
#define wl_proxy_get_version _glfw.wl.client.proxy_get_version
#define wl_proxy_marshal_flags _glfw.wl.client.proxy_marshal_flags
struct wl_shm;
struct wl_output;
#define wl_display_interface _glfw_wl_display_interface
#define wl_subcompositor_interface _glfw_wl_subcompositor_interface
#define wl_compositor_interface _glfw_wl_compositor_interface
#define wl_shm_interface _glfw_wl_shm_interface
#define wl_data_device_manager_interface _glfw_wl_data_device_manager_interface
#define wl_shell_interface _glfw_wl_shell_interface
#define wl_buffer_interface _glfw_wl_buffer_interface
#define wl_callback_interface _glfw_wl_callback_interface
#define wl_data_device_interface _glfw_wl_data_device_interface
#define wl_data_offer_interface _glfw_wl_data_offer_interface
#define wl_data_source_interface _glfw_wl_data_source_interface
#define wl_keyboard_interface _glfw_wl_keyboard_interface
#define wl_output_interface _glfw_wl_output_interface
#define wl_pointer_interface _glfw_wl_pointer_interface
#define wl_region_interface _glfw_wl_region_interface
#define wl_registry_interface _glfw_wl_registry_interface
#define wl_seat_interface _glfw_wl_seat_interface
#define wl_shell_surface_interface _glfw_wl_shell_surface_interface
#define wl_shm_pool_interface _glfw_wl_shm_pool_interface
#define wl_subsurface_interface _glfw_wl_subsurface_interface
#define wl_surface_interface _glfw_wl_surface_interface
#define wl_touch_interface _glfw_wl_touch_interface
#define zwp_idle_inhibitor_v1_interface _glfw_zwp_idle_inhibitor_v1_interface
#define zwp_idle_inhibit_manager_v1_interface _glfw_zwp_idle_inhibit_manager_v1_interface
#define zwp_confined_pointer_v1_interface _glfw_zwp_confined_pointer_v1_interface
#define zwp_locked_pointer_v1_interface _glfw_zwp_locked_pointer_v1_interface
#define zwp_pointer_constraints_v1_interface _glfw_zwp_pointer_constraints_v1_interface
#define zwp_relative_pointer_v1_interface _glfw_zwp_relative_pointer_v1_interface
#define zwp_relative_pointer_manager_v1_interface _glfw_zwp_relative_pointer_manager_v1_interface
#define wp_viewport_interface _glfw_wp_viewport_interface
#define wp_viewporter_interface _glfw_wp_viewporter_interface
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
#define zxdg_toplevel_decoration_v1_interface _glfw_zxdg_toplevel_decoration_v1_interface
#define zxdg_decoration_manager_v1_interface _glfw_zxdg_decoration_manager_v1_interface
#define xdg_popup_interface _glfw_xdg_popup_interface
#define xdg_positioner_interface _glfw_xdg_positioner_interface
#define xdg_surface_interface _glfw_xdg_surface_interface
#define xdg_toplevel_interface _glfw_xdg_toplevel_interface
#define xdg_wm_base_interface _glfw_xdg_wm_base_interface
#define xdg_activation_v1_interface _glfw_xdg_activation_v1_interface
#define xdg_activation_token_v1_interface _glfw_xdg_activation_token_v1_interface
#define wl_surface_interface _glfw_wl_surface_interface
#define wp_fractional_scale_v1_interface _glfw_wp_fractional_scale_v1_interface
#define GLFW_WAYLAND_WINDOW_STATE _GLFWwindowWayland wl;
#define GLFW_WAYLAND_LIBRARY_WINDOW_STATE _GLFWlibraryWayland wl;
#define GLFW_WAYLAND_MONITOR_STATE _GLFWmonitorWayland wl;
#define GLFW_WAYLAND_CURSOR_STATE _GLFWcursorWayland wl;
struct wl_cursor_image {
uint32_t width;
uint32_t height;
uint32_t hotspot_x;
uint32_t hotspot_y;
uint32_t delay;
};
struct wl_cursor {
unsigned int image_count;
struct wl_cursor_image** images;
char* name;
};
typedef struct wl_cursor_theme* (* PFN_wl_cursor_theme_load)(const char*, int, struct wl_shm*);
typedef void (* PFN_wl_cursor_theme_destroy)(struct wl_cursor_theme*);
typedef struct wl_cursor* (* PFN_wl_cursor_theme_get_cursor)(struct wl_cursor_theme*, const char*);
typedef struct wl_buffer* (* PFN_wl_cursor_image_get_buffer)(struct wl_cursor_image*);
#define wl_cursor_theme_load _glfw.wl.cursor.theme_load
#define wl_cursor_theme_destroy _glfw.wl.cursor.theme_destroy
#define wl_cursor_theme_get_cursor _glfw.wl.cursor.theme_get_cursor
#define wl_cursor_image_get_buffer _glfw.wl.cursor.image_get_buffer
typedef struct wl_egl_window* (* PFN_wl_egl_window_create)(struct wl_surface*, int, int);
typedef void (* PFN_wl_egl_window_destroy)(struct wl_egl_window*);
typedef void (* PFN_wl_egl_window_resize)(struct wl_egl_window*, int, int, int, int);
#define wl_egl_window_create _glfw.wl.egl.window_create
#define wl_egl_window_destroy _glfw.wl.egl.window_destroy
#define wl_egl_window_resize _glfw.wl.egl.window_resize
typedef struct xkb_context* (* PFN_xkb_context_new)(enum xkb_context_flags);
typedef void (* PFN_xkb_context_unref)(struct xkb_context*);
typedef struct xkb_keymap* (* PFN_xkb_keymap_new_from_string)(struct xkb_context*, const char*, enum xkb_keymap_format, enum xkb_keymap_compile_flags);
typedef void (* PFN_xkb_keymap_unref)(struct xkb_keymap*);
typedef xkb_mod_index_t (* PFN_xkb_keymap_mod_get_index)(struct xkb_keymap*, const char*);
typedef int (* PFN_xkb_keymap_key_repeats)(struct xkb_keymap*, xkb_keycode_t);
typedef int (* PFN_xkb_keymap_key_get_syms_by_level)(struct xkb_keymap*,xkb_keycode_t,xkb_layout_index_t,xkb_level_index_t,const xkb_keysym_t**);
typedef struct xkb_state* (* PFN_xkb_state_new)(struct xkb_keymap*);
typedef void (* PFN_xkb_state_unref)(struct xkb_state*);
typedef int (* PFN_xkb_state_key_get_syms)(struct xkb_state*, xkb_keycode_t, const xkb_keysym_t**);
typedef enum xkb_state_component (* PFN_xkb_state_update_mask)(struct xkb_state*, xkb_mod_mask_t, xkb_mod_mask_t, xkb_mod_mask_t, xkb_layout_index_t, xkb_layout_index_t, xkb_layout_index_t);
typedef xkb_layout_index_t (* PFN_xkb_state_key_get_layout)(struct xkb_state*,xkb_keycode_t);
typedef int (* PFN_xkb_state_mod_index_is_active)(struct xkb_state*,xkb_mod_index_t,enum xkb_state_component);
#define xkb_context_new _glfw.wl.xkb.context_new
#define xkb_context_unref _glfw.wl.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.wl.xkb.keymap_new_from_string
#define xkb_keymap_unref _glfw.wl.xkb.keymap_unref
#define xkb_keymap_mod_get_index _glfw.wl.xkb.keymap_mod_get_index
#define xkb_keymap_key_repeats _glfw.wl.xkb.keymap_key_repeats
#define xkb_keymap_key_get_syms_by_level _glfw.wl.xkb.keymap_key_get_syms_by_level
#define xkb_state_new _glfw.wl.xkb.state_new
#define xkb_state_unref _glfw.wl.xkb.state_unref
#define xkb_state_key_get_syms _glfw.wl.xkb.state_key_get_syms
#define xkb_state_update_mask _glfw.wl.xkb.state_update_mask
#define xkb_state_key_get_layout _glfw.wl.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.wl.xkb.state_mod_index_is_active
typedef struct xkb_compose_table* (* PFN_xkb_compose_table_new_from_locale)(struct xkb_context*, const char*, enum xkb_compose_compile_flags);
typedef void (* PFN_xkb_compose_table_unref)(struct xkb_compose_table*);
typedef struct xkb_compose_state* (* PFN_xkb_compose_state_new)(struct xkb_compose_table*, enum xkb_compose_state_flags);
typedef void (* PFN_xkb_compose_state_unref)(struct xkb_compose_state*);
typedef enum xkb_compose_feed_result (* PFN_xkb_compose_state_feed)(struct xkb_compose_state*, xkb_keysym_t);
typedef enum xkb_compose_status (* PFN_xkb_compose_state_get_status)(struct xkb_compose_state*);
typedef xkb_keysym_t (* PFN_xkb_compose_state_get_one_sym)(struct xkb_compose_state*);
#define xkb_compose_table_new_from_locale _glfw.wl.xkb.compose_table_new_from_locale
#define xkb_compose_table_unref _glfw.wl.xkb.compose_table_unref
#define xkb_compose_state_new _glfw.wl.xkb.compose_state_new
#define xkb_compose_state_unref _glfw.wl.xkb.compose_state_unref
#define xkb_compose_state_feed _glfw.wl.xkb.compose_state_feed
#define xkb_compose_state_get_status _glfw.wl.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.wl.xkb.compose_state_get_one_sym
struct libdecor;
struct libdecor_frame;
struct libdecor_state;
struct libdecor_configuration;
enum libdecor_error
{
LIBDECOR_ERROR_COMPOSITOR_INCOMPATIBLE,
LIBDECOR_ERROR_INVALID_FRAME_CONFIGURATION,
};
enum libdecor_window_state
{
LIBDECOR_WINDOW_STATE_NONE = 0,
LIBDECOR_WINDOW_STATE_ACTIVE = 1,
LIBDECOR_WINDOW_STATE_MAXIMIZED = 2,
LIBDECOR_WINDOW_STATE_FULLSCREEN = 4,
LIBDECOR_WINDOW_STATE_TILED_LEFT = 8,
LIBDECOR_WINDOW_STATE_TILED_RIGHT = 16,
LIBDECOR_WINDOW_STATE_TILED_TOP = 32,
LIBDECOR_WINDOW_STATE_TILED_BOTTOM = 64
};
enum libdecor_capabilities
{
LIBDECOR_ACTION_MOVE = 1,
LIBDECOR_ACTION_RESIZE = 2,
LIBDECOR_ACTION_MINIMIZE = 4,
LIBDECOR_ACTION_FULLSCREEN = 8,
LIBDECOR_ACTION_CLOSE = 16
};
struct libdecor_interface
{
void (* error)(struct libdecor*,enum libdecor_error,const char*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
struct libdecor_frame_interface
{
void (* configure)(struct libdecor_frame*,struct libdecor_configuration*,void*);
void (* close)(struct libdecor_frame*,void*);
void (* commit)(struct libdecor_frame*,void*);
void (* dismiss_popup)(struct libdecor_frame*,const char*,void*);
void (* reserved0)(void);
void (* reserved1)(void);
void (* reserved2)(void);
void (* reserved3)(void);
void (* reserved4)(void);
void (* reserved5)(void);
void (* reserved6)(void);
void (* reserved7)(void);
void (* reserved8)(void);
void (* reserved9)(void);
};
typedef struct libdecor* (* PFN_libdecor_new)(struct wl_display*,const struct libdecor_interface*);
typedef void (* PFN_libdecor_unref)(struct libdecor*);
typedef int (* PFN_libdecor_get_fd)(struct libdecor*);
typedef int (* PFN_libdecor_dispatch)(struct libdecor*,int);
typedef struct libdecor_frame* (* PFN_libdecor_decorate)(struct libdecor*,struct wl_surface*,const struct libdecor_frame_interface*,void*);
typedef void (* PFN_libdecor_frame_unref)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_app_id)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_title)(struct libdecor_frame*,const char*);
typedef void (* PFN_libdecor_frame_set_minimized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_fullscreen)(struct libdecor_frame*,struct wl_output*);
typedef void (* PFN_libdecor_frame_unset_fullscreen)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_map)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_commit)(struct libdecor_frame*,struct libdecor_state*,struct libdecor_configuration*);
typedef void (* PFN_libdecor_frame_set_min_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_max_content_size)(struct libdecor_frame*,int,int);
typedef void (* PFN_libdecor_frame_set_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_unset_maximized)(struct libdecor_frame*);
typedef void (* PFN_libdecor_frame_set_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_unset_capabilities)(struct libdecor_frame*,enum libdecor_capabilities);
typedef void (* PFN_libdecor_frame_set_visibility)(struct libdecor_frame*,bool visible);
typedef struct xdg_toplevel* (* PFN_libdecor_frame_get_xdg_toplevel)(struct libdecor_frame*);
typedef bool (* PFN_libdecor_configuration_get_content_size)(struct libdecor_configuration*,struct libdecor_frame*,int*,int*);
typedef bool (* PFN_libdecor_configuration_get_window_state)(struct libdecor_configuration*,enum libdecor_window_state*);
typedef struct libdecor_state* (* PFN_libdecor_state_new)(int,int);
typedef void (* PFN_libdecor_state_free)(struct libdecor_state*);
#define libdecor_new _glfw.wl.libdecor.libdecor_new_
#define libdecor_unref _glfw.wl.libdecor.libdecor_unref_
#define libdecor_get_fd _glfw.wl.libdecor.libdecor_get_fd_
#define libdecor_dispatch _glfw.wl.libdecor.libdecor_dispatch_
#define libdecor_decorate _glfw.wl.libdecor.libdecor_decorate_
#define libdecor_frame_unref _glfw.wl.libdecor.libdecor_frame_unref_
#define libdecor_frame_set_app_id _glfw.wl.libdecor.libdecor_frame_set_app_id_
#define libdecor_frame_set_title _glfw.wl.libdecor.libdecor_frame_set_title_
#define libdecor_frame_set_minimized _glfw.wl.libdecor.libdecor_frame_set_minimized_
#define libdecor_frame_set_fullscreen _glfw.wl.libdecor.libdecor_frame_set_fullscreen_
#define libdecor_frame_unset_fullscreen _glfw.wl.libdecor.libdecor_frame_unset_fullscreen_
#define libdecor_frame_map _glfw.wl.libdecor.libdecor_frame_map_
#define libdecor_frame_commit _glfw.wl.libdecor.libdecor_frame_commit_
#define libdecor_frame_set_min_content_size _glfw.wl.libdecor.libdecor_frame_set_min_content_size_
#define libdecor_frame_set_max_content_size _glfw.wl.libdecor.libdecor_frame_set_max_content_size_
#define libdecor_frame_set_maximized _glfw.wl.libdecor.libdecor_frame_set_maximized_
#define libdecor_frame_unset_maximized _glfw.wl.libdecor.libdecor_frame_unset_maximized_
#define libdecor_frame_set_capabilities _glfw.wl.libdecor.libdecor_frame_set_capabilities_
#define libdecor_frame_unset_capabilities _glfw.wl.libdecor.libdecor_frame_unset_capabilities_
#define libdecor_frame_set_visibility _glfw.wl.libdecor.libdecor_frame_set_visibility_
#define libdecor_frame_get_xdg_toplevel _glfw.wl.libdecor.libdecor_frame_get_xdg_toplevel_
#define libdecor_configuration_get_content_size _glfw.wl.libdecor.libdecor_configuration_get_content_size_
#define libdecor_configuration_get_window_state _glfw.wl.libdecor.libdecor_configuration_get_window_state_
#define libdecor_state_new _glfw.wl.libdecor.libdecor_state_new_
#define libdecor_state_free _glfw.wl.libdecor.libdecor_state_free_
typedef struct _GLFWfallbackEdgeWayland
{
struct wl_surface* surface;
struct wl_subsurface* subsurface;
struct wp_viewport* viewport;
} _GLFWfallbackEdgeWayland;
typedef struct _GLFWofferWayland
{
struct wl_data_offer* offer;
GLFWbool text_plain_utf8;
GLFWbool text_uri_list;
} _GLFWofferWayland;
typedef struct _GLFWscaleWayland
{
struct wl_output* output;
int32_t factor;
} _GLFWscaleWayland;
// Wayland-specific per-window data
//
typedef struct _GLFWwindowWayland
{
int width, height;
int fbWidth, fbHeight;
GLFWbool visible;
GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered;
GLFWbool transparent;
GLFWbool scaleFramebuffer;
struct wl_surface* surface;
struct wl_callback* callback;
struct {
struct wl_egl_window* window;
} egl;
struct {
int width, height;
GLFWbool maximized;
GLFWbool iconified;
GLFWbool activated;
GLFWbool fullscreen;
} pending;
struct {
struct xdg_surface* surface;
struct xdg_toplevel* toplevel;
struct zxdg_toplevel_decoration_v1* decoration;
uint32_t decorationMode;
} xdg;
struct {
struct libdecor_frame* frame;
} libdecor;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
char* appId;
// We need to track the monitors the window spans on to calculate the
// optimal scaling factor.
int32_t bufferScale;
_GLFWscaleWayland* outputScales;
size_t outputScaleCount;
size_t outputScaleSize;
struct wp_viewport* scalingViewport;
uint32_t scalingNumerator;
struct wp_fractional_scale_v1* fractionalScale;
struct zwp_relative_pointer_v1* relativePointer;
struct zwp_locked_pointer_v1* lockedPointer;
struct zwp_confined_pointer_v1* confinedPointer;
struct zwp_idle_inhibitor_v1* idleInhibitor;
struct xdg_activation_token_v1* activationToken;
struct {
GLFWbool decorations;
struct wl_buffer* buffer;
_GLFWfallbackEdgeWayland top, left, right, bottom;
struct wl_surface* focus;
} fallback;
} _GLFWwindowWayland;
// Wayland-specific global data
//
typedef struct _GLFWlibraryWayland
{
struct wl_display* display;
struct wl_registry* registry;
struct wl_compositor* compositor;
struct wl_subcompositor* subcompositor;
struct wl_shm* shm;
struct wl_seat* seat;
struct wl_pointer* pointer;
struct wl_keyboard* keyboard;
struct wl_data_device_manager* dataDeviceManager;
struct wl_data_device* dataDevice;
struct xdg_wm_base* wmBase;
struct zxdg_decoration_manager_v1* decorationManager;
struct wp_viewporter* viewporter;
struct zwp_relative_pointer_manager_v1* relativePointerManager;
struct zwp_pointer_constraints_v1* pointerConstraints;
struct zwp_idle_inhibit_manager_v1* idleInhibitManager;
struct xdg_activation_v1* activationManager;
struct wp_fractional_scale_manager_v1* fractionalScaleManager;
_GLFWofferWayland* offers;
unsigned int offerCount;
struct wl_data_offer* selectionOffer;
struct wl_data_source* selectionSource;
struct wl_data_offer* dragOffer;
_GLFWwindow* dragFocus;
uint32_t dragSerial;
const char* tag;
struct wl_cursor_theme* cursorTheme;
struct wl_cursor_theme* cursorThemeHiDPI;
struct wl_surface* cursorSurface;
const char* cursorPreviousName;
int cursorTimerfd;
uint32_t serial;
uint32_t pointerEnterSerial;
int keyRepeatTimerfd;
int32_t keyRepeatRate;
int32_t keyRepeatDelay;
int keyRepeatScancode;
char* clipboardString;
short int keycodes[256];
short int scancodes[GLFW_KEY_LAST + 1];
char keynames[GLFW_KEY_LAST + 1][5];
struct {
void* handle;
struct xkb_context* context;
struct xkb_keymap* keymap;
struct xkb_state* state;
struct xkb_compose_state* composeState;
xkb_mod_index_t controlIndex;
xkb_mod_index_t altIndex;
xkb_mod_index_t shiftIndex;
xkb_mod_index_t superIndex;
xkb_mod_index_t capsLockIndex;
xkb_mod_index_t numLockIndex;
unsigned int modifiers;
PFN_xkb_context_new context_new;
PFN_xkb_context_unref context_unref;
PFN_xkb_keymap_new_from_string keymap_new_from_string;
PFN_xkb_keymap_unref keymap_unref;
PFN_xkb_keymap_mod_get_index keymap_mod_get_index;
PFN_xkb_keymap_key_repeats keymap_key_repeats;
PFN_xkb_keymap_key_get_syms_by_level keymap_key_get_syms_by_level;
PFN_xkb_state_new state_new;
PFN_xkb_state_unref state_unref;
PFN_xkb_state_key_get_syms state_key_get_syms;
PFN_xkb_state_update_mask state_update_mask;
PFN_xkb_state_key_get_layout state_key_get_layout;
PFN_xkb_state_mod_index_is_active state_mod_index_is_active;
PFN_xkb_compose_table_new_from_locale compose_table_new_from_locale;
PFN_xkb_compose_table_unref compose_table_unref;
PFN_xkb_compose_state_new compose_state_new;
PFN_xkb_compose_state_unref compose_state_unref;
PFN_xkb_compose_state_feed compose_state_feed;
PFN_xkb_compose_state_get_status compose_state_get_status;
PFN_xkb_compose_state_get_one_sym compose_state_get_one_sym;
} xkb;
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
struct {
void* handle;
PFN_wl_display_flush display_flush;
PFN_wl_display_cancel_read display_cancel_read;
PFN_wl_display_dispatch_pending display_dispatch_pending;
PFN_wl_display_read_events display_read_events;
PFN_wl_display_disconnect display_disconnect;
PFN_wl_display_roundtrip display_roundtrip;
PFN_wl_display_get_fd display_get_fd;
PFN_wl_display_prepare_read display_prepare_read;
PFN_wl_proxy_marshal proxy_marshal;
PFN_wl_proxy_add_listener proxy_add_listener;
PFN_wl_proxy_destroy proxy_destroy;
PFN_wl_proxy_marshal_constructor proxy_marshal_constructor;
PFN_wl_proxy_marshal_constructor_versioned proxy_marshal_constructor_versioned;
PFN_wl_proxy_get_user_data proxy_get_user_data;
PFN_wl_proxy_set_user_data proxy_set_user_data;
PFN_wl_proxy_get_tag proxy_get_tag;
PFN_wl_proxy_set_tag proxy_set_tag;
PFN_wl_proxy_get_version proxy_get_version;
PFN_wl_proxy_marshal_flags proxy_marshal_flags;
} client;
struct {
void* handle;
PFN_wl_cursor_theme_load theme_load;
PFN_wl_cursor_theme_destroy theme_destroy;
PFN_wl_cursor_theme_get_cursor theme_get_cursor;
PFN_wl_cursor_image_get_buffer image_get_buffer;
} cursor;
struct {
void* handle;
PFN_wl_egl_window_create window_create;
PFN_wl_egl_window_destroy window_destroy;
PFN_wl_egl_window_resize window_resize;
} egl;
struct {
void* handle;
struct libdecor* context;
struct wl_callback* callback;
GLFWbool ready;
PFN_libdecor_new libdecor_new_;
PFN_libdecor_unref libdecor_unref_;
PFN_libdecor_get_fd libdecor_get_fd_;
PFN_libdecor_dispatch libdecor_dispatch_;
PFN_libdecor_decorate libdecor_decorate_;
PFN_libdecor_frame_unref libdecor_frame_unref_;
PFN_libdecor_frame_set_app_id libdecor_frame_set_app_id_;
PFN_libdecor_frame_set_title libdecor_frame_set_title_;
PFN_libdecor_frame_set_minimized libdecor_frame_set_minimized_;
PFN_libdecor_frame_set_fullscreen libdecor_frame_set_fullscreen_;
PFN_libdecor_frame_unset_fullscreen libdecor_frame_unset_fullscreen_;
PFN_libdecor_frame_map libdecor_frame_map_;
PFN_libdecor_frame_commit libdecor_frame_commit_;
PFN_libdecor_frame_set_min_content_size libdecor_frame_set_min_content_size_;
PFN_libdecor_frame_set_max_content_size libdecor_frame_set_max_content_size_;
PFN_libdecor_frame_set_maximized libdecor_frame_set_maximized_;
PFN_libdecor_frame_unset_maximized libdecor_frame_unset_maximized_;
PFN_libdecor_frame_set_capabilities libdecor_frame_set_capabilities_;
PFN_libdecor_frame_unset_capabilities libdecor_frame_unset_capabilities_;
PFN_libdecor_frame_set_visibility libdecor_frame_set_visibility_;
PFN_libdecor_frame_get_xdg_toplevel libdecor_frame_get_xdg_toplevel_;
PFN_libdecor_configuration_get_content_size libdecor_configuration_get_content_size_;
PFN_libdecor_configuration_get_window_state libdecor_configuration_get_window_state_;
PFN_libdecor_state_new libdecor_state_new_;
PFN_libdecor_state_free libdecor_state_free_;
} libdecor;
} _GLFWlibraryWayland;
// Wayland-specific per-monitor data
//
typedef struct _GLFWmonitorWayland
{
struct wl_output* output;
uint32_t name;
int currentMode;
int x;
int y;
int32_t scale;
} _GLFWmonitorWayland;
// Wayland-specific per-cursor data
//
typedef struct _GLFWcursorWayland
{
struct wl_cursor* cursor;
struct wl_cursor* cursorHiDPI;
struct wl_buffer* buffer;
int width, height;
int xhot, yhot;
int currentImage;
} _GLFWcursorWayland;
GLFWbool _glfwConnectWayland(int platformID, _GLFWplatform* platform);
int _glfwInitWayland(void);
void _glfwTerminateWayland(void);
GLFWbool _glfwCreateWindowWayland(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowWayland(_GLFWwindow* window);
void _glfwSetWindowTitleWayland(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconWayland(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosWayland(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosWayland(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeWayland(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeWayland(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsWayland(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioWayland(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeWayland(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeWayland(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleWayland(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowWayland(_GLFWwindow* window);
void _glfwRestoreWindowWayland(_GLFWwindow* window);
void _glfwMaximizeWindowWayland(_GLFWwindow* window);
void _glfwShowWindowWayland(_GLFWwindow* window);
void _glfwHideWindowWayland(_GLFWwindow* window);
void _glfwRequestWindowAttentionWayland(_GLFWwindow* window);
void _glfwFocusWindowWayland(_GLFWwindow* window);
void _glfwSetWindowMonitorWayland(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleWayland(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedWayland(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredWayland(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentWayland(_GLFWwindow* window);
void _glfwSetWindowResizableWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingWayland(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityWayland(_GLFWwindow* window);
void _glfwSetWindowOpacityWayland(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughWayland(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionWayland(_GLFWwindow* window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedWayland(void);
void _glfwPollEventsWayland(void);
void _glfwWaitEventsWayland(void);
void _glfwWaitEventsTimeoutWayland(double timeout);
void _glfwPostEmptyEventWayland(void);
void _glfwGetCursorPosWayland(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosWayland(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeWayland(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameWayland(int scancode);
int _glfwGetKeyScancodeWayland(int key);
GLFWbool _glfwCreateCursorWayland(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorWayland(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorWayland(_GLFWcursor* cursor);
void _glfwSetCursorWayland(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringWayland(const char* string);
const char* _glfwGetClipboardStringWayland(void);
EGLenum _glfwGetEGLPlatformWayland(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayWayland(void);
EGLNativeWindowType _glfwGetEGLNativeWindowWayland(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsWayland(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportWayland(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceWayland(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorWayland(_GLFWmonitor* monitor);
void _glfwGetMonitorPosWayland(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleWayland(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaWayland(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesWayland(_GLFWmonitor* monitor, int* count);
GLFWbool _glfwGetVideoModeWayland(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampWayland(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampWayland(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwAddOutputWayland(uint32_t name, uint32_t version);
void _glfwUpdateBufferScaleFromOutputsWayland(_GLFWwindow* window);
void _glfwAddSeatListenerWayland(struct wl_seat* seat);
void _glfwAddDataDeviceListenerWayland(struct wl_data_device* device);

3309
raylib/external/glfw/src/wl_window.c vendored Normal file

File diff suppressed because it is too large Load Diff

1657
raylib/external/glfw/src/x11_init.c vendored Normal file

File diff suppressed because it is too large Load Diff

641
raylib/external/glfw/src/x11_monitor.c vendored Normal file
View File

@@ -0,0 +1,641 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2019 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_X11)
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
// Check whether the display mode should be included in enumeration
//
static GLFWbool modeIsGood(const XRRModeInfo* mi)
{
return (mi->modeFlags & RR_Interlace) == 0;
}
// Calculates the refresh rate, in Hz, from the specified RandR mode info
//
static int calculateRefreshRate(const XRRModeInfo* mi)
{
if (mi->hTotal && mi->vTotal)
return (int) round((double) mi->dotClock / ((double) mi->hTotal * (double) mi->vTotal));
else
return 0;
}
// Returns the mode info for a RandR mode XID
//
static const XRRModeInfo* getModeInfo(const XRRScreenResources* sr, RRMode id)
{
for (int i = 0; i < sr->nmode; i++)
{
if (sr->modes[i].id == id)
return sr->modes + i;
}
return NULL;
}
// Convert RandR mode info to GLFW video mode
//
static GLFWvidmode vidmodeFromModeInfo(const XRRModeInfo* mi,
const XRRCrtcInfo* ci)
{
GLFWvidmode mode;
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
mode.width = mi->height;
mode.height = mi->width;
}
else
{
mode.width = mi->width;
mode.height = mi->height;
}
mode.refreshRate = calculateRefreshRate(mi);
_glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen),
&mode.redBits, &mode.greenBits, &mode.blueBits);
return mode;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Poll for changes in the set of connected monitors
//
void _glfwPollMonitorsX11(void)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
int disconnectedCount, screenCount = 0;
_GLFWmonitor** disconnected = NULL;
XineramaScreenInfo* screens = NULL;
XRRScreenResources* sr = XRRGetScreenResourcesCurrent(_glfw.x11.display,
_glfw.x11.root);
RROutput primary = XRRGetOutputPrimary(_glfw.x11.display,
_glfw.x11.root);
if (_glfw.x11.xinerama.available)
screens = XineramaQueryScreens(_glfw.x11.display, &screenCount);
disconnectedCount = _glfw.monitorCount;
if (disconnectedCount)
{
disconnected = _glfw_calloc(_glfw.monitorCount, sizeof(_GLFWmonitor*));
memcpy(disconnected,
_glfw.monitors,
_glfw.monitorCount * sizeof(_GLFWmonitor*));
}
for (int i = 0; i < sr->noutput; i++)
{
int j, type, widthMM, heightMM;
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, sr->outputs[i]);
if (oi->connection != RR_Connected || oi->crtc == None)
{
XRRFreeOutputInfo(oi);
continue;
}
for (j = 0; j < disconnectedCount; j++)
{
if (disconnected[j] &&
disconnected[j]->x11.output == sr->outputs[i])
{
disconnected[j] = NULL;
break;
}
}
if (j < disconnectedCount)
{
XRRFreeOutputInfo(oi);
continue;
}
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, oi->crtc);
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
widthMM = oi->mm_height;
heightMM = oi->mm_width;
}
else
{
widthMM = oi->mm_width;
heightMM = oi->mm_height;
}
if (widthMM <= 0 || heightMM <= 0)
{
// HACK: If RandR does not provide a physical size, assume the
// X11 default 96 DPI and calculate from the CRTC viewport
// NOTE: These members are affected by rotation, unlike the mode
// info and output info members
widthMM = (int) (ci->width * 25.4f / 96.f);
heightMM = (int) (ci->height * 25.4f / 96.f);
}
_GLFWmonitor* monitor = _glfwAllocMonitor(oi->name, widthMM, heightMM);
monitor->x11.output = sr->outputs[i];
monitor->x11.crtc = oi->crtc;
for (j = 0; j < screenCount; j++)
{
if (screens[j].x_org == ci->x &&
screens[j].y_org == ci->y &&
screens[j].width == ci->width &&
screens[j].height == ci->height)
{
monitor->x11.index = j;
break;
}
}
if (monitor->x11.output == primary)
type = _GLFW_INSERT_FIRST;
else
type = _GLFW_INSERT_LAST;
_glfwInputMonitor(monitor, GLFW_CONNECTED, type);
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
if (screens)
XFree(screens);
for (int i = 0; i < disconnectedCount; i++)
{
if (disconnected[i])
_glfwInputMonitor(disconnected[i], GLFW_DISCONNECTED, 0);
}
_glfw_free(disconnected);
}
else
{
const int widthMM = DisplayWidthMM(_glfw.x11.display, _glfw.x11.screen);
const int heightMM = DisplayHeightMM(_glfw.x11.display, _glfw.x11.screen);
_glfwInputMonitor(_glfwAllocMonitor("Display", widthMM, heightMM),
GLFW_CONNECTED,
_GLFW_INSERT_FIRST);
}
}
// Set the current video mode for the specified monitor
//
void _glfwSetVideoModeX11(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
GLFWvidmode current;
RRMode native = None;
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
_glfwGetVideoModeX11(monitor, &current);
if (_glfwCompareVideoModes(&current, best) == 0)
return;
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
continue;
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
if (_glfwCompareVideoModes(best, &mode) == 0)
{
native = mi->id;
break;
}
}
if (native)
{
if (monitor->x11.oldMode == None)
monitor->x11.oldMode = ci->mode;
XRRSetCrtcConfig(_glfw.x11.display,
sr, monitor->x11.crtc,
CurrentTime,
ci->x, ci->y,
native,
ci->rotation,
ci->outputs,
ci->noutput);
}
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
}
// Restore the saved (original) video mode for the specified monitor
//
void _glfwRestoreVideoModeX11(_GLFWmonitor* monitor)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
if (monitor->x11.oldMode == None)
return;
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRRSetCrtcConfig(_glfw.x11.display,
sr, monitor->x11.crtc,
CurrentTime,
ci->x, ci->y,
monitor->x11.oldMode,
ci->rotation,
ci->outputs,
ci->noutput);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
monitor->x11.oldMode = None;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorX11(_GLFWmonitor* monitor)
{
}
void _glfwGetMonitorPosX11(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
if (ci)
{
if (xpos)
*xpos = ci->x;
if (ypos)
*ypos = ci->y;
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
}
}
void _glfwGetMonitorContentScaleX11(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = _glfw.x11.contentScaleX;
if (yscale)
*yscale = _glfw.x11.contentScaleY;
}
void _glfwGetMonitorWorkareaX11(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
int areaX = 0, areaY = 0, areaWidth = 0, areaHeight = 0;
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
areaX = ci->x;
areaY = ci->y;
const XRRModeInfo* mi = getModeInfo(sr, ci->mode);
if (ci->rotation == RR_Rotate_90 || ci->rotation == RR_Rotate_270)
{
areaWidth = mi->height;
areaHeight = mi->width;
}
else
{
areaWidth = mi->width;
areaHeight = mi->height;
}
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
else
{
areaWidth = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
areaHeight = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
}
if (_glfw.x11.NET_WORKAREA && _glfw.x11.NET_CURRENT_DESKTOP)
{
Atom* extents = NULL;
Atom* desktop = NULL;
const unsigned long extentCount =
_glfwGetWindowPropertyX11(_glfw.x11.root,
_glfw.x11.NET_WORKAREA,
XA_CARDINAL,
(unsigned char**) &extents);
if (_glfwGetWindowPropertyX11(_glfw.x11.root,
_glfw.x11.NET_CURRENT_DESKTOP,
XA_CARDINAL,
(unsigned char**) &desktop) > 0)
{
if (extentCount >= 4 && *desktop < extentCount / 4)
{
const int globalX = extents[*desktop * 4 + 0];
const int globalY = extents[*desktop * 4 + 1];
const int globalWidth = extents[*desktop * 4 + 2];
const int globalHeight = extents[*desktop * 4 + 3];
if (areaX < globalX)
{
areaWidth -= globalX - areaX;
areaX = globalX;
}
if (areaY < globalY)
{
areaHeight -= globalY - areaY;
areaY = globalY;
}
if (areaX + areaWidth > globalX + globalWidth)
areaWidth = globalX - areaX + globalWidth;
if (areaY + areaHeight > globalY + globalHeight)
areaHeight = globalY - areaY + globalHeight;
}
}
if (extents)
XFree(extents);
if (desktop)
XFree(desktop);
}
if (xpos)
*xpos = areaX;
if (ypos)
*ypos = areaY;
if (width)
*width = areaWidth;
if (height)
*height = areaHeight;
}
GLFWvidmode* _glfwGetVideoModesX11(_GLFWmonitor* monitor, int* count)
{
GLFWvidmode* result;
*count = 0;
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
XRROutputInfo* oi = XRRGetOutputInfo(_glfw.x11.display, sr, monitor->x11.output);
result = _glfw_calloc(oi->nmode, sizeof(GLFWvidmode));
for (int i = 0; i < oi->nmode; i++)
{
const XRRModeInfo* mi = getModeInfo(sr, oi->modes[i]);
if (!modeIsGood(mi))
continue;
const GLFWvidmode mode = vidmodeFromModeInfo(mi, ci);
int j;
for (j = 0; j < *count; j++)
{
if (_glfwCompareVideoModes(result + j, &mode) == 0)
break;
}
// Skip duplicate modes
if (j < *count)
continue;
(*count)++;
result[*count - 1] = mode;
}
XRRFreeOutputInfo(oi);
XRRFreeCrtcInfo(ci);
XRRFreeScreenResources(sr);
}
else
{
*count = 1;
result = _glfw_calloc(1, sizeof(GLFWvidmode));
_glfwGetVideoModeX11(monitor, result);
}
return result;
}
GLFWbool _glfwGetVideoModeX11(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.monitorBroken)
{
XRRScreenResources* sr =
XRRGetScreenResourcesCurrent(_glfw.x11.display, _glfw.x11.root);
const XRRModeInfo* mi = NULL;
XRRCrtcInfo* ci = XRRGetCrtcInfo(_glfw.x11.display, sr, monitor->x11.crtc);
if (ci)
{
mi = getModeInfo(sr, ci->mode);
if (mi)
*mode = vidmodeFromModeInfo(mi, ci);
XRRFreeCrtcInfo(ci);
}
XRRFreeScreenResources(sr);
if (!mi)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "X11: Failed to query video mode");
return GLFW_FALSE;
}
}
else
{
mode->width = DisplayWidth(_glfw.x11.display, _glfw.x11.screen);
mode->height = DisplayHeight(_glfw.x11.display, _glfw.x11.screen);
mode->refreshRate = 0;
_glfwSplitBPP(DefaultDepth(_glfw.x11.display, _glfw.x11.screen),
&mode->redBits, &mode->greenBits, &mode->blueBits);
}
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampX11(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
const size_t size = XRRGetCrtcGammaSize(_glfw.x11.display,
monitor->x11.crtc);
XRRCrtcGamma* gamma = XRRGetCrtcGamma(_glfw.x11.display,
monitor->x11.crtc);
_glfwAllocGammaArrays(ramp, size);
memcpy(ramp->red, gamma->red, size * sizeof(unsigned short));
memcpy(ramp->green, gamma->green, size * sizeof(unsigned short));
memcpy(ramp->blue, gamma->blue, size * sizeof(unsigned short));
XRRFreeGamma(gamma);
return GLFW_TRUE;
}
else if (_glfw.x11.vidmode.available)
{
int size;
XF86VidModeGetGammaRampSize(_glfw.x11.display, _glfw.x11.screen, &size);
_glfwAllocGammaArrays(ramp, size);
XF86VidModeGetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
ramp->size, ramp->red, ramp->green, ramp->blue);
return GLFW_TRUE;
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
return GLFW_FALSE;
}
}
void _glfwSetGammaRampX11(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
if (_glfw.x11.randr.available && !_glfw.x11.randr.gammaBroken)
{
if (XRRGetCrtcGammaSize(_glfw.x11.display, monitor->x11.crtc) != ramp->size)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp size must match current ramp size");
return;
}
XRRCrtcGamma* gamma = XRRAllocGamma(ramp->size);
memcpy(gamma->red, ramp->red, ramp->size * sizeof(unsigned short));
memcpy(gamma->green, ramp->green, ramp->size * sizeof(unsigned short));
memcpy(gamma->blue, ramp->blue, ramp->size * sizeof(unsigned short));
XRRSetCrtcGamma(_glfw.x11.display, monitor->x11.crtc, gamma);
XRRFreeGamma(gamma);
}
else if (_glfw.x11.vidmode.available)
{
XF86VidModeSetGammaRamp(_glfw.x11.display,
_glfw.x11.screen,
ramp->size,
(unsigned short*) ramp->red,
(unsigned short*) ramp->green,
(unsigned short*) ramp->blue);
}
else
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"X11: Gamma ramp access not supported by server");
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW native API //////
//////////////////////////////////////////////////////////////////////////
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized");
return None;
}
return monitor->x11.crtc;
}
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* handle)
{
_GLFWmonitor* monitor = (_GLFWmonitor*) handle;
_GLFW_REQUIRE_INIT_OR_RETURN(None);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "X11: Platform not initialized");
return None;
}
return monitor->x11.output;
}
#endif // _GLFW_X11

1004
raylib/external/glfw/src/x11_platform.h vendored Normal file

File diff suppressed because it is too large Load Diff

3358
raylib/external/glfw/src/x11_window.c vendored Normal file

File diff suppressed because it is too large Load Diff

943
raylib/external/glfw/src/xkb_unicode.c vendored Normal file
View File

@@ -0,0 +1,943 @@
//========================================================================
// GLFW 3.4 X11 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2017 Camilla Löwy <elmindreda@glfw.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
#if defined(_GLFW_X11) || defined(_GLFW_WAYLAND)
/*
* Marcus: This code was originally written by Markus G. Kuhn.
* I have made some slight changes (trimmed it down a bit from >60 KB to
* 20 KB), but the functionality is the same.
*/
/*
* This module converts keysym values into the corresponding ISO 10646
* (UCS, Unicode) values.
*
* The array keysymtab[] contains pairs of X11 keysym values for graphical
* characters and the corresponding Unicode value. The function
* _glfwKeySym2Unicode() maps a keysym onto a Unicode value using a binary
* search, therefore keysymtab[] must remain SORTED by keysym value.
*
* We allow to represent any UCS character in the range U-00000000 to
* U-00FFFFFF by a keysym value in the range 0x01000000 to 0x01ffffff.
* This admittedly does not cover the entire 31-bit space of UCS, but
* it does cover all of the characters up to U-10FFFF, which can be
* represented by UTF-16, and more, and it is very unlikely that higher
* UCS codes will ever be assigned by ISO. So to get Unicode character
* U+ABCD you can directly use keysym 0x0100abcd.
*
* Original author: Markus G. Kuhn <mkuhn@acm.org>, University of
* Cambridge, April 2001
*
* Special thanks to Richard Verhoeven <river@win.tue.nl> for preparing
* an initial draft of the mapping table.
*
*/
//************************************************************************
//**** KeySym to Unicode mapping table ****
//************************************************************************
static const struct codepair {
unsigned short keysym;
unsigned short ucs;
} keysymtab[] = {
{ 0x01a1, 0x0104 },
{ 0x01a2, 0x02d8 },
{ 0x01a3, 0x0141 },
{ 0x01a5, 0x013d },
{ 0x01a6, 0x015a },
{ 0x01a9, 0x0160 },
{ 0x01aa, 0x015e },
{ 0x01ab, 0x0164 },
{ 0x01ac, 0x0179 },
{ 0x01ae, 0x017d },
{ 0x01af, 0x017b },
{ 0x01b1, 0x0105 },
{ 0x01b2, 0x02db },
{ 0x01b3, 0x0142 },
{ 0x01b5, 0x013e },
{ 0x01b6, 0x015b },
{ 0x01b7, 0x02c7 },
{ 0x01b9, 0x0161 },
{ 0x01ba, 0x015f },
{ 0x01bb, 0x0165 },
{ 0x01bc, 0x017a },
{ 0x01bd, 0x02dd },
{ 0x01be, 0x017e },
{ 0x01bf, 0x017c },
{ 0x01c0, 0x0154 },
{ 0x01c3, 0x0102 },
{ 0x01c5, 0x0139 },
{ 0x01c6, 0x0106 },
{ 0x01c8, 0x010c },
{ 0x01ca, 0x0118 },
{ 0x01cc, 0x011a },
{ 0x01cf, 0x010e },
{ 0x01d0, 0x0110 },
{ 0x01d1, 0x0143 },
{ 0x01d2, 0x0147 },
{ 0x01d5, 0x0150 },
{ 0x01d8, 0x0158 },
{ 0x01d9, 0x016e },
{ 0x01db, 0x0170 },
{ 0x01de, 0x0162 },
{ 0x01e0, 0x0155 },
{ 0x01e3, 0x0103 },
{ 0x01e5, 0x013a },
{ 0x01e6, 0x0107 },
{ 0x01e8, 0x010d },
{ 0x01ea, 0x0119 },
{ 0x01ec, 0x011b },
{ 0x01ef, 0x010f },
{ 0x01f0, 0x0111 },
{ 0x01f1, 0x0144 },
{ 0x01f2, 0x0148 },
{ 0x01f5, 0x0151 },
{ 0x01f8, 0x0159 },
{ 0x01f9, 0x016f },
{ 0x01fb, 0x0171 },
{ 0x01fe, 0x0163 },
{ 0x01ff, 0x02d9 },
{ 0x02a1, 0x0126 },
{ 0x02a6, 0x0124 },
{ 0x02a9, 0x0130 },
{ 0x02ab, 0x011e },
{ 0x02ac, 0x0134 },
{ 0x02b1, 0x0127 },
{ 0x02b6, 0x0125 },
{ 0x02b9, 0x0131 },
{ 0x02bb, 0x011f },
{ 0x02bc, 0x0135 },
{ 0x02c5, 0x010a },
{ 0x02c6, 0x0108 },
{ 0x02d5, 0x0120 },
{ 0x02d8, 0x011c },
{ 0x02dd, 0x016c },
{ 0x02de, 0x015c },
{ 0x02e5, 0x010b },
{ 0x02e6, 0x0109 },
{ 0x02f5, 0x0121 },
{ 0x02f8, 0x011d },
{ 0x02fd, 0x016d },
{ 0x02fe, 0x015d },
{ 0x03a2, 0x0138 },
{ 0x03a3, 0x0156 },
{ 0x03a5, 0x0128 },
{ 0x03a6, 0x013b },
{ 0x03aa, 0x0112 },
{ 0x03ab, 0x0122 },
{ 0x03ac, 0x0166 },
{ 0x03b3, 0x0157 },
{ 0x03b5, 0x0129 },
{ 0x03b6, 0x013c },
{ 0x03ba, 0x0113 },
{ 0x03bb, 0x0123 },
{ 0x03bc, 0x0167 },
{ 0x03bd, 0x014a },
{ 0x03bf, 0x014b },
{ 0x03c0, 0x0100 },
{ 0x03c7, 0x012e },
{ 0x03cc, 0x0116 },
{ 0x03cf, 0x012a },
{ 0x03d1, 0x0145 },
{ 0x03d2, 0x014c },
{ 0x03d3, 0x0136 },
{ 0x03d9, 0x0172 },
{ 0x03dd, 0x0168 },
{ 0x03de, 0x016a },
{ 0x03e0, 0x0101 },
{ 0x03e7, 0x012f },
{ 0x03ec, 0x0117 },
{ 0x03ef, 0x012b },
{ 0x03f1, 0x0146 },
{ 0x03f2, 0x014d },
{ 0x03f3, 0x0137 },
{ 0x03f9, 0x0173 },
{ 0x03fd, 0x0169 },
{ 0x03fe, 0x016b },
{ 0x047e, 0x203e },
{ 0x04a1, 0x3002 },
{ 0x04a2, 0x300c },
{ 0x04a3, 0x300d },
{ 0x04a4, 0x3001 },
{ 0x04a5, 0x30fb },
{ 0x04a6, 0x30f2 },
{ 0x04a7, 0x30a1 },
{ 0x04a8, 0x30a3 },
{ 0x04a9, 0x30a5 },
{ 0x04aa, 0x30a7 },
{ 0x04ab, 0x30a9 },
{ 0x04ac, 0x30e3 },
{ 0x04ad, 0x30e5 },
{ 0x04ae, 0x30e7 },
{ 0x04af, 0x30c3 },
{ 0x04b0, 0x30fc },
{ 0x04b1, 0x30a2 },
{ 0x04b2, 0x30a4 },
{ 0x04b3, 0x30a6 },
{ 0x04b4, 0x30a8 },
{ 0x04b5, 0x30aa },
{ 0x04b6, 0x30ab },
{ 0x04b7, 0x30ad },
{ 0x04b8, 0x30af },
{ 0x04b9, 0x30b1 },
{ 0x04ba, 0x30b3 },
{ 0x04bb, 0x30b5 },
{ 0x04bc, 0x30b7 },
{ 0x04bd, 0x30b9 },
{ 0x04be, 0x30bb },
{ 0x04bf, 0x30bd },
{ 0x04c0, 0x30bf },
{ 0x04c1, 0x30c1 },
{ 0x04c2, 0x30c4 },
{ 0x04c3, 0x30c6 },
{ 0x04c4, 0x30c8 },
{ 0x04c5, 0x30ca },
{ 0x04c6, 0x30cb },
{ 0x04c7, 0x30cc },
{ 0x04c8, 0x30cd },
{ 0x04c9, 0x30ce },
{ 0x04ca, 0x30cf },
{ 0x04cb, 0x30d2 },
{ 0x04cc, 0x30d5 },
{ 0x04cd, 0x30d8 },
{ 0x04ce, 0x30db },
{ 0x04cf, 0x30de },
{ 0x04d0, 0x30df },
{ 0x04d1, 0x30e0 },
{ 0x04d2, 0x30e1 },
{ 0x04d3, 0x30e2 },
{ 0x04d4, 0x30e4 },
{ 0x04d5, 0x30e6 },
{ 0x04d6, 0x30e8 },
{ 0x04d7, 0x30e9 },
{ 0x04d8, 0x30ea },
{ 0x04d9, 0x30eb },
{ 0x04da, 0x30ec },
{ 0x04db, 0x30ed },
{ 0x04dc, 0x30ef },
{ 0x04dd, 0x30f3 },
{ 0x04de, 0x309b },
{ 0x04df, 0x309c },
{ 0x05ac, 0x060c },
{ 0x05bb, 0x061b },
{ 0x05bf, 0x061f },
{ 0x05c1, 0x0621 },
{ 0x05c2, 0x0622 },
{ 0x05c3, 0x0623 },
{ 0x05c4, 0x0624 },
{ 0x05c5, 0x0625 },
{ 0x05c6, 0x0626 },
{ 0x05c7, 0x0627 },
{ 0x05c8, 0x0628 },
{ 0x05c9, 0x0629 },
{ 0x05ca, 0x062a },
{ 0x05cb, 0x062b },
{ 0x05cc, 0x062c },
{ 0x05cd, 0x062d },
{ 0x05ce, 0x062e },
{ 0x05cf, 0x062f },
{ 0x05d0, 0x0630 },
{ 0x05d1, 0x0631 },
{ 0x05d2, 0x0632 },
{ 0x05d3, 0x0633 },
{ 0x05d4, 0x0634 },
{ 0x05d5, 0x0635 },
{ 0x05d6, 0x0636 },
{ 0x05d7, 0x0637 },
{ 0x05d8, 0x0638 },
{ 0x05d9, 0x0639 },
{ 0x05da, 0x063a },
{ 0x05e0, 0x0640 },
{ 0x05e1, 0x0641 },
{ 0x05e2, 0x0642 },
{ 0x05e3, 0x0643 },
{ 0x05e4, 0x0644 },
{ 0x05e5, 0x0645 },
{ 0x05e6, 0x0646 },
{ 0x05e7, 0x0647 },
{ 0x05e8, 0x0648 },
{ 0x05e9, 0x0649 },
{ 0x05ea, 0x064a },
{ 0x05eb, 0x064b },
{ 0x05ec, 0x064c },
{ 0x05ed, 0x064d },
{ 0x05ee, 0x064e },
{ 0x05ef, 0x064f },
{ 0x05f0, 0x0650 },
{ 0x05f1, 0x0651 },
{ 0x05f2, 0x0652 },
{ 0x06a1, 0x0452 },
{ 0x06a2, 0x0453 },
{ 0x06a3, 0x0451 },
{ 0x06a4, 0x0454 },
{ 0x06a5, 0x0455 },
{ 0x06a6, 0x0456 },
{ 0x06a7, 0x0457 },
{ 0x06a8, 0x0458 },
{ 0x06a9, 0x0459 },
{ 0x06aa, 0x045a },
{ 0x06ab, 0x045b },
{ 0x06ac, 0x045c },
{ 0x06ae, 0x045e },
{ 0x06af, 0x045f },
{ 0x06b0, 0x2116 },
{ 0x06b1, 0x0402 },
{ 0x06b2, 0x0403 },
{ 0x06b3, 0x0401 },
{ 0x06b4, 0x0404 },
{ 0x06b5, 0x0405 },
{ 0x06b6, 0x0406 },
{ 0x06b7, 0x0407 },
{ 0x06b8, 0x0408 },
{ 0x06b9, 0x0409 },
{ 0x06ba, 0x040a },
{ 0x06bb, 0x040b },
{ 0x06bc, 0x040c },
{ 0x06be, 0x040e },
{ 0x06bf, 0x040f },
{ 0x06c0, 0x044e },
{ 0x06c1, 0x0430 },
{ 0x06c2, 0x0431 },
{ 0x06c3, 0x0446 },
{ 0x06c4, 0x0434 },
{ 0x06c5, 0x0435 },
{ 0x06c6, 0x0444 },
{ 0x06c7, 0x0433 },
{ 0x06c8, 0x0445 },
{ 0x06c9, 0x0438 },
{ 0x06ca, 0x0439 },
{ 0x06cb, 0x043a },
{ 0x06cc, 0x043b },
{ 0x06cd, 0x043c },
{ 0x06ce, 0x043d },
{ 0x06cf, 0x043e },
{ 0x06d0, 0x043f },
{ 0x06d1, 0x044f },
{ 0x06d2, 0x0440 },
{ 0x06d3, 0x0441 },
{ 0x06d4, 0x0442 },
{ 0x06d5, 0x0443 },
{ 0x06d6, 0x0436 },
{ 0x06d7, 0x0432 },
{ 0x06d8, 0x044c },
{ 0x06d9, 0x044b },
{ 0x06da, 0x0437 },
{ 0x06db, 0x0448 },
{ 0x06dc, 0x044d },
{ 0x06dd, 0x0449 },
{ 0x06de, 0x0447 },
{ 0x06df, 0x044a },
{ 0x06e0, 0x042e },
{ 0x06e1, 0x0410 },
{ 0x06e2, 0x0411 },
{ 0x06e3, 0x0426 },
{ 0x06e4, 0x0414 },
{ 0x06e5, 0x0415 },
{ 0x06e6, 0x0424 },
{ 0x06e7, 0x0413 },
{ 0x06e8, 0x0425 },
{ 0x06e9, 0x0418 },
{ 0x06ea, 0x0419 },
{ 0x06eb, 0x041a },
{ 0x06ec, 0x041b },
{ 0x06ed, 0x041c },
{ 0x06ee, 0x041d },
{ 0x06ef, 0x041e },
{ 0x06f0, 0x041f },
{ 0x06f1, 0x042f },
{ 0x06f2, 0x0420 },
{ 0x06f3, 0x0421 },
{ 0x06f4, 0x0422 },
{ 0x06f5, 0x0423 },
{ 0x06f6, 0x0416 },
{ 0x06f7, 0x0412 },
{ 0x06f8, 0x042c },
{ 0x06f9, 0x042b },
{ 0x06fa, 0x0417 },
{ 0x06fb, 0x0428 },
{ 0x06fc, 0x042d },
{ 0x06fd, 0x0429 },
{ 0x06fe, 0x0427 },
{ 0x06ff, 0x042a },
{ 0x07a1, 0x0386 },
{ 0x07a2, 0x0388 },
{ 0x07a3, 0x0389 },
{ 0x07a4, 0x038a },
{ 0x07a5, 0x03aa },
{ 0x07a7, 0x038c },
{ 0x07a8, 0x038e },
{ 0x07a9, 0x03ab },
{ 0x07ab, 0x038f },
{ 0x07ae, 0x0385 },
{ 0x07af, 0x2015 },
{ 0x07b1, 0x03ac },
{ 0x07b2, 0x03ad },
{ 0x07b3, 0x03ae },
{ 0x07b4, 0x03af },
{ 0x07b5, 0x03ca },
{ 0x07b6, 0x0390 },
{ 0x07b7, 0x03cc },
{ 0x07b8, 0x03cd },
{ 0x07b9, 0x03cb },
{ 0x07ba, 0x03b0 },
{ 0x07bb, 0x03ce },
{ 0x07c1, 0x0391 },
{ 0x07c2, 0x0392 },
{ 0x07c3, 0x0393 },
{ 0x07c4, 0x0394 },
{ 0x07c5, 0x0395 },
{ 0x07c6, 0x0396 },
{ 0x07c7, 0x0397 },
{ 0x07c8, 0x0398 },
{ 0x07c9, 0x0399 },
{ 0x07ca, 0x039a },
{ 0x07cb, 0x039b },
{ 0x07cc, 0x039c },
{ 0x07cd, 0x039d },
{ 0x07ce, 0x039e },
{ 0x07cf, 0x039f },
{ 0x07d0, 0x03a0 },
{ 0x07d1, 0x03a1 },
{ 0x07d2, 0x03a3 },
{ 0x07d4, 0x03a4 },
{ 0x07d5, 0x03a5 },
{ 0x07d6, 0x03a6 },
{ 0x07d7, 0x03a7 },
{ 0x07d8, 0x03a8 },
{ 0x07d9, 0x03a9 },
{ 0x07e1, 0x03b1 },
{ 0x07e2, 0x03b2 },
{ 0x07e3, 0x03b3 },
{ 0x07e4, 0x03b4 },
{ 0x07e5, 0x03b5 },
{ 0x07e6, 0x03b6 },
{ 0x07e7, 0x03b7 },
{ 0x07e8, 0x03b8 },
{ 0x07e9, 0x03b9 },
{ 0x07ea, 0x03ba },
{ 0x07eb, 0x03bb },
{ 0x07ec, 0x03bc },
{ 0x07ed, 0x03bd },
{ 0x07ee, 0x03be },
{ 0x07ef, 0x03bf },
{ 0x07f0, 0x03c0 },
{ 0x07f1, 0x03c1 },
{ 0x07f2, 0x03c3 },
{ 0x07f3, 0x03c2 },
{ 0x07f4, 0x03c4 },
{ 0x07f5, 0x03c5 },
{ 0x07f6, 0x03c6 },
{ 0x07f7, 0x03c7 },
{ 0x07f8, 0x03c8 },
{ 0x07f9, 0x03c9 },
{ 0x08a1, 0x23b7 },
{ 0x08a2, 0x250c },
{ 0x08a3, 0x2500 },
{ 0x08a4, 0x2320 },
{ 0x08a5, 0x2321 },
{ 0x08a6, 0x2502 },
{ 0x08a7, 0x23a1 },
{ 0x08a8, 0x23a3 },
{ 0x08a9, 0x23a4 },
{ 0x08aa, 0x23a6 },
{ 0x08ab, 0x239b },
{ 0x08ac, 0x239d },
{ 0x08ad, 0x239e },
{ 0x08ae, 0x23a0 },
{ 0x08af, 0x23a8 },
{ 0x08b0, 0x23ac },
{ 0x08bc, 0x2264 },
{ 0x08bd, 0x2260 },
{ 0x08be, 0x2265 },
{ 0x08bf, 0x222b },
{ 0x08c0, 0x2234 },
{ 0x08c1, 0x221d },
{ 0x08c2, 0x221e },
{ 0x08c5, 0x2207 },
{ 0x08c8, 0x223c },
{ 0x08c9, 0x2243 },
{ 0x08cd, 0x21d4 },
{ 0x08ce, 0x21d2 },
{ 0x08cf, 0x2261 },
{ 0x08d6, 0x221a },
{ 0x08da, 0x2282 },
{ 0x08db, 0x2283 },
{ 0x08dc, 0x2229 },
{ 0x08dd, 0x222a },
{ 0x08de, 0x2227 },
{ 0x08df, 0x2228 },
{ 0x08ef, 0x2202 },
{ 0x08f6, 0x0192 },
{ 0x08fb, 0x2190 },
{ 0x08fc, 0x2191 },
{ 0x08fd, 0x2192 },
{ 0x08fe, 0x2193 },
{ 0x09e0, 0x25c6 },
{ 0x09e1, 0x2592 },
{ 0x09e2, 0x2409 },
{ 0x09e3, 0x240c },
{ 0x09e4, 0x240d },
{ 0x09e5, 0x240a },
{ 0x09e8, 0x2424 },
{ 0x09e9, 0x240b },
{ 0x09ea, 0x2518 },
{ 0x09eb, 0x2510 },
{ 0x09ec, 0x250c },
{ 0x09ed, 0x2514 },
{ 0x09ee, 0x253c },
{ 0x09ef, 0x23ba },
{ 0x09f0, 0x23bb },
{ 0x09f1, 0x2500 },
{ 0x09f2, 0x23bc },
{ 0x09f3, 0x23bd },
{ 0x09f4, 0x251c },
{ 0x09f5, 0x2524 },
{ 0x09f6, 0x2534 },
{ 0x09f7, 0x252c },
{ 0x09f8, 0x2502 },
{ 0x0aa1, 0x2003 },
{ 0x0aa2, 0x2002 },
{ 0x0aa3, 0x2004 },
{ 0x0aa4, 0x2005 },
{ 0x0aa5, 0x2007 },
{ 0x0aa6, 0x2008 },
{ 0x0aa7, 0x2009 },
{ 0x0aa8, 0x200a },
{ 0x0aa9, 0x2014 },
{ 0x0aaa, 0x2013 },
{ 0x0aae, 0x2026 },
{ 0x0aaf, 0x2025 },
{ 0x0ab0, 0x2153 },
{ 0x0ab1, 0x2154 },
{ 0x0ab2, 0x2155 },
{ 0x0ab3, 0x2156 },
{ 0x0ab4, 0x2157 },
{ 0x0ab5, 0x2158 },
{ 0x0ab6, 0x2159 },
{ 0x0ab7, 0x215a },
{ 0x0ab8, 0x2105 },
{ 0x0abb, 0x2012 },
{ 0x0abc, 0x2329 },
{ 0x0abe, 0x232a },
{ 0x0ac3, 0x215b },
{ 0x0ac4, 0x215c },
{ 0x0ac5, 0x215d },
{ 0x0ac6, 0x215e },
{ 0x0ac9, 0x2122 },
{ 0x0aca, 0x2613 },
{ 0x0acc, 0x25c1 },
{ 0x0acd, 0x25b7 },
{ 0x0ace, 0x25cb },
{ 0x0acf, 0x25af },
{ 0x0ad0, 0x2018 },
{ 0x0ad1, 0x2019 },
{ 0x0ad2, 0x201c },
{ 0x0ad3, 0x201d },
{ 0x0ad4, 0x211e },
{ 0x0ad6, 0x2032 },
{ 0x0ad7, 0x2033 },
{ 0x0ad9, 0x271d },
{ 0x0adb, 0x25ac },
{ 0x0adc, 0x25c0 },
{ 0x0add, 0x25b6 },
{ 0x0ade, 0x25cf },
{ 0x0adf, 0x25ae },
{ 0x0ae0, 0x25e6 },
{ 0x0ae1, 0x25ab },
{ 0x0ae2, 0x25ad },
{ 0x0ae3, 0x25b3 },
{ 0x0ae4, 0x25bd },
{ 0x0ae5, 0x2606 },
{ 0x0ae6, 0x2022 },
{ 0x0ae7, 0x25aa },
{ 0x0ae8, 0x25b2 },
{ 0x0ae9, 0x25bc },
{ 0x0aea, 0x261c },
{ 0x0aeb, 0x261e },
{ 0x0aec, 0x2663 },
{ 0x0aed, 0x2666 },
{ 0x0aee, 0x2665 },
{ 0x0af0, 0x2720 },
{ 0x0af1, 0x2020 },
{ 0x0af2, 0x2021 },
{ 0x0af3, 0x2713 },
{ 0x0af4, 0x2717 },
{ 0x0af5, 0x266f },
{ 0x0af6, 0x266d },
{ 0x0af7, 0x2642 },
{ 0x0af8, 0x2640 },
{ 0x0af9, 0x260e },
{ 0x0afa, 0x2315 },
{ 0x0afb, 0x2117 },
{ 0x0afc, 0x2038 },
{ 0x0afd, 0x201a },
{ 0x0afe, 0x201e },
{ 0x0ba3, 0x003c },
{ 0x0ba6, 0x003e },
{ 0x0ba8, 0x2228 },
{ 0x0ba9, 0x2227 },
{ 0x0bc0, 0x00af },
{ 0x0bc2, 0x22a5 },
{ 0x0bc3, 0x2229 },
{ 0x0bc4, 0x230a },
{ 0x0bc6, 0x005f },
{ 0x0bca, 0x2218 },
{ 0x0bcc, 0x2395 },
{ 0x0bce, 0x22a4 },
{ 0x0bcf, 0x25cb },
{ 0x0bd3, 0x2308 },
{ 0x0bd6, 0x222a },
{ 0x0bd8, 0x2283 },
{ 0x0bda, 0x2282 },
{ 0x0bdc, 0x22a2 },
{ 0x0bfc, 0x22a3 },
{ 0x0cdf, 0x2017 },
{ 0x0ce0, 0x05d0 },
{ 0x0ce1, 0x05d1 },
{ 0x0ce2, 0x05d2 },
{ 0x0ce3, 0x05d3 },
{ 0x0ce4, 0x05d4 },
{ 0x0ce5, 0x05d5 },
{ 0x0ce6, 0x05d6 },
{ 0x0ce7, 0x05d7 },
{ 0x0ce8, 0x05d8 },
{ 0x0ce9, 0x05d9 },
{ 0x0cea, 0x05da },
{ 0x0ceb, 0x05db },
{ 0x0cec, 0x05dc },
{ 0x0ced, 0x05dd },
{ 0x0cee, 0x05de },
{ 0x0cef, 0x05df },
{ 0x0cf0, 0x05e0 },
{ 0x0cf1, 0x05e1 },
{ 0x0cf2, 0x05e2 },
{ 0x0cf3, 0x05e3 },
{ 0x0cf4, 0x05e4 },
{ 0x0cf5, 0x05e5 },
{ 0x0cf6, 0x05e6 },
{ 0x0cf7, 0x05e7 },
{ 0x0cf8, 0x05e8 },
{ 0x0cf9, 0x05e9 },
{ 0x0cfa, 0x05ea },
{ 0x0da1, 0x0e01 },
{ 0x0da2, 0x0e02 },
{ 0x0da3, 0x0e03 },
{ 0x0da4, 0x0e04 },
{ 0x0da5, 0x0e05 },
{ 0x0da6, 0x0e06 },
{ 0x0da7, 0x0e07 },
{ 0x0da8, 0x0e08 },
{ 0x0da9, 0x0e09 },
{ 0x0daa, 0x0e0a },
{ 0x0dab, 0x0e0b },
{ 0x0dac, 0x0e0c },
{ 0x0dad, 0x0e0d },
{ 0x0dae, 0x0e0e },
{ 0x0daf, 0x0e0f },
{ 0x0db0, 0x0e10 },
{ 0x0db1, 0x0e11 },
{ 0x0db2, 0x0e12 },
{ 0x0db3, 0x0e13 },
{ 0x0db4, 0x0e14 },
{ 0x0db5, 0x0e15 },
{ 0x0db6, 0x0e16 },
{ 0x0db7, 0x0e17 },
{ 0x0db8, 0x0e18 },
{ 0x0db9, 0x0e19 },
{ 0x0dba, 0x0e1a },
{ 0x0dbb, 0x0e1b },
{ 0x0dbc, 0x0e1c },
{ 0x0dbd, 0x0e1d },
{ 0x0dbe, 0x0e1e },
{ 0x0dbf, 0x0e1f },
{ 0x0dc0, 0x0e20 },
{ 0x0dc1, 0x0e21 },
{ 0x0dc2, 0x0e22 },
{ 0x0dc3, 0x0e23 },
{ 0x0dc4, 0x0e24 },
{ 0x0dc5, 0x0e25 },
{ 0x0dc6, 0x0e26 },
{ 0x0dc7, 0x0e27 },
{ 0x0dc8, 0x0e28 },
{ 0x0dc9, 0x0e29 },
{ 0x0dca, 0x0e2a },
{ 0x0dcb, 0x0e2b },
{ 0x0dcc, 0x0e2c },
{ 0x0dcd, 0x0e2d },
{ 0x0dce, 0x0e2e },
{ 0x0dcf, 0x0e2f },
{ 0x0dd0, 0x0e30 },
{ 0x0dd1, 0x0e31 },
{ 0x0dd2, 0x0e32 },
{ 0x0dd3, 0x0e33 },
{ 0x0dd4, 0x0e34 },
{ 0x0dd5, 0x0e35 },
{ 0x0dd6, 0x0e36 },
{ 0x0dd7, 0x0e37 },
{ 0x0dd8, 0x0e38 },
{ 0x0dd9, 0x0e39 },
{ 0x0dda, 0x0e3a },
{ 0x0ddf, 0x0e3f },
{ 0x0de0, 0x0e40 },
{ 0x0de1, 0x0e41 },
{ 0x0de2, 0x0e42 },
{ 0x0de3, 0x0e43 },
{ 0x0de4, 0x0e44 },
{ 0x0de5, 0x0e45 },
{ 0x0de6, 0x0e46 },
{ 0x0de7, 0x0e47 },
{ 0x0de8, 0x0e48 },
{ 0x0de9, 0x0e49 },
{ 0x0dea, 0x0e4a },
{ 0x0deb, 0x0e4b },
{ 0x0dec, 0x0e4c },
{ 0x0ded, 0x0e4d },
{ 0x0df0, 0x0e50 },
{ 0x0df1, 0x0e51 },
{ 0x0df2, 0x0e52 },
{ 0x0df3, 0x0e53 },
{ 0x0df4, 0x0e54 },
{ 0x0df5, 0x0e55 },
{ 0x0df6, 0x0e56 },
{ 0x0df7, 0x0e57 },
{ 0x0df8, 0x0e58 },
{ 0x0df9, 0x0e59 },
{ 0x0ea1, 0x3131 },
{ 0x0ea2, 0x3132 },
{ 0x0ea3, 0x3133 },
{ 0x0ea4, 0x3134 },
{ 0x0ea5, 0x3135 },
{ 0x0ea6, 0x3136 },
{ 0x0ea7, 0x3137 },
{ 0x0ea8, 0x3138 },
{ 0x0ea9, 0x3139 },
{ 0x0eaa, 0x313a },
{ 0x0eab, 0x313b },
{ 0x0eac, 0x313c },
{ 0x0ead, 0x313d },
{ 0x0eae, 0x313e },
{ 0x0eaf, 0x313f },
{ 0x0eb0, 0x3140 },
{ 0x0eb1, 0x3141 },
{ 0x0eb2, 0x3142 },
{ 0x0eb3, 0x3143 },
{ 0x0eb4, 0x3144 },
{ 0x0eb5, 0x3145 },
{ 0x0eb6, 0x3146 },
{ 0x0eb7, 0x3147 },
{ 0x0eb8, 0x3148 },
{ 0x0eb9, 0x3149 },
{ 0x0eba, 0x314a },
{ 0x0ebb, 0x314b },
{ 0x0ebc, 0x314c },
{ 0x0ebd, 0x314d },
{ 0x0ebe, 0x314e },
{ 0x0ebf, 0x314f },
{ 0x0ec0, 0x3150 },
{ 0x0ec1, 0x3151 },
{ 0x0ec2, 0x3152 },
{ 0x0ec3, 0x3153 },
{ 0x0ec4, 0x3154 },
{ 0x0ec5, 0x3155 },
{ 0x0ec6, 0x3156 },
{ 0x0ec7, 0x3157 },
{ 0x0ec8, 0x3158 },
{ 0x0ec9, 0x3159 },
{ 0x0eca, 0x315a },
{ 0x0ecb, 0x315b },
{ 0x0ecc, 0x315c },
{ 0x0ecd, 0x315d },
{ 0x0ece, 0x315e },
{ 0x0ecf, 0x315f },
{ 0x0ed0, 0x3160 },
{ 0x0ed1, 0x3161 },
{ 0x0ed2, 0x3162 },
{ 0x0ed3, 0x3163 },
{ 0x0ed4, 0x11a8 },
{ 0x0ed5, 0x11a9 },
{ 0x0ed6, 0x11aa },
{ 0x0ed7, 0x11ab },
{ 0x0ed8, 0x11ac },
{ 0x0ed9, 0x11ad },
{ 0x0eda, 0x11ae },
{ 0x0edb, 0x11af },
{ 0x0edc, 0x11b0 },
{ 0x0edd, 0x11b1 },
{ 0x0ede, 0x11b2 },
{ 0x0edf, 0x11b3 },
{ 0x0ee0, 0x11b4 },
{ 0x0ee1, 0x11b5 },
{ 0x0ee2, 0x11b6 },
{ 0x0ee3, 0x11b7 },
{ 0x0ee4, 0x11b8 },
{ 0x0ee5, 0x11b9 },
{ 0x0ee6, 0x11ba },
{ 0x0ee7, 0x11bb },
{ 0x0ee8, 0x11bc },
{ 0x0ee9, 0x11bd },
{ 0x0eea, 0x11be },
{ 0x0eeb, 0x11bf },
{ 0x0eec, 0x11c0 },
{ 0x0eed, 0x11c1 },
{ 0x0eee, 0x11c2 },
{ 0x0eef, 0x316d },
{ 0x0ef0, 0x3171 },
{ 0x0ef1, 0x3178 },
{ 0x0ef2, 0x317f },
{ 0x0ef3, 0x3181 },
{ 0x0ef4, 0x3184 },
{ 0x0ef5, 0x3186 },
{ 0x0ef6, 0x318d },
{ 0x0ef7, 0x318e },
{ 0x0ef8, 0x11eb },
{ 0x0ef9, 0x11f0 },
{ 0x0efa, 0x11f9 },
{ 0x0eff, 0x20a9 },
{ 0x13a4, 0x20ac },
{ 0x13bc, 0x0152 },
{ 0x13bd, 0x0153 },
{ 0x13be, 0x0178 },
{ 0x20ac, 0x20ac },
{ 0xfe50, '`' },
{ 0xfe51, 0x00b4 },
{ 0xfe52, '^' },
{ 0xfe53, '~' },
{ 0xfe54, 0x00af },
{ 0xfe55, 0x02d8 },
{ 0xfe56, 0x02d9 },
{ 0xfe57, 0x00a8 },
{ 0xfe58, 0x02da },
{ 0xfe59, 0x02dd },
{ 0xfe5a, 0x02c7 },
{ 0xfe5b, 0x00b8 },
{ 0xfe5c, 0x02db },
{ 0xfe5d, 0x037a },
{ 0xfe5e, 0x309b },
{ 0xfe5f, 0x309c },
{ 0xfe63, '/' },
{ 0xfe64, 0x02bc },
{ 0xfe65, 0x02bd },
{ 0xfe66, 0x02f5 },
{ 0xfe67, 0x02f3 },
{ 0xfe68, 0x02cd },
{ 0xfe69, 0xa788 },
{ 0xfe6a, 0x02f7 },
{ 0xfe6e, ',' },
{ 0xfe6f, 0x00a4 },
{ 0xfe80, 'a' }, // XK_dead_a
{ 0xfe81, 'A' }, // XK_dead_A
{ 0xfe82, 'e' }, // XK_dead_e
{ 0xfe83, 'E' }, // XK_dead_E
{ 0xfe84, 'i' }, // XK_dead_i
{ 0xfe85, 'I' }, // XK_dead_I
{ 0xfe86, 'o' }, // XK_dead_o
{ 0xfe87, 'O' }, // XK_dead_O
{ 0xfe88, 'u' }, // XK_dead_u
{ 0xfe89, 'U' }, // XK_dead_U
{ 0xfe8a, 0x0259 },
{ 0xfe8b, 0x018f },
{ 0xfe8c, 0x00b5 },
{ 0xfe90, '_' },
{ 0xfe91, 0x02c8 },
{ 0xfe92, 0x02cc },
{ 0xff80 /*XKB_KEY_KP_Space*/, ' ' },
{ 0xff95 /*XKB_KEY_KP_7*/, 0x0037 },
{ 0xff96 /*XKB_KEY_KP_4*/, 0x0034 },
{ 0xff97 /*XKB_KEY_KP_8*/, 0x0038 },
{ 0xff98 /*XKB_KEY_KP_6*/, 0x0036 },
{ 0xff99 /*XKB_KEY_KP_2*/, 0x0032 },
{ 0xff9a /*XKB_KEY_KP_9*/, 0x0039 },
{ 0xff9b /*XKB_KEY_KP_3*/, 0x0033 },
{ 0xff9c /*XKB_KEY_KP_1*/, 0x0031 },
{ 0xff9d /*XKB_KEY_KP_5*/, 0x0035 },
{ 0xff9e /*XKB_KEY_KP_0*/, 0x0030 },
{ 0xffaa /*XKB_KEY_KP_Multiply*/, '*' },
{ 0xffab /*XKB_KEY_KP_Add*/, '+' },
{ 0xffac /*XKB_KEY_KP_Separator*/, ',' },
{ 0xffad /*XKB_KEY_KP_Subtract*/, '-' },
{ 0xffae /*XKB_KEY_KP_Decimal*/, '.' },
{ 0xffaf /*XKB_KEY_KP_Divide*/, '/' },
{ 0xffb0 /*XKB_KEY_KP_0*/, 0x0030 },
{ 0xffb1 /*XKB_KEY_KP_1*/, 0x0031 },
{ 0xffb2 /*XKB_KEY_KP_2*/, 0x0032 },
{ 0xffb3 /*XKB_KEY_KP_3*/, 0x0033 },
{ 0xffb4 /*XKB_KEY_KP_4*/, 0x0034 },
{ 0xffb5 /*XKB_KEY_KP_5*/, 0x0035 },
{ 0xffb6 /*XKB_KEY_KP_6*/, 0x0036 },
{ 0xffb7 /*XKB_KEY_KP_7*/, 0x0037 },
{ 0xffb8 /*XKB_KEY_KP_8*/, 0x0038 },
{ 0xffb9 /*XKB_KEY_KP_9*/, 0x0039 },
{ 0xffbd /*XKB_KEY_KP_Equal*/, '=' }
};
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
// Convert XKB KeySym to Unicode
//
uint32_t _glfwKeySym2Unicode(unsigned int 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;
}
// Also check for directly encoded 24-bit UCS characters
if ((keysym & 0xff000000) == 0x01000000)
return keysym & 0x00ffffff;
// Binary search in table
while (max >= min)
{
mid = (min + max) / 2;
if (keysymtab[mid].keysym < keysym)
min = mid + 1;
else if (keysymtab[mid].keysym > keysym)
max = mid - 1;
else
return keysymtab[mid].ucs;
}
// No matching Unicode value found
return GLFW_INVALID_CODEPOINT;
}
#endif // _GLFW_WAYLAND or _GLFW_X11

30
raylib/external/glfw/src/xkb_unicode.h vendored Normal file
View File

@@ -0,0 +1,30 @@
//========================================================================
// GLFW 3.4 Linux - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2014 Jonas Ådahl <jadahl@gmail.com>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#define GLFW_INVALID_CODEPOINT 0xffffffffu
uint32_t _glfwKeySym2Unicode(unsigned int keysym);