Compare commits

...

13 Commits

Author SHA1 Message Date
Alberto Mardegan
1a71cbea1a
Merge 7c224bcd71 into 8e15281d34 2025-09-06 02:16:21 +01:00
knokko
8e15281d34 Add glfwGetGLXFBConfig native access function
This adds the glfwGetGLXFBConfig function for querying the GLXFBConfig
the GLXWindow of a window.

This commit is a squashed and modified version of PR #1925 by knokko.
The following changes were made by elmindreda:

The function signature was changed to handle GLXFBConfig being an opaque
value in core GLX.  The function error checks were fixed and updated.
The struct member name was changed.  The struct member clearing on
context destruction was removed.  All documentation snippets were
updated.

Closes #1925
2025-09-01 16:05:26 +02:00
Camilla Löwy
621e99d53e Add glfwGetEGLConfig native access function
This adds the glfwGetEGLConfig function for querying the EGLConfig of
the EGLSurface of a window.

This is a re-implementation of the PR #2045 by knokko, slightly
redesigned to handle EGLConfig being an opaque type in core EGL.

Closes #2045
2025-09-01 16:05:24 +02:00
Camilla Löwy
1a0b7827d4 EGL: Fix error return value for glfwGetEGLSurface
This is a semantic fix only.  The behavior is unchanged.
2025-08-29 19:27:21 +02:00
Camilla Löwy
4c64184455 Remove title member from window config
The window title is already available in the window struct.
2025-08-29 19:27:21 +02:00
Camilla Löwy
bfcb98fb6c Replace some Doxygen aliases with Markdown 2025-08-29 19:27:21 +02:00
Camilla Löwy
f8582d26d0 Add Markdown files as sources to IDE docs target 2025-08-29 19:27:21 +02:00
Camilla Löwy
1fdd39cf3e Fix documentation target dependency
Related to #2704
2025-08-29 19:27:08 +02:00
Camilla Löwy
c9b129753a Update Doxygen version handling 2025-08-28 19:05:42 +02:00
Camilla Löwy
04a67c8267 Fix X11 clipboard compatibility description 2025-08-28 19:04:47 +02:00
Camilla Löwy
5c87937e44 Update README 2025-08-28 18:56:20 +02:00
Alberto Mardegan
7c224bcd71 WIP: add GameCube & Wii support 2025-01-27 17:24:14 +03:00
Alberto Mardegan
bc0d63cf82 nuklear: fix big-endian image conversion
This has been submitted upstream as well.
2025-01-27 17:24:14 +03:00
44 changed files with 3239 additions and 195 deletions

View File

@ -24,8 +24,15 @@ if (DEFINED GLFW_USE_WAYLAND AND UNIX AND NOT APPLE)
"GLFW_USE_WAYLAND has been removed; delete the CMake cache and set GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 instead") "GLFW_USE_WAYLAND has been removed; delete the CMake cache and set GLFW_BUILD_WAYLAND and GLFW_BUILD_X11 instead")
endif() endif()
IF(CMAKE_SYSTEM_NAME MATCHES "NintendoWii|NintendoGameCube")
SET(OGC ON)
ELSE()
SET(OGC OFF)
ENDIF()
cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF) cmake_dependent_option(GLFW_BUILD_WIN32 "Build support for Win32" ON "WIN32" OFF)
cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF) cmake_dependent_option(GLFW_BUILD_COCOA "Build support for Cocoa" ON "APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_OGC "Build support for Nintendo GameCube/Wii" ON "OGC" OFF)
cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF) cmake_dependent_option(GLFW_BUILD_X11 "Build support for X11" ON "UNIX;NOT APPLE" OFF)
cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland" ON "UNIX;NOT APPLE" OFF) cmake_dependent_option(GLFW_BUILD_WAYLAND "Build support for Wayland" ON "UNIX;NOT APPLE" OFF)
@ -49,7 +56,7 @@ endif()
list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules") list(APPEND CMAKE_MODULE_PATH "${GLFW_SOURCE_DIR}/CMake/modules")
find_package(Threads REQUIRED) find_package(Threads)
#-------------------------------------------------------------------- #--------------------------------------------------------------------
# Report backend selection # Report backend selection

View File

@ -23,6 +23,7 @@ video tutorials.
- Denis Bernard - Denis Bernard
- BiBi - BiBi
- Doug Binks - Doug Binks
- bitb4ker
- blanco - blanco
- Waris Boonyasiriwat - Waris Boonyasiriwat
- Kyle Brenneman - Kyle Brenneman
@ -123,6 +124,7 @@ video tutorials.
- Josh Kilmer - Josh Kilmer
- Byunghoon Kim - Byunghoon Kim
- Cameron King - Cameron King
- knokko
- Peter Knut - Peter Knut
- Christoph Kubisch - Christoph Kubisch
- Yuri Kunde Schlesner - Yuri Kunde Schlesner

131
README.md
View File

