+++ /dev/null
-//========================================================================
-// 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.
-//
-//========================================================================
-// Please use C89 style variable declarations in this file because VS 2010
-//========================================================================
-
-#include "internal.h"
-
-#include <assert.h>
-#include <float.h>
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-
-// Internal key state used for sticky keys
-#define _GLFW_STICK 3
-
-// Internal constants for gamepad mapping source types
-#define _GLFW_JOYSTICK_AXIS 1
-#define _GLFW_JOYSTICK_BUTTON 2
-#define _GLFW_JOYSTICK_HATBIT 3
-
-// Initializes the platform joystick API if it has not been already
-//
-static GLFWbool initJoysticks(void)
-{
- if (!_glfw.joysticksInitialized)
- {
- if (!_glfwPlatformInitJoysticks())
- {
- _glfwPlatformTerminateJoysticks();
- return GLFW_FALSE;
- }
- }
-
- return _glfw.joysticksInitialized = GLFW_TRUE;
-}
-
-// Finds a mapping based on joystick GUID
-//
-static _GLFWmapping* findMapping(const char* guid)
-{
- int i;
-
- for (i = 0; i < _glfw.mappingCount; i++)
- {
- if (strcmp(_glfw.mappings[i].guid, guid) == 0)
- return _glfw.mappings + i;
- }
-
- return NULL;
-}
-
-// Checks whether a gamepad mapping element is present in the hardware
-//
-static GLFWbool isValidElementForJoystick(const _GLFWmapelement* e,
- const _GLFWjoystick* js)
-{
- if (e->type == _GLFW_JOYSTICK_HATBIT && (e->index >> 4) >= js->hatCount)
- return GLFW_FALSE;
- else if (e->type == _GLFW_JOYSTICK_BUTTON && e->index >= js->buttonCount)
- return GLFW_FALSE;
- else if (e->type == _GLFW_JOYSTICK_AXIS && e->index >= js->axisCount)
- return GLFW_FALSE;
-
- return GLFW_TRUE;
-}
-
-// Finds a mapping based on joystick GUID and verifies element indices
-//
-static _GLFWmapping* findValidMapping(const _GLFWjoystick* js)
-{
- _GLFWmapping* mapping = findMapping(js->guid);
- if (mapping)
- {
- int i;
-
- for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
- {
- if (!isValidElementForJoystick(mapping->buttons + i, js))
- {
- _glfwInputError(GLFW_INVALID_VALUE,
- "Invalid button in gamepad mapping %s (%s)",
- mapping->guid,
- mapping->name);
- return NULL;
- }
- }
-
- for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
- {
- if (!isValidElementForJoystick(mapping->axes + i, js))
- {
- _glfwInputError(GLFW_INVALID_VALUE,
- "Invalid axis in gamepad mapping %s (%s)",
- mapping->guid,
- mapping->name);
- return NULL;
- }
- }
- }
-
- return mapping;
-}
-
-// Parses an SDL_GameControllerDB line and adds it to the mapping list
-//
-static GLFWbool parseMapping(_GLFWmapping* mapping, const char* string)
-{
- const char* c = string;
- size_t i, length;
- struct
- {
- const char* name;
- _GLFWmapelement* element;
- } fields[] =
- {
- { "platform", NULL },
- { "a", mapping->buttons + GLFW_GAMEPAD_BUTTON_A },
- { "b", mapping->buttons + GLFW_GAMEPAD_BUTTON_B },
- { "x", mapping->buttons + GLFW_GAMEPAD_BUTTON_X },
- { "y", mapping->buttons + GLFW_GAMEPAD_BUTTON_Y },
- { "back", mapping->buttons + GLFW_GAMEPAD_BUTTON_BACK },
- { "start", mapping->buttons + GLFW_GAMEPAD_BUTTON_START },
- { "guide", mapping->buttons + GLFW_GAMEPAD_BUTTON_GUIDE },
- { "leftshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_BUMPER },
- { "rightshoulder", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_BUMPER },
- { "leftstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_LEFT_THUMB },
- { "rightstick", mapping->buttons + GLFW_GAMEPAD_BUTTON_RIGHT_THUMB },
- { "dpup", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_UP },
- { "dpright", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_RIGHT },
- { "dpdown", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_DOWN },
- { "dpleft", mapping->buttons + GLFW_GAMEPAD_BUTTON_DPAD_LEFT },
- { "lefttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_TRIGGER },
- { "righttrigger", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_TRIGGER },
- { "leftx", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_X },
- { "lefty", mapping->axes + GLFW_GAMEPAD_AXIS_LEFT_Y },
- { "rightx", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_X },
- { "righty", mapping->axes + GLFW_GAMEPAD_AXIS_RIGHT_Y }
- };
-
- length = strcspn(c, ",");
- if (length != 32 || c[length] != ',')
- {
- _glfwInputError(GLFW_INVALID_VALUE, NULL);
- return GLFW_FALSE;
- }
-
- memcpy(mapping->guid, c, length);
- c += length + 1;
-
- length = strcspn(c, ",");
- if (length >= sizeof(mapping->name) || c[length] != ',')
- {
- _glfwInputError(GLFW_INVALID_VALUE, NULL);
- return GLFW_FALSE;
- }
-
- memcpy(mapping->name, c, length);
- c += length + 1;
-
- while (*c)
- {
- // TODO: Implement output modifiers
- if (*c == '+' || *c == '-')
- return GLFW_FALSE;
-
- for (i = 0; i < sizeof(fields) / sizeof(fields[0]); i++)
- {
- length = strlen(fields[i].name);
- if (strncmp(c, fields[i].name, length) != 0 || c[length] != ':')
- continue;
-
- c += length + 1;
-
- if (fields[i].element)
- {
- _GLFWmapelement* e = fields[i].element;
- int8_t minimum = -1;
- int8_t maximum = 1;
-
- if (*c == '+')
- {
- minimum = 0;
- c += 1;
- }
- else if (*c == '-')
- {
- maximum = 0;
- c += 1;
- }
-
- if (*c == 'a')
- e->type = _GLFW_JOYSTICK_AXIS;
- else if (*c == 'b')
- e->type = _GLFW_JOYSTICK_BUTTON;
- else if (*c == 'h')
- e->type = _GLFW_JOYSTICK_HATBIT;
- else
- break;
-
- if (e->type == _GLFW_JOYSTICK_HATBIT)
- {
- const unsigned long hat = strtoul(c + 1, (char**) &c, 10);
- const unsigned long bit = strtoul(c + 1, (char**) &c, 10);
- e->index = (uint8_t) ((hat << 4) | bit);
- }
- else
- e->index = (uint8_t) strtoul(c + 1, (char**) &c, 10);
-
- if (e->type == _GLFW_JOYSTICK_AXIS)
- {
- e->axisScale = 2 / (maximum - minimum);
- e->axisOffset = -(maximum + minimum);
-
- if (*c == '~')
- {
- e->axisScale = -e->axisScale;
- e->axisOffset = -e->axisOffset;
- }
- }
- }
- else
- {
- length = strlen(_GLFW_PLATFORM_MAPPING_NAME);
- if (strncmp(c, _GLFW_PLATFORM_MAPPING_NAME, length) != 0)
- return GLFW_FALSE;
- }
-
- break;
- }
-
- c += strcspn(c, ",");
- c += strspn(c, ",");
- }
-
- for (i = 0; i < 32; i++)
- {
- if (mapping->guid[i] >= 'A' && mapping->guid[i] <= 'F')
- mapping->guid[i] += 'a' - 'A';
- }
-
- _glfwPlatformUpdateGamepadGUID(mapping->guid);
- return GLFW_TRUE;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-////// GLFW event API //////
-//////////////////////////////////////////////////////////////////////////
-
-// Notifies shared code of a physical key event
-//
-void _glfwInputKey(_GLFWwindow* window, int key, int scancode, int action, int mods)
-{
- if (key >= 0 && key <= GLFW_KEY_LAST)
- {
- GLFWbool repeated = GLFW_FALSE;
-
- if (action == GLFW_RELEASE && window->keys[key] == GLFW_RELEASE)
- return;
-
- if (action == GLFW_PRESS && window->keys[key] == GLFW_PRESS)
- repeated = GLFW_TRUE;
-
- if (action == GLFW_RELEASE && window->stickyKeys)
- window->keys[key] = _GLFW_STICK;
- else
- window->keys[key] = (char) action;
-
- if (repeated)
- action = GLFW_REPEAT;
- }
-
- if (!window->lockKeyMods)
- mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
-
- if (window->callbacks.key)
- window->callbacks.key((GLFWwindow*) window, key, scancode, action, mods);
-}
-
-// Notifies shared code of a Unicode codepoint input event
-// The 'plain' parameter determines whether to emit a regular character event
-//
-void _glfwInputChar(_GLFWwindow* window, unsigned int codepoint, int mods, GLFWbool plain)
-{
- if (codepoint < 32 || (codepoint > 126 && codepoint < 160))
- return;
-
- if (!window->lockKeyMods)
- mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
-
- if (window->callbacks.charmods)
- window->callbacks.charmods((GLFWwindow*) window, codepoint, mods);
-
- if (plain)
- {
- if (window->callbacks.character)
- window->callbacks.character((GLFWwindow*) window, codepoint);
- }
-}
-
-// Notifies shared code of a scroll event
-//
-void _glfwInputScroll(_GLFWwindow* window, double xoffset, double yoffset)
-{
- if (window->callbacks.scroll)
- window->callbacks.scroll((GLFWwindow*) window, xoffset, yoffset);
-}
-
-// Notifies shared code of a mouse button click event
-//
-void _glfwInputMouseClick(_GLFWwindow* window, int button, int action, int mods)
-{
- if (button < 0 || button > GLFW_MOUSE_BUTTON_LAST)
- return;
-
- if (!window->lockKeyMods)
- mods &= ~(GLFW_MOD_CAPS_LOCK | GLFW_MOD_NUM_LOCK);
-
- if (action == GLFW_RELEASE && window->stickyMouseButtons)
- window->mouseButtons[button] = _GLFW_STICK;
- else
- window->mouseButtons[button] = (char) action;
-
- if (window->callbacks.mouseButton)
- window->callbacks.mouseButton((GLFWwindow*) window, button, action, mods);
-}
-
-// Notifies shared code of a cursor motion event
-// The position is specified in content area relative screen coordinates
-//
-void _glfwInputCursorPos(_GLFWwindow* window, double xpos, double ypos)
-{
- if (window->virtualCursorPosX == xpos && window->virtualCursorPosY == ypos)
- return;
-
- window->virtualCursorPosX = xpos;
- window->virtualCursorPosY = ypos;
-
- if (window->callbacks.cursorPos)
- window->callbacks.cursorPos((GLFWwindow*) window, xpos, ypos);
-}
-
-// Notifies shared code of a cursor enter/leave event
-//
-void _glfwInputCursorEnter(_GLFWwindow* window, GLFWbool entered)
-{
- if (window->callbacks.cursorEnter)
- window->callbacks.cursorEnter((GLFWwindow*) window, entered);
-}
-
-// Notifies shared code of files or directories dropped on a window
-//
-void _glfwInputDrop(_GLFWwindow* window, int count, const char** paths)
-{
- if (window->callbacks.drop)
- window->callbacks.drop((GLFWwindow*) window, count, paths);
-}
-
-// Notifies shared code of a joystick connection or disconnection
-//
-void _glfwInputJoystick(_GLFWjoystick* js, int event)
-{
- const int jid = (int) (js - _glfw.joysticks);
-
- if (_glfw.callbacks.joystick)
- _glfw.callbacks.joystick(jid, event);
-}
-
-// Notifies shared code of the new value of a joystick axis
-//
-void _glfwInputJoystickAxis(_GLFWjoystick* js, int axis, float value)
-{
- js->axes[axis] = value;
-}
-
-// Notifies shared code of the new value of a joystick button
-//
-void _glfwInputJoystickButton(_GLFWjoystick* js, int button, char value)
-{
- js->buttons[button] = value;
-}
-
-// Notifies shared code of the new value of a joystick hat
-//
-void _glfwInputJoystickHat(_GLFWjoystick* js, int hat, char value)
-{
- const int base = js->buttonCount + hat * 4;
-
- js->buttons[base + 0] = (value & 0x01) ? GLFW_PRESS : GLFW_RELEASE;
- js->buttons[base + 1] = (value & 0x02) ? GLFW_PRESS : GLFW_RELEASE;
- js->buttons[base + 2] = (value & 0x04) ? GLFW_PRESS : GLFW_RELEASE;
- js->buttons[base + 3] = (value & 0x08) ? GLFW_PRESS : GLFW_RELEASE;
-
- js->hats[hat] = value;
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-////// GLFW internal API //////
-//////////////////////////////////////////////////////////////////////////
-
-// Returns an available joystick object with arrays and name allocated
-//
-_GLFWjoystick* _glfwAllocJoystick(const char* name,
- const char* guid,
- int axisCount,
- int buttonCount,
- int hatCount)
-{
- int jid;
- _GLFWjoystick* js;
-
- for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
- {
- if (!_glfw.joysticks[jid].present)
- break;
- }
-
- if (jid > GLFW_JOYSTICK_LAST)
- return NULL;
-
- js = _glfw.joysticks + jid;
- js->present = GLFW_TRUE;
- js->name = _glfw_strdup(name);
- js->axes = calloc(axisCount, sizeof(float));
- js->buttons = calloc(buttonCount + (size_t) hatCount * 4, 1);
- js->hats = calloc(hatCount, 1);
- js->axisCount = axisCount;
- js->buttonCount = buttonCount;
- js->hatCount = hatCount;
-
- strncpy(js->guid, guid, sizeof(js->guid) - 1);
- js->mapping = findValidMapping(js);
-
- return js;
-}
-
-// Frees arrays and name and flags the joystick object as unused
-//
-void _glfwFreeJoystick(_GLFWjoystick* js)
-{
- free(js->name);
- free(js->axes);
- free(js->buttons);
- free(js->hats);
- memset(js, 0, sizeof(_GLFWjoystick));
-}
-
-// Center the cursor in the content area of the specified window
-//
-void _glfwCenterCursorInContentArea(_GLFWwindow* window)
-{
- int width, height;
-
- _glfwPlatformGetWindowSize(window, &width, &height);
- _glfwPlatformSetCursorPos(window, width / 2.0, height / 2.0);
-}
-
-
-//////////////////////////////////////////////////////////////////////////
-////// GLFW public API //////
-//////////////////////////////////////////////////////////////////////////
-
-GLFWAPI int glfwGetInputMode(GLFWwindow* handle, int mode)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(0);
-
- switch (mode)
- {
- case GLFW_CURSOR:
- return window->cursorMode;
- case GLFW_STICKY_KEYS:
- return window->stickyKeys;
- case GLFW_STICKY_MOUSE_BUTTONS:
- return window->stickyMouseButtons;
- case GLFW_LOCK_KEY_MODS:
- return window->lockKeyMods;
- case GLFW_RAW_MOUSE_MOTION:
- return window->rawMouseMotion;
- }
-
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
- return 0;
-}
-
-GLFWAPI void glfwSetInputMode(GLFWwindow* handle, int mode, int value)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT();
-
- if (mode == GLFW_CURSOR)
- {
- if (value != GLFW_CURSOR_NORMAL &&
- value != GLFW_CURSOR_HIDDEN &&
- value != GLFW_CURSOR_DISABLED)
- {
- _glfwInputError(GLFW_INVALID_ENUM,
- "Invalid cursor mode 0x%08X",
- value);
- return;
- }
-
- if (window->cursorMode == value)
- return;
-
- window->cursorMode = value;
-
- _glfwPlatformGetCursorPos(window,
- &window->virtualCursorPosX,
- &window->virtualCursorPosY);
- _glfwPlatformSetCursorMode(window, value);
- }
- else if (mode == GLFW_STICKY_KEYS)
- {
- value = value ? GLFW_TRUE : GLFW_FALSE;
- if (window->stickyKeys == value)
- return;
-
- if (!value)
- {
- int i;
-
- // Release all sticky keys
- for (i = 0; i <= GLFW_KEY_LAST; i++)
- {
- if (window->keys[i] == _GLFW_STICK)
- window->keys[i] = GLFW_RELEASE;
- }
- }
-
- window->stickyKeys = value;
- }
- else if (mode == GLFW_STICKY_MOUSE_BUTTONS)
- {
- value = value ? GLFW_TRUE : GLFW_FALSE;
- if (window->stickyMouseButtons == value)
- return;
-
- if (!value)
- {
- int i;
-
- // Release all sticky mouse buttons
- for (i = 0; i <= GLFW_MOUSE_BUTTON_LAST; i++)
- {
- if (window->mouseButtons[i] == _GLFW_STICK)
- window->mouseButtons[i] = GLFW_RELEASE;
- }
- }
-
- window->stickyMouseButtons = value;
- }
- else if (mode == GLFW_LOCK_KEY_MODS)
- {
- window->lockKeyMods = value ? GLFW_TRUE : GLFW_FALSE;
- }
- else if (mode == GLFW_RAW_MOUSE_MOTION)
- {
- if (!_glfwPlatformRawMouseMotionSupported())
- {
- _glfwInputError(GLFW_PLATFORM_ERROR,
- "Raw mouse motion is not supported on this system");
- return;
- }
-
- value = value ? GLFW_TRUE : GLFW_FALSE;
- if (window->rawMouseMotion == value)
- return;
-
- window->rawMouseMotion = value;
- _glfwPlatformSetRawMouseMotion(window, value);
- }
- else
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid input mode 0x%08X", mode);
-}
-
-GLFWAPI int glfwRawMouseMotionSupported(void)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
- return _glfwPlatformRawMouseMotionSupported();
-}
-
-GLFWAPI const char* glfwGetKeyName(int key, int scancode)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (key != GLFW_KEY_UNKNOWN)
- {
- if (key != GLFW_KEY_KP_EQUAL &&
- (key < GLFW_KEY_KP_0 || key > GLFW_KEY_KP_ADD) &&
- (key < GLFW_KEY_APOSTROPHE || key > GLFW_KEY_WORLD_2))
- {
- return NULL;
- }
-
- scancode = _glfwPlatformGetKeyScancode(key);
- }
-
- return _glfwPlatformGetScancodeName(scancode);
-}
-
-GLFWAPI int glfwGetKeyScancode(int key)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(-1);
-
- if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
- return GLFW_RELEASE;
- }
-
- return _glfwPlatformGetKeyScancode(key);
-}
-
-GLFWAPI int glfwGetKey(GLFWwindow* handle, int key)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
-
- if (key < GLFW_KEY_SPACE || key > GLFW_KEY_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid key %i", key);
- return GLFW_RELEASE;
- }
-
- if (window->keys[key] == _GLFW_STICK)
- {
- // Sticky mode: release key now
- window->keys[key] = GLFW_RELEASE;
- return GLFW_PRESS;
- }
-
- return (int) window->keys[key];
-}
-
-GLFWAPI int glfwGetMouseButton(GLFWwindow* handle, int button)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_RELEASE);
-
- if (button < GLFW_MOUSE_BUTTON_1 || button > GLFW_MOUSE_BUTTON_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid mouse button %i", button);
- return GLFW_RELEASE;
- }
-
- if (window->mouseButtons[button] == _GLFW_STICK)
- {
- // Sticky mode: release mouse button now
- window->mouseButtons[button] = GLFW_RELEASE;
- return GLFW_PRESS;
- }
-
- return (int) window->mouseButtons[button];
-}
-
-GLFWAPI void glfwGetCursorPos(GLFWwindow* handle, double* xpos, double* ypos)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- if (xpos)
- *xpos = 0;
- if (ypos)
- *ypos = 0;
-
- _GLFW_REQUIRE_INIT();
-
- if (window->cursorMode == GLFW_CURSOR_DISABLED)
- {
- if (xpos)
- *xpos = window->virtualCursorPosX;
- if (ypos)
- *ypos = window->virtualCursorPosY;
- }
- else
- _glfwPlatformGetCursorPos(window, xpos, ypos);
-}
-
-GLFWAPI void glfwSetCursorPos(GLFWwindow* handle, double xpos, double ypos)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT();
-
- if (xpos != xpos || xpos < -DBL_MAX || xpos > DBL_MAX ||
- ypos != ypos || ypos < -DBL_MAX || ypos > DBL_MAX)
- {
- _glfwInputError(GLFW_INVALID_VALUE,
- "Invalid cursor position %f %f",
- xpos, ypos);
- return;
- }
-
- if (!_glfwPlatformWindowFocused(window))
- return;
-
- if (window->cursorMode == GLFW_CURSOR_DISABLED)
- {
- // Only update the accumulated position if the cursor is disabled
- window->virtualCursorPosX = xpos;
- window->virtualCursorPosY = ypos;
- }
- else
- {
- // Update system cursor position
- _glfwPlatformSetCursorPos(window, xpos, ypos);
- }
-}
-
-GLFWAPI GLFWcursor* glfwCreateCursor(const GLFWimage* image, int xhot, int yhot)
-{
- _GLFWcursor* cursor;
-
- assert(image != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- cursor = calloc(1, sizeof(_GLFWcursor));
- cursor->next = _glfw.cursorListHead;
- _glfw.cursorListHead = cursor;
-
- if (!_glfwPlatformCreateCursor(cursor, image, xhot, yhot))
- {
- glfwDestroyCursor((GLFWcursor*) cursor);
- return NULL;
- }
-
- return (GLFWcursor*) cursor;
-}
-
-GLFWAPI GLFWcursor* glfwCreateStandardCursor(int shape)
-{
- _GLFWcursor* cursor;
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (shape != GLFW_ARROW_CURSOR &&
- shape != GLFW_IBEAM_CURSOR &&
- shape != GLFW_CROSSHAIR_CURSOR &&
- shape != GLFW_POINTING_HAND_CURSOR &&
- shape != GLFW_RESIZE_EW_CURSOR &&
- shape != GLFW_RESIZE_NS_CURSOR &&
- shape != GLFW_RESIZE_NWSE_CURSOR &&
- shape != GLFW_RESIZE_NESW_CURSOR &&
- shape != GLFW_RESIZE_ALL_CURSOR &&
- shape != GLFW_NOT_ALLOWED_CURSOR)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid standard cursor 0x%08X", shape);
- return NULL;
- }
-
- cursor = calloc(1, sizeof(_GLFWcursor));
- cursor->next = _glfw.cursorListHead;
- _glfw.cursorListHead = cursor;
-
- if (!_glfwPlatformCreateStandardCursor(cursor, shape))
- {
- glfwDestroyCursor((GLFWcursor*) cursor);
- return NULL;
- }
-
- return (GLFWcursor*) cursor;
-}
-
-GLFWAPI void glfwDestroyCursor(GLFWcursor* handle)
-{
- _GLFWcursor* cursor = (_GLFWcursor*) handle;
-
- _GLFW_REQUIRE_INIT();
-
- if (cursor == NULL)
- return;
-
- // Make sure the cursor is not being used by any window
- {
- _GLFWwindow* window;
-
- for (window = _glfw.windowListHead; window; window = window->next)
- {
- if (window->cursor == cursor)
- glfwSetCursor((GLFWwindow*) window, NULL);
- }
- }
-
- _glfwPlatformDestroyCursor(cursor);
-
- // Unlink cursor from global linked list
- {
- _GLFWcursor** prev = &_glfw.cursorListHead;
-
- while (*prev != cursor)
- prev = &((*prev)->next);
-
- *prev = cursor->next;
- }
-
- free(cursor);
-}
-
-GLFWAPI void glfwSetCursor(GLFWwindow* windowHandle, GLFWcursor* cursorHandle)
-{
- _GLFWwindow* window = (_GLFWwindow*) windowHandle;
- _GLFWcursor* cursor = (_GLFWcursor*) cursorHandle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT();
-
- window->cursor = cursor;
-
- _glfwPlatformSetCursor(window, cursor);
-}
-
-GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* handle, GLFWkeyfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.key, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWcharfun glfwSetCharCallback(GLFWwindow* handle, GLFWcharfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.character, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* handle, GLFWcharmodsfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.charmods, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWmousebuttonfun glfwSetMouseButtonCallback(GLFWwindow* handle,
- GLFWmousebuttonfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.mouseButton, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow* handle,
- GLFWcursorposfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.cursorPos, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWcursorenterfun glfwSetCursorEnterCallback(GLFWwindow* handle,
- GLFWcursorenterfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.cursorEnter, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWscrollfun glfwSetScrollCallback(GLFWwindow* handle,
- GLFWscrollfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.scroll, cbfun);
- return cbfun;
-}
-
-GLFWAPI GLFWdropfun glfwSetDropCallback(GLFWwindow* handle, GLFWdropfun cbfun)
-{
- _GLFWwindow* window = (_GLFWwindow*) handle;
- assert(window != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- _GLFW_SWAP_POINTERS(window->callbacks.drop, cbfun);
- return cbfun;
-}
-
-GLFWAPI int glfwJoystickPresent(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return GLFW_FALSE;
- }
-
- if (!initJoysticks())
- return GLFW_FALSE;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return GLFW_FALSE;
-
- return _glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE);
-}
-
-GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
- assert(count != NULL);
-
- *count = 0;
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_AXES))
- return NULL;
-
- *count = js->axisCount;
- return js->axes;
-}
-
-GLFWAPI const unsigned char* glfwGetJoystickButtons(int jid, int* count)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
- assert(count != NULL);
-
- *count = 0;
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
- return NULL;
-
- if (_glfw.hints.init.hatButtons)
- *count = js->buttonCount + js->hatCount * 4;
- else
- *count = js->buttonCount;
-
- return js->buttons;
-}
-
-GLFWAPI const unsigned char* glfwGetJoystickHats(int jid, int* count)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
- assert(count != NULL);
-
- *count = 0;
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_BUTTONS))
- return NULL;
-
- *count = js->hatCount;
- return js->hats;
-}
-
-GLFWAPI const char* glfwGetJoystickName(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
- return NULL;
-
- return js->name;
-}
-
-GLFWAPI const char* glfwGetJoystickGUID(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
- return NULL;
-
- return js->guid;
-}
-
-GLFWAPI void glfwSetJoystickUserPointer(int jid, void* pointer)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT();
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return;
-
- js->userPointer = pointer;
-}
-
-GLFWAPI void* glfwGetJoystickUserPointer(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- return js->userPointer;
-}
-
-GLFWAPI GLFWjoystickfun glfwSetJoystickCallback(GLFWjoystickfun cbfun)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (!initJoysticks())
- return NULL;
-
- _GLFW_SWAP_POINTERS(_glfw.callbacks.joystick, cbfun);
- return cbfun;
-}
-
-GLFWAPI int glfwUpdateGamepadMappings(const char* string)
-{
- int jid;
- const char* c = string;
-
- assert(string != NULL);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
-
- while (*c)
- {
- if ((*c >= '0' && *c <= '9') ||
- (*c >= 'a' && *c <= 'f') ||
- (*c >= 'A' && *c <= 'F'))
- {
- char line[1024];
-
- const size_t length = strcspn(c, "\r\n");
- if (length < sizeof(line))
- {
- _GLFWmapping mapping = {{0}};
-
- memcpy(line, c, length);
- line[length] = '\0';
-
- if (parseMapping(&mapping, line))
- {
- _GLFWmapping* previous = findMapping(mapping.guid);
- if (previous)
- *previous = mapping;
- else
- {
- _glfw.mappingCount++;
- _glfw.mappings =
- realloc(_glfw.mappings,
- sizeof(_GLFWmapping) * _glfw.mappingCount);
- _glfw.mappings[_glfw.mappingCount - 1] = mapping;
- }
- }
- }
-
- c += length;
- }
- else
- {
- c += strcspn(c, "\r\n");
- c += strspn(c, "\r\n");
- }
- }
-
- for (jid = 0; jid <= GLFW_JOYSTICK_LAST; jid++)
- {
- _GLFWjoystick* js = _glfw.joysticks + jid;
- if (js->present)
- js->mapping = findValidMapping(js);
- }
-
- return GLFW_TRUE;
-}
-
-GLFWAPI int glfwJoystickIsGamepad(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return GLFW_FALSE;
- }
-
- if (!initJoysticks())
- return GLFW_FALSE;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return GLFW_FALSE;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
- return GLFW_FALSE;
-
- return js->mapping != NULL;
-}
-
-GLFWAPI const char* glfwGetGamepadName(int jid)
-{
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
-
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return NULL;
- }
-
- if (!initJoysticks())
- return NULL;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return NULL;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_PRESENCE))
- return NULL;
-
- if (!js->mapping)
- return NULL;
-
- return js->mapping->name;
-}
-
-GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state)
-{
- int i;
- _GLFWjoystick* js;
-
- assert(jid >= GLFW_JOYSTICK_1);
- assert(jid <= GLFW_JOYSTICK_LAST);
- assert(state != NULL);
-
- memset(state, 0, sizeof(GLFWgamepadstate));
-
- _GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
-
- if (jid < 0 || jid > GLFW_JOYSTICK_LAST)
- {
- _glfwInputError(GLFW_INVALID_ENUM, "Invalid joystick ID %i", jid);
- return GLFW_FALSE;
- }
-
- if (!initJoysticks())
- return GLFW_FALSE;
-
- js = _glfw.joysticks + jid;
- if (!js->present)
- return GLFW_FALSE;
-
- if (!_glfwPlatformPollJoystick(js, _GLFW_POLL_ALL))
- return GLFW_FALSE;
-
- if (!js->mapping)
- return GLFW_FALSE;
-
- for (i = 0; i <= GLFW_GAMEPAD_BUTTON_LAST; i++)
- {
- const _GLFWmapelement* e = js->mapping->buttons + i;
- if (e->type == _GLFW_JOYSTICK_AXIS)
- {
- const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
- // HACK: This should be baked into the value transform
- // TODO: Bake into transform when implementing output modifiers
- if (e->axisOffset < 0 || (e->axisOffset == 0 && e->axisScale > 0))
- {
- if (value >= 0.f)
- state->buttons[i] = GLFW_PRESS;
- }
- else
- {
- if (value <= 0.f)
- state->buttons[i] = GLFW_PRESS;
- }
- }
- else if (e->type == _GLFW_JOYSTICK_HATBIT)
- {
- const unsigned int hat = e->index >> 4;
- const unsigned int bit = e->index & 0xf;
- if (js->hats[hat] & bit)
- state->buttons[i] = GLFW_PRESS;
- }
- else if (e->type == _GLFW_JOYSTICK_BUTTON)
- state->buttons[i] = js->buttons[e->index];
- }
-
- for (i = 0; i <= GLFW_GAMEPAD_AXIS_LAST; i++)
- {
- const _GLFWmapelement* e = js->mapping->axes + i;
- if (e->type == _GLFW_JOYSTICK_AXIS)
- {
- const float value = js->axes[e->index] * e->axisScale + e->axisOffset;
- state->axes[i] = _glfw_fminf(_glfw_fmaxf(value, -1.f), 1.f);
- }
- else if (e->type == _GLFW_JOYSTICK_HATBIT)
- {
- const unsigned int hat = e->index >> 4;
- const unsigned int bit = e->index & 0xf;
- if (js->hats[hat] & bit)
- state->axes[i] = 1.f;
- else
- state->axes[i] = -1.f;
- }
- else if (e->type == _GLFW_JOYSTICK_BUTTON)
- state->axes[i] = js->buttons[e->index] * 2.f - 1.f;
- }
-
- return GLFW_TRUE;
-}
-
-GLFWAPI void glfwSetClipboardString(GLFWwindow* handle, const char* string)
-{
- assert(string != NULL);
-
- _GLFW_REQUIRE_INIT();
- _glfwPlatformSetClipboardString(string);
-}
-
-GLFWAPI const char* glfwGetClipboardString(GLFWwindow* handle)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(NULL);
- return _glfwPlatformGetClipboardString();
-}
-
-GLFWAPI double glfwGetTime(void)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(0.0);
- return (double) (_glfwPlatformGetTimerValue() - _glfw.timer.offset) /
- _glfwPlatformGetTimerFrequency();
-}
-
-GLFWAPI void glfwSetTime(double time)
-{
- _GLFW_REQUIRE_INIT();
-
- if (time != time || time < 0.0 || time > 18446744073.0)
- {
- _glfwInputError(GLFW_INVALID_VALUE, "Invalid time %f", time);
- return;
- }
-
- _glfw.timer.offset = _glfwPlatformGetTimerValue() -
- (uint64_t) (time * _glfwPlatformGetTimerFrequency());
-}
-
-GLFWAPI uint64_t glfwGetTimerValue(void)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(0);
- return _glfwPlatformGetTimerValue();
-}
-
-GLFWAPI uint64_t glfwGetTimerFrequency(void)
-{
- _GLFW_REQUIRE_INIT_OR_RETURN(0);
- return _glfwPlatformGetTimerFrequency();
-}