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")
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_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_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")
find_package(Threads REQUIRED)
find_package(Threads)
#--------------------------------------------------------------------
# Report backend selection

View File

@ -23,6 +23,7 @@ video tutorials.
- Denis Bernard
- BiBi
- Doug Binks
- bitb4ker
- blanco
- Waris Boonyasiriwat
- Kyle Brenneman
@ -123,6 +124,7 @@ video tutorials.
- Josh Kilmer
- Byunghoon Kim
- Cameron King
- knokko
- Peter Knut
- Christoph Kubisch
- 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
creating windows, contexts and surfaces, reading input, handling events, etc.
GLFW natively supports Windows, macOS and Linux and other Unix-like systems. On
Linux both Wayland and X11 are supported.
GLFW is written primarily in C99, with parts of macOS support being written in
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
license](https://www.glfw.org/license.html).
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
a corresponding [annotated tag](https://github.com/glfw/glfw/releases) with
source and binary archives.
as source or Windows and macOS binaries. There are [release
tags](https://github.com/glfw/glfw/releases) with source and binary archives
attached for every version since 3.0.
The [documentation](https://www.glfw.org/docs/latest/) is available online and is
included in all source and binary archives. See the [release
notes](https://www.glfw.org/docs/latest/news.html) for new features, caveats and
deprecations in the latest release. For more details see the [version
history](https://www.glfw.org/changelog.html).
The `master` branch is the stable integration branch and _should_ always compile
and run on all supported platforms, although details of newly added features may
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.
also included in source and binary archives, except those generated
automatically by Github. The documentation contains guides, a tutorial and the
API reference. The [release
notes](https://www.glfw.org/docs/latest/news.html) list the new features,
caveats and deprecations in the latest release. The [version
history](https://www.glfw.org/changelog.html) lists every user-visible change
for every release.
GLFW exists because of the contributions of [many people](CONTRIBUTORS.md)
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.
## 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
GLFW supports Windows 7 and later and macOS 10.11 and later. Linux and other
Unix-like systems running the X Window System are supported even without
a desktop environment or modern extensions, although some features require
a running window or clipboard manager. The OSMesa backend requires Mesa 6.3.
GLFW supports Windows 7 and later and macOS 10.11 and later. On GNOME Wayland,
window decorations will be very basic unless the
[libdecor](https://gitlab.freedesktop.org/libdecor/libdecor) package is
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)
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
OS and window system.
GLFW supports compilation with Visual C++ (2013 and later), GCC and Clang. Both
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
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
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
- [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
find that tool.
The documentation is generated with [Doxygen](https://doxygen.org/) when the
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
@ -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
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)
- Removed support for building with original MinGW (#2540)
- [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)
{
int n = 0;
nk_rune *dst;
nk_byte *dst;
const nk_byte *src;
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);
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;
for (n = (int)(img_width * img_height); n > 0; n--)
*dst++ = ((nk_rune)(*src++) << 24) | 0x00FFFFFF;
for (n = (int)(img_width * img_height); n > 0; n--) {
*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_)
#include <process.h>
#include <sys/timeb.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#endif
/* Standard, good-to-have defines */
@ -60,6 +62,8 @@ int mtx_init(mtx_t *mtx, int type)
mtx->mRecursive = type & mtx_recursive;
InitializeCriticalSection(&mtx->mHandle);
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
int ret;
pthread_mutexattr_t attr;
@ -78,6 +82,7 @@ void mtx_destroy(mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
DeleteCriticalSection(&mtx->mHandle);
#elif defined(_TTHREAD_OGC_)
#else
pthread_mutex_destroy(mtx);
#endif
@ -93,6 +98,8 @@ int mtx_lock(mtx_t *mtx)
mtx->mAlreadyLocked = TRUE;
}
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error;
#endif
@ -116,6 +123,8 @@ int mtx_trylock(mtx_t *mtx)
ret = thrd_busy;
}
return ret;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy;
#endif
@ -127,6 +136,8 @@ int mtx_unlock(mtx_t *mtx)
mtx->mAlreadyLocked = FALSE;
LeaveCriticalSection(&mtx->mHandle);
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;;
#endif
@ -161,6 +172,8 @@ int cnd_init(cnd_t *cond)
}
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error;
#endif
@ -178,6 +191,7 @@ void cnd_destroy(cnd_t *cond)
CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]);
}
DeleteCriticalSection(&cond->mWaitersCountLock);
#elif defined(_TTHREAD_OGC_)
#else
pthread_cond_destroy(cond);
#endif
@ -203,6 +217,8 @@ int cnd_signal(cnd_t *cond)
}
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif
@ -228,6 +244,8 @@ int cnd_broadcast(cnd_t *cond)
}
return thrd_success;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error;
#endif
@ -286,6 +304,8 @@ int cnd_wait(cnd_t *cond, mtx_t *mtx)
{
#if defined(_TTHREAD_WIN32_)
return _cnd_timedwait_win32(cond, mtx, INFINITE);
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error;
#endif
@ -303,6 +323,8 @@ int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts)
}
else
return thrd_error;
#elif defined(_TTHREAD_OGC_)
return thrd_error;
#else
int ret;
ret = pthread_cond_timedwait(cond, mtx, ts);
@ -324,14 +346,14 @@ typedef struct {
/* Thread wrapper function. */
#if defined(_TTHREAD_WIN32_)
static unsigned WINAPI _thrd_wrapper_function(void * aArg)
#elif defined(_TTHREAD_POSIX_)
#else
static void * _thrd_wrapper_function(void * aArg)
#endif
{
thrd_start_t fun;
void *arg;
int res;
#if defined(_TTHREAD_POSIX_)
#if defined(_TTHREAD_POSIX_) || defined(_TTHREAD_OGC_)
void *pres;
#endif
@ -394,6 +416,8 @@ thrd_t thrd_current(void)
{
#if defined(_TTHREAD_WIN32_)
return GetCurrentThread();
#elif defined(_TTHREAD_OGC_)
return LWP_GetSelf();
#else
return pthread_self();
#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(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__)
#define _TTHREAD_WIN32_
#elif defined(GEKKO)
#define _TTHREAD_OGC_
#else
#define _TTHREAD_POSIX_
#endif
@ -80,6 +82,8 @@ freely, subject to the following restrictions:
#if defined(_TTHREAD_POSIX_)
#include <sys/time.h>
#include <pthread.h>
#elif defined(_TTHREAD_OGC_)
#include <ogcsys.h>
#elif defined(_TTHREAD_WIN32_)
#ifndef 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 */
#if defined(_TTHREAD_WIN32_)
typedef HANDLE thrd_t;
#elif defined(_TTHREAD_OGC_)
typedef lwp_t thrd_t;
#else
typedef pthread_t thrd_t;
#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
# (i.e. Pages) list in the generated documentation
set(source_files
@ -32,10 +36,10 @@ foreach(file IN LISTS source_files)
endforeach()
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")
message(STATUS "Documentation generation requires Doxygen 1.9.8 or later")
if (NOT DOXYGEN_FOUND)
message(STATUS "Documentation generation requires Doxygen ${MINIMUM_DOXYGEN_VERSION} or later")
else()
configure_file(Doxyfile.in Doxyfile @ONLY)
add_custom_command(OUTPUT "html/index.html"
@ -46,7 +50,7 @@ else()
COMMENT "Generating HTML documentation"
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")
if (GLFW_INSTALL)

View File

@ -278,13 +278,7 @@ ALIASES = "thread_safety=@par Thread safety^^" \
"analysis=@par Analysis^^" \
"reentrancy=@par Reentrancy^^" \
"errors=@par Errors^^" \
"callback_signature=@par Callback signature^^" \
"glfw3=__GLFW 3:__" \
"x11=__X11:__" \
"wayland=__Wayland:__" \
"win32=__Windows:__" \
"macos=__macOS:__" \
"linux=__Linux:__"
"callback_signature=@par Callback signature^^"
# 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

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
additional copying may be performed for each buffer swap of full screen windows.
GLFW uses the [clipboard manager protocol][ClipboardManager] to push a clipboard
string (i.e. selection) owned by a GLFW window about to be destroyed to the
clipboard manager. If there is no running clipboard manager, the clipboard
string will be unavailable once the window has been destroyed.
GLFW uses the [clipboard manager protocol][ClipboardManager] to keep the
clipboard string availble for the user after the libary has been terminated. If
there is no running clipboard manager and the clipboard contents has been set
with @ref glfwSetClipboardString, the clipboard will be emptied when the library
is terminated.
[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
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
main menu and dock icon can be disabled with the @ref GLFW_COCOA_MENUBAR init
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
produce the default (usually sRGB-like) behavior.
@note @wayland An application cannot read or modify the monitor gamma ramp. The
@ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
@note __Wayland:__ An application cannot read or modify the monitor gamma ramp.
The @ref glfwGetGammaRamp, @ref glfwSetGammaRamp and @ref glfwSetGamma functions
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
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}
## Deprecations {#deprecations}
@ -39,6 +52,10 @@ actively maintained and available on many platforms.
### New functions {#new_functions}
- @ref glfwGetEGLConfig
- @ref glfwGetGLXFBConfig
### New types {#new_types}
### 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
`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.
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);
```
@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
[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
`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
`VK_KHR_portability_enumeration` instance extension and set the
`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
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.
@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
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
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
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.
@ -893,7 +893,7 @@ int 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
window hints are ignored. The @ref glfwGetWindowPos and @ref glfwSetWindowPos
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);
```
@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
function can only restore windows from maximization and the iconify callback
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(windows WIN32 MACOSX_BUNDLE windows.c ${ICON} ${GLAD_GL})
target_link_libraries(particles Threads::Threads)
if (Threads_FOUND)
target_link_libraries(particles Threads::Threads)
endif()
if (RT_LIBRARY)
target_link_libraries(particles "${RT_LIBRARY}")
endif()

View File

@ -1228,13 +1228,13 @@ extern "C" {
* The top-left to bottom-right diagonal resize/move shape. This is usually
* 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.
*
* @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.
*
* @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.
*/
#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
* 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.
*
* @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.
*
* @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.
*/
#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
* 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.
*
* @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.
*/
#define GLFW_NOT_ALLOWED_CURSOR 0x0003600A
@ -1342,6 +1342,7 @@ extern "C" {
#define GLFW_PLATFORM_WAYLAND 0x00060003
#define GLFW_PLATFORM_X11 0x00060004
#define GLFW_PLATFORM_NULL 0x00060005
#define GLFW_PLATFORM_OGC 0x00060006
/*! @} */
#define GLFW_DONT_CARE -1
@ -1629,7 +1630,7 @@ typedef void (* GLFWwindowposfun)(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSizeCallback
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1649,7 +1650,7 @@ typedef void (* GLFWwindowsizefun)(GLFWwindow* window, int width, int height);
* @sa @ref glfwSetWindowCloseCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1669,7 +1670,7 @@ typedef void (* GLFWwindowclosefun)(GLFWwindow* window);
* @sa @ref glfwSetWindowRefreshCallback
*
* @since Added in version 2.5.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -1800,7 +1801,7 @@ typedef void (* GLFWwindowcontentscalefun)(GLFWwindow* window, float xscale, flo
* @sa @ref glfwSetMouseButtonCallback
*
* @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
*/
@ -1891,7 +1892,7 @@ typedef void (* GLFWscrollfun)(GLFWwindow* window, double xoffset, double yoffse
* @sa @ref glfwSetKeyCallback
*
* @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
*/
@ -1912,7 +1913,7 @@ typedef void (* GLFWkeyfun)(GLFWwindow* window, int key, int scancode, int actio
* @sa @ref glfwSetCharCallback
*
* @since Added in version 2.4.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -2020,7 +2021,7 @@ typedef void (* GLFWjoystickfun)(int jid, int event);
* @sa @ref glfwGetVideoModes
*
* @since Added in version 1.0.
* @glfw3 Added refresh rate member.
* __GLFW 3:__ Added refresh rate member.
*
* @ingroup monitor
*/
@ -2083,7 +2084,7 @@ typedef struct GLFWgammaramp
* @sa @ref window_icon
*
* @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
*/
@ -2183,12 +2184,12 @@ typedef struct GLFWallocator
* @errors Possible errors include @ref GLFW_PLATFORM_UNAVAILABLE and @ref
* 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
* bundle, if present. This can be disabled with the @ref
* 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
* 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
@ -2203,7 +2204,7 @@ typedef struct GLFWallocator
* to something other than `wayland` or `x11`, the regular detection mechanism
* 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
* 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.
*
* @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.
*
* @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
* 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.
*
* @thread_safety This function must only be called from the main thread.
@ -2861,7 +2862,7 @@ GLFWAPI GLFWmonitorfun glfwSetMonitorCallback(GLFWmonitorfun callback);
* @sa @ref glfwGetVideoMode
*
* @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
*/
@ -2915,7 +2916,7 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref GLFW_INVALID_VALUE,
* @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.
*
* @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
* 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
* 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
* 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.
*
* @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_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.
*
* @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,
* the `IDI_APPLICATION` icon will be used instead. To set a different icon,
* 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.
*
* @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
* 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
* 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.
* For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
*
* [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
* Retina displays unless the
* @remark __macOS:__ The window frame will not be rendered at full resolution
* on Retina displays unless the
* [GLFW_SCALE_FRAMEBUFFER](@ref GLFW_SCALE_FRAMEBUFFER_hint)
* hint is `GLFW_TRUE` and the `NSHighResolutionCapable` key is enabled in the
* 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
*
* @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
* 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
* and provides high quality client-side decorations on compositors like GNOME.
* 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
*
* @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.
*
* @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
* query the final size, position or other attributes directly after window
* 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
* 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
@ -3349,7 +3350,7 @@ GLFWAPI const char* glfwGetWindowTitle(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* 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.
*
* @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
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @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
* 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
* the application bundle's icon. For more information on bundles, see the
* [Bundle Programming Guide][bundle-guide] in the Mac Developer Library.
*
* [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.
* 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
* 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
* 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
* 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
* GLFW_FEATURE_UNAVAILABLE.
*
@ -3474,7 +3475,7 @@ GLFWAPI void glfwGetWindowPos(GLFWwindow* window, int* xpos, int* ypos);
* @sa @ref glfwGetWindowPos
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3504,7 +3505,7 @@ GLFWAPI void glfwSetWindowPos(GLFWwindow* window, int xpos, int ypos);
* @sa @ref glfwSetWindowSize
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @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
* 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.
*
* @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
* 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.
*
* @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
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3778,7 +3779,7 @@ GLFWAPI float glfwGetWindowOpacity(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* 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.
*
* @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
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3834,9 +3835,9 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* GLFW_PLATFORM_ERROR.
*
* @remark @wayland Restoring a window from maximization is not currently part
* of any common Wayland protocol, so this function can only restore windows
* from maximization.
* @remark __Wayland:__ Restoring a window from maximization is not currently
* part of any common Wayland protocol, so this function can only restore
* windows from maximization.
*
* @thread_safety This function must only be called from the main thread.
*
@ -3845,7 +3846,7 @@ GLFWAPI void glfwIconifyWindow(GLFWwindow* window);
* @sa @ref glfwMaximizeWindow
*
* @since Added in version 2.1.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -3892,7 +3893,7 @@ GLFWAPI void glfwMaximizeWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* 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.
* Instead it will become visible the next time the window framebuffer is
* updated after this call.
@ -3955,7 +3956,7 @@ GLFWAPI void glfwHideWindow(GLFWwindow* window);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref
* 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.
*
* @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
* 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.
*
* @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
* 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.
*
* @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
* 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
* 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
* 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.
*
* @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.
*
* @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.
*
* @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
*
* @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
*/
@ -4291,7 +4292,7 @@ GLFWAPI GLFWwindowsizefun glfwSetWindowSizeCallback(GLFWwindow* window, GLFWwind
*
* @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.
*
* @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
*
* @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
*/
@ -4335,7 +4336,7 @@ GLFWAPI GLFWwindowclosefun glfwSetWindowCloseCallback(GLFWwindow* window, GLFWwi
* @sa @ref window_refresh
*
* @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
*/
@ -4396,7 +4397,7 @@ GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwi
*
* @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
* check whether a window is currently iconified.
*
@ -4905,7 +4906,7 @@ GLFWAPI int glfwGetKeyScancode(int key);
* @sa @ref input_key
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -4937,7 +4938,7 @@ GLFWAPI int glfwGetKey(GLFWwindow* window, int key);
* @sa @ref input_mouse_button
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup input
*/
@ -5007,7 +5008,7 @@ GLFWAPI void glfwGetCursorPos(GLFWwindow* window, double* xpos, double* ypos);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* 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.
*
* @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
*
* @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
*/
@ -5248,7 +5249,7 @@ GLFWAPI GLFWkeyfun glfwSetKeyCallback(GLFWwindow* window, GLFWkeyfun callback);
* @sa @ref input_char
*
* @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
*/
@ -5332,7 +5333,7 @@ GLFWAPI GLFWcharmodsfun glfwSetCharModsCallback(GLFWwindow* window, GLFWcharmods
* @sa @ref input_mouse_button
*
* @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
*/
@ -5562,7 +5563,7 @@ GLFWAPI const float* glfwGetJoystickAxes(int jid, int* count);
* @sa @ref joystick_button
*
* @since Added in version 2.2.
* @glfw3 Changed to return a dynamic array.
* __GLFW 3:__ Changed to return a dynamic array.
*
* @ingroup input
*/
@ -5926,7 +5927,7 @@ GLFWAPI int glfwGetGamepadState(int jid, GLFWgamepadstate* state);
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED 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
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* 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
* 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
* cannot acquire the lock then this function emits @ref GLFW_PLATFORM_ERROR and returns.
* It is safe to try this multiple times.
@ -6176,7 +6177,7 @@ GLFWAPI GLFWwindow* glfwGetCurrentContext(void);
* @sa @ref glfwSwapInterval
*
* @since Added in version 1.0.
* @glfw3 Added window handle parameter.
* __GLFW 3:__ Added window handle parameter.
*
* @ingroup window
*/
@ -6443,7 +6444,7 @@ GLFWAPI GLFWvkproc glfwGetInstanceProcAddress(VkInstance instance, const char* p
* @errors Possible errors include @ref GLFW_NOT_INITIALIZED, @ref
* 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
* a `vkGetPhysicalDevice*PresentationSupport` type function.
*
@ -6501,15 +6502,15 @@ GLFWAPI int glfwGetPhysicalDevicePresentationSupport(VkInstance instance, VkPhys
* @ref glfwVulkanSupported and @ref glfwGetRequiredInstanceExtensions should
* 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
* extension, if any, is included in the array returned by @ref
* 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.
*
* @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
* `VK_KHR_xlib_surface` the preferred extension by setting the
* [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
*/
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
#if defined(GLFW_EXPOSE_NATIVE_WAYLAND)
@ -586,6 +609,29 @@ GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
* @ingroup native
*/
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
#if defined(GLFW_EXPOSE_NATIVE_OSMESA)

View File

@ -15,6 +15,9 @@ if (APPLE)
elseif (WIN32)
target_sources(glfw PRIVATE win32_time.h win32_thread.h win32_module.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()
target_sources(glfw PRIVATE posix_time.h posix_thread.h posix_module.c
posix_time.c posix_thread.c)
@ -57,6 +60,13 @@ if (GLFW_BUILD_WAYLAND)
wl_monitor.c wl_window.c)
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 (CMAKE_SYSTEM_NAME STREQUAL "Linux")
target_sources(glfw PRIVATE linux_joystick.h linux_joystick.c)
@ -136,7 +146,9 @@ target_include_directories(glfw PUBLIC
target_include_directories(glfw PRIVATE
"${GLFW_SOURCE_DIR}/src"
"${GLFW_BINARY_DIR}/src")
target_link_libraries(glfw PRIVATE Threads::Threads)
if (Threads_FOUND)
target_link_libraries(glfw PRIVATE Threads::Threads)
endif()
if (GLFW_BUILD_WIN32)
list(APPEND glfw_PKG_LIBS "-lgdi32")
@ -213,6 +225,13 @@ if (GLFW_BUILD_X11)
target_include_directories(glfw PRIVATE "${X11_Xshape_INCLUDE_PATH}")
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)
find_library(RT_LIBRARY rt)
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 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 setAcceptsMouseMovedEvents:YES];
[window->ns.object setRestorable:NO];

View File

@ -939,10 +939,32 @@ GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* handle)
window->context.source != GLFW_NATIVE_CONTEXT_API)
{
_glfwInputError(GLFW_NO_WINDOW_CONTEXT, NULL);
return EGL_NO_CONTEXT;
return EGL_NO_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;
}
window->context.glx.fbconfig = native;
window->context.makeCurrent = makeContextCurrentGLX;
window->context.swapBuffers = swapBuffersGLX;
window->context.swapInterval = swapIntervalGLX;
@ -719,5 +721,29 @@ GLFWAPI GLXWindow glfwGetGLXWindow(GLFWwindow* handle)
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

View File

@ -402,7 +402,6 @@ struct _GLFWwndconfig
int ypos;
int width;
int height;
const char* title;
GLFWbool resizable;
GLFWbool visible;
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,",
"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
#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)
@GLFW_LINUX_MAPPINGS@
#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)
{ GLFW_PLATFORM_X11, _glfwConnectX11 },
#endif
#if defined(_GLFW_OGC)
{ GLFW_PLATFORM_OGC, _glfwConnectOgc },
#endif
};
GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
@ -68,6 +71,7 @@ GLFWbool _glfwSelectPlatform(int desiredID, _GLFWplatform* platform)
desiredID != GLFW_PLATFORM_COCOA &&
desiredID != GLFW_PLATFORM_WAYLAND &&
desiredID != GLFW_PLATFORM_X11 &&
desiredID != GLFW_PLATFORM_OGC &&
desiredID != GLFW_PLATFORM_NULL)
{
_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_THREAD) || \
defined(GLFW_BUILD_COCOA_TIMER) || \
defined(GLFW_BUILD_OGC_MODULE) || \
defined(GLFW_BUILD_OGC_THREAD) || \
defined(GLFW_BUILD_POSIX_TIMER) || \
defined(GLFW_BUILD_POSIX_MODULE) || \
defined(GLFW_BUILD_POSIX_THREAD) || \
@ -90,6 +92,16 @@
#define GLFW_GLX_LIBRARY_CONTEXT_STATE
#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"
#if defined(_GLFW_WIN32)
@ -106,6 +118,13 @@
#define GLFW_COCOA_LIBRARY_JOYSTICK_STATE
#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__)
#define GLFW_BUILD_LINUX_JOYSTICK
#endif
@ -123,6 +142,7 @@
GLFW_WAYLAND_WINDOW_STATE \
GLFW_X11_WINDOW_STATE \
GLFW_NULL_WINDOW_STATE \
GLFW_OGC_WINDOW_STATE \
#define GLFW_PLATFORM_MONITOR_STATE \
GLFW_WIN32_MONITOR_STATE \
@ -130,6 +150,7 @@
GLFW_WAYLAND_MONITOR_STATE \
GLFW_X11_MONITOR_STATE \
GLFW_NULL_MONITOR_STATE \
GLFW_OGC_MONITOR_STATE \
#define GLFW_PLATFORM_CURSOR_STATE \
GLFW_WIN32_CURSOR_STATE \
@ -137,11 +158,13 @@
GLFW_WAYLAND_CURSOR_STATE \
GLFW_X11_CURSOR_STATE \
GLFW_NULL_CURSOR_STATE \
GLFW_OGC_CURSOR_STATE \
#define GLFW_PLATFORM_JOYSTICK_STATE \
GLFW_WIN32_JOYSTICK_STATE \
GLFW_COCOA_JOYSTICK_STATE \
GLFW_LINUX_JOYSTICK_STATE
GLFW_LINUX_JOYSTICK_STATE \
GLFW_OGC_JOYSTICK_STATE \
#define GLFW_PLATFORM_LIBRARY_WINDOW_STATE \
GLFW_WIN32_LIBRARY_WINDOW_STATE \
@ -149,11 +172,13 @@
GLFW_WAYLAND_LIBRARY_WINDOW_STATE \
GLFW_X11_LIBRARY_WINDOW_STATE \
GLFW_NULL_LIBRARY_WINDOW_STATE \
GLFW_OGC_LIBRARY_WINDOW_STATE \
#define GLFW_PLATFORM_LIBRARY_JOYSTICK_STATE \
GLFW_WIN32_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 \
GLFW_WGL_CONTEXT_STATE \
@ -167,6 +192,8 @@
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_THREAD
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_THREAD
#else
#define GLFW_BUILD_POSIX_THREAD
#endif
@ -179,12 +206,18 @@
#include "posix_thread.h"
#define GLFW_PLATFORM_TLS_STATE GLFW_POSIX_TLS_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
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_TIMER
#elif defined(__APPLE__)
#define GLFW_BUILD_COCOA_TIMER
#elif defined(_GLFW_OGC)
#define GLFW_BUILD_OGC_TIMER
#else
#define GLFW_BUILD_POSIX_TIMER
#endif
@ -198,10 +231,15 @@
#elif defined(GLFW_BUILD_POSIX_TIMER)
#include "posix_time.h"
#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
#if defined(_WIN32)
#define GLFW_BUILD_WIN32_MODULE
#elif defined(__wii__) || defined(__gamecube)
#define GLFW_BUILD_OGC_MODULE
#else
#define GLFW_BUILD_POSIX_MODULE
#endif

View File

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

View File

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

View File

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

View File

@ -754,13 +754,13 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
const char* resourceName = getenv("RESOURCE_NAME");
if (resourceName && strlen(resourceName))
hint->res_name = (char*) resourceName;
else if (strlen(wndconfig->title))
hint->res_name = (char*) wndconfig->title;
else if (strlen(window->title))
hint->res_name = (char*) window->title;
else
hint->res_name = (char*) "glfw-application";
if (strlen(wndconfig->title))
hint->res_class = (char*) wndconfig->title;
if (strlen(window->title))
hint->res_class = (char*) window->title;
else
hint->res_class = (char*) "GLFW-Application";
}
@ -780,7 +780,7 @@ static GLFWbool createNativeWindow(_GLFWwindow* window,
if (_glfw.x11.im)
_glfwCreateInputContextX11(window);
_glfwSetWindowTitleX11(window, wndconfig->title);
_glfwSetWindowTitleX11(window, window->title);
_glfwGetWindowPosX11(window, &window->x11.xpos, &window->x11.ypos);
_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(window WIN32 MACOSX_BUNDLE window.c ${GLAD_GL})
target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads)
if (Threads_FOUND)
target_link_libraries(empty Threads::Threads)
target_link_libraries(threads Threads::Threads)
endif()
if (RT_LIBRARY)
target_link_libraries(empty "${RT_LIBRARY}")
target_link_libraries(threads "${RT_LIBRARY}")