@ -9,34 +9,28 @@ GLFW is an Open Source, multi-platform library for OpenGL, OpenGL ES and Vulkan
application development. It provides a simple, platform-independent API for application development. It provides a simple, platform-independent API for
creating windows, contexts and surfaces, reading input, handling events, etc. creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On GLFW is written primarily in C99, with parts of macOS support being written in
Linux both Wayland and X11 are supported. Objective-C.
GLFW supports Windows, macOS and Linux, and also works on many other Unix-like
systems. On Linux both Wayland and X11 are supported.
GLFW is licensed under the [zlib/libpng GLFW is licensed under the [zlib/libpng
license](https://www.glfw.org/license.html). license](https://www.glfw.org/license.html).
You can [download](https://www.glfw.org/download.html) the latest stable release You can [download](https://www.glfw.org/download.html) the latest stable release
as source or Windows binaries. Each release starting with 3.0 also has as source or Windows and macOS binaries. There are [release
a corresponding [annotated tag](https://github.com/glfw/glfw/releases) with tags](https://github.com/glfw/glfw/releases) with source and binary archives
source and binary archives. attached for every version since 3.0.
The [documentation](https://www.glfw.org/docs/latest/) is available online and is The [documentation](https://www.glfw.org/docs/latest/) is available online and is
included in all source and binary archives. See the [release also included in source and binary archives, except those generated
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and automatically by Github. The documentation contains guides, a tutorial and the
deprecations in the latest release. For more details see the [version API reference. The [release
history](https://www.glfw.org/changelog.html). notes](https://www.glfw.org/docs/latest/news.html) list the new features,
caveats and deprecations in the latest release. The [version
The `master` branch is the stable integration branch and _should_ always compile history](https://www.glfw.org/changelog.html) lists every user-visible change
and run on all supported platforms, although details of newly added features may for every release.
change until they have been included in a release. New features and many bug
fixes live in [other branches](https://github.com/glfw/glfw/branches/all) until
they are stable enough to merge.
If you are new to GLFW, you may find the
[tutorial](https://www.glfw.org/docs/latest/quick.html) for GLFW 3 useful. If
you have used GLFW 2 in the past, there is a [transition
guide](https://www.glfw.org/docs/latest/moving.html) for moving to the GLFW
3 API.
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md) GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
around the world, whether by reporting bugs, providing community support, adding around the world, whether by reporting bugs, providing community support, adding
@ -44,57 +38,37 @@ features, reviewing or testing code, debugging, proofreading docs, suggesting
features or fixing bugs. features or fixing bugs.
## Compiling GLFW
GLFW is written primarily in C99, with parts of macOS support being written in
Objective-C. GLFW itself requires only the headers and libraries for your OS
and window system. It does not need any additional headers for context creation
APIs (WGL, GLX, EGL, NSGL, OSMesa) or rendering APIs (OpenGL, OpenGL ES, Vulkan)
to enable support for them.
GLFW supports compilation on Windows with Visual C++ (2013 and later) and
MinGW-w64, on macOS with Clang and on Linux and other Unix-like systems with GCC
and Clang. It will likely compile in other environments as well, but this is
not regularly tested.
There are [pre-compiled binaries](https://www.glfw.org/download.html) available
for all supported compilers on Windows and macOS.
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
more information about how to compile GLFW yourself.
## Using GLFW
See the [documentation](https://www.glfw.org/docs/latest/) for tutorials, guides
and the API reference.
## Contributing to GLFW
See the [contribution
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
more information.
## System requirements ## System requirements
GLFW supports Windows 7 and later and macOS 10.11 and later. Linux and other GLFW supports Windows 7 and later and macOS 10.11 and later. On GNOME Wayland,
Unix-like systems running the X Window System are supported even without window decorations will be very basic unless the
a desktop environment or modern extensions, although some features require [libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) package is
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3. installed. Linux and other Unix-like systems running X11 are supported even
without a desktop environment or modern extensions, although some features
require a clipboard manager or a modern window manager.
See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html) See the [compatibility guide](https://www.glfw.org/docs/latest/compat.html)
in the documentation for more information. for more detailed information.
## Dependencies ## Compiling GLFW
GLFW itself needs only CMake 3.16 or later and the headers and libraries for your GLFW supports compilation with Visual C++ (2013 and later), GCC and Clang. Both
OS and window system. Clang-CL and MinGW-w64 are supported. Other C99 compilers will likely also
work, but this is not regularly tested.
There are [pre-compiled binaries](https://www.glfw.org/download.html)
available for Windows and macOS.
GLFW itself needs only CMake and the headers and libraries for your operating
system and window system. No other SDKs are required.
See the [compilation guide](https://www.glfw.org/docs/latest/compile.html) for
more information about compiling GLFW and the exact dependencies required for
each window system.
The examples and test programs depend on a number of tiny libraries. These are The examples and test programs depend on a number of tiny libraries. These are
located in the `deps/` directory. bundled in the `deps/` directory. The repository has no submodules.
- [getopt\_port](https://github.com/kimgr/getopt_port/) for examples - [getopt\_port](https://github.com/kimgr/getopt_port/) for examples
with command-line options with command-line options
@ -107,8 +81,33 @@ located in the `deps/` directory.
- [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI - [Nuklear](https://github.com/Immediate-Mode-UI/Nuklear) for test and example UI
- [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk - [stb\_image\_write](https://github.com/nothings/stb) for writing images to disk
The documentation is generated with [Doxygen](https://doxygen.org/) if CMake can The documentation is generated with [Doxygen](https://doxygen.org/) when the
find that tool. library is built, provided CMake could find a sufficiently new version of it
during configuration.
## Using GLFW
See the [HTML documentation](https://www.glfw.org/docs/latest/) for a tutorial,
guides and the API reference.
## Contributing to GLFW
See the [contribution
guide](https://github.com/glfw/glfw/blob/master/docs/CONTRIBUTING.md) for
more information.
The `master` branch is the stable integration branch and _should_ always compile
and run on all supported platforms. Details of a newly added feature,
including the public API, may change until it has been included in a release.
The `latest` branch is equivalent to the [highest numbered](https://semver.org/)
release, although it may not always point to the same commit as the tag for that
release.
The `ci` branch is used to trigger continuous integration jobs for code under
testing and should never be relied on for any purpose.
## Reporting bugs ## Reporting bugs
@ -123,6 +122,8 @@ information on what to include when reporting a bug.
- Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond - Added `GLFW_UNLIMITED_MOUSE_BUTTONS` input mode that allows mouse buttons beyond
the limit of the mouse button tokens to be reported (#2423) the limit of the mouse button tokens to be reported (#2423)
- Added `glfwGetEGLConfig` function to query the `EGLConfig` of a window (#2045)
- Added `glfwGetGLXFBConfig` function to query the `GLXFBConfig` of a window (#1925)
- Updated minimum CMake version to 3.16 (#2541) - Updated minimum CMake version to 3.16 (#2541)
- Removed support for building with original MinGW (#2540) - Removed support for building with original MinGW (#2540)
- [Win32] Removed support for Windows XP and Vista (#2505) - [Win32] Removed support for Windows XP and Vista (#2505)

12
deps/nuklear.h vendored
View File

@ -12988,7 +12988,7 @@ nk_font_bake_convert(void *out_memory, int img_width, int img_height,
const void *in_memory) const void *in_memory)
{ {
int n = 0; int n = 0;
nk_rune *dst; nk_byte *dst;
const nk_byte *src; const nk_byte *src;
NK_ASSERT(out_memory); NK_ASSERT(out_memory);
@ -12997,10 +12997,14 @@ nk_font_bake_convert(void *out_memory, int img_width, int img_height,
NK_ASSERT(img_height); NK_ASSERT(img_height);
if (!out_memory || !in_memory || !img_height || !img_width) return; if (!out_memory || !in_memory || !img_height || !img_width) return;
dst = (nk_rune*)out_memory; dst = (nk_byte*)out_memory;
src = (const nk_byte*)in_memory; src = (const nk_byte*)in_memory;
for (n = (int)(img_width * img_height); n > 0; n--) for (n = (int)(img_width * img_height); n > 0; n--) {
*dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF; *dst++ = 0xff; // r
*dst++ = 0xff; // g
*dst++ = 0xff; // b
*dst++ = *src++; // a
}
} }
/* ------------------------------------------------------------- /* -------------------------------------------------------------

28
deps/tinycthread.c vendored
View File

@ -40,6 +40,8 @@ freely, subject to the following restrictions:
#elif defined(_TTHREAD_WIN32_) #elif defined(_TTHREAD_WIN32_)
#include <process.h> #include <process.h>
#include <sys/timeb.h> #include <sys/timeb.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#endif #endif
/* Standard, good-to-have defines */ /* Standard, good-to-have defines */
@ -60,6 +62,8 @@ int mtx_init(mtx_t *mtx, int type)
mtx->mRecursive = type & mtx_recursive; mtx->mRecursive = type & mtx_recursive;
InitializeCriticalSection(&mtx->mHandle); InitializeCriticalSection(&mtx->mHandle);
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
int ret; int ret;
pthread_mutexattr_t attr; pthread_mutexattr_t attr;
@ -78,6 +82,7 @@ void mtx_destroy(mtx_t *mtx)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
DeleteCriticalSection(&mtx->mHandle); DeleteCriticalSection(&mtx->mHandle);
#elif defined(_TTHREAD_OGC_)
#else #else
pthread_mutex_destroy(mtx); pthread_mutex_destroy(mtx);
#endif #endif
@ -93,6 +98,8 @@ int mtx_lock(mtx_t *mtx)
mtx->mAlreadyLocked = TRUE; mtx->mAlreadyLocked = TRUE;
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -116,6 +123,8 @@ int mtx_trylock(mtx_t *mtx)
ret = thrd_busy; ret = thrd_busy;
} }
return ret; return ret;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
#endif #endif
@ -127,6 +136,8 @@ int mtx_unlock(mtx_t *mtx)
mtx->mAlreadyLocked = FALSE; mtx->mAlreadyLocked = FALSE;
LeaveCriticalSection(&mtx->mHandle); LeaveCriticalSection(&mtx->mHandle);
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
#endif #endif
@ -161,6 +172,8 @@ int cnd_init(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -178,6 +191,7 @@ void cnd_destroy(cnd_t *cond)
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
} }
DeleteCriticalSection(&cond->mWaitersCountLock); DeleteCriticalSection(&cond->mWaitersCountLock);
#elif defined(_TTHREAD_OGC_)
#else #else
pthread_cond_destroy(cond); pthread_cond_destroy(cond);
#endif #endif
@ -203,6 +217,8 @@ int cnd_signal(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -228,6 +244,8 @@ int cnd_broadcast(cnd_t *cond)
} }
return thrd_success; return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -286,6 +304,8 @@ int cnd_wait(cnd_t *cond, mtx_t *mtx)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
return _cnd_timedwait_win32(cond, mtx, INFINITE); return _cnd_timedwait_win32(cond, mtx, INFINITE);
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
#endif #endif
@ -303,6 +323,8 @@ int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
} }
else else
return thrd_error; return thrd_error;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else #else
int ret; int ret;
ret = pthread_cond_timedwait(cond, mtx, ts); ret = pthread_cond_timedwait(cond, mtx, ts);
@ -324,14 +346,14 @@ typedef struct {
/* Thread wrapper function. */ /* Thread wrapper function. */
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
static unsigned WINAPI _thrd_wrapper_function(void * aArg) static unsigned WINAPI _thrd_wrapper_function(void * aArg)
#elif defined(_TTHREAD_POSIX_) #else
static void * _thrd_wrapper_function(void * aArg) static void * _thrd_wrapper_function(void * aArg)
#endif #endif
{ {
thrd_start_t fun; thrd_start_t fun;
void *arg; void *arg;
int res; int res;
#if defined(_TTHREAD_POSIX_) #if defined(_TTHREAD_POSIX_) || defined(_TTHREAD_OGC_)
void *pres; void *pres;
#endif #endif
@ -394,6 +416,8 @@ thrd_t thrd_current(void)
{ {
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
return GetCurrentThread(); return GetCurrentThread();
#elif defined(_TTHREAD_OGC_)
return LWP_GetSelf();
#else #else
return pthread_self(); return pthread_self();
#endif #endif

6
deps/tinycthread.h vendored
View File

@ -51,6 +51,8 @@ freely, subject to the following restrictions:
#if !defined(_TTHREAD_PLATFORM_DEFINED_) #if !defined(_TTHREAD_PLATFORM_DEFINED_)
#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define _TTHREAD_WIN32_ #define _TTHREAD_WIN32_
#elif defined(GEKKO)
#define _TTHREAD_OGC_
#else #else
#define _TTHREAD_POSIX_ #define _TTHREAD_POSIX_
#endif #endif
@ -80,6 +82,8 @@ freely, subject to the following restrictions:
#if defined(_TTHREAD_POSIX_) #if defined(_TTHREAD_POSIX_)
#include <sys/time.h> #include <sys/time.h>
#include <pthread.h> #include <pthread.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#elif defined(_TTHREAD_WIN32_) #elif defined(_TTHREAD_WIN32_)
#ifndef WIN32_LEAN_AND_MEAN #ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -313,6 +317,8 @@ int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts);
/* Thread */ /* Thread */
#if defined(_TTHREAD_WIN32_) #if defined(_TTHREAD_WIN32_)
typedef HANDLE thrd_t; typedef HANDLE thrd_t;
#elif defined(_TTHREAD_OGC_)
typedef lwp_t thrd_t;
#else #else
typedef pthread_t thrd_t; typedef pthread_t thrd_t;
#endif #endif

View File

@ -1,4 +1,8 @@
# Because of bugs and limitations in its Markdown support, only fairly recent
# versions of Doxygen can produce acceptable output
set(MINIMUM_DOXYGEN_VERSION 1.9.8)
# NOTE: The order of this list determines the order of items in the Guides # NOTE: The order of this list determines the order of items in the Guides
# (i.e. Pages) list in the generated documentation # (i.e. Pages) list in the generated documentation
set(source_files set(source_files
@ -32,10 +36,10 @@ foreach(file IN LISTS source_files)
endforeach() endforeach()
set(DOXYGEN_SKIP_DOT TRUE) set(DOXYGEN_SKIP_DOT TRUE)
find_package(Doxygen) find_package(Doxygen ${MINIMUM_DOXYGEN_VERSION} QUIET)
if (NOT DOXYGEN_FOUND OR DOXYGEN_VERSION VERSION_LESS "1.9.8") if (NOT DOXYGEN_FOUND)
message(STATUS "Documentation generation requires Doxygen 1.9.8 or later") message(STATUS "Documentation generation requires Doxygen ${MINIMUM_DOXYGEN_VERSION} or later")
else() else()
configure_file(Doxyfile.in Doxyfile @ONLY) configure_file(Doxyfile.in Doxyfile @ONLY)
add_custom_command(OUTPUT "html/index.html" add_custom_command(OUTPUT "html/index.html"
@ -46,7 +50,7 @@ else()
COMMENT "Generating HTML documentation" COMMENT "Generating HTML documentation"
VERBATIM) VERBATIM)
add_custom_target(docs ALL SOURCES "html/index.html") add_custom_target(docs ALL SOURCES ${source_files} DEPENDS "html/index.html")
set_target_properties(docs PROPERTIES FOLDER "GLFW3") set_target_properties(docs PROPERTIES FOLDER "GLFW3")
if (GLFW_INSTALL) if (GLFW_INSTALL)

View File

@ -278,13 +278,7 @@ ALIASES = "thread_safety=@par Thread safety^^" \
"analysis=@par Analysis^^" \ "analysis=@par Analysis^^" \
"reentrancy=@par Reentrancy^^" \ "reentrancy=@par Reentrancy^^" \
"errors=@par Errors^^" \ "errors=@par Errors^^" \
"callback_signature=@par Callback signature^^" \ "callback_signature=@par Callback signature^^"
"glfw3=__GLFW 3:__" \
"x11=__X11:__" \
"wayland=__Wayland:__" \
"win32=__Windows:__" \
"macos=__macOS:__" \
"linux=__Linux:__"
# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
# only. Doxygen will then generate output that is more tailored for C. For # only. Doxygen will then generate output that is more tailored for C. For

View File

@ -50,10 +50,11 @@ compositing window manager to un-redirect full screen GLFW windows. If the
running window manager uses compositing but does not support this property then running window manager uses compositing but does not support this property then
additional copying may be performed for each buffer swap of full screen windows. additional copying may be performed for each buffer swap of full screen windows.
GLFW uses the [clipboard manager protocol][ClipboardManager] to push a clipboard GLFW uses the [clipboard manager protocol][ClipboardManager] to keep the
string (i.e. selection) owned by a GLFW window about to be destroyed to the clipboard string availble for the user after the libary has been terminated. If
clipboard manager. If there is no running clipboard manager, the clipboard there is no running clipboard manager and the clipboard contents has been set
string will be unavailable once the window has been destroyed. with @ref glfwSetClipboardString, the clipboard will be emptied when the library
is terminated.
[clipboardManager]: https://www.freedesktop.org/wiki/ClipboardManager/ [clipboardManager]: https://www.freedesktop.org/wiki/ClipboardManager/

View File

@ -63,7 +63,7 @@ before the application exits. Modern systems are very good at freeing resources
allocated by programs that exit, but GLFW sometimes has to change global system allocated by programs that exit, but GLFW sometimes has to change global system
settings and these might not be restored without termination. settings and these might not be restored without termination.
@macos When the library is initialized the main menu and dock icon are created. __macOS:__ When the library is initialized the main menu and dock icon are created.
These are not desirable for a command-line only program. The creation of the These are not desirable for a command-line only program. The creation of the
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
hint. hint.

View File

@ -255,7 +255,7 @@ hardware gamma correction, which today is typically an approximation of sRGB
gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will gamma. This means that setting a perfectly linear ramp, or gamma 1.0, will
produce the default (usually sRGB-like) behavior. produce the default (usually sRGB-like) behavior.
@note @wayland An application cannot read or modify the monitor gamma ramp. The @note __Wayland:__ An application cannot read or modify the monitor gamma ramp.
@ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions The @ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
emit @ref GLFW_FEATURE_UNAVAILABLE. emit @ref GLFW_FEATURE_UNAVAILABLE.

View File

@ -14,6 +14,19 @@ values over 8. For compatibility with older versions, the
@ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of @ref GLFW_UNLIMITED_MOUSE_BUTTONS input mode needs to be set to make use of
this. this.
### EGLConfig native access function {#eglconfig}
GLFW now provides the @ref glfwGetEGLConfig native access function for querying
the `EGLConfig` of a window that has a `EGLSurface`.
### GLXFBConfig native access function {#glxfbconfig}
GLFW now provides the @ref glfwGetGLXFBConfig native access function for
querying the `GLXFBConfig` of a window that has a `GLXWindow`.
## Caveats {#caveats} ## Caveats {#caveats}
## Deprecations {#deprecations} ## Deprecations {#deprecations}
@ -39,6 +52,10 @@ actively maintained and available on many platforms.
### New functions {#new_functions} ### New functions {#new_functions}
- @ref glfwGetEGLConfig
- @ref glfwGetGLXFBConfig
### New types {#new_types} ### New types {#new_types}
### New constants {#new_constants} ### New constants {#new_constants}

View File

@ -35,7 +35,7 @@ By default, GLFW will load the Vulkan loader dynamically at runtime via its stan
`vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and `vulkan-1.dll` on Windows, `libvulkan.so.1` on Linux and other Unix-like systems and
`libvulkan.1.dylib` on macOS. `libvulkan.1.dylib` on macOS.
@macos GLFW will also look up and search the `Frameworks` subdirectory of your __macOS:__ GLFW will also look up and search the `Frameworks` subdirectory of your
application bundle. application bundle.
If your code is using a Vulkan loader with a different name or in a non-standard location If your code is using a Vulkan loader with a different name or in a non-standard location
@ -47,7 +47,7 @@ entry point retrieval. This prevents GLFW from dynamically loading the Vulkan l
glfwInitVulkanLoader(vkGetInstanceProcAddr); glfwInitVulkanLoader(vkGetInstanceProcAddr);
``` ```
@macos To make your application be redistributable you will need to set up the application __macOS:__ To make your application be redistributable you will need to set up the application
bundle according to the LunarG SDK documentation. This is explained in more detail in the bundle according to the LunarG SDK documentation. This is explained in more detail in the
[SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html). [SDK documentation for macOS](https://vulkan.lunarg.com/doc/sdk/latest/mac/getting_started.html).
@ -186,7 +186,7 @@ check whether any extensions you wish to enable are already in the returned
array, as it is an error to specify an extension more than once in the array, as it is an error to specify an extension more than once in the
`VkInstanceCreateInfo` struct. `VkInstanceCreateInfo` struct.
@macos MoltenVK is (as of July 2022) not yet a fully conformant implementation __macOS:__ MoltenVK is (as of July 2022) not yet a fully conformant implementation
of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the of Vulkan. As of Vulkan SDK 1.3.216.0, this means you must also enable the
`VK_KHR_portability_enumeration` instance extension and set the `VK_KHR_portability_enumeration` instance extension and set the
`VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation `VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR` bit in the instance creation

View File

@ -363,10 +363,10 @@ which API was used to create the current context may fail if you change this
hint. This can be resolved by having it load functions via @ref hint. This can be resolved by having it load functions via @ref
glfwGetProcAddress. glfwGetProcAddress.
@note @wayland The EGL API _is_ the native context creation API, so this hint @note __Wayland:__ The EGL API _is_ the native context creation API, so this hint
will have no effect. will have no effect.
@note @x11 On some Linux systems, creating contexts via both the native and EGL @note __X11:__ On some Linux systems, creating contexts via both the native and EGL
APIs in a single process will cause the application to segfault. Stick to one APIs in a single process will cause the application to segfault. Stick to one
API or the other on Linux for now. API or the other on Linux for now.
@ -400,7 +400,7 @@ requested. Additionally, OpenGL ES 1.x cannot be returned if 2.0 or later was
requested, and vice versa. This is because OpenGL ES 3.x is backward compatible requested, and vice versa. This is because OpenGL ES 3.x is backward compatible
with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x. with 2.0, but OpenGL ES 2.0 is not backward compatible with 1.x.
@note @macos The OS only supports core profile contexts for OpenGL versions 3.2 @note __macOS:__ The OS only supports core profile contexts for OpenGL versions 3.2
and later. Before creating an OpenGL context of version 3.2 or later you must and later. Before creating an OpenGL context of version 3.2 or later you must
set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly. set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) hint accordingly.
OpenGL 3.0 and 3.1 contexts are not supported at all on macOS. OpenGL 3.0 and 3.1 contexts are not supported at all on macOS.
@ -893,7 +893,7 @@ int xpos, ypos;
glfwGetWindowPos(window, &xpos, &ypos); glfwGetWindowPos(window, &xpos, &ypos);
``` ```
@note @wayland An applications cannot know the positions of its windows or @note __Wayland:__ An applications cannot know the positions of its windows or
whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y whether one has been moved. The @ref GLFW_POSITION_X and @ref GLFW_POSITION_Y
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will functions emit @ref GLFW_FEATURE_UNAVAILABLE. The window position callback will
@ -1044,7 +1044,7 @@ You can also get the current iconification state with @ref glfwGetWindowAttrib.
int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED); int iconified = glfwGetWindowAttrib(window, GLFW_ICONIFIED);
``` ```
@note @wayland An application cannot know if any of its windows have been @note __Wayland:__ An application cannot know if any of its windows have been
iconified or restore one from iconification. The @ref glfwRestoreWindow iconified or restore one from iconification. The @ref glfwRestoreWindow
function can only restore windows from maximization and the iconify callback function can only restore windows from maximization and the iconify callback
will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute will not be called. The [GLFW_ICONIFIED](@ref GLFW_ICONIFIED_attrib) attribute

View File

@ -37,7 +37,9 @@ add_executable(triangle-opengles WIN32 MACOSX_BUNDLE triangle-opengles.c ${ICON}
add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL}) add_executable(wave WIN32 MACOSX_BUNDLE wave.c ${ICON} ${GLAD_GL})
add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL}) add_executable(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
if (Threads_FOUND)
target_link_libraries(particles Threads::Threads) target_link_libraries(particles Threads::Threads)
endif()
if (RT_LIBRARY) if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}") target_link_libraries(particles "${RT_LIBRARY}")
endif() endif()

View File

@ -1228,13 +1228,13 @@ extern "C" {
* The top-left to bottom-right diagonal resize/move shape. This is usually * The top-left to bottom-right diagonal resize/move shape. This is usually
* a diagonal double-headed arrow. * a diagonal double-headed arrow.
* *
* @note @macos This shape is provided by a private system API and may fail * @note __macOS:__ This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future. * with @ref GLFW_CURSOR_UNAVAILABLE in the future.
* *
* @note @wayland This shape is provided by a newer standard not supported by * @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes. * all cursor themes.
* *
* @note @x11 This shape is provided by a newer standard not supported by all * @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes. * cursor themes.
*/ */
#define GLFW_RESIZE_NWSE_CURSOR 0x00036007 #define GLFW_RESIZE_NWSE_CURSOR 0x00036007
@ -1243,13 +1243,13 @@ extern "C" {
* The top-right to bottom-left diagonal resize/move shape. This is usually * The top-right to bottom-left diagonal resize/move shape. This is usually
* a diagonal double-headed arrow. * a diagonal double-headed arrow.
* *
* @note @macos This shape is provided by a private system API and may fail * @note __macOS:__ This shape is provided by a private system API and may fail
* with @ref GLFW_CURSOR_UNAVAILABLE in the future. * with @ref GLFW_CURSOR_UNAVAILABLE in the future.
* *
* @note @wayland This shape is provided by a newer standard not supported by * @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes. * all cursor themes.
* *
* @note @x11 This shape is provided by a newer standard not supported by all * @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes. * cursor themes.
*/ */
#define GLFW_RESIZE_NESW_CURSOR 0x00036008 #define GLFW_RESIZE_NESW_CURSOR 0x00036008
@ -1264,10 +1264,10 @@ extern "C" {
* The operation-not-allowed shape. This is usually a circle with a diagonal * The operation-not-allowed shape. This is usually a circle with a diagonal
* line through it. * line through it.
* *
* @note @wayland This shape is provided by a newer standard not supported by * @note __Wayland:__ This shape is provided by a newer standard not supported by
* all cursor themes. * all cursor themes.
* *
* @note @x11 This shape is provided by a newer standard not supported by all * @note __X11:__ This shape is provided by a newer standard not supported by all
* cursor themes. * cursor themes.
*/ */
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A #define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
@ -1342,6 +1342,7 @@ extern "C" {
#define GLFW_PLATFORM_WAYLAND 0x00060003 #define GLFW_PLATFORM_WAYLAND 0x00060003
#define GLFW_PLATFORM_X11 0x00060004 #define GLFW_PLATFORM_X11 0x00060004
#define GLFW_PLATFORM_NULL 0x00060005 #define GLFW_PLATFORM_NULL 0x00060005
#define GLFW_PLATFORM_OGC 0x00060006
/*! @} */ /*! @} */
#define GLFW_DONT_CARE -1 #define GLFW_DONT_CARE -1
@ -1629,7 +1630,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSizeCallback * @sa @ref glfwSetWindowSizeCallback
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -1649,7 +1650,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
* @sa @ref glfwSetWindowCloseCallback * @sa @ref glfwSetWindowCloseCallback
* *
* @since Added in version 2.5. * @since Added in version 2.5.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -1669,7 +1670,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
* @sa @ref glfwSetWindowRefreshCallback * @sa @ref glfwSetWindowRefreshCallback
* *
* @since Added in version 2.5. * @since Added in version 2.5.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -1800,7 +1801,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, flo
* @sa @ref glfwSetMouseButtonCallback * @sa @ref glfwSetMouseButtonCallback
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle and modifier mask parameters. * __GLFW 3:__ Added window handle and modifier mask parameters.
* *
* @ingroup input * @ingroup input
*/ */
@ -1891,7 +1892,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse
* @sa @ref glfwSetKeyCallback * @sa @ref glfwSetKeyCallback
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle, scancode and modifier mask parameters. * __GLFW 3:__ Added window handle, scancode and modifier mask parameters.
* *
* @ingroup input * @ingroup input
*/ */
@ -1912,7 +1913,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int actio
* @sa @ref glfwSetCharCallback * @sa @ref glfwSetCharCallback
* *
* @since Added in version 2.4. * @since Added in version 2.4.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup input * @ingroup input
*/ */
@ -2020,7 +2021,7 @@ typedef void (* GLFWjoystickfun)(int jid, int event);
* @sa @ref glfwGetVideoModes * @sa @ref glfwGetVideoModes
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added refresh rate member. * __GLFW 3:__ Added refresh rate member.
* *
* @ingroup monitor * @ingroup monitor
*/ */
@ -2083,7 +2084,7 @@ typedef struct GLFWgammaramp
* @sa @ref window_icon * @sa @ref window_icon
* *
* @since Added in version 2.1. * @since Added in version 2.1.
* @glfw3 Removed format and bytes-per-pixel members. * __GLFW 3:__ Removed format and bytes-per-pixel members.
* *
* @ingroup window * @ingroup window
*/ */
@ -2183,12 +2184,12 @@ typedef struct GLFWallocator
* @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref * @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @macos This function will change the current directory of the * @remark __macOS:__ This function will change the current directory of the
* application to the `Contents/Resources` subdirectory of the application's * application to the `Contents/Resources` subdirectory of the application's
* bundle, if present. This can be disabled with the @ref * bundle, if present. This can be disabled with the @ref
* GLFW_COCOA_CHDIR_RESOURCES init hint. * GLFW_COCOA_CHDIR_RESOURCES init hint.
* *
* @remark @macos This function will create the main menu and dock icon for the * @remark __macOS:__ This function will create the main menu and dock icon for the
* application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to * application. If GLFW finds a `MainMenu.nib` it is loaded and assumed to
* contain a menu bar. Otherwise a minimal menu bar is created manually with * contain a menu bar. Otherwise a minimal menu bar is created manually with
* common commands like Hide, Quit and About. The About entry opens a minimal * common commands like Hide, Quit and About. The About entry opens a minimal
@ -2203,7 +2204,7 @@ typedef struct GLFWallocator
* to something other than `wayland` or `x11`, the regular detection mechanism * to something other than `wayland` or `x11`, the regular detection mechanism
* will be used instead. * will be used instead.
* *
* @remark @x11 This function will set the `LC_CTYPE` category of the * @remark __X11:__ This function will set the `LC_CTYPE` category of the
* application locale according to the current environment if that category is * application locale according to the current environment if that category is
* still "C". This is because the "C" locale breaks Unicode text input. * still "C". This is because the "C" locale breaks Unicode text input.
* *
@ -2679,7 +2680,7 @@ GLFWAPI void glfwGetMonitorWorkarea(GLFWmonitor* monitor, int* xpos, int* ypos,
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @win32 On Windows 8 and earlier the physical size is calculated from * @remark __Win32:__ On Windows 8 and earlier the physical size is calculated from
* the current resolution and system DPI instead of querying the monitor EDID data. * the current resolution and system DPI instead of querying the monitor EDID data.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -2713,7 +2714,7 @@ GLFWAPI void glfwGetMonitorPhysicalSize(GLFWmonitor* monitor, int* widthMM, int*
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland Fractional scaling information is not yet available for * @remark __Wayland:__ Fractional scaling information is not yet available for
* monitors, so this function only returns integer content scales. * monitors, so this function only returns integer content scales.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -2861,7 +2862,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
* @sa @ref glfwGetVideoMode * @sa @ref glfwGetVideoMode
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Changed to return an array of modes for a specific monitor. * __GLFW 3:__ Changed to return an array of modes for a specific monitor.
* *
* @ingroup monitor * @ingroup monitor
*/ */
@ -2915,7 +2916,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE, * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
* @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * @ref GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland Monitor gamma is a privileged protocol, so this function * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -2939,7 +2940,7 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* monitor, float gamma);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_PLATFORM_ERROR
* and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland Monitor gamma is a privileged protocol, so this function * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE while
* returning `NULL`. * returning `NULL`.
* *
@ -2981,9 +2982,9 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor);
* @remark The size of the specified gamma ramp should match the size of the * @remark The size of the specified gamma ramp should match the size of the
* current ramp for that monitor. * current ramp for that monitor.
* *
* @remark @win32 The gamma ramp size must be 256. * @remark __Win32:__ The gamma ramp size must be 256.
* *
* @remark @wayland Monitor gamma is a privileged protocol, so this function * @remark __Wayland:__ Monitor gamma is a privileged protocol, so this function
* cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE. * cannot be implemented and emits @ref GLFW_FEATURE_UNAVAILABLE.
* *
* @pointer_lifetime The specified gamma ramp is copied before this function * @pointer_lifetime The specified gamma ramp is copied before this function
@ -3159,32 +3160,32 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref * GLFW_VERSION_UNAVAILABLE, @ref GLFW_FORMAT_UNAVAILABLE, @ref
* GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR. * GLFW_NO_WINDOW_CONTEXT and @ref GLFW_PLATFORM_ERROR.
* *
* @remark @win32 Window creation will fail if the Microsoft GDI software * @remark __Win32:__ Window creation will fail if the Microsoft GDI software
* OpenGL implementation is the only one available. * OpenGL implementation is the only one available.
* *
* @remark @win32 If the executable has an icon resource named `GLFW_ICON,` it * @remark __Win32:__ If the executable has an icon resource named `GLFW_ICON,` it
* will be set as the initial icon for the window. If no such icon is present, * will be set as the initial icon for the window. If no such icon is present,
* the `IDI_APPLICATION` icon will be used instead. To set a different icon, * the `IDI_APPLICATION` icon will be used instead. To set a different icon,
* see @ref glfwSetWindowIcon. * see @ref glfwSetWindowIcon.
* *
* @remark @win32 The context to share resources with must not be current on * @remark __Win32:__ The context to share resources with must not be current on
* any other thread. * any other thread.
* *
* @remark @macos The OS only supports core profile contexts for OpenGL * @remark __macOS:__ The OS only supports core profile contexts for OpenGL
* versions 3.2 and later. Before creating an OpenGL context of version 3.2 or * versions 3.2 and later. Before creating an OpenGL context of version 3.2 or
* later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint) * later you must set the [GLFW_OPENGL_PROFILE](@ref GLFW_OPENGL_PROFILE_hint)
* hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all * hint accordingly. OpenGL 3.0 and 3.1 contexts are not supported at all
* on macOS. * on macOS.
* *
* @remark @macos The GLFW window has no icon, as it is not a document * @remark __macOS:__ The GLFW window has no icon, as it is not a document
* window, but the dock icon will be the same as the application bundle's icon. * window, but the dock icon will be the same as the application bundle's icon.
* For more information on bundles, see the * For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
* *
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
* *
* @remark @macos The window frame will not be rendered at full resolution on * @remark __macOS:__ The window frame will not be rendered at full resolution
* Retina displays unless the * on Retina displays unless the
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint) * [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the * hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* application bundle's `Info.plist`. For more information, see * application bundle's `Info.plist`. For more information, see
@ -3195,11 +3196,11 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* *
* [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html * [hidpi-guide]: https://developer.apple.com/library/mac/documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/Explained/Explained.html
* *
* @remark @macos When activating frame autosaving with * @remark __macOS:__ When activating frame autosaving with
* [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified * [GLFW_COCOA_FRAME_NAME](@ref GLFW_COCOA_FRAME_NAME_hint), the specified
* window size and position may be overridden by previously saved values. * window size and position may be overridden by previously saved values.
* *
* @remark @wayland GLFW uses [libdecor][] where available to create its window * @remark __Wayland:__ GLFW uses [libdecor][] where available to create its window
* decorations. This in turn uses server-side XDG decorations where available * decorations. This in turn uses server-side XDG decorations where available
* and provides high quality client-side decorations on compositors like GNOME. * and provides high quality client-side decorations on compositors like GNOME.
* If both XDG decorations and libdecor are unavailable, GLFW falls back to * If both XDG decorations and libdecor are unavailable, GLFW falls back to
@ -3208,15 +3209,15 @@ GLFWAPI void glfwWindowHintString(int hint, const char* value);
* *
* [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor * [libdecor]: https://gitlab.freedesktop.org/libdecor/libdecor
* *
* @remark @x11 Some window managers will not respect the placement of * @remark __X11:__ Some window managers will not respect the placement of
* initially hidden windows. * initially hidden windows.
* *
* @remark @x11 Due to the asynchronous nature of X11, it may take a moment for * @remark __X11:__ Due to the asynchronous nature of X11, it may take a moment for
* a window to reach its requested state. This means you may not be able to * a window to reach its requested state. This means you may not be able to
* query the final size, position or other attributes directly after window * query the final size, position or other attributes directly after window
* creation. * creation.
* *
* @remark @x11 The class part of the `WM_CLASS` window property will by * @remark __X11:__ The class part of the `WM_CLASS` window property will by
* default be set to the window title passed to this function. The instance * default be set to the window title passed to this function. The instance
* part will use the contents of the `RESOURCE_NAME` environment variable, if * part will use the contents of the `RESOURCE_NAME` environment variable, if
* present and not empty, or fall back to the window title. Set the * present and not empty, or fall back to the window title. Set the
@ -3349,7 +3350,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @macos The window title will not be updated until the next time you * @remark __macOS:__ The window title will not be updated until the next time you
* process events. * process events.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3358,7 +3359,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
* @sa @ref glfwGetWindowTitle * @sa @ref glfwGetWindowTitle
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3392,14 +3393,14 @@ GLFWAPI void glfwSetWindowTitle(GLFWwindow* window, const char* title);
* @pointer_lifetime The specified image data is copied before this function * @pointer_lifetime The specified image data is copied before this function
* returns. * returns.
* *
* @remark @macos Regular windows do not have icons on macOS. This function * @remark __macOS:__ Regular windows do not have icons on macOS. This function
* will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as * will emit @ref GLFW_FEATURE_UNAVAILABLE. The dock icon will be the same as
* the application bundle's icon. For more information on bundles, see the * the application bundle's icon. For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library. * [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
* *
* [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/ * [bundle-guide]: https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/
* *
* @remark @wayland There is no existing protocol to change an icon, the * @remark __Wayland:__ There is no existing protocol to change an icon, the
* window will thus inherit the one defined in the application's desktop file. * window will thus inherit the one defined in the application's desktop file.
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE. * This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
* *
@ -3430,7 +3431,7 @@ GLFWAPI void glfwSetWindowIcon(GLFWwindow* window, int count, const GLFWimage* i
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland Window positions are not currently part of any common * @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref * Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE. * GLFW_FEATURE_UNAVAILABLE.
* *
@ -3464,7 +3465,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland Window positions are not currently part of any common * @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol, so this function cannot be implemented and will emit @ref * Wayland protocol, so this function cannot be implemented and will emit @ref
* GLFW_FEATURE_UNAVAILABLE. * GLFW_FEATURE_UNAVAILABLE.
* *
@ -3474,7 +3475,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @sa @ref glfwGetWindowPos * @sa @ref glfwGetWindowPos
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3504,7 +3505,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSize * @sa @ref glfwSetWindowSize
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3539,7 +3540,7 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height);
* @remark If you set size limits and an aspect ratio that conflict, the * @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined. * results are undefined.
* *
* @remark @wayland The size limits will not be applied until the window is * @remark __Wayland:__ The size limits will not be applied until the window is
* actually resized, either by the user or by the compositor. * actually resized, either by the user or by the compositor.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3582,7 +3583,7 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe
* @remark If you set size limits and an aspect ratio that conflict, the * @remark If you set size limits and an aspect ratio that conflict, the
* results are undefined. * results are undefined.
* *
* @remark @wayland The aspect ratio will not be applied until the window is * @remark __Wayland:__ The aspect ratio will not be applied until the window is
* actually resized, either by the user or by the compositor. * actually resized, either by the user or by the compositor.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3628,7 +3629,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom);
* @sa @ref glfwSetWindowMonitor * @sa @ref glfwSetWindowMonitor
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3778,7 +3779,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland There is no way to set an opacity factor for a window. * @remark __Wayland:__ There is no way to set an opacity factor for a window.
* This function will emit @ref GLFW_FEATURE_UNAVAILABLE. * This function will emit @ref GLFW_FEATURE_UNAVAILABLE.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3814,7 +3815,7 @@ GLFWAPI void glfwSetWindowOpacity(GLFWwindow* window, float opacity);
* @sa @ref glfwMaximizeWindow * @sa @ref glfwMaximizeWindow
* *
* @since Added in version 2.1. * @since Added in version 2.1.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3834,9 +3835,9 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland Restoring a window from maximization is not currently part * @remark __Wayland:__ Restoring a window from maximization is not currently
* of any common Wayland protocol, so this function can only restore windows * part of any common Wayland protocol, so this function can only restore
* from maximization. * windows from maximization.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
* *
@ -3845,7 +3846,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @sa @ref glfwMaximizeWindow * @sa @ref glfwMaximizeWindow
* *
* @since Added in version 2.1. * @since Added in version 2.1.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -3892,7 +3893,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland Because Wayland wants every frame of the desktop to be * @remark __Wayland:__ Because Wayland wants every frame of the desktop to be
* complete, this function does not immediately make the window visible. * complete, this function does not immediately make the window visible.
* Instead it will become visible the next time the window framebuffer is * Instead it will become visible the next time the window framebuffer is
* updated after this call. * updated after this call.
@ -3955,7 +3956,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @wayland The compositor will likely ignore focus requests unless * @remark __Wayland:__ The compositor will likely ignore focus requests unless
* another window created by the same application already has input focus. * another window created by the same application already has input focus.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -3983,7 +3984,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @macos Attention is requested to the application as a whole, not the * @remark __macOS:__ Attention is requested to the application as a whole, not the
* specific window. * specific window.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -4058,7 +4059,7 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window);
* affected by any resizing or mode switching, although you may need to update * affected by any resizing or mode switching, although you may need to update
* your viewport if the framebuffer size has changed. * your viewport if the framebuffer size has changed.
* *
* @remark @wayland Window positions are not currently part of any common * @remark __Wayland:__ Window positions are not currently part of any common
* Wayland protocol. The window position arguments are ignored. * Wayland protocol. The window position arguments are ignored.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -4096,7 +4097,7 @@ GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int
* errors. However, this function should not fail as long as it is passed * errors. However, this function should not fail as long as it is passed
* valid arguments and the library has been [initialized](@ref intro_init). * valid arguments and the library has been [initialized](@ref intro_init).
* *
* @remark @wayland Checking whether a window is iconified is not currently * @remark __Wayland:__ Checking whether a window is iconified is not currently
* part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute * part of any common Wayland protocol, so the @ref GLFW_ICONIFIED attribute
* cannot be implemented and is always `GLFW_FALSE`. * cannot be implemented and is always `GLFW_FALSE`.
* *
@ -4140,7 +4141,7 @@ GLFWAPI int glfwGetWindowAttrib(GLFWwindow* window, int attrib);
* @remark Calling @ref glfwGetWindowAttrib will always return the latest * @remark Calling @ref glfwGetWindowAttrib will always return the latest
* value, even if that value is ignored by the current mode of the window. * value, even if that value is ignored by the current mode of the window.
* *
* @remark @wayland The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is * @remark __Wayland:__ The [GLFW_FLOATING](@ref GLFW_FLOATING_attrib) window attribute is
* not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE. * not supported. Setting this will emit @ref GLFW_FEATURE_UNAVAILABLE.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -4220,7 +4221,7 @@ GLFWAPI void* glfwGetWindowUserPointer(GLFWwindow* window);
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @wayland This callback will not be called. The Wayland protocol * @remark __Wayland:__ This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is moved. * provides no way to be notified of when a window is moved.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -4259,7 +4260,7 @@ GLFWAPI GLFWwindowposfun glfwSetWindowPosCallback(GLFWwindow* window, GLFWwindow
* @sa @ref window_size * @sa @ref window_size
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup window * @ingroup window
*/ */
@ -4291,7 +4292,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @macos Selecting Quit from the application menu will trigger the * @remark __macOS:__ Selecting Quit from the application menu will trigger the
* close callback for all windows. * close callback for all windows.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -4299,7 +4300,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
* @sa @ref window_close * @sa @ref window_close
* *
* @since Added in version 2.5. * @since Added in version 2.5.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup window * @ingroup window
*/ */
@ -4335,7 +4336,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
* @sa @ref window_refresh * @sa @ref window_refresh
* *
* @since Added in version 2.5. * @since Added in version 2.5.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup window * @ingroup window
*/ */
@ -4396,7 +4397,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
* *
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED. * @errors Possible errors include @ref GLFW_NOT_INITIALIZED.
* *
* @remark @wayland This callback will not be called. The Wayland protocol * @remark __Wayland:__ This callback will not be called. The Wayland protocol
* provides no way to be notified of when a window is iconified, and no way to * provides no way to be notified of when a window is iconified, and no way to
* check whether a window is currently iconified. * check whether a window is currently iconified.
* *
@ -4905,7 +4906,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
* @sa @ref input_key * @sa @ref input_key
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup input * @ingroup input
*/ */
@ -4937,7 +4938,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* @sa @ref input_mouse_button * @sa @ref input_mouse_button
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup input * @ingroup input
*/ */
@ -5007,7 +5008,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks). * GLFW_PLATFORM_ERROR and @ref GLFW_FEATURE_UNAVAILABLE (see remarks).
* *
* @remark @wayland This function will only work when the cursor mode is * @remark __Wayland:__ This function will only work when the cursor mode is
* `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE. * `GLFW_CURSOR_DISABLED`, otherwise it will emit @ref GLFW_FEATURE_UNAVAILABLE.
* *
* @thread_safety This function must only be called from the main thread. * @thread_safety This function must only be called from the main thread.
@ -5205,7 +5206,7 @@ GLFWAPI void glfwSetCursor(GLFWwindow* window, GLFWcursor* cursor);
* @sa @ref input_key * @sa @ref input_key
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup input * @ingroup input
*/ */
@ -5248,7 +5249,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
* @sa @ref input_char * @sa @ref input_char
* *
* @since Added in version 2.4. * @since Added in version 2.4.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup input * @ingroup input
*/ */
@ -5332,7 +5333,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* @sa @ref input_mouse_button * @sa @ref input_mouse_button
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter and return value. * __GLFW 3:__ Added window handle parameter and return value.
* *
* @ingroup input * @ingroup input
*/ */
@ -5562,7 +5563,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
* @sa @ref joystick_button * @sa @ref joystick_button
* *
* @since Added in version 2.2. * @since Added in version 2.2.
* @glfw3 Changed to return a dynamic array. * __GLFW 3:__ Changed to return a dynamic array.
* *
* @ingroup input * @ingroup input
*/ */
@ -5926,7 +5927,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR. * GLFW_PLATFORM_ERROR.
* *
* @remark @win32 The clipboard on Windows has a single global lock for reading and * @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it * writing. GLFW tries to acquire it a few times, which is almost always enough. If it
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* It is safe to try this multiple times. * It is safe to try this multiple times.
@ -5959,7 +5960,7 @@ GLFWAPI void glfwSetClipboardString(GLFWwindow* window, const char* string);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * GLFW_FORMAT_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
* *
* @remark @win32 The clipboard on Windows has a single global lock for reading and * @remark __Win32:__ The clipboard on Windows has a single global lock for reading and
* writing. GLFW tries to acquire it a few times, which is almost always enough. If it * writing. GLFW tries to acquire it a few times, which is almost always enough. If it
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns. * cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* It is safe to try this multiple times. * It is safe to try this multiple times.
@ -6176,7 +6177,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @sa @ref glfwSwapInterval * @sa @ref glfwSwapInterval
* *
* @since Added in version 1.0. * @since Added in version 1.0.
* @glfw3 Added window handle parameter. * __GLFW 3:__ Added window handle parameter.
* *
* @ingroup window * @ingroup window
*/ */
@ -6443,7 +6444,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref * @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR. * GLFW_API_UNAVAILABLE and @ref GLFW_PLATFORM_ERROR.
* *
* @remark @macos This function currently always returns `GLFW_TRUE`, as the * @remark __macOS:__ This function currently always returns `GLFW_TRUE`, as the
* `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide * `VK_MVK_macos_surface` and `VK_EXT_metal_surface` extensions do not provide
* a `vkGetPhysicalDevice*PresentationSupport` type function. * a `vkGetPhysicalDevice*PresentationSupport` type function.
* *
@ -6501,15 +6502,15 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should * @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
* eliminate almost all occurrences of these errors. * eliminate almost all occurrences of these errors.
* *
* @remark @macos GLFW prefers the `VK_EXT_metal_surface` extension, with the * @remark __macOS:__ GLFW prefers the `VK_EXT_metal_surface` extension, with the
* `VK_MVK_macos_surface` extension as a fallback. The name of the selected * `VK_MVK_macos_surface` extension as a fallback. The name of the selected
* extension, if any, is included in the array returned by @ref * extension, if any, is included in the array returned by @ref
* glfwGetRequiredInstanceExtensions. * glfwGetRequiredInstanceExtensions.
* *
* @remark @macos This function creates and sets a `CAMetalLayer` instance for * @remark __macOS:__ This function creates and sets a `CAMetalLayer` instance for
* the window content view, which is required for MoltenVK to function. * the window content view, which is required for MoltenVK to function.
* *
* @remark @x11 By default GLFW prefers the `VK_KHR_xcb_surface` extension, * @remark __X11:__ By default GLFW prefers the `VK_KHR_xcb_surface` extension,
* with the `VK_KHR_xlib_surface` extension as a fallback. You can make * with the `VK_KHR_xlib_surface` extension as a fallback. You can make
* `VK_KHR_xlib_surface` the preferred extension by setting the * `VK_KHR_xlib_surface` the preferred extension by setting the
* [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init * [GLFW_X11_XCB_VULKAN_SURFACE](@ref GLFW_X11_XCB_VULKAN_SURFACE_hint) init

View File

@ -478,6 +478,29 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
* @ingroup native * @ingroup native
*/ */
GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window); GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* window);
/*! @brief Retrieves the `GLXFBConfig` of the specified window's `GLXWindow`.
*
* @param[in] window The window whose `GLXWindow` to query.
* @param[out] config The `GLXFBConfig` of the window `GLXWindow`, if available.
* @return `GLFW_TRUE` if successful, or `GLFW_FALSE` 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.
*
* @remark `GLXFBConfig` is an opaque type. Unlike other GLFW functions, the
* @p config out parameter is not cleared on error, as core GLX does not define
* any invalid value.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.5
*
* @ingroup native
*/
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* window, GLXFBConfig* config);
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND) #if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
@ -586,6 +609,29 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @ingroup native * @ingroup native
*/ */
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window); GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
/*! @brief Retrieves the `EGLConfig` of the specified window's `EGLSurface`.
*
* @param[in] window The window whose `EGLSurface` to query.
* @param[out] config The `EGLConfig` of the window `EGLSurface`, if available.
* @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.
*
* @remark `EGLConfig` is an opaque type. Unlike other GLFW functions, the @p
* config out parameter is not cleared on error, as core EGL does not define
* any invalid value.
*
* @thread_safety This function may be called from any thread. Access is not
* synchronized.
*
* @since Added in version 3.5.
*
* @ingroup native
*/
GLFWAPI int glfwGetEGLConfig(GLFWwindow* window, EGLConfig* config);
#endif #endif
#if defined(GLFW_EXPOSE_NATIVE_OSMESA) #if defined(GLFW_EXPOSE_NATIVE_OSMESA)

View File

@ -15,6 +15,9 @@ if (APPLE)
elseif (WIN32) elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.c
win32_time.c win32_thread.c) win32_time.c win32_thread.c)
elseif (OGC)
target_sources(glfw PRIVATE ogc_time.h ogc_thread.h ogc_module.c
ogc_time.c ogc_thread.c)
else() else()
target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c
posix_time.c posix_thread.c) posix_time.c posix_thread.c)
@ -57,6 +60,13 @@ if (GLFW_BUILD_WAYLAND)
wl_monitor.c wl_window.c) wl_monitor.c wl_window.c)
endif() endif()
if (GLFW_BUILD_OGC)
target_compile_definitions(glfw PRIVATE _GLFW_OGC)
target_sources(glfw PRIVATE ogc_platform.h ogc_init.c ogc_joystick.c
ogc_monitor.c ogc_window.c ogc_context.c
ogc_cursor.h)
endif()
if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND) if (GLFW_BUILD_X11 OR GLFW_BUILD_WAYLAND)
if (CMAKE_SYSTEM_NAME STREQUAL "Linux") if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c) target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
@ -136,7 +146,9 @@ target_include_directories(glfw PUBLIC
target_include_directories(glfw PRIVATE target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src" "${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src") "${GLFW_BINARY_DIR}/src")
if (Threads_FOUND)
target_link_libraries(glfw PRIVATE Threads::Threads) target_link_libraries(glfw PRIVATE Threads::Threads)
endif()
if (GLFW_BUILD_WIN32) if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32") list(APPEND glfw_PKG_LIBS "-lgdi32")
@ -213,6 +225,13 @@ if (GLFW_BUILD_X11)
target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}") target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}")
endif() endif()
if (GLFW_BUILD_OGC)
include(FindPkgConfig)
pkg_check_modules(Opengx REQUIRED IMPORTED_TARGET opengl)
target_link_libraries(glfw PRIVATE PkgConfig::Opengx wiikeyboard fat)
endif()
if (UNIX AND NOT APPLE) if (UNIX AND NOT APPLE)
find_library(RT_LIBRARY rt) find_library(RT_LIBRARY rt)
mark_as_advanced(RT_LIBRARY) mark_as_advanced(RT_LIBRARY)

View File

@ -884,7 +884,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
[window->ns.object setContentView:window->ns.view]; [window->ns.object setContentView:window->ns.view];
[window->ns.object makeFirstResponder:window->ns.view]; [window->ns.object makeFirstResponder:window->ns.view];
[window->ns.object setTitle:@(wndconfig->title)]; [window->ns.object setTitle:@(window->title)];
[window->ns.object setDelegate:window->ns.delegate]; [window->ns.object setDelegate:window->ns.delegate];
[window->ns.object setAcceptsMouseMovedEvents:YES]; [window->ns.object setAcceptsMouseMovedEvents:YES];
[window->ns.object setRestorable:NO]; [window->ns.object setRestorable:NO];

View File

@ -939,10 +939,32 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
window->context.source != GLFW_NATIVE_CONTEXT_API) window->context.source != GLFW_NATIVE_CONTEXT_API)
{ {
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL); _glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT; return EGL_NO_SURFACE;
} }
} }
return window->context.egl.surface; return window->context.egl.surface;
} }
GLFWAPI int glfwGetEGLConfig(GLFWwindow* handle, EGLConfig* config)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(config != NULL);
if (window->context.source != GLFW_EGL_CONTEXT_API)
{
if (_glfw.platform.platformID != GLFW_PLATFORM_WAYLAND ||
window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
}
*config = window->context.egl.config;
return GLFW_TRUE;
}

View File

@ -626,6 +626,8 @@ GLFWbool _glfwCreateContextGLX(_GLFWwindow* window,
return GLFW_FALSE; return GLFW_FALSE;
} }
window->context.glx.fbconfig = native;
window->context.makeCurrent = makeContextCurrentGLX; window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffersGLX; window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapIntervalGLX; window->context.swapInterval = swapIntervalGLX;
@ -719,5 +721,29 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
return window->context.glx.window; return window->context.glx.window;
} }
GLFWAPI int glfwGetGLXFBConfig(GLFWwindow* handle, GLXFBConfig* config)
{
_GLFW_REQUIRE_INIT_OR_RETURN(GLFW_FALSE);
if (_glfw.platform.platformID != GLFW_PLATFORM_X11)
{
_glfwInputError(GLFW_PLATFORM_UNAVAILABLE, "GLX: Platform not initialized");
return GLFW_FALSE;
}
_GLFWwindow* window = (_GLFWwindow*) handle;
assert(window != NULL);
assert(config != NULL);
if (window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return GLFW_FALSE;
}
*config = window->context.glx.fbconfig;
return GLFW_TRUE;
}
#endif // _GLFW_X11 #endif // _GLFW_X11

View File

@ -402,7 +402,6 @@ struct _GLFWwndconfig
int ypos; int ypos;
int width; int width;
int height; int height;
const char* title;
GLFWbool resizable; GLFWbool resizable;
GLFWbool visible; GLFWbool visible;
GLFWbool decorated; GLFWbool decorated;

View File

@ -997,5 +997,13 @@ const char* _glfwDefaultMappings[] =
"03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000100e000011010000,ZEROPLUS P4 Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
"03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,", "03000000120c0000101e000011010000,ZEROPLUS P4 Wired Gamepad,a:b1,b:b2,back:b8,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,platform:Linux,",
#endif // GLFW_BUILD_LINUX_JOYSTICK #endif // GLFW_BUILD_LINUX_JOYSTICK
#if defined(_GLFW_OGC)
"05002bf87e0500000105000001000000,Nintendo Wiimote 1,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500ea387e0500000106000001000000,Nintendo Wiimote 2,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500aa397e0500000107000001000000,Nintendo Wiimote 3,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"05006bf97e0500000108000001000000,Nintendo Wiimote 4,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
"0500b98e7e0500000305000001000000,Nintendo Wii Classic 1,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
#endif
}; };

View File

@ -78,5 +78,9 @@ const char* _glfwDefaultMappings[] =
#if defined(GLFW_BUILD_LINUX_JOYSTICK) #if defined(GLFW_BUILD_LINUX_JOYSTICK)
@GLFW_LINUX_MAPPINGS@ @GLFW_LINUX_MAPPINGS@
#endif // GLFW_BUILD_LINUX_JOYSTICK #endif // GLFW_BUILD_LINUX_JOYSTICK
#if defined(_GLFW_OGC)
"05002bf87e0500000105000001000000,Nintendo Wiimote,a:b0,b:b1,x:b2,y:b3,back:b6,guide:b4,start:b5,dpup:h0.1,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,platform:Ogc,",
#endif
}; };

204
src/ogc_context.c Normal file
View File

@ -0,0 +1,204 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <stdlib.h>
#include <string.h>
#include <opengx.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
#ifdef __wii__
static void drawCursorRect(_GLFWcursor* cursor)
{
short xhot = cursor->ogc.xhot;
short yhot = cursor->ogc.yhot;
u16 width = GX_GetTexObjWidth(&cursor->ogc.texobj);
u16 height = GX_GetTexObjHeight(&cursor->ogc.texobj);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
GX_Position2s16(-xhot, -yhot);
GX_TexCoord2u8(0, 0);
GX_Position2s16(width - xhot, -yhot);
GX_TexCoord2u8(1, 0);
GX_Position2s16(width - xhot, height - yhot);
GX_TexCoord2u8(1, 1);
GX_Position2s16(-xhot, height - yhot);
GX_TexCoord2u8(0, 1);
GX_End();
}
static void drawCursor(_GLFWwindow* window)
{
Mtx44 proj;
Mtx mv;
_GLFWcursor* cursor = window->ogc.currentCursor;
if (!cursor) return;
GX_LoadTexObj(&cursor->ogc.texobj, GX_TEXMAP0);
int width = window->ogc.width;
int height = window->ogc.height;
guOrtho(proj, 0, height, 0, width, 0, 1);
GX_LoadProjectionMtx(proj, GX_ORTHOGRAPHIC);
guMtxIdentity(mv);
guMtxScaleApply(mv, mv,
width / 640.0f,
height / 480.0f, 1.0f);
if (cursor->ogc.canRotate) {
Mtx rot;
float angle;
WPADData *data = WPAD_Data(0);
angle = data->ir.angle;
guMtxRotDeg(rot, 'z', angle);
guMtxConcat(mv, rot, mv);
}
guMtxTransApply(mv, mv,
window->virtualCursorPosX,
window->virtualCursorPosY, 0);
GX_LoadPosMtxImm(mv, GX_PNMTX1);
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_DIRECT);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U8, 0);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetNumTevStages(1);
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
GX_SetNumTexGens(1);
GX_SetCurrentMtx(GX_PNMTX1);
GX_SetZMode(GX_DISABLE, GX_ALWAYS, GX_FALSE);
GX_SetScissor(0, 0, width, height);
drawCursorRect(cursor);
GX_SetCurrentMtx(GX_PNMTX0);
GX_DrawDone();
}
#endif // __wii__
static void makeContextCurrentOgc(_GLFWwindow* window)
{
_glfwPlatformSetTls(&_glfw.contextSlot, window);
}
static GLFWglproc getProcAddressOgc(const char* procname)
{
return (GLFWglproc) ogx_get_proc_address(procname);
}
static void destroyContextOgc(_GLFWwindow* window)
{
}
static void swapBuffersOgc(_GLFWwindow* window)
{
void *xfb;
u8 mustClear, mustWait;
if (ogx_prepare_swap_buffers() < 0) return;
#ifdef __wii__
if (window->ogc.hovered &&
(window->callbacks.mouseButton || window->callbacks.cursorPos))
drawCursor(window);
#endif // __wii__
if (window->doublebuffer) {
mustClear = GX_TRUE;
mustWait = GX_TRUE;
xfb = _glfw.ogc.xfb[_glfw.ogc.fbIndex];
_glfw.ogc.fbIndex ^= 1;
} else {
mustClear = GX_FALSE;
mustWait = GX_FALSE;
xfb = _glfw.ogc.xfb[0];
}
GX_CopyDisp(xfb, mustClear);
GX_DrawDone();
GX_Flush();
VIDEO_SetNextFramebuffer(xfb);
VIDEO_Flush();
if (mustWait)
VIDEO_WaitVSync();
}
static void swapIntervalOgc(int interval)
{
// No swap interval on Ogc
}
static int extensionSupportedOgc(const char* extension)
{
const char *extensions = (const char*)glGetString(GL_EXTENSIONS);
return strstr(extensions, extensions) != NULL;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateContextOgc(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
if (ctxconfig->client == GLFW_OPENGL_ES_API)
{
_glfwInputError(GLFW_API_UNAVAILABLE,
"Ogc: OpenGL ES is not available on Ogc");
return GLFW_FALSE;
}
ogx_enable_double_buffering(fbconfig->doublebuffer);
if (fbconfig->stencilBits > 0) {
OgxStencilFlags stencilFlags = OGX_STENCIL_NONE;
if (fbconfig->stencilBits > 4) stencilFlags |= OGX_STENCIL_8BIT;
ogx_stencil_create(stencilFlags);
}
window->context.makeCurrent = makeContextCurrentOgc;
window->context.swapBuffers = swapBuffersOgc;
window->context.swapInterval = swapIntervalOgc;
window->context.extensionSupported = extensionSupportedOgc;
window->context.getProcAddress = getProcAddressOgc;
window->context.destroy = destroyContextOgc;
return GLFW_TRUE;
}

487
src/ogc_cursor.h Normal file
View File

@ -0,0 +1,487 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <gctypes.h>
typedef struct {
u16 width;
u16 height;
u8 hot_x;
u8 hot_y;
u8 bytes_per_pixel;
u8 pixel_data[];
} _GLFWcursorDataOgc;
static const _GLFWcursorDataOgc OGC_cursor_hand = {
37, 52, 11, 0, 4,
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000Q\000"
"\000\000\262\000\000\000\337\000\000\000\345\000\000\000\313\000\000\000\203\000\000\000\032\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\005"
"\000\000\000\224\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000"
"\000\000\330\000\000\000\062\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\177\000\000\000\377\000\000\000\377\026\026\026\377bbb\377ttt\377"
"<<<\377\000\000\000\377\000\000\000\377\000\000\000\334\000\000\000\030\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000%\000\000\000\364\000\000\000\377...\377\327\327"
"\327\377\377\377\377\377\377\377\377\377\373\373\373\377\177\177\177\377"
"\000\000\000\377\000\000\000\377\000\000\000\206\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000n\000\000\000\377\005\005\005\377\277\277\277\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377BBB\377\000"
"\000\000\377\000\000\000\323\000\000\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\225\000\000\000\377###\377\366\366\366\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\206\206\206\377\000\000"
"\000\377\000\000\000\356\000\000\000\033\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\231\000\000\000\377+++\377\370\370\370\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\217\217\217\377\000\000\000\377"
"\000\000\000\361\000\000\000\040\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\230\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000"
"\000\000\360\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230"
"\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000"
"\360\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000"
"\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360"
"\000\000\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000"
"\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000"
"\000\037\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377"
"***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000\000\037"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377"
"\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\360\000\000\000\037\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367"
"\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\357\000\000\000\026\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367\367"
"\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\370\000\000\000\244\000\000\000\223"
"\000\000\000e\000\000\000\032\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367\367"
"\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\215\215\215\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377\000\000\000\340\000\000\000Z\000\000\000\000\000\000\000\003\000\000\000\022\000\000\000\006\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000\377***\377\367"
"\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\215\215\215\377\000\000\000\377\001\001\001\377%%%\377\036\036\036"
"\377\000\000\000\377\000\000\000\377\000\000\000\373\000\000\000\244\000\000\000\310\000\000\000\341\000\000\000\320"
"\000\000\000\220\000\000\000*\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\230\000\000\000"
"\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\210\210\210\377\022\022\022\377\270\270\270"
"\377\356\356\356\377\351\351\351\377\236\236\236\377\022\022\022\377\000\000\000\377"
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\357\000\000\000[\000\000\000"
"\030\000\000\000<\000\000\000B\000\000\000(\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\227\000\000\000\377***\377\367\367\367\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\202\202\202\377\065\065\065\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\246\246\246\377\001\001\001\377\003\003\003\377@@@\377iii\377DD"
"D\377\002\002\002\377\000\000\000\377\000\000\000\372\000\000\000\342\000\000\000\375\000\000\000\377\000\000\000\360"
"\000\000\000\264\000\000\000:\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\233\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061"
"\377\375\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\372"
"\372\372\377\036\036\036\377kkk\377\375\375\375\377\377\377\377\377\377\377"
"\377\377\253\253\253\377\015\015\015\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000"
"\377\000\000\000\377\000\000\000\377\000\000\000\366\000\000\000U\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\016"
"\000\000\000n\000\000\000\272\000\000\000\360\000\000\000\377***\377\367\367\367\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\203"
"\203\203\377\061\061\061\377\375\375\375\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\376\376\376\377\063\063\063\377\211\211\211\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\177\177\177\377\000\000"
"\000\377AAA\377\236\236\236\377\256\256\256\377lll\377\011\011\011\377\000\000\000\377"
"\000\000\000\360\000\000\000)\000\000\000\000\000\000\000!\000\000\000\304\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377***\377\367\367\367\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061\377\375"
"\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375"
"\377\061\061\061\377\203\203\203\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\304\304\304\377\011\011\011\377\327\327\327\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\247\247\247\377\006\006\006\377\000"
"\000\000\377\000\000\000\225\000\000\000\016\000\000\000\312\000\000\000\377\000\000\000\377(((\377aaa\377\067"
"\067\067\377'''\377\366\366\366\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\203\203\203\377\061\061\061\377\375"
"\375\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375"
"\377\061\061\061\377\203\203\203\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\313\313\313\377\015\015\015\377\323\323\323\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377NNN\377\000\000\000"
"\377\000\000\000\324\000\000\000s\000\000\000\377\000\000\000\377fff\377\357\357\357\377\377\377"
"\377\377\244\244\244\377###\377\365\365\365\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377|||\377&&&\377\375\375"
"\375\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\375\377"
"&&&\377|||\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\306\306\306\377\001\001\001\377\317\317\317\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\200\200\200\377\000\000\000\377\000\000\000\345"
"\000\000\000\305\000\000\000\377\062\062\062\377\371\371\371\377\377\377\377\377\377\377"
"\377\377\235\235\235\377###\377\365\365\365\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\274\274\274\377\221"
"\221\221\377\376\376\376\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\376\376\376\377\221\221\221\377\274\274\274\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\342\342\340\377\200\200\200"
"\377\347\347\347\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\202\202\202\377\000\000\000\377\000\000\000\345\000\000\000\342\000\000\000\377www\377"
"\377\377\377\377\376\376\376\377\377\377\377\377\235\235\235\377!##\377\365"
"\365\365\377\377\377\377\377\374\376\376\377\374\376\376\377\374\376\376"
"\377\374\376\376\377\377\377\377\377\377\377\377\377\374\376\376\377\374"
"\376\376\377\374\376\376\377\374\376\376\377\374\376\376\377\377\377\377"
"\377\377\377\377\377\374\376\376\377\374\376\376\377\374\376\376\377\374"
"\376\376\377\377\377\377\377\377\377\377\377\377\377\377\377\374\376\376"
"\377\374\376\376\377\374\376\376\377\377\377\377\377\201\201\201\377\000\000"
"\000\377\000\000\000\345\000\000\000\346\000\000\000\377\203\203\203\377\377\377\377\377\375"
"\373\375\377\377\377\377\377\233\233\235\377!!#\377\363\363\365\377\377\377"
"\377\377\373\373\376\377\373\373\376\377\373\373\376\377\373\373\376\377"
"\373\373\376\377\373\373\376\377\373\373\376\377\373\373\375\377\373\373"
"\376\377\373\373\376\377\373\373\376\377\373\373\375\377\373\373\376\377"
"\373\373\376\377\373\373\376\377\373\373\376\377\373\373\376\377\373\373"
"\376\377\373\373\375\377\373\373\375\377\373\373\375\377\373\373\376\377"
"\373\374\376\377\377\377\377\377\201\201\201\377\000\000\000\377\000\000\000\345\000\000"
"\000\345\000\000\000\377\177\201\201\377\377\377\377\377\371\373\376\377\377\377"
"\377\377\233\233\235\377\"\"\"\377\361\363\366\377\375\377\377\377\371\373"
"\376\377\371\373\376\377\371\373\376\377\367\372\376\377\367\372\376\377"
"\371\371\376\377\371\371\376\377\371\373\376\377\371\373\376\377\371\373"
"\376\377\371\373\376\377\367\372\376\377\367\372\376\377\371\373\376\377"
"\367\372\376\377\367\372\376\377\371\373\376\377\367\372\376\377\371\373"
"\376\377\371\373\376\377\367\372\376\377\367\372\376\377\371\373\376\377"
"\377\377\377\377\177\201\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377"
"\177\177\201\377\377\377\377\377\365\370\377\377\377\377\377\377\234\234"
"\234\377\"\"\"\377\356\361\365\377\372\375\377\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377"
"\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377"
"\365\370\375\377\365\370\375\377\365\370\375\377\365\370\375\377\365\370"
"\375\377\365\370\375\377\365\370\375\377\366\371\376\377\377\377\377\377"
"\177\177\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377}\200\202\377\377"
"\377\377\377\363\366\375\377\377\377\377\377\232\234\234\377\"\"\"\377\355"
"\357\364\377\370\372\377\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363"
"\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363"
"\366\375\377\363\366\375\377\363\366\375\377\363\366\375\377\363\366\375"
"\377\363\366\375\377\364\367\376\377\377\377\377\377~\177\201\377\000\000\000\377"
"\000\000\000\345\000\000\000\345\000\000\000\377|~\201\377\377\377\377\377\357\362\374\377"
"\377\377\377\377\231\232\234\377\"\"\"\377\352\355\364\377\364\370\377\377"
"\357\362\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\362"
"\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364\374\377"
"\357\362\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364"
"\374\377\357\364\374\377\357\364\374\377\357\364\374\377\357\364\374\377"
"\357\364\374\377\357\364\374\377\357\362\374\377\357\364\374\377\360\363"
"\375\377\377\377\377\377|~\201\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377"
"z|\201\377\377\377\377\377\353\360\374\377\375\377\377\377\230\232\235\377"
"\"\"\"\377\347\352\364\377\360\364\377\377\353\360\374\377\355\360\374\377"
"\355\360\374\377\355\360\374\377\353\360\374\377\355\360\374\377\353\360"
"\374\377\353\360\374\377\353\360\374\377\355\360\374\377\355\360\374\377"
"\355\360\374\377\355\362\374\377\355\360\374\377\353\360\374\377\353\360"
"\374\377\355\360\374\377\353\360\374\377\355\360\374\377\355\360\374\377"
"\355\360\374\377\353\360\374\377\355\362\374\377\377\377\377\377z|\201\377"
"\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377y{\201\377\377\377\377\377\351\356"
"\372\377\373\377\377\377\220\223\230\377\026\026\026\377\344\351\363\377\353"
"\362\377\377\350\357\374\377\350\357\372\377\350\357\372\377\350\357\374"
"\377\350\357\374\377\350\357\372\377\350\357\374\377\350\357\372\377\350"
"\357\372\377\350\357\374\377\350\357\374\377\350\357\374\377\350\357\372"
"\377\350\357\372\377\350\357\372\377\350\357\374\377\350\357\374\377\350"
"\357\372\377\350\357\372\377\350\357\372\377\350\357\372\377\350\357\372"
"\377\351\360\373\377\377\377\377\377y{\201\377\000\000\000\377\000\000\000\345\000\000\000"
"\345\000\000\000\377xz\200\377\375\377\377\377\346\354\373\377\352\362\376\377"
"\304\313\325\377\226\233\243\377\343\353\370\377\345\355\374\377\345\355"
"\372\377\345\355\372\377\345\353\372\377\345\353\372\377\345\355\372\377"
"\345\355\372\377\345\353\372\377\345\353\372\377\345\353\372\377\345\355"
"\372\377\345\355\372\377\345\353\372\377\345\353\372\377\345\353\372\377"
"\345\353\372\377\345\353\372\377\345\353\372\377\345\353\372\377\345\353"
"\372\377\345\353\372\377\345\353\372\377\345\353\372\377\344\354\373\377"
"\375\377\377\377xz\200\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377ux\201"
"\377\373\377\377\377\342\352\373\377\340\350\371\377\350\360\377\377\362"
"\370\377\377\341\351\373\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341"
"\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341"
"\351\372\377\341\351\372\377\341\351\372\377\341\351\372\377\341\351\372"
"\377\341\351\372\377\341\351\372\377\342\352\373\377\373\377\377\377ux\201"
"\377\000\000\000\377\000\000\000\345\000\000\000\345\000\000\000\377ty\200\377\367\375\377\377\336"
"\346\372\377\334\346\372\377\334\346\372\377\334\346\370\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335"
"\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\335\345\371\377\334\346\372\377\335"
"\345\371\377\335\345\371\377\335\345\371\377\335\345\371\377\335\345\371"
"\377\335\345\371\377\335\345\371\377\334\346\372\377\335\345\371\377\335"
"\345\371\377\335\347\373\377\367\375\377\377ty\200\377\000\000\000\377\000\000\000\345"
"\000\000\000\345\000\000\000\377sx\200\377\366\373\377\377\334\344\372\377\331\344\370"
"\377\330\343\371\377\331\344\370\377\330\343\371\377\330\343\371\377\331"
"\344\370\377\331\344\370\377\331\344\370\377\331\344\370\377\330\343\371"
"\377\331\344\370\377\331\344\370\377\331\344\370\377\331\344\370\377\331"
"\344\370\377\330\343\371\377\330\343\371\377\330\343\371\377\331\344\370"
"\377\331\344\370\377\331\344\370\377\330\343\371\377\330\342\371\377\331"
"\344\370\377\331\343\370\377\331\344\370\377\331\343\370\377\334\344\370"
"\377\366\373\377\377sx\200\377\000\000\000\377\000\000\000\345\000\000\000\346\000\000\000\377QV"
"[\377\365\373\377\377\334\346\372\377\325\341\370\377\325\337\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325"
"\341\370\377\325\341\370\377\325\341\370\377\325\341\370\377\325\341\370"
"\377\324\341\370\377\324\341\370\377\334\346\372\377\365\373\377\377PU\\"
"\377\000\000\000\377\000\000\000\346\000\000\000\314\000\000\000\377\012\012\014\377\254\264\301\377"
"\362\370\377\377\325\341\370\377\321\335\367\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\320\335\370\377\320\335\370\377\320\335\370\377"
"\320\335\370\377\320\335\370\377\321\335\367\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\320\335\370\377\320\335\370\377\321\335\367\377"
"\321\335\367\377\320\335\370\377\320\335\370\377\320\335\370\377\320\335"
"\370\377\320\335\370\377\321\335\367\377\320\335\370\377\321\335\367\377"
"\326\340\371\377\362\370\377\377\254\264\301\377\012\012\014\377\000\000\000\377\000"
"\000\000\314\000\000\000d\000\000\000\377\000\000\000\377\024\025\027\377\262\274\314\377\355\365"
"\377\377\323\336\367\377\315\334\366\377\315\334\366\377\314\333\367\377"
"\315\334\366\377\314\333\367\377\314\333\367\377\314\333\367\377\314\333"
"\367\377\316\333\367\377\314\333\367\377\314\333\367\377\315\334\366\377"
"\315\334\366\377\315\334\366\377\316\333\367\377\316\333\367\377\314\333"
"\367\377\314\333\367\377\315\334\366\377\315\334\366\377\314\333\367\377"
"\314\333\367\377\314\333\367\377\323\340\367\377\356\365\377\377\262\274"
"\314\377\024\025\027\377\000\000\000\377\000\000\000\377\000\000\000d\000\000\000\002\000\000\000\220\000\000\000"
"\377\000\000\000\377\025\027\032\377\261\273\315\377\352\362\377\377\317\333\367\377"
"\311\326\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330"
"\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377"
"\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330"
"\366\377\311\330\366\377\311\330\366\377\311\330\366\377\311\330\366\377"
"\311\330\366\377\311\330\366\377\311\330\366\377\317\333\367\377\352\362"
"\377\377\261\271\315\377\025\027\032\377\000\000\000\377\000\000\000\377\000\000\000\220\000\000\000"
"\002\000\000\000\000\000\000\000\002\000\000\000\224\000\000\000\377\000\000\000\377\025\030\032\377\257\272\320"
"\377\346\356\377\377\313\330\366\377\305\325\365\377\305\324\365\377\305"
"\324\365\377\305\325\365\377\305\324\365\377\305\324\365\377\305\325\365"
"\377\305\325\365\377\305\324\365\377\305\325\365\377\305\325\365\377\305"
"\324\365\377\305\325\365\377\305\325\365\377\305\325\365\377\305\325\365"
"\377\305\325\365\377\305\324\365\377\305\324\365\377\313\332\366\377\346"
"\356\377\377\257\272\320\377\025\027\032\377\000\000\000\377\000\000\000\377\000\000\000\224\000"
"\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\004\000\000\000\235\000\000\000\377\000\000\000\377\031\032"
"\034\377\267\304\335\377\327\345\377\377\307\326\365\377\302\322\365\377\302"
"\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365"
"\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302"
"\322\365\377\302\322\365\377\302\322\365\377\302\322\365\377\302\322\365"
"\377\302\322\365\377\302\322\365\377\305\326\367\377\327\343\377\377\267"
"\304\335\377\031\032\034\377\000\000\000\377\000\000\000\377\000\000\000\235\000\000\000\004\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\006\000\000\000\241\000\000\000\377\000\000\000\377GJV\377"
"\327\345\377\377\311\330\367\377\275\317\365\377\276\317\365\377\276\320"
"\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377"
"\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320"
"\365\377\276\320\365\377\276\320\365\377\276\320\365\377\276\320\365\377"
"\275\317\365\377\311\330\367\377\326\345\377\377GJV\377\000\000\000\377\000\000\000\377"
"\000\000\000\241\000\000\000\006\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\011\000\000\000\313\000\000\000\377\015\015\017\377\270\305\341\377\312\334\374"
"\377\271\315\364\377\272\314\364\377\272\316\364\377\272\316\364\377\272"
"\316\364\377\272\316\364\377\272\316\364\377\272\316\364\377\272\316\364"
"\377\272\316\364\377\272\316\364\377\272\316\364\377\272\316\364\377\272"
"\316\364\377\272\316\364\377\272\316\364\377\271\316\364\377\312\334\374"
"\377\270\305\341\377\015\015\017\377\000\000\000\377\000\000\000\313\000\000\000\011\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000s\000\000"
"\000\377\004\004\006\377\254\270\324\377\311\332\376\377\267\313\364\377\270\312"
"\363\377\270\314\363\377\270\314\363\377\270\314\363\377\270\314\363\377"
"\270\312\363\377\270\312\363\377\270\314\363\377\270\314\363\377\270\314"
"\363\377\270\314\363\377\270\312\363\377\270\314\363\377\270\314\363\377"
"\270\314\363\377\267\313\364\377\311\332\376\377\254\270\324\377\004\004\006\377"
"\000\000\000\377\000\000\000s\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000a\000\000\000\377\005\005\007\377\253\270\324\377\306\332"
"\376\377\263\310\363\377\264\311\363\377\264\311\363\377\264\311\363\377"
"\264\311\363\377\264\311\363\377\264\311\364\377\264\311\364\377\264\311"
"\363\377\264\311\363\377\264\311\363\377\264\311\363\377\264\311\363\377"
"\264\311\363\377\264\311\364\377\264\311\364\377\263\310\363\377\306\332"
"\376\377\253\270\324\377\005\005\007\377\000\000\000\377\000\000\000a\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000d\000\000\000\377"
"\005\005\007\377\255\274\332\377\306\330\376\377\261\306\363\377\262\307\362\377"
"\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307"
"\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377"
"\262\307\362\377\262\307\362\377\262\307\362\377\262\307\362\377\262\307"
"\362\377\261\306\363\377\306\330\376\377\255\274\332\377\005\005\007\377\000\000\000"
"\377\000\000\000d\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000W\000\000\000\377\002\002\002\377\205\220\251\377\341\354\377"
"\377\313\333\377\377\311\333\377\377\311\333\377\377\311\333\377\377\311"
"\333\377\377\311\333\377\377\311\333\377\377\311\333\377\377\311\333\377"
"\377\311\333\377\377\310\332\377\377\311\333\377\377\311\333\377\377\311"
"\333\377\377\310\332\377\377\310\332\377\377\313\333\377\377\340\354\377"
"\377\205\220\251\377\002\002\002\377\000\000\000\377\000\000\000W\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\034\000\000\000\354"
"\000\000\000\377\020\022\025\377RZi\377]ev\377Zdt\377Zdt\377[ct\377[ct\377Zdt\377"
"Zdt\377Zdt\377[ct\377[ct\377Zds\377[ct\377[ct\377Zdt\377[cr\377Zds\377]e"
"v\377RZi\377\020\022\025\377\000\000\000\377\000\000\000\354\000\000\000\034\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000f\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377"
"\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000"
"\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000\000\377\000\000"
"\000\377\000\000\000\377\000\000\000f\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000R\000\000\000\275\000"
"\000\000\344\000\000\000\345\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000"
"\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000\344\000\000\000"
"\344\000\000\000\344\000\000\000\344\000\000\000\345\000\000\000\344\000\000\000\275\000\000\000R\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
};
static const _GLFWcursorDataOgc OGC_cursor_arrow = {
24, 31, 0, 0, 4,
"\002\002\002\337\000\000\000\224\000\000\000\007\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377"
"\005\005\005\321\000\000\000$\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377ddd\377\037\037\037\373\003\003\003\364"
"\000\000\000V\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\361\361\361\377VVV\376\000\000\000\377"
"\002\002\002\243\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\241"
"\241\241\377\007\007\007\375\005\005\005\322\000\000\000%\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\315\315\315\377!!!\373\003\003\003\365\000\000\000Y\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\362\362\362\377"
"WWW\376\000\000\000\377\002\002\002\243\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\241\241\241\377\007\007\007\375\005"
"\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\316\316\316\377!!!\373\003\003\003\365\000\000\000Z"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\362\362\362\377XXX\376\000\000\000\377\002\002\002\243\000\000\000"
"\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\375\375\377\377\373\374\376\377\235\236\240\377\007\007\007\374\005"
"\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\375\375\377\377"
"\373\374\376\377\371\373\376\377\367\371\376\377\366\370\375\377\305\310"
"\314\377\037!\"\373\003\003\003\366\000\000\000[\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\375\375\377\377\373\374\376\377\371"
"\373\376\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375"
"\377\360\364\374\377\342\347\357\377QSW\376\000\000\000\377\002\002\002\243\000\000\000\012"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\225\225\225\377\377\377"
"\377\377\377\377\377\377\375\375\377\377\373\374\376\377\371\373\376\377"
"\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377\360\364"
"\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357\373\377"
"\222\226\236\377\007\007\007\374\004\005\005\331\000\000\000+\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\377\225\225\225\377\375\375\377\377\373\374\376\377\371\373\376"
"\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377\360"
"\364\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357\373"
"\377\347\356\373\377\345\354\373\377\343\353\372\377\275\303\321\377#%'\373"
"\003\003\003\366\000\000\000[\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\223\223\224\377\371\373"
"\376\377\367\371\376\377\366\370\375\377\364\367\375\377\362\365\375\377"
"\360\364\374\377\356\363\374\377\354\362\374\377\353\360\374\377\351\357"
"\373\377\347\356\373\377\345\354\373\377\343\353\372\377\342\352\372\377"
"\340\350\372\377\336\347\371\377\321\332\354\377LOW\376\000\000\000\377\002\002\002\243"
"\000\000\000\012\000\000\000\000\000\000\000\377\220\221\224\377\366\370\375\377\364\367\375\377"
"\362\365\375\377\360\364\374\377\356\363\374\377\354\362\374\377\353\360"
"\374\377\351\357\373\377\347\356\373\377\345\354\373\377\343\353\372\377"
"\342\352\372\377\340\350\372\377\336\347\371\377\334\346\371\377\332\344"
"\371\377\330\343\370\377\327\342\370\377\206\215\235\377\006\006\007\374\004\004\005"
"\332\000\000\000,\000\000\000\377\217\220\224\377\362\365\375\377\360\364\374\377\356"
"\363\374\377\354\361\374\377\353\360\374\377\351\357\373\377\347\356\373"
"\377\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372\377\336"
"\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342\370"
"\377\325\340\370\377\323\337\370\377\321\336\367\377pw\206\377\000\000\000\377"
"\001\001\001\347\000\000\000\377\214\217\223\377\356\363\374\377\354\361\374\377\353"
"\360\374\377\351\357\373\377\347\356\373\377\345\354\373\377\343\353\372"
"\377\342\352\372\377\340\350\372\377\336\347\371\377\334\346\371\377\332"
"\344\371\377\330\343\370\377\327\342\370\377\325\340\370\377\323\337\370"
"\377\321\336\367\377\225\236\261\377,/\065\374\000\000\000\377\004\004\005\316\000\000\000F"
"\000\000\000\377\212\215\223\377\353\360\374\377\351\357\373\377\347\356\373\377"
"\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372\377\336\347"
"\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342\370\377"
"\325\340\370\377\323\337\370\377\321\336\367\377\236\250\275\377\062\065<\374"
"\000\000\000\377\002\004\004\323\000\000\000U\000\000\000\001\000\000\000\000\000\000\000\377\210\214\223\377\347"
"\356\373\377\345\354\373\377\343\353\372\377\342\352\372\377\340\350\372"
"\377\336\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327"
"\342\370\377\325\340\370\377\323\337\370\377\321\336\367\377\230\241\265"
"\377,/\064\374\000\000\000\377\002\004\004\323\000\000\000U\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\377\206\212\223\377\343\353\372\377\341\352\372\377\340\350\372\377"
"\336\347\371\377\334\346\371\377\332\344\371\377\330\343\370\377\327\342"
"\370\377\325\340\370\377\323\337\370\377\321\336\367\377\317\334\367\377"
"DHQ\374\000\000\000\377\004\004\004\314\000\000\000J\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377\203\211\222\377\340\350\372\377\336\347\371\377\334"
"\346\371\377\332\344\371\377\330\343\370\377\327\342\370\377\325\340\370"
"\377\323\337\370\377\321\336\367\377\317\334\367\377\315\333\367\377\314"
"\332\366\377JOZ\376\002\002\003\362\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\202\207\221\377\334\346\371\377\332\344"
"\371\377\330\343\370\377\327\342\370\377\325\340\370\377\323\337\370\377"
"\321\336\367\377\316\333\366\377\315\333\367\377\314\332\366\377\312\330"
"\366\377\310\327\366\377\250\266\320\377\002\002\002\376\000\000\000r\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\177\205\221\377\330\343"
"\370\377\327\342\370\377\325\340\370\377\323\337\370\377\321\336\367\377"
"\223\234\257\377),\062\374\036\040$\374\306\324\361\377\310\327\366\377\306"
"\326\365\377\304\324\365\377\303\323\365\377FLX\376\003\003\004\354\000\000\000\012\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377~\204\221\377\325"
"\340\370\377\323\337\370\377\321\336\367\377\222\233\256\377)-\063\374\000\000"
"\000\377\002\004\004\321\000\000\000\376y\203\226\377\304\324\365\377\303\323\365\377\301"
"\322\364\377\277\320\364\377\242\261\321\377\001\002\002\376\000\000\000s\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377{\202\221\377\321\336\367\377"
"\222\233\256\377),\062\374\000\000\000\377\004\004\005\313\000\000\000I\000\000\000\000\001\001\003\263\026"
"\030\034\373\275\316\357\377\277\320\364\377\275\317\364\377\273\316\364\377"
"\271\314\363\377CJY\376\003\003\004\354\000\000\000\012\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\377INW\377)+\061\373\000\000\000\377\004\004\004\312\000\000\000H\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\062\000\000\000\376t\177\225\377\273\316\364\377\271\314\363"
"\377\270\313\363\377\212\232\271\377(,\066\375\000\000\000\377\000\000\000F\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\377\000\000\000\377\004\004\004\311\000\000\000H\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001\003\003\262\025\027\034\373\264\307"
"\356\377\212\232\271\377.\063>\374\000\000\000\377\004\004\005\330\000\000\000V\000\000\000\001\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000t\000\000\000G\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\062\000\000\000\376\032\035$\375"
"\000\000\000\377\004\004\005\327\000\000\000V\000\000\000\002\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\002\003\003\247\004\004\005\325\000\000\000U\000\000\000\002\000\000"
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000",
};

161
src/ogc_init.c Normal file
View File

@ -0,0 +1,161 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC)
#include <assert.h>
#include <fat.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiikeyboard/keyboard.h>
#include <wiiuse/wpad.h>
#define FIFO_SIZE (256*1024)
char _glfwUnimplementedFmt[] = "Ogc: the platform does not support %s";
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwConnectOgc(int platformID, _GLFWplatform* platform)
{
const _GLFWplatform ogc =
{
.platformID = GLFW_PLATFORM_OGC,
.init = _glfwInitOgc,
.terminate = _glfwTerminateOgc,
.getCursorPos = _glfwGetCursorPosOgc,
.setCursorPos = _glfwSetCursorPosOgc,
.setCursorMode = _glfwSetCursorModeOgc,
.setRawMouseMotion = _glfwSetRawMouseMotionOgc,
.rawMouseMotionSupported = _glfwRawMouseMotionSupportedOgc,
.createCursor = _glfwCreateCursorOgc,
.createStandardCursor = _glfwCreateStandardCursorOgc,
.destroyCursor = _glfwDestroyCursorOgc,
.setCursor = _glfwSetCursorOgc,
.getScancodeName = _glfwGetScancodeNameOgc,
.getKeyScancode = _glfwGetKeyScancodeOgc,
.setClipboardString = _glfwSetClipboardStringOgc,
.getClipboardString = _glfwGetClipboardStringOgc,
.initJoysticks = _glfwInitJoysticksOgc,
.terminateJoysticks = _glfwTerminateJoysticksOgc,
.pollJoystick = _glfwPollJoystickOgc,
.getMappingName = _glfwGetMappingNameOgc,
.updateGamepadGUID = _glfwUpdateGamepadGUIDOgc,
.freeMonitor = _glfwFreeMonitorOgc,
.getMonitorPos = _glfwGetMonitorPosOgc,
.getMonitorContentScale = _glfwGetMonitorContentScaleOgc,
.getMonitorWorkarea = _glfwGetMonitorWorkareaOgc,
.getVideoModes = _glfwGetVideoModesOgc,
.getVideoMode = _glfwGetVideoModeOgc,
.getGammaRamp = _glfwGetGammaRampOgc,
.setGammaRamp = _glfwSetGammaRampOgc,
.createWindow = _glfwCreateWindowOgc,
.destroyWindow = _glfwDestroyWindowOgc,
.setWindowTitle = _glfwSetWindowTitleOgc,
.setWindowIcon = _glfwSetWindowIconOgc,
.getWindowPos = _glfwGetWindowPosOgc,
.setWindowPos = _glfwSetWindowPosOgc,
.getWindowSize = _glfwGetWindowSizeOgc,
.setWindowSize = _glfwSetWindowSizeOgc,
.setWindowSizeLimits = _glfwSetWindowSizeLimitsOgc,
.setWindowAspectRatio = _glfwSetWindowAspectRatioOgc,
.getFramebufferSize = _glfwGetFramebufferSizeOgc,
.getWindowFrameSize = _glfwGetWindowFrameSizeOgc,
.getWindowContentScale = _glfwGetWindowContentScaleOgc,
.iconifyWindow = _glfwIconifyWindowOgc,
.restoreWindow = _glfwRestoreWindowOgc,
.maximizeWindow = _glfwMaximizeWindowOgc,
.showWindow = _glfwShowWindowOgc,
.hideWindow = _glfwHideWindowOgc,
.requestWindowAttention = _glfwRequestWindowAttentionOgc,
.focusWindow = _glfwFocusWindowOgc,
.setWindowMonitor = _glfwSetWindowMonitorOgc,
.windowFocused = _glfwWindowFocusedOgc,
.windowIconified = _glfwWindowIconifiedOgc,
.windowVisible = _glfwWindowVisibleOgc,
.windowMaximized = _glfwWindowMaximizedOgc,
.windowHovered = _glfwWindowHoveredOgc,
.framebufferTransparent = _glfwFramebufferTransparentOgc,
.getWindowOpacity = _glfwGetWindowOpacityOgc,
.setWindowResizable = _glfwSetWindowResizableOgc,
.setWindowDecorated = _glfwSetWindowDecoratedOgc,
.setWindowFloating = _glfwSetWindowFloatingOgc,
.setWindowOpacity = _glfwSetWindowOpacityOgc,
.setWindowMousePassthrough = _glfwSetWindowMousePassthroughOgc,
.pollEvents = _glfwPollEventsOgc,
.waitEvents = _glfwWaitEventsOgc,
.waitEventsTimeout = _glfwWaitEventsTimeoutOgc,
.postEmptyEvent = _glfwPostEmptyEventOgc,
.getEGLPlatform = _glfwGetEGLPlatformOgc,
.getEGLNativeDisplay = _glfwGetEGLNativeDisplayOgc,
.getEGLNativeWindow = _glfwGetEGLNativeWindowOgc,
.getRequiredInstanceExtensions = _glfwGetRequiredInstanceExtensionsOgc,
.getPhysicalDevicePresentationSupport = _glfwGetPhysicalDevicePresentationSupportOgc,
.createWindowSurface = _glfwCreateWindowSurfaceOgc
};
*platform = ogc;
return GLFW_TRUE;
}
int _glfwInitOgc(void)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
VIDEO_Init();
void *fifoBuffer = MEM_K0_TO_K1(memalign(32, FIFO_SIZE));
memset(fifoBuffer, 0, FIFO_SIZE);
GX_Init(fifoBuffer, FIFO_SIZE);
fatInitDefault();
PAD_Init();
KEYBOARD_Init(NULL);
#ifdef __wii__
WPAD_Init();
WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR);
WPAD_SetVRes(WPAD_CHAN_ALL, 640, 480);
#endif
_glfwCreateMonitorOgc();
return GLFW_TRUE;
}
void _glfwTerminateOgc(void)
{
_glfwTerminateEGL();
_glfwTerminateOSMesa();
}
#endif // _GLFW_OGC

417
src/ogc_joystick.c Normal file
View File

@ -0,0 +1,417 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC)
#include <ogc/lwp_watchdog.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
#define MAX_FAILED_GC_READS 10
#define MAX_GC_AXES 6
#define MAX_GC_BUTTONS 8
#define MAX_GC_HATS 1
/* PAD_ScanPads() returns 0 if no joystick is connected, but also if querying
* the hardware failed for whatever reason. This can occasionally happen at
* runtime; so, we want to ignore these events and only report the joystick
* disconnection if PAD_ScanPads() consistently returns 0.
*
* This function returns true if the scanPads value is reliable.
*/
static GLFWbool readGCJoysticks(u32 *scanPads)
{
static GLFWbool lastReadFailed = GLFW_FALSE;
static u64 firstDisconnectedTimestamp = 0;
u32 currScanPads;
u64 timestamp;
currScanPads = PAD_ScanPads();
if (currScanPads == 0) {
timestamp = gettime();
if (lastReadFailed) {
if (ticks_to_millisecs(timestamp - firstDisconnectedTimestamp) < 500)
return GLFW_FALSE;
} else {
firstDisconnectedTimestamp = timestamp;
lastReadFailed = GLFW_TRUE;
return GLFW_FALSE;
}
} else {
lastReadFailed = GLFW_FALSE;
}
*scanPads = currScanPads;
return GLFW_TRUE;
}
static void readGCJoystick(_GLFWjoystick* js)
{
u32 id = js->ogc.id;
u16 btns = PAD_ButtonsHeld(id);
js->buttons[0] = btns & PAD_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & PAD_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & PAD_BUTTON_X ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & PAD_BUTTON_Y ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & PAD_TRIGGER_L ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & PAD_TRIGGER_R ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & PAD_TRIGGER_Z ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[7] = btns & PAD_BUTTON_START ? GLFW_PRESS : GLFW_RELEASE;
js->axes[0] = PAD_StickX(id) / 100.0;
js->axes[1] = PAD_StickY(id) / 100.0;
js->axes[2] = PAD_SubStickX(id) / 100.0;
js->axes[3] = PAD_SubStickY(id) / 100.0;
js->axes[4] = PAD_TriggerL(id) / 200.0;
js->axes[5] = PAD_TriggerR(id) / 200.0;
unsigned char hat = 0;
if (btns & PAD_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & PAD_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
if (btns & PAD_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & PAD_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
_glfwInputJoystickHat(js, 0, hat);
}
/* CRC algorithm used by SDL */
static uint16_t crc16_for_byte(uint8_t r)
{
uint16_t crc = 0;
int i;
for (i = 0; i < 8; ++i) {
crc = ((crc ^ r) & 1 ? 0xA001 : 0) ^ crc >> 1;
r >>= 1;
}
return crc;
}
uint16_t SDL_crc16(uint16_t crc, const void *data, size_t len)
{
/* As an optimization we can precalculate a 256 entry table for each byte */
size_t i;
for (i = 0; i < len; ++i) {
crc = crc16_for_byte((uint8_t)crc ^ ((const uint8_t *)data)[i]) ^ crc >> 8;
}
return crc;
}
static _GLFWjoystick* addJoystick(int deviceId,
const char *name, const char* guid,
int axisCount, int buttonCount, int hatCount)
{
fprintf(stderr, "Add controller %d %s\n", deviceId, name);
_GLFWjoystick* js =
_glfwAllocJoystick(name, guid,
axisCount, buttonCount, hatCount);
js->ogc.id = deviceId;
_glfw.ogcjs.joystickIndex[deviceId] = js - _glfw.joysticks;
_glfwInputJoystick(js, GLFW_CONNECTED);
return js;
}
static void addGCJoystick(int deviceId)
{
char name[16], guid[33];
uint16_t nameCrc;
sprintf(name, "Gamecube %d", deviceId);
nameCrc = SDL_crc16(0, name, strlen(name));
sprintf(guid, "0000%02x%02x7e050000000%d000001000000",
nameCrc & 0xff, nameCrc >> 8, deviceId + 1);
addJoystick(deviceId, name, guid,
MAX_GC_AXES, MAX_GC_BUTTONS, MAX_GC_HATS);
}
#ifdef __wii__
static inline float readAxis(uint8_t pos, uint8_t center, uint8_t min, uint8_t max)
{
if (pos < center) {
return (pos - center) / (float)(center - min);
} else {
return (pos - center) / (float)(max - center);
}
}
static void readJoystickAxes(_GLFWjoystick* js, int index, const joystick_t *data)
{
js->axes[index] = readAxis(data->pos.x, data->center.x, data->min.x, data->max.x);
js->axes[index + 1] = readAxis(data->pos.y, data->center.y, data->min.y, data->max.y);
}
static inline float clampUnity(float value)
{
if (value < -1.0f) return -1.0f;
if (value > 1.0f) return 1.0f;
return value;
}
static void readOrientationAxes(_GLFWjoystick* js, int index, const orient_t *data)
{
/* Orientation fields range from -180 to 180 (they are measured in
* degrees), but in order to use them as joystick axes it's more reasonable
* to limit their range to -90/90. */
js->axes[index] = clampUnity(-data->pitch / 90.0f);
js->axes[index + 1] = clampUnity(data->roll / 90.0f);
js->axes[index + 2] = clampUnity(data->yaw / 90.0f);
}
static void readWiimote(_GLFWjoystick* js)
{
u32 id = js->ogc.id - MAX_GC_JOYSTICKS;
WPADData *data = WPAD_Data(id);
u32 btns = data->btns_h | data->btns_d;
unsigned char hat = 0;
GLFWbool readWiimote = GLFW_FALSE;
GLFWbool wiimotePointer = GLFW_FALSE;
int wiimoteFirstAxis = 0;
if (js->ogc.expansion == EXP_NUNCHUK) {
js->buttons[7] = btns & WPAD_NUNCHUK_BUTTON_Z ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[8] = btns & WPAD_NUNCHUK_BUTTON_C ? GLFW_PRESS : GLFW_RELEASE;
/* When a nunchuk is connected, we report its joystick as the first two axes,
* followed by three axes from the wiimote orientation, followed by
* three axes from the nunchuk orientation. */
readJoystickAxes(js, 0, &data->exp.nunchuk.js);
readWiimote = GLFW_TRUE;
wiimotePointer = GLFW_TRUE;
wiimoteFirstAxis = 2;
readOrientationAxes(js, wiimoteFirstAxis + 3, &data->exp.nunchuk.orient);
} else if (js->ogc.expansion == EXP_CLASSIC) {
if (btns & WPAD_CLASSIC_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_CLASSIC_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
if (btns & WPAD_CLASSIC_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & WPAD_CLASSIC_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
js->buttons[0] = btns & WPAD_CLASSIC_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & WPAD_CLASSIC_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & WPAD_CLASSIC_BUTTON_X ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & WPAD_CLASSIC_BUTTON_Y ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & WPAD_CLASSIC_BUTTON_FULL_L ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & WPAD_CLASSIC_BUTTON_FULL_R ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & WPAD_CLASSIC_BUTTON_ZL ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[7] = btns & WPAD_CLASSIC_BUTTON_ZR ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[8] = btns & WPAD_CLASSIC_BUTTON_MINUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[9] = btns & WPAD_CLASSIC_BUTTON_PLUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[10] = btns & WPAD_CLASSIC_BUTTON_HOME ? GLFW_PRESS : GLFW_RELEASE;
readJoystickAxes(js, 0, &data->exp.classic.ljs);
readJoystickAxes(js, 2, &data->exp.classic.rjs);
} else if (js->ogc.expansion == EXP_NONE) {
readWiimote = GLFW_TRUE;
wiimotePointer = data->ir.valid;
}
if (readWiimote) {
if (wiimotePointer) {
if (btns & WPAD_BUTTON_LEFT) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_BUTTON_RIGHT) hat |= GLFW_HAT_RIGHT;
if (btns & WPAD_BUTTON_UP) hat |= GLFW_HAT_UP;
if (btns & WPAD_BUTTON_DOWN) hat |= GLFW_HAT_DOWN;
} else {
if (btns & WPAD_BUTTON_LEFT) hat |= GLFW_HAT_DOWN;
if (btns & WPAD_BUTTON_RIGHT) hat |= GLFW_HAT_UP;
if (btns & WPAD_BUTTON_UP) hat |= GLFW_HAT_LEFT;
if (btns & WPAD_BUTTON_DOWN) hat |= GLFW_HAT_RIGHT;
}
js->buttons[0] = btns & WPAD_BUTTON_1 ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[1] = btns & WPAD_BUTTON_2 ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[2] = btns & WPAD_BUTTON_A ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[3] = btns & WPAD_BUTTON_B ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[4] = btns & WPAD_BUTTON_MINUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[5] = btns & WPAD_BUTTON_PLUS ? GLFW_PRESS : GLFW_RELEASE;
js->buttons[6] = btns & WPAD_BUTTON_HOME ? GLFW_PRESS : GLFW_RELEASE;
readOrientationAxes(js, wiimoteFirstAxis, &data->orient);
}
_glfwInputJoystickHat(js, 0, hat);
/* On the Wii, let's close the window when the HOME button is pressed,
* since that's the default behaviour for homebrew applications. The close
* event can anyway be overridden in the application, if this behaviour is
* not desired. */
if (btns & WPAD_BUTTON_HOME && _glfw.windowListHead) {
_glfwInputWindowCloseRequest(_glfw.windowListHead);
}
}
static void addWiimote(int deviceId, uint8_t expansion)
{
char name[64], guid[40];
uint16_t nameCrc;
int axisCount, buttonCount, hatCount;
/* These counters are for the bare Wiimote */
axisCount = 3;
buttonCount = 7;
hatCount = 1;
char *name_ptr = name;
name_ptr += sprintf(name_ptr, "Wiimote %d", deviceId - MAX_GC_JOYSTICKS);
switch (expansion) {
case WPAD_EXP_NUNCHUK:
strcpy(name_ptr, " + Nunchuk");
axisCount += 5;
buttonCount += 2;
break;
case WPAD_EXP_CLASSIC:
strcpy(name_ptr, " + Classic");
axisCount = 4;
buttonCount = 11;
hatCount = 1;
break;
case WPAD_EXP_GUITARHERO3:
strcpy(name_ptr, " + Guitar Hero 3");
break;
case WPAD_EXP_WIIBOARD:
strcpy(name_ptr, " + Balance board");
break;
}
nameCrc = SDL_crc16(0, name, strlen(name));
sprintf(guid, "0500%02x%02x7e0500000%d0%d000001000000",
nameCrc & 0xff, nameCrc >> 8, expansion + 1, deviceId + 1);
_GLFWjoystick *js = addJoystick(deviceId, name, guid,
axisCount, buttonCount, hatCount);
js->ogc.expansion = expansion;
}
#endif /* __wii__ */
static void removeJoystick(int deviceId)
{
_GLFWjoystick* js = JOYSTICK_FROM_DEVICE(deviceId);
_glfwInputJoystick(js, GLFW_DISCONNECTED);
_glfwFreeJoystick(js);
_glfw.ogcjs.joystickIndex[deviceId] = -1;
fprintf(stderr, "Removed controller %d\n", deviceId);
}
static GLFWbool updateJoysticks()
{
u32 scanPads = 0;
if (_glfw.joysticksInitialized && readGCJoysticks(&scanPads)) {
for (int i = 0; i < MAX_GC_JOYSTICKS; i++) {
GLFWbool connected = !!(scanPads & (1 << i));
int joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(i);
GLFWbool wasConnected = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].connected : GLFW_FALSE;
if (connected != wasConnected) {
if (connected) {
addGCJoystick(i);
joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(i);
} else {
removeJoystick(i);
}
}
if (connected)
readGCJoystick(&_glfw.joysticks[joystickIndex]);
}
}
#ifdef __wii__
/* The WPAD data is also used for the mouse, so we read it even if
* joysticks haven't been initialized */
WPAD_ReadPending(WPAD_CHAN_ALL, NULL);
if (_glfw.joysticksInitialized) {
for (int i = 0; i < MAX_WIIMOTES; i++) {
int deviceId = i + MAX_GC_JOYSTICKS;
int joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(deviceId);
WPADData *data = WPAD_Data(i);
/* Ignore all reads where an error occurred */
if (data->err != WPAD_ERR_NONE) continue;
GLFWbool connected = data->data_present != 0;
uint8_t expansion = data->data_present & WPAD_DATA_EXPANSION ?
data->exp.type : EXP_NONE;
GLFWbool wasConnected = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].connected : GLFW_FALSE;
uint8_t hadExpansion = joystickIndex >= 0 ?
_glfw.joysticks[joystickIndex].ogc.expansion : EXP_NONE;
if (connected != wasConnected || expansion != hadExpansion) {
if (wasConnected) {
removeJoystick(deviceId);
}
if (connected) {
addWiimote(deviceId, expansion);
joystickIndex = JOYSTICK_INDEX_FROM_DEVICE(deviceId);
}
}
if (connected)
readWiimote(&_glfw.joysticks[joystickIndex]);
}
}
#endif
return GLFW_TRUE;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPollJoysticksOgc(void)
{
return updateJoysticks();
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwInitJoysticksOgc(void)
{
/* Hardware initialization done in ogc_init.c, since we want it to happen
* ASAP */
for (int i = 0; i < MAX_JOYSTICKS; i++) {
_glfw.ogcjs.joystickIndex[i] = -1;
}
return GLFW_TRUE;
}
void _glfwTerminateJoysticksOgc(void)
{
// TODO
}
GLFWbool _glfwPollJoystickOgc(_GLFWjoystick* js, int mode)
{
updateJoysticks();
return js->connected;
}
const char* _glfwGetMappingNameOgc(void)
{
return "Ogc";
}
void _glfwUpdateGamepadGUIDOgc(char* guid)
{
}
#endif // _GLFW_OGC

64
src/ogc_joystick.h Normal file
View File

@ -0,0 +1,64 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC_JOYSTICK_STATE _GLFWjoystickOgc ogc;
#define GLFW_OGC_LIBRARY_JOYSTICK_STATE _GLFWlibraryJoystickOgc ogcjs;
#define MAX_GC_JOYSTICKS 4
#ifdef __wii__
#define MAX_WIIMOTES 4
#else
#define MAX_WIIMOTES 0
#endif
#define MAX_JOYSTICKS (MAX_GC_JOYSTICKS + MAX_WIIMOTES)
// Ogc-specific joystick data
//
typedef struct _GLFWjoystickOgc
{
int id;
uint8_t expansion;
} _GLFWjoystickOgc;
typedef struct _GLFWlibraryJoystickOgc
{
char joystickIndex[MAX_JOYSTICKS];
} _GLFWlibraryJoystickOgc;
#define JOYSTICK_INDEX_FROM_DEVICE(deviceId) \
((int)_glfw.ogcjs.joystickIndex[deviceId])
#define JOYSTICK_FROM_DEVICE(deviceId) \
(&_glfw.joysticks[JOYSTICK_INDEX_FROM_DEVICE(deviceId)])
GLFWbool _glfwPollJoysticksOgc(void);
GLFWbool _glfwInitJoysticksOgc(void);
void _glfwTerminateJoysticksOgc(void);
GLFWbool _glfwPollJoystickOgc(_GLFWjoystick* js, int mode);
const char* _glfwGetMappingNameOgc(void);
void _glfwUpdateGamepadGUIDOgc(char* guid);

50
src/ogc_module.c Normal file
View File

@ -0,0 +1,50 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC_MODULE)
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void* _glfwPlatformLoadModule(const char* path)
{
return NULL;
}
void _glfwPlatformFreeModule(void* module)
{
}
GLFWproc _glfwPlatformGetModuleSymbol(void* module, const char* name)
{
return NULL;
}
#endif // GLFW_BUILD_OGC_MODULE

248
src/ogc_monitor.c Normal file
View File

@ -0,0 +1,248 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC)
#include <ogc/color.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define MAX_OGC_MODES 4 /* - VIDEO_GetPreferredMode()
- 240p progressive mode
- 480p progressive mode
- 528p PAL progressive mode
*/
static GXRModeObj *s_videoModes[MAX_OGC_MODES + 1]; // +1 for the NULL entry
// Inverse of the VI_TVMODE macro
#define VI_FORMAT_FROM_MODE(tvmode) (tvmode >> 2)
static void setupXfb(_GLFWmonitor* monitor)
{
if (_glfw.ogc.xfb[0]) {
free(MEM_K1_TO_K0(_glfw.ogc.xfb[0]));
_glfw.ogc.xfb[0] = NULL;
}
if (_glfw.ogc.xfb[1]) {
free(MEM_K1_TO_K0(_glfw.ogc.xfb[1]));
_glfw.ogc.xfb[1] = NULL;
}
if (!_glfw.ogc.xfb[0]) {
_glfw.ogc.xfb[0] =
MEM_K0_TO_K1(SYS_AllocateFramebuffer(monitor->ogc.ogcMode));
}
if (monitor->window && monitor->window->doublebuffer) {
_glfw.ogc.xfb[1] =
MEM_K0_TO_K1(SYS_AllocateFramebuffer(monitor->ogc.ogcMode));
}
_glfw.ogc.fbIndex = 0;
}
static void ogcVideoModeToGlfw(const GXRModeObj *in, GLFWvidmode *out)
{
out->width = in->fbWidth;
out->height = in->efbHeight;
out->redBits = out->greenBits = out->blueBits = 8;
u32 format = VI_FORMAT_FROM_MODE(in->viTVMode);
switch (format) {
case VI_DEBUG:
case VI_NTSC:
case VI_EURGB60:
case VI_MPAL:
out->refreshRate = 60;
break;
case VI_PAL:
case VI_DEBUG_PAL:
out->refreshRate = 50;
break;
}
}
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
void _glfwCreateMonitorOgc()
{
_GLFWmonitor* monitor = _glfwAllocMonitor("", 0, 0);
_glfwInputMonitor(monitor, GLFW_CONNECTED, _GLFW_INSERT_FIRST);
}
void _glfwSetVideoModeOgc(_GLFWmonitor* monitor, const GLFWvidmode* desired)
{
int i;
const GLFWvidmode* best = _glfwChooseVideoMode(monitor, desired);
fprintf(stderr, "%s:%d %s chosen %dx%d window %p\n", __FILE__, __LINE__, __func__,
best->width, best->height, monitor->window);
for (i = 0; i < monitor->modeCount; i++) {
GLFWvidmode tmp;
ogcVideoModeToGlfw(s_videoModes[i], &tmp);
if (_glfwCompareVideoModes(best, &tmp) == 0)
break;
}
/* In the unlikely case that this is not one of our modes, just pick our
* preferred one */
if (i >= monitor->modeCount) i = 0;
GXRModeObj *vmode = s_videoModes[i];
monitor->ogc.currentMode = i;
monitor->ogc.ogcMode = vmode;
setupXfb(monitor);
VIDEO_Configure(vmode);
VIDEO_ClearFrameBuffer(vmode, _glfw.ogc.xfb[0], COLOR_BLACK);
VIDEO_SetNextFramebuffer(_glfw.ogc.xfb[0]);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if (vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync();
float yscale = GX_GetYScaleFactor(vmode->efbHeight, vmode->xfbHeight);
GX_SetDispCopyYScale(yscale);
GX_SetDispCopySrc(0, 0, vmode->fbWidth, vmode->efbHeight);
GX_SetDispCopyDst(vmode->fbWidth, vmode->xfbHeight);
GX_SetCopyFilter(vmode->aa, vmode->sample_pattern, GX_TRUE, vmode->vfilter);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwFreeMonitorOgc(_GLFWmonitor* monitor)
{
}
void _glfwGetMonitorPosOgc(_GLFWmonitor* monitor, int* xpos, int* ypos)
{
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
}
void _glfwGetMonitorContentScaleOgc(_GLFWmonitor* monitor,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.0f;
if (yscale)
*yscale = 1.0f;
}
void _glfwGetMonitorWorkareaOgc(_GLFWmonitor* monitor,
int* xpos, int* ypos,
int* width, int* height)
{
if (xpos)
*xpos = 0;
if (ypos)
*ypos = 0;
if (width)
*width = monitor->modes[monitor->ogc.currentMode].width;
if (height)
*height = monitor->modes[monitor->ogc.currentMode].height;
}
GLFWvidmode* _glfwGetVideoModesOgc(_GLFWmonitor* monitor, int* found)
{
int i, count;
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
i = 0;
s_videoModes[i++] = VIDEO_GetPreferredMode(NULL);
/* Add more video modes, depending on the TV mode of the preferred mode
* (NTSC, PAL, etc.) */
switch (VI_FORMAT_FROM_MODE(s_videoModes[0]->viTVMode))
{
case VI_DEBUG:
case VI_NTSC:
s_videoModes[i++] = &TVNtsc240Ds;
s_videoModes[i++] = &TVNtsc480Prog;
break;
case VI_MPAL:
s_videoModes[i++] = &TVMpal240Ds;
s_videoModes[i++] = &TVMpal480Prog;
break;
case VI_EURGB60:
s_videoModes[i++] = &TVEurgb60Hz240Ds;
s_videoModes[i++] = &TVEurgb60Hz480Prog;
s_videoModes[i++] = &TVPal528Prog;
break;
case VI_PAL:
case VI_DEBUG_PAL:
s_videoModes[i++] = &TVPal264Ds;
s_videoModes[i++] = &TVPal576ProgScale; // EFB height is 480
s_videoModes[i++] = &TVPal528Prog;
break;
default:
return NULL;
}
s_videoModes[i] = NULL;
GLFWvidmode* modes = _glfw_calloc(i, sizeof(GLFWvidmode));
count = i;
for (int i = 0; i < count; i++)
{
ogcVideoModeToGlfw(s_videoModes[i], &modes[i]);
}
*found = count;
return modes;
}
GLFWbool _glfwGetVideoModeOgc(_GLFWmonitor* monitor, GLFWvidmode* mode)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
*mode = monitor->modes[monitor->ogc.currentMode];
return GLFW_TRUE;
}
GLFWbool _glfwGetGammaRampOgc(_GLFWmonitor* monitor, GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"gamma ramp");
return GLFW_FALSE;
}
void _glfwSetGammaRampOgc(_GLFWmonitor* monitor, const GLFWgammaramp* ramp)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"gamma ramp");
}
#endif // _GLFW_OGC

252
src/ogc_platform.h Normal file
View File

@ -0,0 +1,252 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <ogc/gx.h>
#include <ogc/system.h>
#include <ogc/video.h>
#define GLFW_OGC_WINDOW_STATE _GLFWwindowOgc ogc;
#define GLFW_OGC_LIBRARY_WINDOW_STATE _GLFWlibraryOgc ogc;
#define GLFW_OGC_MONITOR_STATE _GLFWmonitorOgc ogc;
#define GLFW_OGC_CURSOR_STATE _GLFWcursorOgc ogc;
extern char _glfwUnimplementedFmt[];
#if 0
typedef struct ogc_cursor_theme* (* PFN_ogc_cursor_theme_load)(const char*, int, struct ogc_shm*);
typedef void (* PFN_ogc_cursor_theme_destroy)(struct ogc_cursor_theme*);
typedef struct ogc_cursor* (* PFN_ogc_cursor_theme_get_cursor)(struct ogc_cursor_theme*, const char*);
typedef struct ogc_buffer* (* PFN_ogc_cursor_image_get_buffer)(struct ogc_cursor_image*);
#define ogc_cursor_theme_load _glfw.ogc.cursor.theme_load
#define ogc_cursor_theme_destroy _glfw.ogc.cursor.theme_destroy
#define ogc_cursor_theme_get_cursor _glfw.ogc.cursor.theme_get_cursor
#define ogc_cursor_image_get_buffer _glfw.ogc.cursor.image_get_buffer
typedef struct ogc_egl_window* (* PFN_ogc_egl_window_create)(struct ogc_surface*, int, int);
typedef void (* PFN_ogc_egl_window_destroy)(struct ogc_egl_window*);
typedef void (* PFN_ogc_egl_window_resize)(struct ogc_egl_window*, int, int, int, int);
#define ogc_egl_window_create _glfw.ogc.egl.window_create
#define ogc_egl_window_destroy _glfw.ogc.egl.window_destroy
#define ogc_egl_window_resize _glfw.ogc.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);
typedef uint32_t (* PFN_xkb_keysym_to_utf32)(xkb_keysym_t);
typedef int (* PFN_xkb_keysym_to_utf8)(xkb_keysym_t, char*, size_t);
#define xkb_context_new _glfw.ogc.xkb.context_new
#define xkb_context_unref _glfw.ogc.xkb.context_unref
#define xkb_keymap_new_from_string _glfw.ogc.xkb.keymap_new_from_string
#define xkb_keymap_unref _glfw.ogc.xkb.keymap_unref
#define xkb_keymap_mod_get_index _glfw.ogc.xkb.keymap_mod_get_index
#define xkb_keymap_key_repeats _glfw.ogc.xkb.keymap_key_repeats
#define xkb_keymap_key_get_syms_by_level _glfw.ogc.xkb.keymap_key_get_syms_by_level
#define xkb_state_new _glfw.ogc.xkb.state_new
#define xkb_state_unref _glfw.ogc.xkb.state_unref
#define xkb_state_key_get_syms _glfw.ogc.xkb.state_key_get_syms
#define xkb_state_update_mask _glfw.ogc.xkb.state_update_mask
#define xkb_state_key_get_layout _glfw.ogc.xkb.state_key_get_layout
#define xkb_state_mod_index_is_active _glfw.ogc.xkb.state_mod_index_is_active
#define xkb_keysym_to_utf32 _glfw.ogc.xkb.keysym_to_utf32
#define xkb_keysym_to_utf8 _glfw.ogc.xkb.keysym_to_utf8
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.ogc.xkb.compose_table_new_from_locale
#define xkb_compose_table_unref _glfw.ogc.xkb.compose_table_unref
#define xkb_compose_state_new _glfw.ogc.xkb.compose_state_new
#define xkb_compose_state_unref _glfw.ogc.xkb.compose_state_unref
#define xkb_compose_state_feed _glfw.ogc.xkb.compose_state_feed
#define xkb_compose_state_get_status _glfw.ogc.xkb.compose_state_get_status
#define xkb_compose_state_get_one_sym _glfw.ogc.xkb.compose_state_get_one_sym
#endif
// Ogc-specific per-window data
//
typedef struct _GLFWwindowOgc
{
int width, height;
GLFWbool maximized;
GLFWbool activated;
GLFWbool fullscreen;
GLFWbool hovered;
GLFWbool transparent;
GLFWbool scaleFramebuffer;
struct ogc_surface* surface;
struct ogc_callback* callback;
_GLFWcursor* currentCursor;
double cursorPosX, cursorPosY;
char* appId;
} _GLFWwindowOgc;
// Ogc-specific global data
//
typedef struct _GLFWlibraryOgc
{
void * xfb[2];
int fbIndex;
struct ogc_cursor_theme* cursorTheme;
struct ogc_cursor_theme* cursorThemeHiDPI;
struct ogc_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];
_GLFWwindow* pointerFocus;
_GLFWwindow* keyboardFocus;
} _GLFWlibraryOgc;
// Ogc-specific per-monitor data
//
typedef struct _GLFWmonitorOgc
{
int currentMode;
GXRModeObj* ogcMode;
} _GLFWmonitorOgc;
// Ogc-specific per-cursor data
//
typedef struct _GLFWcursorOgc
{
GXTexObj texobj;
short xhot, yhot;
GLFWbool canRotate;
} _GLFWcursorOgc;
GLFWbool _glfwConnectOgc(int platformID, _GLFWplatform* platform);
int _glfwInitOgc(void);
void _glfwTerminateOgc(void);
void _glfwCreateMonitorOgc(void);
void _glfwSetVideoModeOgc(_GLFWmonitor* monitor, const GLFWvidmode* desired);
GLFWbool _glfwCreateContextOgc(_GLFWwindow* window,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig);
GLFWbool _glfwCreateWindowOgc(_GLFWwindow* window, const _GLFWwndconfig* wndconfig, const _GLFWctxconfig* ctxconfig, const _GLFWfbconfig* fbconfig);
void _glfwDestroyWindowOgc(_GLFWwindow* window);
void _glfwSetWindowTitleOgc(_GLFWwindow* window, const char* title);
void _glfwSetWindowIconOgc(_GLFWwindow* window, int count, const GLFWimage* images);
void _glfwGetWindowPosOgc(_GLFWwindow* window, int* xpos, int* ypos);
void _glfwSetWindowPosOgc(_GLFWwindow* window, int xpos, int ypos);
void _glfwGetWindowSizeOgc(_GLFWwindow* window, int* width, int* height);
void _glfwSetWindowSizeOgc(_GLFWwindow* window, int width, int height);
void _glfwSetWindowSizeLimitsOgc(_GLFWwindow* window, int minwidth, int minheight, int maxwidth, int maxheight);
void _glfwSetWindowAspectRatioOgc(_GLFWwindow* window, int numer, int denom);
void _glfwGetFramebufferSizeOgc(_GLFWwindow* window, int* width, int* height);
void _glfwGetWindowFrameSizeOgc(_GLFWwindow* window, int* left, int* top, int* right, int* bottom);
void _glfwGetWindowContentScaleOgc(_GLFWwindow* window, float* xscale, float* yscale);
void _glfwIconifyWindowOgc(_GLFWwindow* window);
void _glfwRestoreWindowOgc(_GLFWwindow* window);
void _glfwMaximizeWindowOgc(_GLFWwindow* window);
void _glfwShowWindowOgc(_GLFWwindow* window);
void _glfwHideWindowOgc(_GLFWwindow* window);
void _glfwRequestWindowAttentionOgc(_GLFWwindow* window);
void _glfwFocusWindowOgc(_GLFWwindow* window);
void _glfwSetWindowMonitorOgc(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate);
GLFWbool _glfwWindowFocusedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowIconifiedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowVisibleOgc(_GLFWwindow* window);
GLFWbool _glfwWindowMaximizedOgc(_GLFWwindow* window);
GLFWbool _glfwWindowHoveredOgc(_GLFWwindow* window);
GLFWbool _glfwFramebufferTransparentOgc(_GLFWwindow* window);
void _glfwSetWindowResizableOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowDecoratedOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetWindowFloatingOgc(_GLFWwindow* window, GLFWbool enabled);
float _glfwGetWindowOpacityOgc(_GLFWwindow* window);
void _glfwSetWindowOpacityOgc(_GLFWwindow* window, float opacity);
void _glfwSetWindowMousePassthroughOgc(_GLFWwindow* window, GLFWbool enabled);
void _glfwSetRawMouseMotionOgc(_GLFWwindow* window, GLFWbool enabled);
GLFWbool _glfwRawMouseMotionSupportedOgc(void);
void _glfwPollEventsOgc(void);
void _glfwWaitEventsOgc(void);
void _glfwWaitEventsTimeoutOgc(double timeout);
void _glfwPostEmptyEventOgc(void);
void _glfwGetCursorPosOgc(_GLFWwindow* window, double* xpos, double* ypos);
void _glfwSetCursorPosOgc(_GLFWwindow* window, double xpos, double ypos);
void _glfwSetCursorModeOgc(_GLFWwindow* window, int mode);
const char* _glfwGetScancodeNameOgc(int scancode);
int _glfwGetKeyScancodeOgc(int key);
GLFWbool _glfwCreateCursorOgc(_GLFWcursor* cursor, const GLFWimage* image, int xhot, int yhot);
GLFWbool _glfwCreateStandardCursorOgc(_GLFWcursor* cursor, int shape);
void _glfwDestroyCursorOgc(_GLFWcursor* cursor);
void _glfwSetCursorOgc(_GLFWwindow* window, _GLFWcursor* cursor);
void _glfwSetClipboardStringOgc(const char* string);
const char* _glfwGetClipboardStringOgc(void);
EGLenum _glfwGetEGLPlatformOgc(EGLint** attribs);
EGLNativeDisplayType _glfwGetEGLNativeDisplayOgc(void);
EGLNativeWindowType _glfwGetEGLNativeWindowOgc(_GLFWwindow* window);
void _glfwGetRequiredInstanceExtensionsOgc(char** extensions);
GLFWbool _glfwGetPhysicalDevicePresentationSupportOgc(VkInstance instance, VkPhysicalDevice device, uint32_t queuefamily);
VkResult _glfwCreateWindowSurfaceOgc(VkInstance instance, _GLFWwindow* window, const VkAllocationCallbacks* allocator, VkSurfaceKHR* surface);
void _glfwFreeMonitorOgc(_GLFWmonitor* monitor);
void _glfwGetMonitorPosOgc(_GLFWmonitor* monitor, int* xpos, int* ypos);
void _glfwGetMonitorContentScaleOgc(_GLFWmonitor* monitor, float* xscale, float* yscale);
void _glfwGetMonitorWorkareaOgc(_GLFWmonitor* monitor, int* xpos, int* ypos, int* width, int* height);
GLFWvidmode* _glfwGetVideoModesOgc(_GLFWmonitor* monitor, int* count);
GLFWbool _glfwGetVideoModeOgc(_GLFWmonitor* monitor, GLFWvidmode* mode);
GLFWbool _glfwGetGammaRampOgc(_GLFWmonitor* monitor, GLFWgammaramp* ramp);
void _glfwSetGammaRampOgc(_GLFWmonitor* monitor, const GLFWgammaramp* ramp);
void _glfwAddOutputOgc(uint32_t name, uint32_t version);
void _glfwUpdateBufferScaleFromOutputsOgc(_GLFWwindow* window);

237
src/ogc_thread.c Normal file
View File

@ -0,0 +1,237 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC_THREAD)
#include <assert.h>
#include <ogcsys.h>
#include <string.h>
#define MAX_THREADS 32
#define INITIAL_STORAGE_CAPACITY 64
#define INCREMENT_STORAGE_CAPACITY 64
typedef struct _GLFWthreadStorageOgc {
size_t capacity;
size_t used;
void *data[0]; /* Array of pointers to the stored data element */
} _GLFWthreadStorageOgc;
#define RESERVED_PTR ((void*)0x1)
typedef struct _GLFWthreadMapOgc {
lwp_t threadId;
_GLFWthreadStorageOgc *storage;
} _GLFWthreadMapOgc;
static _GLFWthreadMapOgc threadMap[MAX_THREADS];
static mutex_t threadMapMutex = 0; // TODO initialize!
static _GLFWthreadMapOgc *storageEntryForThread()
{
lwp_t currentThreadId = LWP_GetSelf();
/* We are not creating entries here and only our thread can modify our
* entry, so we don't need to lock the mutex here. */
for (int i = 0; i < MAX_THREADS; i++) {
_GLFWthreadMapOgc *entry = &threadMap[i];
if (entry->threadId == currentThreadId) {
return entry;
}
}
return NULL;
}
static inline _GLFWthreadStorageOgc *storageForThread()
{
_GLFWthreadMapOgc *entry = storageEntryForThread();
return entry ? entry->storage : NULL;
}
static _GLFWthreadMapOgc *createStorageEntryForThread()
{
size_t initialSize = sizeof(_GLFWthreadStorageOgc) +
INITIAL_STORAGE_CAPACITY * sizeof(void*);
_GLFWthreadStorageOgc *storage = _glfw_calloc(1, initialSize);
if (!storage) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to allocate TLS data");
return NULL;
}
storage->capacity = INITIAL_STORAGE_CAPACITY;
storage->used = 0;
if (!LWP_MutexLock(threadMapMutex)) {
_glfw_free(storage);
_glfwInputError(GLFW_PLATFORM_ERROR,
"OGC: Failed to lock TLS mutex");
return NULL;
}
_GLFWthreadMapOgc *entry = NULL;
lwp_t currentThreadId = LWP_GetSelf();
for (int i = 0; i < MAX_THREADS; i++) {
entry = &threadMap[i];
if (!entry->threadId) {
entry->threadId = currentThreadId;
entry->storage = storage;
break;
}
}
if (entry->threadId != currentThreadId) {
// We didn't find a free slot
entry = NULL;
}
LWP_MutexUnlock(threadMapMutex);
return entry;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwPlatformCreateTls(_GLFWtls* tls)
{
assert(tls->ogc.allocated == GLFW_FALSE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
if (!entry) {
entry = createStorageEntryForThread();
if (!entry) {
// The error has already been logged
return GLFW_FALSE;
}
}
_GLFWthreadStorageOgc *storage = entry->storage;
if (storage->used >= storage->capacity) {
size_t newSize = sizeof(_GLFWthreadStorageOgc) +
(storage->capacity + INCREMENT_STORAGE_CAPACITY) * sizeof(void*);
storage = _glfw_realloc(storage, newSize);
if (!storage) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to reallocate TLS data");
return GLFW_FALSE;
}
// No need to lock the map, since we are changing our own thread's
// entry
entry->storage = storage;
storage->capacity += INCREMENT_STORAGE_CAPACITY;
}
// Find the first free entry in the TLS data
int index = -1;
for (int i = 0; i < storage->capacity; i++) {
if (!storage->data[i]) {
index = i;
break;
}
}
/* We know that storage->capacity > storage->used, so there must be free
* slots */
assert(index >= 0);
storage->data[index] = RESERVED_PTR;
storage->used++;
tls->ogc.index = index;
tls->ogc.allocated = GLFW_TRUE;
return GLFW_TRUE;
}
void _glfwPlatformDestroyTls(_GLFWtls* tls)
{
if (tls->ogc.allocated) {
_GLFWthreadMapOgc *entry = storageEntryForThread();
if (entry) {
assert(entry->storage->capacity > tls->ogc.index);
assert(entry->storage->used > 0);
entry->storage->data[tls->ogc.index] = NULL;
entry->storage->used--;
}
}
memset(tls, 0, sizeof(_GLFWtls));
}
void* _glfwPlatformGetTls(_GLFWtls* tls)
{
assert(tls->ogc.allocated == GLFW_TRUE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
void *ptr = entry->storage->data[tls->ogc.index];
return ptr == RESERVED_PTR ? NULL : ptr;
}
void _glfwPlatformSetTls(_GLFWtls* tls, void* value)
{
assert(tls->posix.allocated == GLFW_TRUE);
_GLFWthreadMapOgc *entry = storageEntryForThread();
entry->storage->data[tls->ogc.index] = value;
}
GLFWbool _glfwPlatformCreateMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_FALSE);
if (LWP_MutexInit(&mutex->ogc.handle, false) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR, "OGC: Failed to create mutex");
return GLFW_FALSE;
}
return mutex->ogc.allocated = GLFW_TRUE;
}
void _glfwPlatformDestroyMutex(_GLFWmutex* mutex)
{
if (mutex->ogc.allocated)
LWP_MutexDestroy(mutex->ogc.handle);
memset(mutex, 0, sizeof(_GLFWmutex));
}
void _glfwPlatformLockMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_TRUE);
LWP_MutexLock(mutex->ogc.handle);
}
void _glfwPlatformUnlockMutex(_GLFWmutex* mutex)
{
assert(mutex->ogc.allocated == GLFW_TRUE);
LWP_MutexUnlock(mutex->ogc.handle);
}
void _glfwThreadInitMutexOgc()
{
LWP_MutexInit(&threadMapMutex, false);
}
#endif // GLFW_BUILD_OGC_THREAD

