diff options
author | David Robillard <d@drobilla.net> | 2020-03-07 14:39:41 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-03-07 14:39:41 +0100 |
commit | c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d (patch) | |
tree | 039210592cf10344c050303eddcbbcef68216f83 /pugl | |
parent | b0b4c5603986d025d1b4d6b340cea942e3ccff3c (diff) | |
download | pugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.tar.gz pugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.tar.bz2 pugl-c0c6e93c0c3702fdd7a3f9fb4927dd7f7271000d.zip |
Improve documentation
Diffstat (limited to 'pugl')
-rw-r--r-- | pugl/pugl.h | 266 |
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); |