aboutsummaryrefslogtreecommitdiffstats
path: root/pugl
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-03-07 14:39:41 +0100
committerDavid Robillard <d@drobilla.net>2020-03-07 14:39:41 +0100
commitc0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d (patch)
tree039210592cf10344c050303eddcbbcef68216f83 /pugl
parentb0b4c5603986d025d1b4d6b340cea942e3ccff3c (diff)
downloadpugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.tar.gz
pugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.tar.bz2
pugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.zip
Improve documentation
Diffstat (limited to 'pugl')
-rw-r--r--pugl/pugl.h266
1 files changed, 184 insertions, 82 deletions
diff --git a/pugl/pugl.h b/pugl/pugl.h
index 17df6ea..3b156ed 100644
--- a/pugl/pugl.h
+++ b/pugl/pugl.h
@@ -87,16 +87,18 @@ typedef enum {
typedef uint32_t PuglMods;
/**
- Special keyboard keys.
+ Keyboard key codepoints.
- All keys, special or not, are expressed as a Unicode code point. This
+ All keys are identified by a Unicode code point in PuglEventKey::key. This
enumeration defines constants for special keys that do not have a standard
- code point, and some convenience constants for control characters.
+ 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.
+ 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
@@ -212,7 +214,12 @@ typedef struct {
} PuglEventButton;
/**
- Configure event for when window size or position has changed.
+ Window resize or move event.
+
+ A configure event is sent whenever the window 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
@@ -225,6 +232,10 @@ typedef struct {
/**
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
@@ -238,6 +249,9 @@ typedef struct {
/**
Window close event.
+
+ This event is sent when the window is to be closed, for example when the
+ user clicks the close button.
*/
typedef struct {
PuglEventType type; ///< #PUGL_CLOSE
@@ -245,16 +259,21 @@ typedef struct {
} PuglEventClose;
/**
- Key press/release event.
+ Key press or 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.
+ 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 as Unicode code points, using the "natural" code point
- for the key wherever possible (see #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).
+ 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
@@ -272,8 +291,13 @@ typedef struct {
/**
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.
+ 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
@@ -290,7 +314,11 @@ typedef struct {
} PuglEventText;
/**
- Pointer crossing event (enter and leave).
+ 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_ENTER_NOTIFY or #PUGL_LEAVE_NOTIFY
@@ -324,7 +352,7 @@ typedef struct {
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` =
+ 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.
@@ -344,6 +372,9 @@ typedef struct {
/**
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
@@ -352,11 +383,11 @@ typedef struct {
} PuglEventFocus;
/**
- Interface event.
+ View event.
- This is a union of all event structs. 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.
+ 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.
*/
typedef union {
PuglEventAny any; ///< Valid for all event types
@@ -399,25 +430,31 @@ puglStrerror(PuglStatus status);
/**
@anchor world
@name World
- The top level context of a Pugl application.
+
+ 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 things that are not associated with a particular view.
- Several worlds can be created in a process (which is the case when many
- plugins use Pugl, for example), but code using different worlds must be
- isolated so they are never mixed. Views are strongly associated with the
- world they were created for.
+ 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;
/**
Create a new world.
- @return A newly created world.
+ @return A new world, which must be later freed with puglFreeWorld().
*/
PUGL_API PuglWorld*
puglNewWorld(void);
@@ -431,9 +468,10 @@ puglFreeWorld(PuglWorld* world);
/**
Return a pointer to the native handle of the world.
- On X11, this returns a pointer to the Display.
- On OSX, this returns NULL.
- On Windows, this returns a handle to the calling process module.
+ @return
+ - X11: A pointer to the `Display`.
+ - MacOS: `NULL`.
+ - Windows: The `HMODULE` of the calling process.
*/
PUGL_API void*
puglGetNativeWorld(PuglWorld* world);
@@ -463,13 +501,15 @@ puglGetTime(const PuglWorld* world);
/**
Poll for events that are ready to be processed.
- This polls for events that are ready for any view in the application,
- potentially blocking depending on `timeout`.
+ 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 world The world for all the views to poll.
@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.
+
+ @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if not, or an error.
*/
PUGL_API PuglStatus
puglPollEvents(PuglWorld* world, double timeout);
@@ -479,7 +519,7 @@ puglPollEvents(PuglWorld* world, double timeout);
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 it will return
+ function does not block, if no events are pending then it will return
immediately.
*/
PUGL_API PuglStatus
@@ -489,27 +529,43 @@ puglDispatchEvents(PuglWorld* world);
@}
@anchor view
@name View
- A view is a drawing region that receives events, which may correspond to a
- top-level window or be embedded in some other window.
+
+ 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 Pugl view.
+ A drawable region that receives events.
*/
typedef struct PuglViewImpl PuglView;
/**
- Graphics backend interface.
+ 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 window handle.
- On X11, this is a Window.
- On OSX, this is an NSView*.
- On Windows, this is a HWND.
+ X11: This is a `Window`.
+
+ MacOS: This is a pointer to an `NSView*`.
+
+ Windows: This is a `HWND`.
*/
typedef uintptr_t PuglNativeWindow;
@@ -519,7 +575,7 @@ typedef uintptr_t PuglNativeWindow;
typedef void* PuglHandle;
/**
- Window hint.
+ A hint for configuring a view.
*/
typedef enum {
PUGL_USE_COMPAT_PROFILE, ///< Use compatible (not core) OpenGL profile
@@ -542,7 +598,7 @@ typedef enum {
} PuglViewHint;
/**
- Special window hint value.
+ A special view hint value.
*/
typedef enum {
PUGL_DONT_CARE = -1, ///< Use best available value
@@ -558,8 +614,8 @@ typedef PuglStatus (*PuglEventFunc)(PuglView* view, const PuglEvent* event);
/**
Create a new view.
- A view represents a window, but a window will not be shown until configured
- with the various puglInit functions and shown with puglShowWindow().
+ A newly created view does not correspond to a real system view or window.
+ It must first be configured, then be realised by calling puglCreateWindow().
*/
PUGL_API PuglView*
puglNewView(PuglWorld* world);
@@ -577,27 +633,38 @@ PUGL_API PuglWorld*
puglGetWorld(PuglView* view);
/**
- Set the handle to be passed to all callbacks.
+ 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.
- This is generally a pointer to a struct which contains all necessary state.
- Everything needed in callbacks should be 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 handle to be passed to all callbacks.
+ Get the user data for a view.
*/
PUGL_API PuglHandle
puglGetHandle(PuglView* view);
/**
- Set the graphics backend to use.
+ Set the graphics backend to use for a view.
+
+ This must be called once to set the graphics backend before calling
+ puglCreateWindow().
- 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.h and
- pugl_cairo.h, respectively.
+ Pugl includes the following backends:
+
+ - puglGlBackend(), declared in pugl_gl.h
+ - puglCairoBackend(), declared in pugl_cairo.h
+
+ 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);
@@ -626,12 +693,16 @@ puglSetViewHint(PuglView* view, PuglViewHint hint, int value);
/**
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.
*/
PUGL_API PuglStatus
puglSetFrame(PuglView* view, PuglRect frame);
@@ -639,7 +710,9 @@ puglSetFrame(PuglView* view, PuglRect frame);
/**
Set the minimum size of the view.
- To avoid stutter, this should be called before creating the window.
+ If an initial minimum size is known, this should be called before
+ puglCreateWindow() to avoid stutter, though it can be called afterwards as
+ well.
*/
PUGL_API PuglStatus
puglSetMinSize(PuglView* view, int width, int height);
@@ -653,6 +726,10 @@ puglSetMinSize(PuglView* view, int width, int height);
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.
+
+ If an initial aspect ratio is known, this should be called before
+ puglCreateWindow() to avoid stutter, though it can be called afterwards as
+ well.
*/
PUGL_API PuglStatus
puglSetAspectRatio(PuglView* view, int minX, int minY, int maxX, int maxY);
@@ -675,10 +752,9 @@ PUGL_API PuglStatus
puglSetWindowTitle(PuglView* view, const char* title);
/**
- Set the parent window before creating a window (for embedding).
+ Set the parent window for embedding a view in an existing window.
- This only works when called before creating the window with
- puglCreateWindow(), reparenting is not supported.
+ This must be called before puglCreateWindow(), reparenting is not supported.
*/
PUGL_API PuglStatus
puglSetParentWindow(PuglView* view, PuglNativeWindow parent);
@@ -686,22 +762,27 @@ puglSetParentWindow(PuglView* view, PuglNativeWindow parent);
/**
Set the transient parent of the window.
- This is used for things like dialogs, to have them associated with the
- window they are a transient child of properly.
+ Set this for transient children like dialogs, to have them properly
+ associated with their parent window. This should be called before
+ puglCreateWindow().
*/
PUGL_API PuglStatus
puglSetTransientFor(PuglView* view, PuglNativeWindow parent);
/**
- Create a window with the settings given by the various puglInit functions.
+ Realise a view by creating a corresponding system view or window.
- @return 1 (pugl does not currently support multiple windows).
+ 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
puglCreateWindow(PuglView* view, const char* title);
/**
Show the current window.
+
+ If the window is currently hidden, it will be shown and possibly raised to
+ the top depending on the platform.
*/
PUGL_API PuglStatus
puglShowWindow(PuglView* view);
@@ -732,22 +813,28 @@ puglGetNativeWindow(PuglView* view);
*/
/**
- Get the drawing context.
+ Get the graphics context.
- The context is only guaranteed to be available during an expose.
+ This is a backend-specific context used for drawing if the backend graphics
+ API requires one. It is only available during an expose.
- For OpenGL backends, this is unused and returns NULL.
- For Cairo backends, this returns a pointer to a `cairo_t`.
+ @return
+ - OpenGL: `NULL`.
+ - Cairo: A pointer to a
+ [`cairo_t`](http://www.cairographics.org/manual/cairo-cairo-t.html).
*/
PUGL_API void*
puglGetContext(PuglView* view);
/**
- Enter the drawing context.
+ Enter the graphics context.
+
+ Note that, unlike some similar libraries, Pugl automatically enters and
+ leaves the graphics context when required and application should not
+ normally do this. Drawing in Pugl is only allowed during the processing 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
+ However, this can be used to enter the graphics context elsewhere, for example
to call any GL functions during setup.
@param view The view being entered.
@@ -757,7 +844,7 @@ PUGL_API PuglStatus
puglEnterContext(PuglView* view, bool drawing);
/**
- Leave the drawing context.
+ Leave the graphics context.
This must be called after puglEnterContext() with a matching `drawing`
parameter.
@@ -770,12 +857,21 @@ puglLeaveContext(PuglView* view, bool drawing);
/**
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);
@@ -784,27 +880,30 @@ puglPostRedisplayRect(PuglView* view, PuglRect rect);
@}
@anchor interaction
@name Interaction
- Interacting with the system and user with events.
+ Functions for interacting with the user.
@{
*/
/**
- Grab the input focus.
+ Grab the keyboard input focus.
*/
PUGL_API PuglStatus
puglGrabFocus(PuglView* view);
/**
- Return true iff `view` has the input focus.
+ Return whether `view` has the keyboard input focus.
*/
PUGL_API bool
puglHasFocus(const PuglView* view);
/**
- Set clipboard contents.
+ 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 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).
*/
@@ -815,7 +914,10 @@ puglSetClipboard(PuglView* view,
size_t len);
/**
- Get clipboard contents.
+ 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[out] type Set to the MIME type of the data.
@@ -830,7 +932,7 @@ puglGetClipboard(PuglView* view, const char** type, size_t* len);
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.
+ something like a flashing task bar entry or bouncing application icon.
*/
PUGL_API PuglStatus
puglRequestAttention(PuglView* view);