49
src/ogc_thread.h Normal file
View File

@ -0,0 +1,49 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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 <ogc/mutex.h>
#define GLFW_OGC_TLS_STATE _GLFWtlsOgc ogc;
#define GLFW_OGC_MUTEX_STATE _GLFWmutexOgc ogc;
// POSIX-specific thread local storage data
//
typedef struct _GLFWtlsOgc
{
GLFWbool allocated;
int index;
} _GLFWtlsOgc;
// POSIX-specific mutex data
//
typedef struct _GLFWmutexOgc
{
GLFWbool allocated;
mutex_t handle;
} _GLFWmutexOgc;
void _glfwThreadInitMutexOgc();

52
src/ogc_time.c Normal file
View File

@ -0,0 +1,52 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC_TIMER)
#include <ogc/lwp_watchdog.h>
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
void _glfwPlatformInitTimer(void)
{
}
uint64_t _glfwPlatformGetTimerValue(void)
{
return gettime();
}
uint64_t _glfwPlatformGetTimerFrequency(void)
{
return secs_to_ticks(1);
}
#endif // GLFW_BUILD_OGC_TIMER

28
src/ogc_time.h Normal file
View File

@ -0,0 +1,28 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC_LIBRARY_TIMER_STATE

564
src/ogc_window.c Normal file
View File

