Mercurial > hg > pub > prymula > com
diff DPF-Prymula-audioplugins/dpf/dgl/src/pugl-upstream/include/pugl/pugl.h @ 3:84e66ea83026
DPF-Prymula-audioplugins-0.231015-2
author | prymula <prymula76@outlook.com> |
---|---|
date | Mon, 16 Oct 2023 21:53:34 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/DPF-Prymula-audioplugins/dpf/dgl/src/pugl-upstream/include/pugl/pugl.h Mon Oct 16 21:53:34 2023 +0200 @@ -0,0 +1,1932 @@ +// Copyright 2012-2022 David Robillard <d@drobilla.net> +// SPDX-License-Identifier: ISC + +#ifndef PUGL_PUGL_H +#define PUGL_PUGL_H + +#include <stddef.h> +#include <stdint.h> + +#ifndef __cplusplus +# include <stdbool.h> +#endif + +#ifndef PUGL_API +# if defined(_WIN32) && !defined(PUGL_STATIC) && defined(PUGL_INTERNAL) +# define PUGL_API __declspec(dllexport) +# elif defined(_WIN32) && !defined(PUGL_STATIC) +# define PUGL_API __declspec(dllimport) +# elif defined(__GNUC__) +# define PUGL_API __attribute__((visibility("default"))) +# else +# define PUGL_API +# endif +#endif + +#ifndef PUGL_DISABLE_DEPRECATED +# if defined(__clang__) +# define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("", rep))) +# elif defined(__GNUC__) +# define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("Use " rep))) +# else +# define PUGL_DEPRECATED_BY(rep) +# endif +#endif + +#if defined(__GNUC__) +# define PUGL_CONST_FUNC __attribute__((const)) +#else +# define PUGL_CONST_FUNC +#endif + +#define PUGL_CONST_API \ + PUGL_API \ + PUGL_CONST_FUNC + +#define PUGL_BEGIN_DECLS +#define PUGL_END_DECLS + +PUGL_BEGIN_DECLS + +/** + @defgroup pugl Pugl C API + Pugl C API. + @{ +*/ + +/** + A pixel coordinate within/of a view. + + This is relative to the top left corner of the view's parent, or to the top + left corner of the view itself, depending on the context. + + There are platform-imposed limits on window positions. For portability, + applications should keep coordinates between -16000 and 16000. Note that + negative frame coordinates are possible, for example with multiple screens. +*/ +typedef int16_t PuglCoord; + +/** + A pixel span (width or height) within/of a view. + + Due to platform limits, the span of a view in either dimension should be + between 1 and 10000. +*/ +typedef uint16_t PuglSpan; + +/** + A rectangle in a view or on the screen. + + This type is used to describe two things: the position and size of a view + (for configuring), or a rectangle within a view (for exposing). + + The coordinate (0, 0) represents the top-left pixel of the parent window (or + display if there isn't one), or the top-left pixel of the view, + respectively. +*/ +typedef struct { + PuglCoord x; + PuglCoord y; + PuglSpan width; + PuglSpan height; +} PuglRect; + +/** + @defgroup events Events + + All updates to the view happen via events, which are dispatched to the + view's event function. Most events map directly to one from the underlying + window system, but some are constructed by Pugl itself so there is not + necessarily a direct correspondence. + + @{ +*/ + +/// Keyboard modifier flags +typedef enum { + PUGL_MOD_SHIFT = 1u << 0u, ///< Shift key + PUGL_MOD_CTRL = 1u << 1u, ///< Control key + PUGL_MOD_ALT = 1u << 2u, ///< Alt/Option key + PUGL_MOD_SUPER = 1u << 3u ///< Mod4/Command/Windows key +} PuglMod; + +/// Bitwise OR of #PuglMod values +typedef uint32_t PuglMods; + +/** + Keyboard key codepoints. + + All keys are identified by a Unicode code point in PuglKeyEvent::key. This + enumeration defines constants for special keys that do not have a standard + code point, and some convenience constants for control characters. Note + that all keys are handled in the same way, this enumeration is just for + convenience when writing hard-coded key bindings. + + Keys that do not have a standard code point use values in the Private Use + Area in the Basic Multilingual Plane (`U+E000` to `U+F8FF`). Applications + must take care to not interpret these values beyond key detection, the + mapping used here is arbitrary and specific to Pugl. +*/ +typedef enum { + // ASCII control codes + PUGL_KEY_BACKSPACE = 0x08, + PUGL_KEY_ESCAPE = 0x1B, + PUGL_KEY_DELETE = 0x7F, + + // Unicode Private Use Area + PUGL_KEY_F1 = 0xE000, + PUGL_KEY_F2, + PUGL_KEY_F3, + PUGL_KEY_F4, + PUGL_KEY_F5, + PUGL_KEY_F6, + PUGL_KEY_F7, + PUGL_KEY_F8, + PUGL_KEY_F9, + PUGL_KEY_F10, + PUGL_KEY_F11, + PUGL_KEY_F12, + PUGL_KEY_LEFT, + PUGL_KEY_UP, + PUGL_KEY_RIGHT, + PUGL_KEY_DOWN, + PUGL_KEY_PAGE_UP, + PUGL_KEY_PAGE_DOWN, + PUGL_KEY_HOME, + PUGL_KEY_END, + PUGL_KEY_INSERT, + PUGL_KEY_SHIFT, + PUGL_KEY_SHIFT_L = PUGL_KEY_SHIFT, + PUGL_KEY_SHIFT_R, + PUGL_KEY_CTRL, + PUGL_KEY_CTRL_L = PUGL_KEY_CTRL, + PUGL_KEY_CTRL_R, + PUGL_KEY_ALT, + PUGL_KEY_ALT_L = PUGL_KEY_ALT, + PUGL_KEY_ALT_R, + PUGL_KEY_SUPER, + PUGL_KEY_SUPER_L = PUGL_KEY_SUPER, + PUGL_KEY_SUPER_R, + PUGL_KEY_MENU, + PUGL_KEY_CAPS_LOCK, + PUGL_KEY_SCROLL_LOCK, + PUGL_KEY_NUM_LOCK, + PUGL_KEY_PRINT_SCREEN, + PUGL_KEY_PAUSE +} PuglKey; + +/// The type of a PuglEvent +typedef enum { + PUGL_NOTHING, ///< No event + PUGL_CREATE, ///< View created, a #PuglCreateEvent + PUGL_DESTROY, ///< View destroyed, a #PuglDestroyEvent + PUGL_CONFIGURE, ///< View moved/resized, a #PuglConfigureEvent + PUGL_MAP, ///< View made visible, a #PuglMapEvent + PUGL_UNMAP, ///< View made invisible, a #PuglUnmapEvent + PUGL_UPDATE, ///< View ready to draw, a #PuglUpdateEvent + PUGL_EXPOSE, ///< View must be drawn, a #PuglExposeEvent + PUGL_CLOSE, ///< View will be closed, a #PuglCloseEvent + PUGL_FOCUS_IN, ///< Keyboard focus entered view, a #PuglFocusEvent + PUGL_FOCUS_OUT, ///< Keyboard focus left view, a #PuglFocusEvent + PUGL_KEY_PRESS, ///< Key pressed, a #PuglKeyEvent + PUGL_KEY_RELEASE, ///< Key released, a #PuglKeyEvent + PUGL_TEXT, ///< Character entered, a #PuglTextEvent + PUGL_POINTER_IN, ///< Pointer entered view, a #PuglCrossingEvent + PUGL_POINTER_OUT, ///< Pointer left view, a #PuglCrossingEvent + PUGL_BUTTON_PRESS, ///< Mouse button pressed, a #PuglButtonEvent + PUGL_BUTTON_RELEASE, ///< Mouse button released, a #PuglButtonEvent + PUGL_MOTION, ///< Pointer moved, a #PuglMotionEvent + PUGL_SCROLL, ///< Scrolled, a #PuglScrollEvent + PUGL_CLIENT, ///< Custom client message, a #PuglClientEvent + PUGL_TIMER, ///< Timer triggered, a #PuglTimerEvent + PUGL_LOOP_ENTER, ///< Recursive loop entered, a #PuglLoopEnterEvent + PUGL_LOOP_LEAVE, ///< Recursive loop left, a #PuglLoopLeaveEvent + PUGL_DATA_OFFER, ///< Data offered from clipboard, a #PuglDataOfferEvent + PUGL_DATA, ///< Data available from clipboard, a #PuglDataEvent +} PuglEventType; + +/// Common flags for all event types +typedef enum { + PUGL_IS_SEND_EVENT = 1, ///< Event is synthetic + PUGL_IS_HINT = 2 ///< Event is a hint (not direct user input) +} PuglEventFlag; + +/// Bitwise OR of #PuglEventFlag values +typedef uint32_t PuglEventFlags; + +/// Reason for a PuglCrossingEvent +typedef enum { + PUGL_CROSSING_NORMAL, ///< Crossing due to pointer motion + PUGL_CROSSING_GRAB, ///< Crossing due to a grab + PUGL_CROSSING_UNGRAB ///< Crossing due to a grab release +} PuglCrossingMode; + +/** + Scroll direction. + + Describes the direction of a #PuglScrollEvent along with whether the scroll + is a "smooth" scroll. The discrete directions are for devices like mouse + wheels with constrained axes, while a smooth scroll is for those with + arbitrary scroll direction freedom, like some touchpads. +*/ +typedef enum { + PUGL_SCROLL_UP, ///< Scroll up + PUGL_SCROLL_DOWN, ///< Scroll down + PUGL_SCROLL_LEFT, ///< Scroll left + PUGL_SCROLL_RIGHT, ///< Scroll right + PUGL_SCROLL_SMOOTH ///< Smooth scroll in any direction +} PuglScrollDirection; + +/// Common header for all event structs +typedef struct { + PuglEventType type; ///< Event type + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values +} PuglAnyEvent; + +/** + View create event. + + This event is sent when a view is realized before it is first displayed, + with the graphics context entered. This is typically used for setting up + the graphics system, for example by loading OpenGL extensions. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglCreateEvent; + +/** + View destroy event. + + This event is the counterpart to #PuglCreateEvent, and it is sent when the + view is being destroyed. This is typically used for tearing down the + graphics system, or otherwise freeing any resources allocated when the + create event was handled. + + This is the last event sent to any view, and immediately after it is + processed, the view is destroyed and may no longer be used. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglDestroyEvent; + +/** + View resize or move event. + + A configure event is sent whenever the view is resized or moved. When a + configure event is received, the graphics context is active but not set up + for drawing. For example, it is valid to adjust the OpenGL viewport or + otherwise configure the context, but not to draw anything. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_CONFIGURE + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + PuglCoord x; ///< Parent-relative X coordinate of view + PuglCoord y; ///< Parent-relative Y coordinate of view + PuglSpan width; ///< Width of view + PuglSpan height; ///< Height of view +} PuglConfigureEvent; + +/** + View show event. + + This event is sent when a view is mapped to the screen and made visible. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglMapEvent; + +/** + View hide event. + + This event is sent when a view is unmapped from the screen and made + invisible. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglUnmapEvent; + +/** + View update event. + + This event is sent to every view near the end of a main loop iteration when + any pending exposures are about to be redrawn. It is typically used to mark + regions to expose with puglPostRedisplay() or puglPostRedisplayRect(). For + example, to continuously animate, a view calls puglPostRedisplay() when an + update event is received, and it will then shortly receive an expose event. +*/ +typedef PuglAnyEvent PuglUpdateEvent; + +/** + Expose event for when a region must be redrawn. + + When an expose event is received, the graphics context is active, and the + view must draw the entire specified region. The contents of the region are + undefined, there is no preservation of anything drawn previously. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_EXPOSE + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + PuglCoord x; ///< View-relative top-left X coordinate of region + PuglCoord y; ///< View-relative top-left Y coordinate of region + PuglSpan width; ///< Width of exposed region + PuglSpan height; ///< Height of exposed region +} PuglExposeEvent; + +/** + View close event. + + This event is sent when the view is to be closed, for example when the user + clicks the close button. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglCloseEvent; + +/** + Keyboard focus event. + + This event is sent whenever the view gains or loses the keyboard focus. The + view with the keyboard focus will receive any key press or release events. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_FOCUS_IN or #PUGL_FOCUS_OUT + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + PuglCrossingMode mode; ///< Reason for focus change +} PuglFocusEvent; + +/** + Key press or release event. + + This event represents low-level key presses and releases. This can be used + for "direct" keyboard handing like key bindings, but must not be interpreted + as text input. + + Keys are represented portably as Unicode code points, using the "natural" + code point for the key where possible (see #PuglKey for details). The `key` + field is the code for the pressed key, without any modifiers applied. For + example, a press or release of the 'A' key will have `key` 97 ('a') + regardless of whether shift or control are being held. + + Alternatively, the raw `keycode` can be used to work directly with physical + keys, but note that this value is not portable and differs between platforms + and hardware. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_KEY_PRESS or #PUGL_KEY_RELEASE + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + uint32_t keycode; ///< Raw key code + uint32_t key; ///< Unshifted Unicode character code, or 0 +} PuglKeyEvent; + +/** + Character input event. + + This event represents text input, usually as the result of a key press. The + text is given both as a Unicode character code and a UTF-8 string. + + Note that this event is generated by the platform's input system, so there + is not necessarily a direct correspondence between text events and physical + key presses. For example, with some input methods a sequence of several key + presses will generate a single character. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_TEXT + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + uint32_t keycode; ///< Raw key code + uint32_t character; ///< Unicode character code + char string[8]; ///< UTF-8 string +} PuglTextEvent; + +/** + Pointer enter or leave event. + + This event is sent when the pointer enters or leaves the view. This can + happen for several reasons (not just the user dragging the pointer over the + window edge), as described by the `mode` field. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_POINTER_IN or #PUGL_POINTER_OUT + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + PuglCrossingMode mode; ///< Reason for crossing +} PuglCrossingEvent; + +/** + Button press or release event. + + Button numbers start from 0, and are ordered: primary, secondary, middle. + So, on a typical right-handed mouse, the button numbers are: + + Left: 0 + Right: 1 + Middle (often a wheel): 2 + + Higher button numbers are reported in the same order they are represented on + the system. There is no universal standard here, but buttons 3 and 4 are + typically a pair of buttons or a rocker, which are usually bound to "back" + and "forward" operations. + + Note that these numbers may differ from those used on the underlying + platform, since they are manipulated to provide a consistent portable API. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_BUTTON_PRESS or #PUGL_BUTTON_RELEASE + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + uint32_t button; ///< Button number starting from 0 +} PuglButtonEvent; + +/** + Pointer motion event. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_MOTION + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags +} PuglMotionEvent; + +/** + Scroll event. + + The scroll distance is expressed in "lines", an arbitrary unit that + corresponds to a single tick of a detented mouse wheel. For example, `dy` = + 1.0 scrolls 1 line up. Some systems and devices support finer resolution + and/or higher values for fast scrolls, so programs should handle any value + gracefully. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_SCROLL + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + double x; ///< View-relative X coordinate + double y; ///< View-relative Y coordinate + double xRoot; ///< Root-relative X coordinate + double yRoot; ///< Root-relative Y coordinate + PuglMods state; ///< Bitwise OR of #PuglMod flags + PuglScrollDirection direction; ///< Scroll direction + double dx; ///< Scroll X distance in lines + double dy; ///< Scroll Y distance in lines +} PuglScrollEvent; + +/** + Custom client message event. + + This can be used to send a custom message to a view, which is delivered via + the window system and processed in the event loop as usual. Among other + things, this makes it possible to wake up the event loop for any reason. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_CLIENT + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + uintptr_t data1; ///< Client-specific data + uintptr_t data2; ///< Client-specific data +} PuglClientEvent; + +/** + Timer event. + + This event is sent at the regular interval specified in the call to + puglStartTimer() that activated it. + + The `id` is the application-specific ID given to puglStartTimer() which + distinguishes this timer from others. It should always be checked in the + event handler, even in applications that register only one timer. +*/ +typedef struct { + PuglEventType type; ///< #PUGL_TIMER + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + uintptr_t id; ///< Timer ID +} PuglTimerEvent; + +/** + Clipboard data offer event. + + This event is sent when a clipboard has data present, possibly with several + datatypes. While handling this event, the types can be investigated with + puglGetClipboardType() to decide whether to accept the offer with + puglAcceptOffer(). +*/ +typedef struct { + PuglEventType type; ///< #PUGL_DATA_OFFER + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds +} PuglDataOfferEvent; + +/** + Clipboard data event. + + This event is sent after accepting a data offer when the data has been + retrieved and converted. While handling this event, the data can be + accessed with puglGetClipboard(). +*/ +typedef struct { + PuglEventType type; ///< #PUGL_DATA + PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values + double time; ///< Time in seconds + uint32_t typeIndex; ///< Index of datatype +} PuglDataEvent; + +/** + Recursive loop enter event. + + This event is sent when the window system enters a recursive loop. The main + loop will be stalled and no expose events will be received while in the + recursive loop. To give the application full control, Pugl does not do any + special handling of this situation, but this event can be used to install a + timer to perform continuous actions (such as drawing) on platforms that do + this. + + - MacOS: A recursive loop is entered while the window is being live resized. + + - Windows: A recursive loop is entered while the window is being live + resized or the menu is shown. + + - X11: A recursive loop is never entered and the event loop runs as usual + while the view is being resized. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglLoopEnterEvent; + +/** + Recursive loop leave event. + + This event is sent after a loop enter event when the recursive loop is + finished and normal iteration will continue. + + This event type has no extra fields. +*/ +typedef PuglAnyEvent PuglLoopLeaveEvent; + +/** + View event. + + This is a union of all event types. The type must be checked to determine + which fields are safe to access. A pointer to PuglEvent can either be cast + to the appropriate type, or the union members used. + + The graphics system may only be accessed when handling certain events. The + graphics context is active for #PUGL_CREATE, #PUGL_DESTROY, #PUGL_CONFIGURE, + and #PUGL_EXPOSE, but only enabled for drawing for #PUGL_EXPOSE. +*/ +typedef union { + PuglAnyEvent any; ///< Valid for all event types + PuglEventType type; ///< Event type + PuglButtonEvent button; ///< #PUGL_BUTTON_PRESS, #PUGL_BUTTON_RELEASE + PuglConfigureEvent configure; ///< #PUGL_CONFIGURE + PuglExposeEvent expose; ///< #PUGL_EXPOSE + PuglKeyEvent key; ///< #PUGL_KEY_PRESS, #PUGL_KEY_RELEASE + PuglTextEvent text; ///< #PUGL_TEXT + PuglCrossingEvent crossing; ///< #PUGL_POINTER_IN, #PUGL_POINTER_OUT + PuglMotionEvent motion; ///< #PUGL_MOTION + PuglScrollEvent scroll; ///< #PUGL_SCROLL + PuglFocusEvent focus; ///< #PUGL_FOCUS_IN, #PUGL_FOCUS_OUT + PuglClientEvent client; ///< #PUGL_CLIENT + PuglTimerEvent timer; ///< #PUGL_TIMER + PuglDataOfferEvent offer; ///< #PUGL_DATA_OFFER + PuglDataEvent data; ///< #PUGL_DATA +} PuglEvent; + +/** + @} + @defgroup status Status + + Most functions return a status code which can be used to check for errors. + + @{ +*/ + +/// Return status code +typedef enum { + PUGL_SUCCESS, ///< Success + PUGL_FAILURE, ///< Non-fatal failure + PUGL_UNKNOWN_ERROR, ///< Unknown system error + PUGL_BAD_BACKEND, ///< Invalid or missing backend + PUGL_BAD_CONFIGURATION, ///< Invalid view configuration + PUGL_BAD_PARAMETER, ///< Invalid parameter + PUGL_BACKEND_FAILED, ///< Backend initialization failed + PUGL_REGISTRATION_FAILED, ///< Class registration failed + PUGL_REALIZE_FAILED, ///< System view realization failed + PUGL_SET_FORMAT_FAILED, ///< Failed to set pixel format + PUGL_CREATE_CONTEXT_FAILED, ///< Failed to create drawing context + PUGL_UNSUPPORTED, ///< Unsupported operation + PUGL_NO_MEMORY, ///< Failed to allocate memory +} PuglStatus; + +/// Return a string describing a status code +PUGL_CONST_API +const char* +puglStrerror(PuglStatus status); + +/** + @} + @defgroup world World + + The top-level context of a Pugl application or plugin. + + The world contains all library-wide state. There is no static data in Pugl, + so it is safe to use multiple worlds in a single process. This is to + facilitate plugins or other situations where it is not possible to share a + world, but a single world should be shared for all views where possible. + + @{ +*/ + +/** + The "world" of application state. + + The world represents everything that is not associated with a particular + view. Several worlds can be created in a single process, but code using + different worlds must be isolated so they are never mixed. Views are + strongly associated with the world they were created in. +*/ +typedef struct PuglWorldImpl PuglWorld; + +/// Handle for the world's opaque user data +typedef void* PuglWorldHandle; + +/// The type of a World +typedef enum { + PUGL_PROGRAM, ///< Top-level application + PUGL_MODULE ///< Plugin or module within a larger application +} PuglWorldType; + +/// World flags +typedef enum { + /** + Set up support for threads if necessary. + + X11: Calls XInitThreads() which is required for some drivers. + */ + PUGL_WORLD_THREADS = 1u << 0u +} PuglWorldFlag; + +/// Bitwise OR of #PuglWorldFlag values +typedef uint32_t PuglWorldFlags; + +/** + Create a new world. + + @param type The type, which dictates what this world is responsible for. + @param flags Flags to control world features. + @return A new world, which must be later freed with puglFreeWorld(). +*/ +PUGL_API +PuglWorld* +puglNewWorld(PuglWorldType type, PuglWorldFlags flags); + +/// Free a world allocated with puglNewWorld() +PUGL_API +void +puglFreeWorld(PuglWorld* world); + +/** + Set the user data for the world. + + This is usually a pointer to a struct that contains all the state which must + be accessed by several views. + + The handle is opaque to Pugl and is not interpreted in any way. +*/ +PUGL_API +void +puglSetWorldHandle(PuglWorld* world, PuglWorldHandle handle); + +/// Get the user data for the world +PUGL_API +PuglWorldHandle +puglGetWorldHandle(PuglWorld* world); + +/** + Return a pointer to the native handle of the world. + + X11: Returns a pointer to the `Display`. + + MacOS: Returns a pointer to the `NSApplication`. + + Windows: Returns the `HMODULE` of the calling process. +*/ +PUGL_API +void* +puglGetNativeWorld(PuglWorld* world); + +/** + Set the class name of the application. + + This is a stable identifier for the application, used as the window + class/instance name on X11 and Windows. It is not displayed to the user, + but can be used in scripts and by window managers, so it should be the same + for every instance of the application, but different from other + applications. +*/ +PUGL_API +PuglStatus +puglSetClassName(PuglWorld* world, const char* name); + +/// Get the class name of the application, or null +PUGL_API +const char* +puglGetClassName(const PuglWorld* world); + +/** + Return the time in seconds. + + This is a monotonically increasing clock with high resolution. The returned + time is only useful to compare against other times returned by this + function, its absolute value has no meaning. +*/ +PUGL_API +double +puglGetTime(const PuglWorld* world); + +/** + Update by processing events from the window system. + + This function is a single iteration of the main loop, and should be called + repeatedly to update all views. + + If `timeout` is zero, then this function will not block. Plugins should + always use a timeout of zero to avoid blocking the host. + + If a positive `timeout` is given, then events will be processed for that + amount of time, starting from when this function was called. + + If a negative `timeout` is given, this function will block indefinitely + until an event occurs. + + For continuously animating programs, a timeout that is a reasonable fraction + of the ideal frame period should be used, to minimize input latency by + ensuring that as many input events are consumed as possible before drawing. + + @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if no events are + read, or an error. +*/ +PUGL_API +PuglStatus +puglUpdate(PuglWorld* world, double timeout); + +/** + @} + @defgroup view View + + A drawable region that receives events. + + A view can be thought of as a window, but does not necessarily correspond to + a top-level window in a desktop environment. For example, a view can be + embedded in some other window, or represent an embedded system where there + is no concept of multiple windows at all. + + @{ +*/ + +/// A drawable region that receives events +typedef struct PuglViewImpl PuglView; + +/** + A graphics backend. + + The backend dictates how graphics are set up for a view, and how drawing is + performed. A backend must be set by calling puglSetBackend() before + realising a view. + + If you are using a local copy of Pugl, it is possible to implement a custom + backend. See the definition of `PuglBackendImpl` in the source code for + details. +*/ +typedef struct PuglBackendImpl PuglBackend; + +/** + A native view handle. + + X11: This is a `Window`. + + MacOS: This is a pointer to an `NSView*`. + + Windows: This is a `HWND`. +*/ +typedef uintptr_t PuglNativeView; + +/// Handle for a view's opaque user data +typedef void* PuglHandle; + +/// A hint for configuring a view +typedef enum { + PUGL_USE_COMPAT_PROFILE, ///< Use compatible (not core) OpenGL profile + PUGL_USE_DEBUG_CONTEXT, ///< True to use a debug OpenGL context + PUGL_CONTEXT_VERSION_MAJOR, ///< OpenGL context major version + PUGL_CONTEXT_VERSION_MINOR, ///< OpenGL context minor version + PUGL_RED_BITS, ///< Number of bits for red channel + PUGL_GREEN_BITS, ///< Number of bits for green channel + PUGL_BLUE_BITS, ///< Number of bits for blue channel + PUGL_ALPHA_BITS, ///< Number of bits for alpha channel + PUGL_DEPTH_BITS, ///< Number of bits for depth buffer + PUGL_STENCIL_BITS, ///< Number of bits for stencil buffer + PUGL_SAMPLES, ///< Number of samples per pixel (AA) + PUGL_DOUBLE_BUFFER, ///< True if double buffering should be used + PUGL_SWAP_INTERVAL, ///< Number of frames between buffer swaps + PUGL_RESIZABLE, ///< True if view should be resizable + PUGL_IGNORE_KEY_REPEAT, ///< True if key repeat events are ignored + PUGL_REFRESH_RATE, ///< Refresh rate in Hz +} PuglViewHint; + +/// The number of #PuglViewHint values +#define PUGL_NUM_VIEW_HINTS ((unsigned)PUGL_REFRESH_RATE + 1u) + +/// A special view hint value +typedef enum { + PUGL_DONT_CARE = -1, ///< Use best available value + PUGL_FALSE = 0, ///< Explicitly false + PUGL_TRUE = 1 ///< Explicitly true +} PuglViewHintValue; + +/** + A hint for configuring/constraining the size of a view. + + The system will attempt to make the view's window adhere to these, but they + are suggestions, not hard constraints. Applications should handle any view + size gracefully. +*/ +typedef enum { + PUGL_DEFAULT_SIZE, ///< Default size + PUGL_MIN_SIZE, ///< Minimum size + PUGL_MAX_SIZE, ///< Maximum size + + /** + Fixed aspect ratio. + + If set, the view's size should be constrained to this aspect ratio. + Mutually exclusive with #PUGL_MIN_ASPECT and #PUGL_MAX_ASPECT. + */ + PUGL_FIXED_ASPECT, + + /** + Minimum aspect ratio. + + If set, the view's size should be constrained to an aspect ratio no lower + than this. Mutually exclusive with #PUGL_FIXED_ASPECT. + */ + PUGL_MIN_ASPECT, + + /** + Maximum aspect ratio. + + If set, the view's size should be constrained to an aspect ratio no higher + than this. Mutually exclusive with #PUGL_FIXED_ASPECT. + */ + PUGL_MAX_ASPECT +} PuglSizeHint; + +/// The number of #PuglSizeHint values +#define PUGL_NUM_SIZE_HINTS ((unsigned)PUGL_MAX_ASPECT + 1u) + +/// A function called when an event occurs +typedef PuglStatus (*PuglEventFunc)(PuglView* view, const PuglEvent* event); + +/** + @defgroup setup Setup + Functions for creating and destroying a view. + @{ +*/ + +/** + Create a new view. + + A newly created view does not correspond to a real system view or window. + It must first be configured, then the system view can be created with + puglRealize(). +*/ +PUGL_API +PuglView* +puglNewView(PuglWorld* world); + +/// Free a view created with puglNewView() +PUGL_API +void +puglFreeView(PuglView* view); + +/// Return the world that `view` is a part of +PUGL_API +PuglWorld* +puglGetWorld(PuglView* view); + +/** + Set the user data for a view. + + This is usually a pointer to a struct that contains all the state which must + be accessed by a view. Everything needed to process events should be stored + here, not in static variables. + + The handle is opaque to Pugl and is not interpreted in any way. +*/ +PUGL_API +void +puglSetHandle(PuglView* view, PuglHandle handle); + +/// Get the user data for a view +PUGL_API +PuglHandle +puglGetHandle(PuglView* view); + +/** + Set the graphics backend to use for a view. + + This must be called once to set the graphics backend before calling + puglRealize(). + + Pugl includes the following backends: + + - puglCairoBackend() + - puglGlBackend() + - puglVulkanBackend() + + Note that backends are modular and not compiled into the main Pugl library + to avoid unnecessary dependencies. To use a particular backend, + applications must link against the appropriate backend library, or be sure + to compile in the appropriate code if using a local copy of Pugl. +*/ +PUGL_API +PuglStatus +puglSetBackend(PuglView* view, const PuglBackend* backend); + +/// Return the graphics backend used by a view +const PuglBackend* +puglGetBackend(const PuglView* view); + +/// Set the function to call when an event occurs +PUGL_API +PuglStatus +puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc); + +/** + Set a hint to configure view properties. + + This only has an effect when called before puglRealize(). +*/ +PUGL_API +PuglStatus +puglSetViewHint(PuglView* view, PuglViewHint hint, int value); + +/** + Get the value for a view hint. + + If the view has been realized, this can be used to get the actual value of a + hint which was initially set to PUGL_DONT_CARE, or has been adjusted from + the suggested value. +*/ +PUGL_API +int +puglGetViewHint(const PuglView* view, PuglViewHint hint); + +/** + Return the scale factor of the view. + + This factor describe how large UI elements (especially text) should be + compared to "normal". For example, 2.0 means the UI should be drawn twice + as large. + + "Normal" is loosely defined, but means a good size on a "standard DPI" + display (around 96 DPI). In other words, the scale 1.0 should have text + that is reasonably sized on a 96 DPI display, and the scale 2.0 should have + text twice that large. +*/ +PUGL_API +double +puglGetScaleFactor(const PuglView* view); + +/** + @} + @defgroup frame Frame + Functions for working with the position and size of a view. + @{ +*/ + +/** + Get the current position and size of the view. + + The position is in screen coordinates with an upper left origin. +*/ +PUGL_API +PuglRect +puglGetFrame(const PuglView* view); + +/** + Set the current position and size of the view. + + The position is in screen coordinates with an upper left origin. + + @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is + unchanged. +*/ +PUGL_API +PuglStatus +puglSetFrame(PuglView* view, PuglRect frame); + +/** + Set the current position of the view. + + @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is + unchanged. +*/ +PUGL_API +PuglStatus +puglSetPosition(PuglView* view, int x, int y); + +/** + Set the current size of the view. + + @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is + unchanged. +*/ +PUGL_API +PuglStatus +puglSetSize(PuglView* view, unsigned width, unsigned height); + +/** + Set a size hint for the view. + + This can be used to set the default, minimum, and maximum size of a view, + as well as the supported range of aspect ratios. + + This should be called before puglRealize() so the initial window for the + view can be configured correctly. + + @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is + not yet realized. +*/ +PUGL_API +PuglStatus +puglSetSizeHint(PuglView* view, + PuglSizeHint hint, + PuglSpan width, + PuglSpan height); + +/** + @} + @defgroup window Window + Functions to control the top-level window of a view. + @{ +*/ + +/** + Set the title of the window. + + This only makes sense for non-embedded views that will have a corresponding + top-level window, and sets the title, typically displayed in the title bar + or in window switchers. +*/ +PUGL_API +PuglStatus +puglSetWindowTitle(PuglView* view, const char* title); + +/// Return the title of the window, or null +PUGL_API +const char* +puglGetWindowTitle(const PuglView* view); + +/** + Set the parent window for embedding a view in an existing window. + + This must be called before puglRealize(), reparenting is not supported. +*/ +PUGL_API +PuglStatus +puglSetParentWindow(PuglView* view, PuglNativeView parent); + +/// Return the parent window this view is embedded in, or null +PUGL_API +PuglNativeView +puglGetParentWindow(const PuglView* view); + +/** + Set the transient parent of the window. + + Set this for transient children like dialogs, to have them properly + associated with their parent window. This should be called before + puglRealize(). + + A view can either have a parent (for embedding) or a transient parent (for + top-level windows like dialogs), but not both. +*/ +PUGL_API +PuglStatus +puglSetTransientParent(PuglView* view, PuglNativeView parent); + +/** + Return the transient parent of the window. + + @return The native handle to the window this view is a transient child of, + or null. +*/ +PUGL_API +PuglNativeView +puglGetTransientParent(const PuglView* view); + +/** + Realize a view by creating a corresponding system view or window. + + After this call, the (initially invisible) underlying system view exists and + can be accessed with puglGetNativeView(). There is currently no + corresponding unrealize function, the system view will be destroyed along + with the view when puglFreeView() is called. + + The view should be fully configured using the above functions before this is + called. This function may only be called once per view. +*/ +PUGL_API +PuglStatus +puglRealize(PuglView* view); + +/** + Show the view. + + If the view has not yet been realized, the first call to this function will + do so automatically. + + If the view is currently hidden, it will be shown and possibly raised to the + top depending on the platform. +*/ +PUGL_API +PuglStatus +puglShow(PuglView* view); + +/// Hide the current window +PUGL_API +PuglStatus +puglHide(PuglView* view); + +/// Return true iff the view is currently visible +PUGL_API +bool +puglGetVisible(const PuglView* view); + +/// Return the native window handle +PUGL_API +PuglNativeView +puglGetNativeView(PuglView* view); + +/** + @} + @defgroup graphics Graphics + Functions for working with the graphics context and scheduling redisplays. + @{ +*/ + +/** + Get the graphics context. + + This is a backend-specific context used for drawing if the backend graphics + API requires one. It is only available during an expose. + + Cairo: Returns a pointer to a + [cairo_t](http://www.cairographics.org/manual/cairo-cairo-t.html). + + All other backends: returns null. +*/ +PUGL_API +void* +puglGetContext(PuglView* view); + +/** + Request a redisplay for the entire view. + + This will cause an expose event to be dispatched later. If called from + within the event handler, the expose should arrive at the end of the current + event loop iteration, though this is not strictly guaranteed on all + platforms. If called elsewhere, an expose will be enqueued to be processed + in the next event loop iteration. +*/ +PUGL_API +PuglStatus +puglPostRedisplay(PuglView* view); + +/** + Request a redisplay of the given rectangle within the view. + + This has the same semantics as puglPostRedisplay(), but allows giving a + precise region for redrawing only a portion of the view. +*/ +PUGL_API +PuglStatus +puglPostRedisplayRect(PuglView* view, PuglRect rect); + +/** + @} + @defgroup interaction Interaction + Functions for interacting with the user and window system. + @{ +*/ + +/** + A mouse cursor type. + + This is a portable subset of mouse cursors that exist on X11, MacOS, and + Windows. +*/ +typedef enum { + PUGL_CURSOR_ARROW, ///< Default pointing arrow + PUGL_CURSOR_CARET, ///< Caret (I-Beam) for text entry + PUGL_CURSOR_CROSSHAIR, ///< Cross-hair + PUGL_CURSOR_HAND, ///< Hand with a pointing finger + PUGL_CURSOR_NO, ///< Operation not allowed + PUGL_CURSOR_LEFT_RIGHT, ///< Left/right arrow for horizontal resize + PUGL_CURSOR_UP_DOWN, ///< Up/down arrow for vertical resize + PUGL_CURSOR_DIAGONAL, ///< Top-left to bottom-right arrow for diagonal resize + PUGL_CURSOR_ANTI_DIAGONAL, ///< Bottom-left to top-right arrow for diagonal resize +} PuglCursor; + +/// The number of #PuglCursor values +#define PUGL_NUM_CURSORS ((unsigned)PUGL_CURSOR_ANTI_DIAGONAL + 1u) + +/** + Grab the keyboard input focus. + + Note that this will fail if the view is not mapped and so should not, for + example, be called immediately after puglShow(). + + @return #PUGL_SUCCESS if the focus was successfully grabbed, or an error. +*/ +PUGL_API +PuglStatus +puglGrabFocus(PuglView* view); + +/// Return whether `view` has the keyboard input focus +PUGL_API +bool +puglHasFocus(const PuglView* view); + +/** + Request data from the general copy/paste clipboard. + + A #PUGL_DATA_OFFER event will be sent if data is available. +*/ +PUGL_API +PuglStatus +puglPaste(PuglView* view); + +/** + Return the number of types available for the data in a clipboard. + + Returns zero if the clipboard is empty. +*/ +PUGL_API +uint32_t +puglGetNumClipboardTypes(const PuglView* view); + +/** + Return the identifier of a type available in a clipboard. + + This is usually a MIME type, but may also be another platform-specific type + identifier. Applications must ignore any type they do not recognize. + + Returns null if `typeIndex` is out of bounds according to + puglGetNumClipboardTypes(). +*/ +PUGL_API +const char* +puglGetClipboardType(const PuglView* view, uint32_t typeIndex); + +/** + Accept data offered from a clipboard. + + To accept data, this must be called while handling a #PUGL_DATA_OFFER event. + Doing so will request the data from the source as the specified type. When + the data is available, a #PUGL_DATA event will be sent to the view which can + then retrieve the data with puglGetClipboard(). + + @param view The view. + + @param offer The data offer event. + + @param typeIndex The index of the type that the view will accept. This is + the `typeIndex` argument to the call of puglGetClipboardType() that returned + the accepted type. +*/ +PUGL_API +PuglStatus +puglAcceptOffer(PuglView* view, + const PuglDataOfferEvent* offer, + uint32_t typeIndex); + +/** + Set the clipboard contents. + + This sets the system clipboard contents, which can be retrieved with + puglGetClipboard() or pasted into other applications. + + @param view The view. + @param type The MIME type of the data, "text/plain" is assumed if `NULL`. + @param data The data to copy to the clipboard. + @param len The length of data in bytes (including terminator if necessary). +*/ +PUGL_API +PuglStatus +puglSetClipboard(PuglView* view, + const char* type, + const void* data, + size_t len); + +/** + Get the clipboard contents. + + This gets the system clipboard contents, which may have been set with + puglSetClipboard() or copied from another application. + + @param view The view. + @param typeIndex Index of the data type to get the item as. + @param[out] len Set to the length of the data in bytes. + @return The clipboard contents, or null. +*/ +PUGL_API +const void* +puglGetClipboard(PuglView* view, uint32_t typeIndex, size_t* len); + +/** + Set the mouse cursor. + + This changes the system cursor that is displayed when the pointer is inside + the view. May fail if setting the cursor is not supported on this system, + for example if compiled on X11 without Xcursor support. + + @return #PUGL_BAD_PARAMETER if the given cursor is invalid, + #PUGL_FAILURE if the cursor is known but loading it system fails. +*/ +PUGL_API +PuglStatus +puglSetCursor(PuglView* view, PuglCursor cursor); + +/** + Request user attention. + + This hints to the system that the window or application requires attention + from the user. The exact effect depends on the platform, but is usually + something like a flashing task bar entry or bouncing application icon. +*/ +PUGL_API +PuglStatus +puglRequestAttention(PuglView* view); + +/** + Activate a repeating timer event. + + This starts a timer which will send a #PuglTimerEvent to `view` every + `timeout` seconds. This can be used to perform some action in a view at a + regular interval with relatively low frequency. Note that the frequency of + timer events may be limited by how often puglUpdate() is called. + + If the given timer already exists, it is replaced. + + @param view The view to begin sending #PUGL_TIMER events to. + + @param id The identifier for this timer. This is an application-specific ID + that should be a low number, typically the value of a constant or `enum` + that starts from 0. There is a platform-specific limit to the number of + supported timers, and overhead associated with each, so applications should + create only a few timers and perform several tasks in one if necessary. + + @param timeout The period, in seconds, of this timer. This is not + guaranteed to have a resolution better than 10ms (the maximum timer + resolution on Windows) and may be rounded up if it is too short. On X11 and + MacOS, a resolution of about 1ms can usually be relied on. + + @return #PUGL_FAILURE if timers are not supported by the system, + #PUGL_UNKNOWN_ERROR if setting the timer failed. +*/ +PUGL_API +PuglStatus +puglStartTimer(PuglView* view, uintptr_t id, double timeout); + +/** + Stop an active timer. + + @param view The view that the timer is set for. + @param id The ID previously passed to puglStartTimer(). + + @return #PUGL_FAILURE if timers are not supported by this system, + #PUGL_UNKNOWN_ERROR if stopping the timer failed. +*/ +PUGL_API +PuglStatus +puglStopTimer(PuglView* view, uintptr_t id); + +/** + Send an event to a view via the window system. + + If supported, the event will be delivered to the view via the event loop + like other events. Note that this function only works for certain event + types. + + Currently, only #PUGL_CLIENT events are supported on all platforms. + + X11: A #PUGL_EXPOSE event can be sent, which is similar to calling + puglPostRedisplayRect(), but will always send a message to the X server, + even when called in an event handler. + + @return #PUGL_UNSUPPORTED if sending events of this type is not supported, + #PUGL_UNKNOWN_ERROR if sending the event failed. +*/ +PUGL_API +PuglStatus +puglSendEvent(PuglView* view, const PuglEvent* event); + +/** + @} +*/ + +#ifndef PUGL_DISABLE_DEPRECATED + +/** + @} + @defgroup deprecated Deprecated API + @{ +*/ + +PUGL_DEPRECATED_BY("PuglCreateEvent") +typedef PuglCreateEvent PuglEventCreate; + +PUGL_DEPRECATED_BY("PuglDestroyEvent") +typedef PuglDestroyEvent PuglEventDestroy; + +PUGL_DEPRECATED_BY("PuglConfigureEvent") +typedef PuglConfigureEvent PuglEventConfigure; + +PUGL_DEPRECATED_BY("PuglMapEvent") +typedef PuglMapEvent PuglEventMap; + +PUGL_DEPRECATED_BY("PuglUnmapEvent") +typedef PuglUnmapEvent PuglEventUnmap; + +PUGL_DEPRECATED_BY("PuglUpdateEvent") +typedef PuglUpdateEvent PuglEventUpdate; + +PUGL_DEPRECATED_BY("PuglExposeEvent") +typedef PuglExposeEvent PuglEventExpose; + +PUGL_DEPRECATED_BY("PuglCloseEvent") +typedef PuglCloseEvent PuglEventClose; + +PUGL_DEPRECATED_BY("PuglFocusEvent") +typedef PuglFocusEvent PuglEventFocus; + +PUGL_DEPRECATED_BY("PuglKeyEvent") +typedef PuglKeyEvent PuglEventKey; + +PUGL_DEPRECATED_BY("PuglTextEvent") +typedef PuglTextEvent PuglEventText; + +PUGL_DEPRECATED_BY("PuglCrossingEvent") +typedef PuglCrossingEvent PuglEventCrossing; + +PUGL_DEPRECATED_BY("PuglButtonEvent") +typedef PuglButtonEvent PuglEventButton; + +PUGL_DEPRECATED_BY("PuglMotionEvent") +typedef PuglMotionEvent PuglEventMotion; + +PUGL_DEPRECATED_BY("PuglScrollEvent") +typedef PuglScrollEvent PuglEventScroll; + +PUGL_DEPRECATED_BY("PuglClientEvent") +typedef PuglClientEvent PuglEventClient; + +PUGL_DEPRECATED_BY("PuglTimerEvent") +typedef PuglTimerEvent PuglEventTimer; + +PUGL_DEPRECATED_BY("PuglLoopEnterEvent") +typedef PuglLoopEnterEvent PuglEventLoopEnter; + +PUGL_DEPRECATED_BY("PuglLoopLeaveEvent") +typedef PuglLoopLeaveEvent PuglEventLoopLeave; + +/** + A native window handle. + + X11: This is a `Window`. + + MacOS: This is a pointer to an `NSView*`. + + Windows: This is a `HWND`. +*/ +PUGL_DEPRECATED_BY("PuglNativeView") +typedef uintptr_t PuglNativeWindow; + +/** + Create a Pugl application and view. + + To create a window, call the various puglInit* functions as necessary, then + call puglRealize(). + + @deprecated Use puglNewApp() and puglNewView(). + + @param pargc Pointer to argument count (currently unused). + @param argv Arguments (currently unused). + @return A newly created view. +*/ +static inline PUGL_DEPRECATED_BY("puglNewView") +PuglView* +puglInit(const int* pargc, char** argv) +{ + (void)pargc; + (void)argv; + + return puglNewView(puglNewWorld(PUGL_MODULE, 0)); +} + +/** + Destroy an app and view created with `puglInit()`. + + @deprecated Use puglFreeApp() and puglFreeView(). +*/ +static inline PUGL_DEPRECATED_BY("puglFreeView") +void +puglDestroy(PuglView* view) +{ + PuglWorld* const world = puglGetWorld(view); + + puglFreeView(view); + puglFreeWorld(world); +} + +/** + Set the window class name before creating a window. +*/ +static inline PUGL_DEPRECATED_BY("puglSetClassName") +void +puglInitWindowClass(PuglView* view, const char* name) +{ + puglSetClassName(puglGetWorld(view), name); +} + +/** + Set the window size before creating a window. + + @deprecated Use puglSetFrame(). +*/ +static inline PUGL_DEPRECATED_BY("puglSetFrame") +void +puglInitWindowSize(PuglView* view, int width, int height) +{ + PuglRect frame = puglGetFrame(view); + + frame.width = (PuglSpan)width; + frame.height = (PuglSpan)height; + + puglSetFrame(view, frame); +} + +/** + Set the minimum window size before creating a window. +*/ +static inline PUGL_DEPRECATED_BY("puglSetMinSize") +void +puglInitWindowMinSize(PuglView* view, int width, int height) +{ + puglSetSizeHint(view, PUGL_MIN_SIZE, (PuglSpan)width, (PuglSpan)height); +} + +/** + Set the window aspect ratio range before creating a window. + + The x and y values here represent a ratio of width to height. To set a + fixed aspect ratio, set the minimum and maximum values to the same ratio. + + Note that setting different minimum and maximum constraints does not + currently work on MacOS (the minimum is used), so only setting a fixed + aspect ratio works properly across all platforms. +*/ +static inline PUGL_DEPRECATED_BY("puglSetAspectRatio") +void +puglInitWindowAspectRatio(PuglView* view, + int minX, + int minY, + int maxX, + int maxY) +{ + puglSetSizeHint(view, PUGL_MIN_ASPECT, (PuglSpan)minX, (PuglSpan)minY); + puglSetSizeHint(view, PUGL_MAX_ASPECT, (PuglSpan)maxX, (PuglSpan)maxY); +} + +/** + Set transient parent before creating a window. + + On X11, parent must be a Window. + On OSX, parent must be an NSView*. +*/ +static inline PUGL_DEPRECATED_BY("puglSetTransientParent") +void +puglInitTransientFor(PuglView* view, uintptr_t parent) +{ + puglSetTransientParent(view, (PuglNativeWindow)parent); +} + +/** + Set transient parent before creating a window. + + @deprecated Use puglSetTransientParent(). +*/ +static inline PUGL_DEPRECATED_BY("puglSetTransientParent") +PuglStatus +puglSetTransientFor(PuglView* view, uintptr_t parent) +{ + return puglSetTransientParent(view, (PuglNativeWindow)parent); +} + +/** + Enable or disable resizing before creating a window. + + @deprecated Use puglSetViewHint() with #PUGL_RESIZABLE. +*/ +static inline PUGL_DEPRECATED_BY("puglSetViewHint") +void +puglInitResizable(PuglView* view, bool resizable) +{ + puglSetViewHint(view, PUGL_RESIZABLE, resizable); +} + +/** + Get the current size of the view. + + @deprecated Use puglGetFrame(). + +*/ +static inline PUGL_DEPRECATED_BY("puglGetFrame") +void +puglGetSize(PuglView* view, int* width, int* height) +{ + const PuglRect frame = puglGetFrame(view); + + *width = (int)frame.width; + *height = (int)frame.height; +} + +/** + Ignore synthetic repeated key events. + + @deprecated Use puglSetViewHint() with #PUGL_IGNORE_KEY_REPEAT. +*/ +static inline PUGL_DEPRECATED_BY("puglSetViewHint") +void +puglIgnoreKeyRepeat(PuglView* view, bool ignore) +{ + puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, ignore); +} + +/** + Set a hint before creating a window. + + @deprecated Use puglSetWindowHint(). +*/ +static inline PUGL_DEPRECATED_BY("puglSetViewHint") +void +puglInitWindowHint(PuglView* view, PuglViewHint hint, int value) +{ + puglSetViewHint(view, hint, value); +} + +/** + Set the parent window before creating a window (for embedding). + + @deprecated Use puglSetWindowParent(). +*/ +static inline PUGL_DEPRECATED_BY("puglSetParentWindow") +void +puglInitWindowParent(PuglView* view, PuglNativeWindow parent) +{ + puglSetParentWindow(view, parent); +} + +/** + Set the graphics backend to use. + + @deprecated Use puglSetBackend(). +*/ +static inline PUGL_DEPRECATED_BY("puglSetBackend") +int +puglInitBackend(PuglView* view, const PuglBackend* backend) +{ + return (int)puglSetBackend(view, backend); +} + +/** + Realize a view by creating a corresponding system view or window. + + The view should be fully configured using the above functions before this is + called. This function may only be called once per view. + + @deprecated Use puglRealize(), or just show the view. +*/ +static inline PUGL_DEPRECATED_BY("puglRealize") +PuglStatus +puglCreateWindow(PuglView* view, const char* title) +{ + puglSetWindowTitle(view, title); + return puglRealize(view); +} + +/** + Block and wait for an event to be ready. + + This can be used in a loop to only process events via puglProcessEvents when + necessary. This function will block indefinitely if no events are + available, so is not appropriate for use in programs that need to perform + regular updates (e.g. animation). + + @deprecated Use puglPollEvents(). +*/ +PUGL_API +PUGL_DEPRECATED_BY("puglPollEvents") +PuglStatus +puglWaitForEvent(PuglView* view); + +/** + Process all pending window events. + + This handles input events as well as rendering, so it should be called + regularly and rapidly enough to keep the UI responsive. This function does + not block if no events are pending. + + @deprecated Use puglDispatchEvents(). +*/ +PUGL_API +PUGL_DEPRECATED_BY("puglDispatchEvents") +PuglStatus +puglProcessEvents(PuglView* view); + +/** + Poll for events that are ready to be processed. + + This polls for events that are ready for any view in the world, potentially + blocking depending on `timeout`. + + @param world The world to poll for events. + + @param timeout Maximum time to wait, in seconds. If zero, the call returns + immediately, if negative, the call blocks indefinitely. + + @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if not, or an error. + + @deprecated Use puglUpdate(). +*/ +static inline PUGL_DEPRECATED_BY("puglUpdate") +PuglStatus +puglPollEvents(PuglWorld* world, double timeout) +{ + return puglUpdate(world, timeout); +} + +/** + Dispatch any pending events to views. + + This processes all pending events, dispatching them to the appropriate + views. View event handlers will be called in the scope of this call. This + function does not block, if no events are pending then it will return + immediately. + + @deprecated Use puglUpdate(). +*/ +static inline PUGL_DEPRECATED_BY("puglUpdate") +PuglStatus +puglDispatchEvents(PuglWorld* world) +{ + return puglUpdate(world, 0.0); +} + +static inline PUGL_DEPRECATED_BY("puglShow") +PuglStatus +puglShowWindow(PuglView* view) +{ + return puglShow(view); +} + +static inline PUGL_DEPRECATED_BY("puglHide") +PuglStatus +puglHideWindow(PuglView* view) +{ + return puglHide(view); +} + +/** + Set the default size of the view. + + This should be called before puglRealize() to set the default size of the + view, which will be the initial size of the window if this is a top level + view. + + @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is + not yet realized. +*/ +static inline PUGL_DEPRECATED_BY("puglSetSizeHint") +PuglStatus +puglSetDefaultSize(PuglView* view, int width, int height) +{ + return puglSetSizeHint( + view, PUGL_DEFAULT_SIZE, (PuglSpan)width, (PuglSpan)height); +} + +/** + Set the minimum size of the view. + + If an initial minimum size is known, this should be called before + puglRealize() to avoid stutter, though it can be called afterwards as well. + + @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is + not yet realized. +*/ +static inline PUGL_DEPRECATED_BY("puglSetSizeHint") +PuglStatus +puglSetMinSize(PuglView* view, int width, int height) +{ + return puglSetSizeHint( + view, PUGL_MIN_SIZE, (PuglSpan)width, (PuglSpan)height); +} + +/** + Set the maximum size of the view. + + If an initial maximum size is known, this should be called before + puglRealize() to avoid stutter, though it can be called afterwards as well. + + @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is + not yet realized. +*/ +static inline PUGL_DEPRECATED_BY("puglSetSizeHint") +PuglStatus +puglSetMaxSize(PuglView* view, int width, int height) +{ + return puglSetSizeHint( + view, PUGL_MAX_SIZE, (PuglSpan)width, (PuglSpan)height); +} + +/** + Set the view aspect ratio range. + + The x and y values here represent a ratio of width to height. To set a + fixed aspect ratio, set the minimum and maximum values to the same ratio. + + Note that setting different minimum and maximum constraints does not + currently work on MacOS (the minimum is used), so only setting a fixed + aspect ratio works properly across all platforms. + + If an initial aspect ratio is known, this should be called before + puglRealize() to avoid stutter, though it can be called afterwards as well. + + @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is + not yet realized. +*/ +static inline PUGL_DEPRECATED_BY("puglSetSizeHint") +PuglStatus +puglSetAspectRatio(PuglView* view, int minX, int minY, int maxX, int maxY) +{ + const PuglStatus st0 = + puglSetSizeHint(view, PUGL_MIN_ASPECT, (PuglSpan)minX, (PuglSpan)minY); + + const PuglStatus st1 = + puglSetSizeHint(view, PUGL_MAX_ASPECT, (PuglSpan)maxX, (PuglSpan)maxY); + + return st0 ? st0 : st1; +} + +/// Return the native window handle +static inline PUGL_DEPRECATED_BY("puglGetNativeView") +PuglNativeView +puglGetNativeWindow(PuglView* view) +{ + return puglGetNativeView(view); +} + +#endif // PUGL_DISABLE_DEPRECATED + +/** + @} + @} +*/ + +PUGL_END_DECLS + +#endif // PUGL_PUGL_H