aboutsummaryrefslogtreecommitdiff
path: root/pugl/pugl/pugl.h
diff options
context:
space:
mode:
Diffstat (limited to 'pugl/pugl/pugl.h')
-rw-r--r--pugl/pugl/pugl.h279
1 files changed, 184 insertions, 95 deletions
diff --git a/pugl/pugl/pugl.h b/pugl/pugl/pugl.h
index dbbad90..d04f1aa 100644
--- a/pugl/pugl/pugl.h
+++ b/pugl/pugl/pugl.h
@@ -1,5 +1,5 @@
/*
- Copyright 2012-2016 David Robillard <http://drobilla.net>
+ Copyright 2012-2019 David Robillard <http://drobilla.net>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -15,12 +15,13 @@
*/
/**
- @file pugl.h API for Pugl, a minimal portable API for OpenGL.
+ @file pugl.h Public Pugl API.
*/
#ifndef PUGL_H_INCLUDED
#define PUGL_H_INCLUDED
+#include <stdbool.h>
#include <stdint.h>
#ifdef PUGL_SHARED
@@ -40,10 +41,16 @@
# define PUGL_API
#endif
+#if defined(__clang__)
+# define PUGL_DEPRECATED_BY(name) __attribute__((deprecated("", name)))
+#elif defined(__GNUC__)
+# define PUGL_DEPRECATED_BY(name) __attribute__((deprecated("Use " name)))
+#else
+# define PUGL_DEPRECATED_BY(name)
+#endif
+
#ifdef __cplusplus
extern "C" {
-#else
-# include <stdbool.h>
#endif
/**
@@ -58,6 +65,11 @@ extern "C" {
typedef struct PuglViewImpl PuglView;
/**
+ Graphics backend interface.
+*/
+typedef struct PuglBackendImpl PuglBackend;
+
+/**
A native window handle.
On X11, this is a Window.
@@ -75,26 +87,39 @@ typedef void* PuglHandle;
Return status code.
*/
typedef enum {
- PUGL_SUCCESS = 0
+ PUGL_SUCCESS,
+ PUGL_ERR_CREATE_WINDOW,
+ PUGL_ERR_SET_FORMAT,
+ PUGL_ERR_CREATE_CONTEXT,
} PuglStatus;
/**
- Drawing context type.
+ Window hint.
*/
typedef enum {
- PUGL_GL = 0x1,
- PUGL_CAIRO = 0x2,
- PUGL_CAIRO_GL = 0x3
-} PuglContextType;
-
-/**
- Convenience symbols for ASCII control characters.
+ PUGL_USE_COMPAT_PROFILE, /**< Use compatible (not core) OpenGL profile */
+ 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_RESIZABLE, /**< True if window should be resizable */
+ PUGL_IGNORE_KEY_REPEAT, /**< True if key repeat events are ignored */
+} PuglWindowHint;
+
+/**
+ Special window hint value.
*/
typedef enum {
- PUGL_CHAR_BACKSPACE = 0x08,
- PUGL_CHAR_ESCAPE = 0x1B,
- PUGL_CHAR_DELETE = 0x7F
-} PuglChar;
+ PUGL_DONT_CARE = -1, /**< Use best available value */
+ PUGL_FALSE = 0, /**< Explicitly false */
+ PUGL_TRUE = 1 /**< Explicitly true */
+} PuglWindowHintValue;
/**
Keyboard modifier flags.
@@ -107,14 +132,24 @@ typedef enum {
} PuglMod;
/**
- Special (non-Unicode) keyboard keys.
+ Special keyboard keys.
+
+ All keys, special or not, are expressed as a Unicode code point. This
+ enumeration defines constants for special keys that do not have a standard
+ code point, and some convenience constants for control characters.
- The numerical values of these symbols occupy a reserved range of Unicode
- points, so it is possible to express either a PuglKey value or a Unicode
- character in the same variable. This is sometimes useful for interfacing
- with APIs that do not make this distinction.
+ 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,
@@ -137,9 +172,23 @@ typedef enum {
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_SUPER
+ 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;
/**
@@ -154,6 +203,7 @@ typedef enum {
PUGL_CLOSE, /**< Close view */
PUGL_KEY_PRESS, /**< Key press */
PUGL_KEY_RELEASE, /**< Key release */
+ PUGL_TEXT, /**< Character entry */
PUGL_ENTER_NOTIFY, /**< Pointer entered view */
PUGL_LEAVE_NOTIFY, /**< Pointer left view */
PUGL_MOTION_NOTIFY, /**< Pointer motion */
@@ -180,7 +230,6 @@ typedef enum {
*/
typedef struct {
PuglEventType type; /**< Event type. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
} PuglEventAny;
@@ -191,15 +240,14 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_BUTTON_PRESS or PUGL_BUTTON_RELEASE. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
+ double time; /**< Time in seconds. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
double x_root; /**< Root-relative X coordinate. */
double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- unsigned button; /**< 1-relative button number. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t button; /**< 1-relative button number. */
} PuglEventButton;
/**
@@ -207,7 +255,6 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_CONFIGURE. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
double x; /**< New parent-relative X coordinate. */
double y; /**< New parent-relative Y coordinate. */
@@ -220,7 +267,6 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_EXPOSE. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
@@ -234,61 +280,66 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_CLOSE. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
} PuglEventClose;
/**
Key press/release event.
- Keys that correspond to a Unicode character have `character` and `utf8` set.
- Other keys will have `character` 0, but `special` may be set if this is a
- known special key.
-
- A key press may be part of a multi-key sequence to generate a wide
- character. If `filter` is set, this event is part of a multi-key sequence
- and should be ignored if the application is reading textual input.
- Following the series of filtered press events, a press event with
- `character` and `utf8` (but `keycode` 0) will be sent. This event will have
- no corresponding release event.
+ This represents low-level key press and release events. This event type
+ should be used for "raw" keyboard handing (key bindings, for example), but
+ must not be interpreted as text input.
- Generally, an application should either work with raw keyboard press/release
- events based on `keycode` (ignoring events with `keycode` 0), or
- read textual input based on `character` or `utf8` (ignoring releases and
- events with `filter` 1). Note that blindly appending `utf8` will yield
- incorrect text, since press events are sent for both individually composed
- keys and the resulting synthetic multi-byte press.
+ Keys are represented as Unicode code points, using the "natural" code point
+ for the key wherever possible (see @ref PuglKey for details). The `key`
+ field will be set to the code for the pressed key, without any modifiers
+ applied (by the shift or control keys).
*/
typedef struct {
PuglEventType type; /**< PUGL_KEY_PRESS or PUGL_KEY_RELEASE. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
+ double time; /**< Time in seconds. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
double x_root; /**< Root-relative X coordinate. */
double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
- unsigned keycode; /**< Raw key code. */
- uint32_t character; /**< Unicode character code, or 0. */
- PuglKey special; /**< Special key, or 0. */
- uint8_t utf8[8]; /**< UTF-8 string. */
- bool filter; /**< True if part of a multi-key sequence. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t keycode; /**< Raw key code. */
+ uint32_t key; /**< Unshifted Unicode character code, or 0. */
} PuglEventKey;
/**
+ Character input event.
+
+ This 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.
+*/
+typedef struct {
+ PuglEventType type; /**< PUGL_CHAR. */
+ uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
+ double time; /**< Time in seconds. */
+ double x; /**< View-relative X coordinate. */
+ double y; /**< View-relative Y coordinate. */
+ double x_root; /**< Root-relative X coordinate. */
+ double y_root; /**< Root-relative Y coordinate. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t keycode; /**< Raw key code. */
+ uint32_t character; /**< Unicode character code */
+ char string[8]; /**< UTF-8 string. */
+} PuglEventText;
+
+/**
Pointer crossing event (enter and leave).
*/
typedef struct {
PuglEventType type; /**< PUGL_ENTER_NOTIFY or PUGL_LEAVE_NOTIFY. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
+ double time; /**< Time in seconds. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
double x_root; /**< Root-relative X coordinate. */
double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
PuglCrossingMode mode; /**< Reason for crossing. */
} PuglEventCrossing;
@@ -297,14 +348,13 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_MOTION_NOTIFY. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
+ double time; /**< Time in seconds. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
double x_root; /**< Root-relative X coordinate. */
double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
bool is_hint; /**< True iff this event is a motion hint. */
bool focus; /**< True iff this is the focused window. */
} PuglEventMotion;
@@ -320,14 +370,13 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_SCROLL. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
- uint32_t time; /**< Time in milliseconds. */
+ double time; /**< Time in seconds. */
double x; /**< View-relative X coordinate. */
double y; /**< View-relative Y coordinate. */
double x_root; /**< Root-relative X coordinate. */
double y_root; /**< Root-relative Y coordinate. */
- unsigned state; /**< Bitwise OR of PuglMod flags. */
+ uint32_t state; /**< Bitwise OR of PuglMod flags. */
double dx; /**< Scroll X distance in lines. */
double dy; /**< Scroll Y distance in lines. */
} PuglEventScroll;
@@ -337,7 +386,6 @@ typedef struct {
*/
typedef struct {
PuglEventType type; /**< PUGL_FOCUS_IN or PUGL_FOCUS_OUT. */
- PuglView* view; /**< View that received this event. */
uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */
bool grab; /**< True iff this is a grab/ungrab event. */
} PuglEventFocus;
@@ -357,6 +405,7 @@ typedef union {
PuglEventExpose expose; /**< PUGL_EXPOSE. */
PuglEventClose close; /**< PUGL_CLOSE. */
PuglEventKey key; /**< PUGL_KEY_PRESS, PUGL_KEY_RELEASE. */
+ PuglEventText text; /**< PUGL_TEXT. */
PuglEventCrossing crossing; /**< PUGL_ENTER_NOTIFY, PUGL_LEAVE_NOTIFY. */
PuglEventMotion motion; /**< PUGL_MOTION_NOTIFY. */
PuglEventScroll scroll; /**< PUGL_SCROLL. */
@@ -383,6 +432,12 @@ PUGL_API PuglView*
puglInit(int* pargc, char** argv);
/**
+ Set a hint before creating a window.
+*/
+PUGL_API void
+puglInitWindowHint(PuglView* view, PuglWindowHint hint, int value);
+
+/**
Set the window class name before creating a window.
*/
PUGL_API void
@@ -411,6 +466,10 @@ puglInitWindowMinSize(PuglView* view, int width, int height);
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
+ currenty work on MacOS (the minimum is used), so only setting a fixed aspect
+ ratio works properly across all platforms.
*/
PUGL_API void
puglInitWindowAspectRatio(PuglView* view,
@@ -421,8 +480,10 @@ puglInitWindowAspectRatio(PuglView* view,
/**
Enable or disable resizing before creating a window.
+
+ @deprecated Use puglInitWindowHint() with @ref PUGL_RESIZABLE.
*/
-PUGL_API void
+PUGL_API PUGL_DEPRECATED_BY("puglInitWindowHint") void
puglInitResizable(PuglView* view, bool resizable);
/**
@@ -435,16 +496,18 @@ PUGL_API void
puglInitTransientFor(PuglView* view, uintptr_t parent);
/**
- Set the context type before creating a window.
-*/
-PUGL_API void
-puglInitContextType(PuglView* view, PuglContextType type);
+ Set the graphics backend to use.
-/**
- @}
+ This needs to be called once before creating the window to set the graphics
+ backend. There are two backend accessors included with pugl:
+ puglGlBackend() and puglCairoBackend(), declared in pugl_gl_backend.h and
+ pugl_cairo_backend.h, respectively.
*/
+PUGL_API int
+puglInitBackend(PuglView* view, const PuglBackend* backend);
/**
+ @}
@name Windows
Functions for creating and managing a visible window for a view.
@{
@@ -516,37 +579,42 @@ puglGetSize(PuglView* view, int* width, int* height);
/**
Get the drawing context.
- For PUGL_GL contexts, this is unused and returns NULL.
- For PUGL_CAIRO contexts, this returns a pointer to a cairo_t.
+ The context is only guaranteed to be available during an expose.
+
+ For OpenGL backends, this is unused and returns NULL.
+ For Cairo backends, this returns a pointer to a `cairo_t`.
*/
PUGL_API void*
puglGetContext(PuglView* view);
-
/**
Enter the drawing context.
- This must be called before any code that accesses the drawing context,
- including any GL functions. This is only necessary for code that does so
- outside the usual draw callback or handling of an expose event.
+ Note that pugl automatically enters and leaves the drawing context during
+ configure and expose events, so it is not normally necessary to call this.
+ However, it can be used to enter the drawing context elsewhere, for example
+ to call any GL functions during setup.
+
+ @param view The view being entered.
+ @param drawing If true, prepare for drawing.
*/
PUGL_API void
-puglEnterContext(PuglView* view);
+puglEnterContext(PuglView* view, bool drawing);
/**
Leave the drawing context.
- This must be called after puglEnterContext and applies the results of the
- drawing code (for example, by swapping buffers).
+ This must be called after puglEnterContext() with a matching `drawing`
+ parameter.
+
+ @param view The view being left.
+ @param drawing If true, finish drawing, for example by swapping buffers.
*/
PUGL_API void
-puglLeaveContext(PuglView* view, bool flush);
+puglLeaveContext(PuglView* view, bool drawing);
/**
@}
-*/
-
-/**
@name Event Handling
@{
*/
@@ -564,27 +632,27 @@ puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc);
/**
Ignore synthetic repeated key events.
+
+ @deprecated Use puglInitWindowHint() with @ref PUGL_IGNORE_KEY_REPEAT.
*/
-PUGL_API void
+PUGL_API PUGL_DEPRECATED_BY("puglInitWindowHint") void
puglIgnoreKeyRepeat(PuglView* view, bool ignore);
/**
- Copy selection to clipboard.
+ Grab the input focus.
*/
PUGL_API void
-puglCopyToClipboard(PuglView* view, const char* selection, size_t len);
+puglGrabFocus(PuglView* view);
/**
- Paste selection from clipboard.
-*/
-PUGL_API const char*
-puglPasteFromClipboard(PuglView* view, size_t* len);
+ Request user attention.
-/**
- Grab the input focus.
+ 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 flashing a task bar entry.
*/
PUGL_API void
-puglGrabFocus(PuglView* view);
+puglRequestAttention(PuglView* view);
/**
Block and wait for an event to be ready.
@@ -612,6 +680,27 @@ puglProcessEvents(PuglView* view);
*/
/**
+ OpenGL extension function.
+*/
+typedef void (*PuglGlFunc)(void);
+
+/**
+ Return the address of an OpenGL extension function.
+*/
+PUGL_API PuglGlFunc
+puglGetProcAddress(const char* name);
+
+/**
+ 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(PuglView* view);
+
+/**
Request a redisplay on the next call to puglProcessEvents().
*/
PUGL_API void