@ -0,0 +1,564 @@
//========================================================================
// GLFW 3.5 OGC - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2024 Alberto Mardegan <info@mardy.it>
//
// 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_OGC)
#include "ogc_cursor.h"
#include <assert.h>
#include <errno.h>
#include <malloc.h>
#include <opengx.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiikeyboard/keyboard.h>
#ifdef __wii__
#include <wiiuse/wpad.h>
#endif
static void keysym_to_utf8(uint16_t symbol, char *utf8)
{
/* ignore private symbols, used by wiikeyboard for special keys */
if ((symbol >= 0xE000 && symbol <= 0xF8FF) || symbol == 0xFFFF)
return;
/* convert UCS-2 to UTF-8 */
if (symbol < 0x80) {
utf8[0] = symbol;
} else if (symbol < 0x800) {
utf8[0] = 0xC0 | (symbol >> 6);
utf8[1] = 0x80 | (symbol & 0x3F);
} else {
utf8[0] = 0xE0 | (symbol >> 12);
utf8[1] = 0x80 | ((symbol >> 6) & 0x3F);
utf8[2] = 0x80 | (symbol & 0x3F);
}
}
static void acquireMonitor(_GLFWwindow* window)
{
fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, __func__);
if (!window->monitor) {
window->monitor = _glfw.monitors[0];
}
_glfwInputMonitorWindow(window->monitor, window);
_glfwSetVideoModeOgc(window->monitor, &window->videoMode);
}
static void releaseMonitor(_GLFWwindow* window)
{
if (window->monitor->window != window)
return;
_glfwInputMonitorWindow(window->monitor, NULL);
}
/* Convert the RGBA pixels to the 4x4 tile ARGB texture used by GX */
static void setPixelToTextureARGB(char *texture, u32 offset, u32 color)
{
*(u16*)(texture + offset) = color >> 16;
*(u16*)(texture + offset + 32) = color;
}
static void setPixelToTextureRGBA(char *texture, u32 offset, u32 color)
{
setPixelToTextureARGB(texture, offset, (color << 24) | (color >> 8));
}
static void pixelsToTextureARGB(const void *pixels, s16 width, s16 height,
s16 pitch, void *texture)
{
s16 tex_pitch = (width + 3) / 4 * 4;
int row, col;
for (row = 0; row < height; row++) {
int y = row;
u32 *src = (u32 *)((u8 *)pixels + pitch * row);
for (col = 0; col < width; col++) {
int x = col;
u32 offset = (((y >> 2) << 4) * tex_pitch) +
((x >> 2) << 6) + (((y % 4 << 2) + x % 4) << 1);
setPixelToTextureRGBA(texture, offset, *src++);
}
}
}
static void* createRGBAtexture(const GLFWimage* image)
{
u32 textureSize;
void *texels;
textureSize = GX_GetTexBufferSize(image->width, image->height, GX_TF_RGBA8,
GX_FALSE, 0);
texels = memalign(32, textureSize);
if (!texels) {
_glfwInputError(GLFW_OUT_OF_MEMORY,
"OGC: Failed to allocate cursor texture");
return NULL;
}
pixelsToTextureARGB(image->pixels, image->width, image->height,
image->width * 4, texels);
DCStoreRange(texels, textureSize);
return texels;
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
GLFWbool _glfwCreateWindowOgc(_GLFWwindow* window,
const _GLFWwndconfig* wndconfig,
const _GLFWctxconfig* ctxconfig,
const _GLFWfbconfig* fbconfig)
{
fprintf(stderr, "%s:%d %s %p\n", __FILE__, __LINE__, __func__, window);
acquireMonitor(window);
window->ogc.width = window->monitor->ogc.ogcMode->fbWidth;
window->ogc.height = window->monitor->ogc.ogcMode->efbHeight;
if (ctxconfig->client != GLFW_NO_API)
{
ogx_initialize();
if (!_glfwCreateContextOgc(window, ctxconfig, fbconfig))
return GLFW_FALSE;
if (!_glfwRefreshContextAttribs(window, ctxconfig))
return GLFW_FALSE;
}
/* Set the default Wii cursor */
GLFWcursor *cursor = glfwCreateStandardCursor(GLFW_POINTING_HAND_CURSOR);
_glfwSetCursorOgc(window, (_GLFWcursor*) cursor);
return GLFW_TRUE;
}
void _glfwDestroyWindowOgc(_GLFWwindow* window)
{
if (window->monitor)
releaseMonitor(window);
}
void _glfwSetWindowTitleOgc(_GLFWwindow* window, const char* title)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window title");
}
void _glfwSetWindowIconOgc(_GLFWwindow* window,
int count, const GLFWimage* images)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window icon");
}
void _glfwGetWindowPosOgc(_GLFWwindow* window, int* xpos, int* ypos)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"getting the window position");
}
void _glfwSetWindowPosOgc(_GLFWwindow* window, int xpos, int ypos)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window position");
}
void _glfwGetWindowSizeOgc(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->ogc.width;
if (height)
*height = window->ogc.height;
}
void _glfwSetWindowSizeOgc(_GLFWwindow* window, int width, int height)
{
fprintf(stderr, "%s:%d %s %dx%d\n", __FILE__, __LINE__, __func__, width, height);
if (window->monitor)
{
}
else
{
_glfwInputWindowDamage(window);
}
}
void _glfwSetWindowSizeLimitsOgc(_GLFWwindow* window,
int minwidth, int minheight,
int maxwidth, int maxheight)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the size limits");
}
void _glfwSetWindowAspectRatioOgc(_GLFWwindow* window, int numer, int denom)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the aspect ratio");
}
void _glfwGetFramebufferSizeOgc(_GLFWwindow* window, int* width, int* height)
{
if (width)
*width = window->monitor->ogc.ogcMode->fbWidth;
if (height)
*height = window->monitor->ogc.ogcMode->efbHeight;;
}
void _glfwGetWindowFrameSizeOgc(_GLFWwindow* window,
int* left, int* top,
int* right, int* bottom)
{
*left = *top = *right = *bottom = 0;
}
void _glfwGetWindowContentScaleOgc(_GLFWwindow* window,
float* xscale, float* yscale)
{
if (xscale)
*xscale = 1.0f;
if (yscale)
*yscale = 1.0f;
}
void _glfwIconifyWindowOgc(_GLFWwindow* window)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"iconifying the window");
}
void _glfwRestoreWindowOgc(_GLFWwindow* window)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"restoring the window");
}
void _glfwMaximizeWindowOgc(_GLFWwindow* window)
{
}
void _glfwShowWindowOgc(_GLFWwindow* window)
{
}
void _glfwHideWindowOgc(_GLFWwindow* window)
{
}
void _glfwRequestWindowAttentionOgc(_GLFWwindow* window)
{
}
void _glfwFocusWindowOgc(_GLFWwindow* window)
{
}
void _glfwSetWindowMonitorOgc(_GLFWwindow* window,
_GLFWmonitor* monitor,
int xpos, int ypos,
int width, int height,
int refreshRate)
{
}
GLFWbool _glfwWindowFocusedOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowIconifiedOgc(_GLFWwindow* window)
{
return GLFW_FALSE;
}
GLFWbool _glfwWindowVisibleOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowMaximizedOgc(_GLFWwindow* window)
{
return GLFW_TRUE;
}
GLFWbool _glfwWindowHoveredOgc(_GLFWwindow* window)
{
return window->ogc.hovered;
}
GLFWbool _glfwFramebufferTransparentOgc(_GLFWwindow* window)
{
return GLFW_FALSE;
}
void _glfwSetWindowResizableOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwSetWindowDecoratedOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
void _glfwSetWindowFloatingOgc(_GLFWwindow* window, GLFWbool enabled)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"making a window floating");
}
void _glfwSetWindowMousePassthroughOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
float _glfwGetWindowOpacityOgc(_GLFWwindow* window)
{
return 1.f;
}
void _glfwSetWindowOpacityOgc(_GLFWwindow* window, float opacity)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the window opacity");
}
void _glfwSetRawMouseMotionOgc(_GLFWwindow* window, GLFWbool enabled)
{
}
GLFWbool _glfwRawMouseMotionSupportedOgc(void)
{
return GLFW_FALSE;
}
#ifdef __wii__
static void handleWiimoteCursorOgc(_GLFWwindow* window)
{
WPADData *data = WPAD_Data(0);
float x, y;
GLFWbool mouseActive = !!data->ir.valid;
if (mouseActive != window->ogc.hovered) {
window->ogc.hovered = mouseActive;
_glfwInputCursorEnter(window, mouseActive);
}
if (!mouseActive) return;
x = data->ir.x * window->ogc.width / data->ir.vres[0];
y = data->ir.y * window->ogc.height / data->ir.vres[1];
_glfwInputCursorPos(window, x, y);
if (data->btns_d & WPAD_BUTTON_A)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_PRESS, 0);
if (data->btns_u & WPAD_BUTTON_A)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_1, GLFW_RELEASE, 0);
if (data->btns_d & WPAD_BUTTON_B)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_2, GLFW_PRESS, 0);
if (data->btns_u & WPAD_BUTTON_B)
_glfwInputMouseClick(window, GLFW_MOUSE_BUTTON_2, GLFW_RELEASE, 0);
}
#endif
void _glfwPollEventsOgc(void)
{
//fprintf(stderr, "Polling for events %d\n", 0);
GLFWbool hasEvents = GLFW_FALSE;
if (_glfwPollJoysticksOgc()) {
hasEvents = GLFW_TRUE;
#ifdef __wii__
/* Use the first wiimote as mouse */
if (_glfw.windowListHead)
handleWiimoteCursorOgc(_glfw.windowListHead);
#endif
}
}
void _glfwWaitEventsOgc(void)
{
// TODO: check if events were produced or sleep?
_glfwPollEventsOgc();
}
void _glfwWaitEventsTimeoutOgc(double timeout)
{
// TODO: check if events were produced or sleep?
_glfwPollEventsOgc();
}
void _glfwPostEmptyEventOgc(void)
{
}
void _glfwGetCursorPosOgc(_GLFWwindow* window, double* xpos, double* ypos)
{
if (xpos)
*xpos = window->virtualCursorPosX;
if (ypos)
*ypos = window->virtualCursorPosY;
}
void _glfwSetCursorPosOgc(_GLFWwindow* window, double x, double y)
{
_glfwInputError(GLFW_FEATURE_UNAVAILABLE, _glfwUnimplementedFmt,
"setting the cursor position");
}
void _glfwSetCursorModeOgc(_GLFWwindow* window, int mode)
{
// TODO
}
const char* _glfwGetScancodeNameOgc(int scancode)
{
static char name[10];
name[0] = name[1] = '\0';
switch (scancode) {
case KS_Return: name[0] = '\n'; break;
case KS_Escape: return "ESC";
default:
keysym_to_utf8(scancode, name);
}
return name;
}
int _glfwGetKeyScancodeOgc(int key)
{
return _glfw.ogc.scancodes[key];
}
GLFWbool _glfwCreateCursorOgc(_GLFWcursor* cursor,
const GLFWimage* image,
int xhot, int yhot)
{
void* texels = createRGBAtexture(image);
if (!texels) return GLFW_FALSE;
cursor->ogc.xhot = xhot;
cursor->ogc.yhot = yhot;
GX_InvalidateTexAll();
GX_InitTexObj(&cursor->ogc.texobj, texels,
image->width, image->height,
GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
GX_InitTexObjLOD(&cursor->ogc.texobj, GX_LINEAR, GX_LINEAR,
0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
return GLFW_TRUE;
}
GLFWbool _glfwCreateStandardCursorOgc(_GLFWcursor* cursor, int shape)
{
const _GLFWcursorDataOgc* cd = NULL;
switch (shape)
{
case GLFW_ARROW_CURSOR:
cd = &OGC_cursor_arrow;
break;
case GLFW_POINTING_HAND_CURSOR:
cd = &OGC_cursor_hand;
break;
default:
return GLFW_FALSE;
}
GLFWimage image = {
cd->width, cd->height, cd->pixel_data
};
return _glfwCreateCursorOgc(cursor, &image,
cd->hot_x, cd->hot_y);
}
void _glfwDestroyCursorOgc(_GLFWcursor* cursor)
{
void *data = GX_GetTexObjData(&cursor->ogc.texobj);
if (data != 0)
free(MEM_PHYSICAL_TO_K0(data));
}
void _glfwSetCursorOgc(_GLFWwindow* window, _GLFWcursor* cursor)
{
window->ogc.currentCursor = cursor;
}
void _glfwSetClipboardStringOgc(const char* string)
{
}
const char* _glfwGetClipboardStringOgc(void)
{
return NULL;
}
EGLenum _glfwGetEGLPlatformOgc(EGLint** attribs)
{
return EGL_PLATFORM_ANGLE_ANGLE;
}
EGLNativeDisplayType _glfwGetEGLNativeDisplayOgc(void)
{
return EGL_DEFAULT_DISPLAY;
}
EGLNativeWindowType _glfwGetEGLNativeWindowOgc(_GLFWwindow* window)
{
return 0;
}
void _glfwGetRequiredInstanceExtensionsOgc(char** extensions)
{
}
GLFWbool _glfwGetPhysicalDevicePresentationSupportOgc(VkInstance instance,
VkPhysicalDevice device,
uint32_t queuefamily)
{
return GLFW_FALSE;
}
VkResult _glfwCreateWindowSurfaceOgc(VkInstance instance,
_GLFWwindow* window,
const VkAllocationCallbacks* allocator,
VkSurfaceKHR* surface)
{
return VK_ERROR_EXTENSION_NOT_PRESENT;
}
#endif // _GLFW_OGC

View File

@ -56,6 +56,9 @@ static const struct
#if defined(_GLFW_X11) #if defined(_GLFW_X11)
{ GLFW_PLATFORM_X11, _glfwConnectX11 }, { GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif #endif
#if defined(_GLFW_OGC)
{ GLFW_PLATFORM_OGC, _glfwConnectOgc },
#endif
}; };
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform) GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
@ -68,6 +71,7 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
desiredID != GLFW_PLATFORM_COCOA && desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND && desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 && desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_OGC &&
desiredID != GLFW_PLATFORM_NULL) desiredID != GLFW_PLATFORM_NULL)
{ {
_glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID); _glfwInputError(GLFW_INVALID_ENUM, "Invalid platform ID 0x%08X", desiredID);

View File

@ -29,6 +29,8 @@
defined(GLFW_BUILD_WIN32_MODULE) || \ defined(GLFW_BUILD_WIN32_MODULE) || \
defined(GLFW_BUILD_WIN32_THREAD) || \ defined(GLFW_BUILD_WIN32_THREAD) || \
defined(GLFW_BUILD_COCOA_TIMER) || \ defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_OGC_MODULE) || \
defined(GLFW_BUILD_OGC_THREAD) || \
defined(GLFW_BUILD_POSIX_TIMER) || \ defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \ defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \ defined(GLFW_BUILD_POSIX_THREAD) || \
@ -90,6 +92,16 @@
#define GLFW_GLX_LIBRARY_CONTEXT_STATE #define GLFW_GLX_LIBRARY_CONTEXT_STATE
#endif #endif
#if defined(_GLFW_OGC)
#include "ogc_platform.h"
#define GLFW_EXPOSE_NATIVE_OGC
#else
#define GLFW_OGC_WINDOW_STATE
#define GLFW_OGC_MONITOR_STATE
#define GLFW_OGC_CURSOR_STATE
#define GLFW_OGC_LIBRARY_WINDOW_STATE
#endif
#include "null_joystick.h" #include "null_joystick.h"
#if defined(_GLFW_WIN32) #if defined(_GLFW_WIN32)
@ -106,6 +118,13 @@
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE #define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#endif #endif
#if defined(_GLFW_OGC)
#include "ogc_joystick.h"
#else
#define GLFW_OGC_JOYSTICK_STATE
#define GLFW_OGC_LIBRARY_JOYSTICK_STATE
#endif
#if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__) #if (defined(_GLFW_X11) || defined(_GLFW_WAYLAND)) && defined(__linux__)
#define GLFW_BUILD_LINUX_JOYSTICK #define GLFW_BUILD_LINUX_JOYSTICK
#endif #endif
@ -123,6 +142,7 @@
GLFW_WAYLAND_WINDOW_STATE \ GLFW_WAYLAND_WINDOW_STATE \
GLFW_X11_WINDOW_STATE \ GLFW_X11_WINDOW_STATE \
GLFW_NULL_WINDOW_STATE \ GLFW_NULL_WINDOW_STATE \
GLFW_OGC_WINDOW_STATE \
#define GLFW_PLATFORM_MONITOR_STATE \ #define GLFW_PLATFORM_MONITOR_STATE \
GLFW_WIN32_MONITOR_STATE \ GLFW_WIN32_MONITOR_STATE \
@ -130,6 +150,7 @@
GLFW_WAYLAND_MONITOR_STATE \ GLFW_WAYLAND_MONITOR_STATE \
GLFW_X11_MONITOR_STATE \ GLFW_X11_MONITOR_STATE \
GLFW_NULL_MONITOR_STATE \ GLFW_NULL_MONITOR_STATE \
GLFW_OGC_MONITOR_STATE \
#define GLFW_PLATFORM_CURSOR_STATE \ #define GLFW_PLATFORM_CURSOR_STATE \
GLFW_WIN32_CURSOR_STATE \ GLFW_WIN32_CURSOR_STATE \
@ -137,11 +158,13 @@
GLFW_WAYLAND_CURSOR_STATE \ GLFW_WAYLAND_CURSOR_STATE \
GLFW_X11_CURSOR_STATE \ GLFW_X11_CURSOR_STATE \
GLFW_NULL_CURSOR_STATE \ GLFW_NULL_CURSOR_STATE \
GLFW_OGC_CURSOR_STATE \
#define GLFW_PLATFORM_JOYSTICK_STATE \ #define GLFW_PLATFORM_JOYSTICK_STATE \
GLFW_WIN32_JOYSTICK_STATE \ GLFW_WIN32_JOYSTICK_STATE \
GLFW_COCOA_JOYSTICK_STATE \ GLFW_COCOA_JOYSTICK_STATE \
GLFW_LINUX_JOYSTICK_STATE GLFW_LINUX_JOYSTICK_STATE \
GLFW_OGC_JOYSTICK_STATE \
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \ #define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
GLFW_WIN32_LIBRARY_WINDOW_STATE \ GLFW_WIN32_LIBRARY_WINDOW_STATE \
@ -149,11 +172,13 @@
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \ GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
GLFW_X11_LIBRARY_WINDOW_STATE \ GLFW_X11_LIBRARY_WINDOW_STATE \
GLFW_NULL_LIBRARY_WINDOW_STATE \ GLFW_NULL_LIBRARY_WINDOW_STATE \
GLFW_OGC_LIBRARY_WINDOW_STATE \
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \ #define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
GLFW_WIN32_LIBRARY_JOYSTICK_STATE \ GLFW_WIN32_LIBRARY_JOYSTICK_STATE \
GLFW_COCOA_LIBRARY_JOYSTICK_STATE \ GLFW_COCOA_LIBRARY_JOYSTICK_STATE \
GLFW_LINUX_LIBRARY_JOYSTICK_STATE GLFW_LINUX_LIBRARY_JOYSTICK_STATE \
GLFW_OGC_LIBRARY_JOYSTICK_STATE \
#define GLFW_PLATFORM_CONTEXT_STATE \ #define GLFW_PLATFORM_CONTEXT_STATE \
GLFW_WGL_CONTEXT_STATE \ GLFW_WGL_CONTEXT_STATE \
@ -167,6 +192,8 @@
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_THREAD #define GLFW_BUILD_WIN32_THREAD
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_THREAD
#else #else
#define GLFW_BUILD_POSIX_THREAD #define GLFW_BUILD_POSIX_THREAD
#endif #endif
@ -179,12 +206,18 @@
#include "posix_thread.h" #include "posix_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE #define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE #define GLFW_PLATFORM_MUTEX_STATE GLFW_POSIX_MUTEX_STATE
#elif defined(GLFW_BUILD_OGC_THREAD)
#include "ogc_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_OGC_TLS_STATE
#define GLFW_PLATFORM_MUTEX_STATE GLFW_OGC_MUTEX_STATE
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER #define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__) #elif defined(__APPLE__)
#define GLFW_BUILD_COCOA_TIMER #define GLFW_BUILD_COCOA_TIMER
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_TIMER
#else #else
#define GLFW_BUILD_POSIX_TIMER #define GLFW_BUILD_POSIX_TIMER
#endif #endif
@ -198,10 +231,15 @@
#elif defined(GLFW_BUILD_POSIX_TIMER) #elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h" #include "posix_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE #define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_POSIX_LIBRARY_TIMER_STATE
#elif defined(GLFW_BUILD_OGC_TIMER)
#include "ogc_time.h"
#define GLFW_PLATFORM_LIBRARY_TIMER_STATE GLFW_OGC_LIBRARY_TIMER_STATE
#endif #endif
#if defined(_WIN32) #if defined(_WIN32)
#define GLFW_BUILD_WIN32_MODULE #define GLFW_BUILD_WIN32_MODULE
#elif defined(__wii__) || defined(__gamecube)
#define GLFW_BUILD_OGC_MODULE
#else #else
#define GLFW_BUILD_POSIX_MODULE #define GLFW_BUILD_POSIX_MODULE
#endif #endif

View File

@ -1377,7 +1377,7 @@ static int createNativeWindow(_GLFWwindow* window,
frameHeight = rect.bottom - rect.top; frameHeight = rect.bottom - rect.top;
} }
wideTitle = _glfwCreateWideStringFromUTF8Win32(wndconfig->title); wideTitle = _glfwCreateWideStringFromUTF8Win32(window->title);
if (!wideTitle) if (!wideTitle)
return GLFW_FALSE; return GLFW_FALSE;

View File

@ -208,7 +208,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height,
wndconfig.width = width; wndconfig.width = width;
wndconfig.height = height; wndconfig.height = height;
wndconfig.title = title;
ctxconfig.share = (_GLFWwindow*) share; ctxconfig.share = (_GLFWwindow*) share;
if (!_glfwIsValidContextConfig(&ctxconfig)) if (!_glfwIsValidContextConfig(&ctxconfig))

View File

@ -470,6 +470,7 @@ typedef struct _GLFWcontextGLX
{ {
GLXContext handle; GLXContext handle;
GLXWindow window; GLXWindow window;
GLXFBConfig fbconfig;
} _GLFWcontextGLX; } _GLFWcontextGLX;
// GLX-specific global data // GLX-specific global data

View File

@ -754,13 +754,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
const char* resourceName = getenv("RESOURCE_NAME"); const char* resourceName = getenv("RESOURCE_NAME");
if (resourceName && strlen(resourceName)) if (resourceName && strlen(resourceName))
hint->res_name = (char*) resourceName; hint->res_name = (char*) resourceName;
else if (strlen(wndconfig->title)) else if (strlen(window->title))
hint->res_name = (char*) wndconfig->title; hint->res_name = (char*) window->title;
else else
hint->res_name = (char*) "glfw-application"; hint->res_name = (char*) "glfw-application";
if (strlen(wndconfig->title)) if (strlen(window->title))
hint->res_class = (char*) wndconfig->title; hint->res_class = (char*) window->title;
else else
hint->res_class = (char*) "GLFW-Application"; hint->res_class = (char*) "GLFW-Application";
} }
@ -780,7 +780,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
if (_glfw.x11.im) if (_glfw.x11.im)
_glfwCreateInputContextX11(window); _glfwCreateInputContextX11(window);
_glfwSetWindowTitleX11(window, wndconfig->title); _glfwSetWindowTitleX11(window, window->title);
_glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos); _glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos);
_glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height); _glfwGetWindowSizeX11(window, &window->x11.width, &window->x11.height);

View File

@ -41,8 +41,10 @@ add_executable(title WIN32 MACOSX_BUNDLE title.c ${GLAD_GL})
add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN}) add_executable(triangle-vulkan WIN32 triangle-vulkan.c ${GLAD_VULKAN})
add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL}) add_executable(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
if (Threads_FOUND)
target_link_libraries(empty Threads::Threads) target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads) target_link_libraries(threads Threads::Threads)
endif()
if (RT_LIBRARY) if (RT_LIBRARY)
target_link_libraries(empty "${RT_LIBRARY}") target_link_libraries(empty "${RT_LIBRARY}")
target_link_libraries(threads "${RT_LIBRARY}") target_link_libraries(threads "${RT_LIBRARY}")