1 /*
2   Copyright 2012-2020 David Robillard <d@drobilla.net>
3 
4   Permission to use, copy, modify, and/or distribute this software for any
5   purpose with or without fee is hereby granted, provided that the above
6   copyright notice and this permission notice appear in all copies.
7 
8   THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16 
17 #ifndef PUGL_PUGL_H
18 #define PUGL_PUGL_H
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #define PUGL_API
25 
26 #ifndef PUGL_DISABLE_DEPRECATED
27 #  if defined(__clang__)
28 #    define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("", rep)))
29 #  elif defined(__GNUC__)
30 #    define PUGL_DEPRECATED_BY(rep) __attribute__((deprecated("Use " rep)))
31 #  else
32 #    define PUGL_DEPRECATED_BY(rep)
33 #  endif
34 #endif
35 
36 #if defined(__GNUC__)
37 #  define PUGL_CONST_FUNC __attribute__((const))
38 #else
39 #  define PUGL_CONST_FUNC
40 #endif
41 
42 #define PUGL_CONST_API \
43   PUGL_API             \
44   PUGL_CONST_FUNC
45 
46 #ifdef __cplusplus
47 #  define PUGL_BEGIN_DECLS extern "C" {
48 #  define PUGL_END_DECLS }
49 #else
50 #  define PUGL_BEGIN_DECLS
51 #  define PUGL_END_DECLS
52 #endif
53 
54 PUGL_BEGIN_DECLS
55 
56 /**
57    @defgroup pugl Pugl C API
58    Pugl C API.
59    @{
60 */
61 
62 /**
63    A rectangle.
64 
65    This is used to describe things like view position and size.  Pugl generally
66    uses coordinates where the top left corner is 0,0.
67 */
68 typedef struct {
69   double x;
70   double y;
71   double width;
72   double height;
73 } PuglRect;
74 
75 /**
76    @defgroup events Events
77 
78    All updates to the view happen via events, which are dispatched to the
79    view's event function.  Most events map directly to one from the underlying
80    window system, but some are constructed by Pugl itself so there is not
81    necessarily a direct correspondence.
82 
83    @{
84 */
85 
86 /// Keyboard modifier flags
87 typedef enum {
88   PUGL_MOD_SHIFT = 1u << 0u, ///< Shift key
89   PUGL_MOD_CTRL  = 1u << 1u, ///< Control key
90   PUGL_MOD_ALT   = 1u << 2u, ///< Alt/Option key
91   PUGL_MOD_SUPER = 1u << 3u  ///< Mod4/Command/Windows key
92 } PuglMod;
93 
94 /// Bitwise OR of #PuglMod values
95 typedef uint32_t PuglMods;
96 
97 /**
98    Keyboard key codepoints.
99 
100    All keys are identified by a Unicode code point in PuglEventKey::key.  This
101    enumeration defines constants for special keys that do not have a standard
102    code point, and some convenience constants for control characters.  Note
103    that all keys are handled in the same way, this enumeration is just for
104    convenience when writing hard-coded key bindings.
105 
106    Keys that do not have a standard code point use values in the Private Use
107    Area in the Basic Multilingual Plane (`U+E000` to `U+F8FF`).  Applications
108    must take care to not interpret these values beyond key detection, the
109    mapping used here is arbitrary and specific to Pugl.
110 */
111 typedef enum {
112   // ASCII control codes
113   PUGL_KEY_BACKSPACE = 0x08,
114   PUGL_KEY_ESCAPE    = 0x1B,
115   PUGL_KEY_DELETE    = 0x7F,
116 
117   // Unicode Private Use Area
118   PUGL_KEY_F1 = 0xE000,
119   PUGL_KEY_F2,
120   PUGL_KEY_F3,
121   PUGL_KEY_F4,
122   PUGL_KEY_F5,
123   PUGL_KEY_F6,
124   PUGL_KEY_F7,
125   PUGL_KEY_F8,
126   PUGL_KEY_F9,
127   PUGL_KEY_F10,
128   PUGL_KEY_F11,
129   PUGL_KEY_F12,
130   PUGL_KEY_LEFT,
131   PUGL_KEY_UP,
132   PUGL_KEY_RIGHT,
133   PUGL_KEY_DOWN,
134   PUGL_KEY_PAGE_UP,
135   PUGL_KEY_PAGE_DOWN,
136   PUGL_KEY_HOME,
137   PUGL_KEY_END,
138   PUGL_KEY_INSERT,
139   PUGL_KEY_SHIFT,
140   PUGL_KEY_SHIFT_L = PUGL_KEY_SHIFT,
141   PUGL_KEY_SHIFT_R,
142   PUGL_KEY_CTRL,
143   PUGL_KEY_CTRL_L = PUGL_KEY_CTRL,
144   PUGL_KEY_CTRL_R,
145   PUGL_KEY_ALT,
146   PUGL_KEY_ALT_L = PUGL_KEY_ALT,
147   PUGL_KEY_ALT_R,
148   PUGL_KEY_SUPER,
149   PUGL_KEY_SUPER_L = PUGL_KEY_SUPER,
150   PUGL_KEY_SUPER_R,
151   PUGL_KEY_MENU,
152   PUGL_KEY_CAPS_LOCK,
153   PUGL_KEY_SCROLL_LOCK,
154   PUGL_KEY_NUM_LOCK,
155   PUGL_KEY_PRINT_SCREEN,
156   PUGL_KEY_PAUSE
157 } PuglKey;
158 
159 /// The type of a PuglEvent
160 typedef enum {
161   PUGL_NOTHING,        ///< No event
162   PUGL_CREATE,         ///< View created, a #PuglEventCreate
163   PUGL_DESTROY,        ///< View destroyed, a #PuglEventDestroy
164   PUGL_CONFIGURE,      ///< View moved/resized, a #PuglEventConfigure
165   PUGL_MAP,            ///< View made visible, a #PuglEventMap
166   PUGL_UNMAP,          ///< View made invisible, a #PuglEventUnmap
167   PUGL_UPDATE,         ///< View ready to draw, a #PuglEventUpdate
168   PUGL_EXPOSE,         ///< View must be drawn, a #PuglEventExpose
169   PUGL_CLOSE,          ///< View will be closed, a #PuglEventClose
170   PUGL_FOCUS_IN,       ///< Keyboard focus entered view, a #PuglEventFocus
171   PUGL_FOCUS_OUT,      ///< Keyboard focus left view, a #PuglEventFocus
172   PUGL_KEY_PRESS,      ///< Key pressed, a #PuglEventKey
173   PUGL_KEY_RELEASE,    ///< Key released, a #PuglEventKey
174   PUGL_TEXT,           ///< Character entered, a #PuglEventText
175   PUGL_POINTER_IN,     ///< Pointer entered view, a #PuglEventCrossing
176   PUGL_POINTER_OUT,    ///< Pointer left view, a #PuglEventCrossing
177   PUGL_BUTTON_PRESS,   ///< Mouse button pressed, a #PuglEventButton
178   PUGL_BUTTON_RELEASE, ///< Mouse button released, a #PuglEventButton
179   PUGL_MOTION,         ///< Pointer moved, a #PuglEventMotion
180   PUGL_SCROLL,         ///< Scrolled, a #PuglEventScroll
181   PUGL_CLIENT,         ///< Custom client message, a #PuglEventClient
182   PUGL_TIMER,          ///< Timer triggered, a #PuglEventTimer
183   PUGL_LOOP_ENTER,     ///< Recursive loop entered, a #PuglEventLoopEnter
184   PUGL_LOOP_LEAVE,     ///< Recursive loop left, a #PuglEventLoopLeave
185 
186 #ifndef PUGL_DISABLE_DEPRECATED
187   PUGL_ENTER_NOTIFY  PUGL_DEPRECATED_BY("PUGL_POINTER_IN")  = PUGL_POINTER_IN,
188   PUGL_LEAVE_NOTIFY  PUGL_DEPRECATED_BY("PUGL_POINTER_OUT") = PUGL_POINTER_OUT,
189   PUGL_MOTION_NOTIFY PUGL_DEPRECATED_BY("PUGL_MOTION")      = PUGL_MOTION,
190 #endif
191 
192 } PuglEventType;
193 
194 /// Common flags for all event types
195 typedef enum {
196   PUGL_IS_SEND_EVENT = 1, ///< Event is synthetic
197   PUGL_IS_HINT       = 2  ///< Event is a hint (not direct user input)
198 } PuglEventFlag;
199 
200 /// Bitwise OR of #PuglEventFlag values
201 typedef uint32_t PuglEventFlags;
202 
203 /// Reason for a PuglEventCrossing
204 typedef enum {
205   PUGL_CROSSING_NORMAL, ///< Crossing due to pointer motion
206   PUGL_CROSSING_GRAB,   ///< Crossing due to a grab
207   PUGL_CROSSING_UNGRAB  ///< Crossing due to a grab release
208 } PuglCrossingMode;
209 
210 /**
211    Scroll direction.
212 
213    Describes the direction of a #PuglEventScroll along with whether the scroll
214    is a "smooth" scroll.  The discrete directions are for devices like mouse
215    wheels with constrained axes, while a smooth scroll is for those with
216    arbitrary scroll direction freedom, like some touchpads.
217 */
218 typedef enum {
219   PUGL_SCROLL_UP,    ///< Scroll up
220   PUGL_SCROLL_DOWN,  ///< Scroll down
221   PUGL_SCROLL_LEFT,  ///< Scroll left
222   PUGL_SCROLL_RIGHT, ///< Scroll right
223   PUGL_SCROLL_SMOOTH ///< Smooth scroll in any direction
224 } PuglScrollDirection;
225 
226 /// Common header for all event structs
227 typedef struct {
228   PuglEventType  type;  ///< Event type
229   PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values
230 } PuglEventAny;
231 
232 /**
233    View create event.
234 
235    This event is sent when a view is realized before it is first displayed,
236    with the graphics context entered.  This is typically used for setting up
237    the graphics system, for example by loading OpenGL extensions.
238 
239    This event type has no extra fields.
240 */
241 typedef PuglEventAny PuglEventCreate;
242 
243 /**
244    View destroy event.
245 
246    This event is the counterpart to #PuglEventCreate, and it is sent when the
247    view is being destroyed.  This is typically used for tearing down the
248    graphics system, or otherwise freeing any resources allocated when the
249    create event was handled.
250 
251    This is the last event sent to any view, and immediately after it is
252    processed, the view is destroyed and may no longer be used.
253 
254    This event type has no extra fields.
255 */
256 typedef PuglEventAny PuglEventDestroy;
257 
258 /**
259    View resize or move event.
260 
261    A configure event is sent whenever the view is resized or moved.  When a
262    configure event is received, the graphics context is active but not set up
263    for drawing.  For example, it is valid to adjust the OpenGL viewport or
264    otherwise configure the context, but not to draw anything.
265 */
266 typedef struct {
267   PuglEventType  type;   ///< #PUGL_CONFIGURE
268   PuglEventFlags flags;  ///< Bitwise OR of #PuglEventFlag values
269   double         x;      ///< New parent-relative X coordinate
270   double         y;      ///< New parent-relative Y coordinate
271   double         width;  ///< New width
272   double         height; ///< New height
273 } PuglEventConfigure;
274 
275 /**
276    View show event.
277 
278    This event is sent when a view is mapped to the screen and made visible.
279 
280    This event type has no extra fields.
281 */
282 typedef PuglEventAny PuglEventMap;
283 
284 /**
285    View hide event.
286 
287    This event is sent when a view is unmapped from the screen and made
288    invisible.
289 
290    This event type has no extra fields.
291 */
292 typedef PuglEventAny PuglEventUnmap;
293 
294 /**
295    View update event.
296 
297    This event is sent to every view near the end of a main loop iteration when
298    any pending exposures are about to be redrawn.  It is typically used to mark
299    regions to expose with puglPostRedisplay() or puglPostRedisplayRect().  For
300    example, to continuously animate, a view calls puglPostRedisplay() when an
301    update event is received, and it will then shortly receive an expose event.
302 */
303 typedef PuglEventAny PuglEventUpdate;
304 
305 /**
306    Expose event for when a region must be redrawn.
307 
308    When an expose event is received, the graphics context is active, and the
309    view must draw the entire specified region.  The contents of the region are
310    undefined, there is no preservation of anything drawn previously.
311 */
312 typedef struct {
313   PuglEventType  type;   ///< #PUGL_EXPOSE
314   PuglEventFlags flags;  ///< Bitwise OR of #PuglEventFlag values
315   double         x;      ///< View-relative X coordinate
316   double         y;      ///< View-relative Y coordinate
317   double         width;  ///< Width of exposed region
318   double         height; ///< Height of exposed region
319 } PuglEventExpose;
320 
321 /**
322    View close event.
323 
324    This event is sent when the view is to be closed, for example when the user
325    clicks the close button.
326 
327    This event type has no extra fields.
328 */
329 typedef PuglEventAny PuglEventClose;
330 
331 /**
332    Keyboard focus event.
333 
334    This event is sent whenever the view gains or loses the keyboard focus.  The
335    view with the keyboard focus will receive any key press or release events.
336 */
337 typedef struct {
338   PuglEventType    type;  ///< #PUGL_FOCUS_IN or #PUGL_FOCUS_OUT
339   PuglEventFlags   flags; ///< Bitwise OR of #PuglEventFlag values
340   PuglCrossingMode mode;  ///< Reason for focus change
341 } PuglEventFocus;
342 
343 /**
344    Key press or release event.
345 
346    This event represents low-level key presses and releases.  This can be used
347    for "direct" keyboard handing like key bindings, but must not be interpreted
348    as text input.
349 
350    Keys are represented portably as Unicode code points, using the "natural"
351    code point for the key where possible (see #PuglKey for details).  The `key`
352    field is the code for the pressed key, without any modifiers applied.  For
353    example, a press or release of the 'A' key will have `key` 97 ('a')
354    regardless of whether shift or control are being held.
355 
356    Alternatively, the raw `keycode` can be used to work directly with physical
357    keys, but note that this value is not portable and differs between platforms
358    and hardware.
359 */
360 typedef struct {
361   PuglEventType  type;    ///< #PUGL_KEY_PRESS or #PUGL_KEY_RELEASE
362   PuglEventFlags flags;   ///< Bitwise OR of #PuglEventFlag values
363   double         time;    ///< Time in seconds
364   double         x;       ///< View-relative X coordinate
365   double         y;       ///< View-relative Y coordinate
366   double         xRoot;   ///< Root-relative X coordinate
367   double         yRoot;   ///< Root-relative Y coordinate
368   PuglMods       state;   ///< Bitwise OR of #PuglMod flags
369   uint32_t       keycode; ///< Raw key code
370   uint32_t       key;     ///< Unshifted Unicode character code, or 0
371 } PuglEventKey;
372 
373 /**
374    Character input event.
375 
376    This event represents text input, usually as the result of a key press.  The
377    text is given both as a Unicode character code and a UTF-8 string.
378 
379    Note that this event is generated by the platform's input system, so there
380    is not necessarily a direct correspondence between text events and physical
381    key presses.  For example, with some input methods a sequence of several key
382    presses will generate a single character.
383 */
384 typedef struct {
385   PuglEventType  type;      ///< #PUGL_TEXT
386   PuglEventFlags flags;     ///< Bitwise OR of #PuglEventFlag values
387   double         time;      ///< Time in seconds
388   double         x;         ///< View-relative X coordinate
389   double         y;         ///< View-relative Y coordinate
390   double         xRoot;     ///< Root-relative X coordinate
391   double         yRoot;     ///< Root-relative Y coordinate
392   PuglMods       state;     ///< Bitwise OR of #PuglMod flags
393   uint32_t       keycode;   ///< Raw key code
394   uint32_t       character; ///< Unicode character code
395   char           string[8]; ///< UTF-8 string
396 } PuglEventText;
397 
398 /**
399    Pointer enter or leave event.
400 
401    This event is sent when the pointer enters or leaves the view.  This can
402    happen for several reasons (not just the user dragging the pointer over the
403    window edge), as described by the `mode` field.
404 */
405 typedef struct {
406   PuglEventType    type;  ///< #PUGL_POINTER_IN or #PUGL_POINTER_OUT
407   PuglEventFlags   flags; ///< Bitwise OR of #PuglEventFlag values
408   double           time;  ///< Time in seconds
409   double           x;     ///< View-relative X coordinate
410   double           y;     ///< View-relative Y coordinate
411   double           xRoot; ///< Root-relative X coordinate
412   double           yRoot; ///< Root-relative Y coordinate
413   PuglMods         state; ///< Bitwise OR of #PuglMod flags
414   PuglCrossingMode mode;  ///< Reason for crossing
415 } PuglEventCrossing;
416 
417 /**
418    Button press or release event.
419 */
420 typedef struct {
421   PuglEventType  type;   ///< #PUGL_BUTTON_PRESS or #PUGL_BUTTON_RELEASE
422   PuglEventFlags flags;  ///< Bitwise OR of #PuglEventFlag values
423   double         time;   ///< Time in seconds
424   double         x;      ///< View-relative X coordinate
425   double         y;      ///< View-relative Y coordinate
426   double         xRoot;  ///< Root-relative X coordinate
427   double         yRoot;  ///< Root-relative Y coordinate
428   PuglMods       state;  ///< Bitwise OR of #PuglMod flags
429   uint32_t       button; ///< Button number starting from 1
430 } PuglEventButton;
431 
432 /**
433    Pointer motion event.
434 */
435 typedef struct {
436   PuglEventType  type;  ///< #PUGL_MOTION
437   PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values
438   double         time;  ///< Time in seconds
439   double         x;     ///< View-relative X coordinate
440   double         y;     ///< View-relative Y coordinate
441   double         xRoot; ///< Root-relative X coordinate
442   double         yRoot; ///< Root-relative Y coordinate
443   PuglMods       state; ///< Bitwise OR of #PuglMod flags
444 } PuglEventMotion;
445 
446 /**
447    Scroll event.
448 
449    The scroll distance is expressed in "lines", an arbitrary unit that
450    corresponds to a single tick of a detented mouse wheel.  For example, `dy` =
451    1.0 scrolls 1 line up.  Some systems and devices support finer resolution
452    and/or higher values for fast scrolls, so programs should handle any value
453    gracefully.
454 */
455 typedef struct {
456   PuglEventType       type;      ///< #PUGL_SCROLL
457   PuglEventFlags      flags;     ///< Bitwise OR of #PuglEventFlag values
458   double              time;      ///< Time in seconds
459   double              x;         ///< View-relative X coordinate
460   double              y;         ///< View-relative Y coordinate
461   double              xRoot;     ///< Root-relative X coordinate
462   double              yRoot;     ///< Root-relative Y coordinate
463   PuglMods            state;     ///< Bitwise OR of #PuglMod flags
464   PuglScrollDirection direction; ///< Scroll direction
465   double              dx;        ///< Scroll X distance in lines
466   double              dy;        ///< Scroll Y distance in lines
467 } PuglEventScroll;
468 
469 /**
470    Custom client message event.
471 
472    This can be used to send a custom message to a view, which is delivered via
473    the window system and processed in the event loop as usual.  Among other
474    things, this makes it possible to wake up the event loop for any reason.
475 */
476 typedef struct {
477   PuglEventType  type;  ///< #PUGL_CLIENT
478   PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values
479   uintptr_t      data1; ///< Client-specific data
480   uintptr_t      data2; ///< Client-specific data
481 } PuglEventClient;
482 
483 /**
484    Timer event.
485 
486    This event is sent at the regular interval specified in the call to
487    puglStartTimer() that activated it.
488 
489    The `id` is the application-specific ID given to puglStartTimer() which
490    distinguishes this timer from others.  It should always be checked in the
491    event handler, even in applications that register only one timer.
492 */
493 typedef struct {
494   PuglEventType  type;  ///< #PUGL_TIMER
495   PuglEventFlags flags; ///< Bitwise OR of #PuglEventFlag values
496   uintptr_t      id;    ///< Timer ID
497 } PuglEventTimer;
498 
499 /**
500    Recursive loop enter event.
501 
502    This event is sent when the window system enters a recursive loop.  The main
503    loop will be stalled and no expose events will be received while in the
504    recursive loop.  To give the application full control, Pugl does not do any
505    special handling of this situation, but this event can be used to install a
506    timer to perform continuous actions (such as drawing) on platforms that do
507    this.
508 
509    - MacOS: A recursive loop is entered while the window is being live resized.
510 
511    - Windows: A recursive loop is entered while the window is being live
512      resized or the menu is shown.
513 
514    - X11: A recursive loop is never entered and the event loop runs as usual
515      while the view is being resized.
516 
517    This event type has no extra fields.
518 */
519 typedef PuglEventAny PuglEventLoopEnter;
520 
521 /**
522    Recursive loop leave event.
523 
524    This event is sent after a loop enter event when the recursive loop is
525    finished and normal iteration will continue.
526 
527    This event type has no extra fields.
528 */
529 typedef PuglEventAny PuglEventLoopLeave;
530 
531 /**
532    View event.
533 
534    This is a union of all event types.  The type must be checked to determine
535    which fields are safe to access.  A pointer to PuglEvent can either be cast
536    to the appropriate type, or the union members used.
537 
538    The graphics system may only be accessed when handling certain events.  The
539    graphics context is active for #PUGL_CREATE, #PUGL_DESTROY, #PUGL_CONFIGURE,
540    and #PUGL_EXPOSE, but only enabled for drawing for #PUGL_EXPOSE.
541 */
542 typedef union {
543   PuglEventAny       any;       ///< Valid for all event types
544   PuglEventType      type;      ///< Event type
545   PuglEventButton    button;    ///< #PUGL_BUTTON_PRESS, #PUGL_BUTTON_RELEASE
546   PuglEventConfigure configure; ///< #PUGL_CONFIGURE
547   PuglEventExpose    expose;    ///< #PUGL_EXPOSE
548   PuglEventKey       key;       ///< #PUGL_KEY_PRESS, #PUGL_KEY_RELEASE
549   PuglEventText      text;      ///< #PUGL_TEXT
550   PuglEventCrossing  crossing;  ///< #PUGL_POINTER_IN, #PUGL_POINTER_OUT
551   PuglEventMotion    motion;    ///< #PUGL_MOTION
552   PuglEventScroll    scroll;    ///< #PUGL_SCROLL
553   PuglEventFocus     focus;     ///< #PUGL_FOCUS_IN, #PUGL_FOCUS_OUT
554   PuglEventClient    client;    ///< #PUGL_CLIENT
555   PuglEventTimer     timer;     ///< #PUGL_TIMER
556 } PuglEvent;
557 
558 /**
559    @}
560    @defgroup status Status
561 
562    Most functions return a status code which can be used to check for errors.
563 
564    @{
565 */
566 
567 /// Return status code
568 typedef enum {
569   PUGL_SUCCESS,               ///< Success
570   PUGL_FAILURE,               ///< Non-fatal failure
571   PUGL_UNKNOWN_ERROR,         ///< Unknown system error
572   PUGL_BAD_BACKEND,           ///< Invalid or missing backend
573   PUGL_BAD_CONFIGURATION,     ///< Invalid view configuration
574   PUGL_BAD_PARAMETER,         ///< Invalid parameter
575   PUGL_BACKEND_FAILED,        ///< Backend initialization failed
576   PUGL_REGISTRATION_FAILED,   ///< Class registration failed
577   PUGL_REALIZE_FAILED,        ///< System view realization failed
578   PUGL_SET_FORMAT_FAILED,     ///< Failed to set pixel format
579   PUGL_CREATE_CONTEXT_FAILED, ///< Failed to create drawing context
580   PUGL_UNSUPPORTED_TYPE,      ///< Unsupported data type
581 } PuglStatus;
582 
583 /// Return a string describing a status code
584 PUGL_CONST_API
585 const char*
586 puglStrerror(PuglStatus status);
587 
588 /**
589    @}
590    @defgroup world World
591 
592    The top-level context of a Pugl application or plugin.
593 
594    The world contains all library-wide state.  There is no static data in Pugl,
595    so it is safe to use multiple worlds in a single process.  This is to
596    facilitate plugins or other situations where it is not possible to share a
597    world, but a single world should be shared for all views where possible.
598 
599    @{
600 */
601 
602 /**
603    The "world" of application state.
604 
605    The world represents everything that is not associated with a particular
606    view.  Several worlds can be created in a single process, but code using
607    different worlds must be isolated so they are never mixed.  Views are
608    strongly associated with the world they were created in.
609 */
610 typedef struct PuglWorldImpl PuglWorld;
611 
612 /// Handle for the world's opaque user data
613 typedef void* PuglWorldHandle;
614 
615 /// The type of a World
616 typedef enum {
617   PUGL_PROGRAM, ///< Top-level application
618   PUGL_MODULE   ///< Plugin or module within a larger application
619 } PuglWorldType;
620 
621 /// World flags
622 typedef enum {
623   /**
624      Set up support for threads if necessary.
625 
626      - X11: Calls XInitThreads() which is required for some drivers.
627   */
628   PUGL_WORLD_THREADS = 1u << 0u
629 } PuglWorldFlag;
630 
631 /// Bitwise OR of #PuglWorldFlag values
632 typedef uint32_t PuglWorldFlags;
633 
634 /**
635    Create a new world.
636 
637    @param type The type, which dictates what this world is responsible for.
638    @param flags Flags to control world features.
639    @return A new world, which must be later freed with puglFreeWorld().
640 */
641 PUGL_API
642 PuglWorld*
643 puglNewWorld(PuglWorldType type, PuglWorldFlags flags);
644 
645 /// Free a world allocated with puglNewWorld()
646 PUGL_API
647 void
648 puglFreeWorld(PuglWorld* world);
649 
650 /**
651    Set the user data for the world.
652 
653    This is usually a pointer to a struct that contains all the state which must
654    be accessed by several views.
655 
656    The handle is opaque to Pugl and is not interpreted in any way.
657 */
658 PUGL_API
659 void
660 puglSetWorldHandle(PuglWorld* world, PuglWorldHandle handle);
661 
662 /// Get the user data for the world
663 PUGL_API
664 PuglWorldHandle
665 puglGetWorldHandle(PuglWorld* world);
666 
667 /**
668    Return a pointer to the native handle of the world.
669 
670    X11: Returns a pointer to the `Display`.
671 
672    MacOS: Returns null.
673 
674    Windows: Returns the `HMODULE` of the calling process.
675 */
676 PUGL_API
677 void*
678 puglGetNativeWorld(PuglWorld* world);
679 
680 /**
681    Set the class name of the application.
682 
683    This is a stable identifier for the application, used as the window
684    class/instance name on X11 and Windows.  It is not displayed to the user,
685    but can be used in scripts and by window managers, so it should be the same
686    for every instance of the application, but different from other
687    applications.
688 */
689 PUGL_API
690 PuglStatus
691 puglSetClassName(PuglWorld* world, const char* name);
692 
693 /**
694    Return the time in seconds.
695 
696    This is a monotonically increasing clock with high resolution.  The returned
697    time is only useful to compare against other times returned by this
698    function, its absolute value has no meaning.
699 */
700 PUGL_API
701 double
702 puglGetTime(const PuglWorld* world);
703 
704 /**
705    Update by processing events from the window system.
706 
707    This function is a single iteration of the main loop, and should be called
708    repeatedly to update all views.
709 
710    If `timeout` is zero, then this function will not block.  Plugins should
711    always use a timeout of zero to avoid blocking the host.
712 
713    If a positive `timeout` is given, then events will be processed for that
714    amount of time, starting from when this function was called.
715 
716    If a negative `timeout` is given, this function will block indefinitely
717    until an event occurs.
718 
719    For continuously animating programs, a timeout that is a reasonable fraction
720    of the ideal frame period should be used, to minimize input latency by
721    ensuring that as many input events are consumed as possible before drawing.
722 
723    @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if no events are
724    read, or an error.
725 */
726 PUGL_API
727 PuglStatus
728 puglUpdate(PuglWorld* world, double timeout);
729 
730 /**
731    @}
732    @defgroup view View
733 
734    A drawable region that receives events.
735 
736    A view can be thought of as a window, but does not necessarily correspond to
737    a top-level window in a desktop environment.  For example, a view can be
738    embedded in some other window, or represent an embedded system where there
739    is no concept of multiple windows at all.
740 
741    @{
742 */
743 
744 /// A drawable region that receives events
745 typedef struct PuglViewImpl PuglView;
746 
747 /**
748    A graphics backend.
749 
750    The backend dictates how graphics are set up for a view, and how drawing is
751    performed.  A backend must be set by calling puglSetBackend() before
752    realising a view.
753 
754    If you are using a local copy of Pugl, it is possible to implement a custom
755    backend.  See the definition of `PuglBackendImpl` in the source code for
756    details.
757 */
758 typedef struct PuglBackendImpl PuglBackend;
759 
760 /**
761    A native view handle.
762 
763    X11: This is a `Window`.
764 
765    MacOS: This is a pointer to an `NSView*`.
766 
767    Windows: This is a `HWND`.
768 */
769 typedef uintptr_t PuglNativeView;
770 
771 /// Handle for a view's opaque user data
772 typedef void* PuglHandle;
773 
774 /// A hint for configuring a view
775 typedef enum {
776   PUGL_USE_COMPAT_PROFILE,    ///< Use compatible (not core) OpenGL profile
777   PUGL_USE_DEBUG_CONTEXT,     ///< True to use a debug OpenGL context
778   PUGL_CONTEXT_VERSION_MAJOR, ///< OpenGL context major version
779   PUGL_CONTEXT_VERSION_MINOR, ///< OpenGL context minor version
780   PUGL_RED_BITS,              ///< Number of bits for red channel
781   PUGL_GREEN_BITS,            ///< Number of bits for green channel
782   PUGL_BLUE_BITS,             ///< Number of bits for blue channel
783   PUGL_ALPHA_BITS,            ///< Number of bits for alpha channel
784   PUGL_DEPTH_BITS,            ///< Number of bits for depth buffer
785   PUGL_STENCIL_BITS,          ///< Number of bits for stencil buffer
786   PUGL_SAMPLES,               ///< Number of samples per pixel (AA)
787   PUGL_DOUBLE_BUFFER,         ///< True if double buffering should be used
788   PUGL_SWAP_INTERVAL,         ///< Number of frames between buffer swaps
789   PUGL_RESIZABLE,             ///< True if view should be resizable
790   PUGL_IGNORE_KEY_REPEAT,     ///< True if key repeat events are ignored
791   PUGL_REFRESH_RATE,          ///< Refresh rate in Hz
792 
793   PUGL_NUM_VIEW_HINTS
794 } PuglViewHint;
795 
796 /// A special view hint value
797 typedef enum {
798   PUGL_DONT_CARE = -1, ///< Use best available value
799   PUGL_FALSE     = 0,  ///< Explicitly false
800   PUGL_TRUE      = 1   ///< Explicitly true
801 } PuglViewHintValue;
802 
803 /// A function called when an event occurs
804 typedef PuglStatus (*PuglEventFunc)(PuglView* view, const PuglEvent* event);
805 
806 /**
807    @defgroup setup Setup
808    Functions for creating and destroying a view.
809    @{
810 */
811 
812 /**
813    Create a new view.
814 
815    A newly created view does not correspond to a real system view or window.
816    It must first be configured, then the system view can be created with
817    puglRealize().
818 */
819 PUGL_API
820 PuglView*
821 puglNewView(PuglWorld* world);
822 
823 /// Free a view created with puglNewView()
824 PUGL_API
825 void
826 puglFreeView(PuglView* view);
827 
828 /// Return the world that `view` is a part of
829 PUGL_API
830 PuglWorld*
831 puglGetWorld(PuglView* view);
832 
833 /**
834    Set the user data for a view.
835 
836    This is usually a pointer to a struct that contains all the state which must
837    be accessed by a view.  Everything needed to process events should be stored
838    here, not in static variables.
839 
840    The handle is opaque to Pugl and is not interpreted in any way.
841 */
842 PUGL_API
843 void
844 puglSetHandle(PuglView* view, PuglHandle handle);
845 
846 /// Get the user data for a view
847 PUGL_API
848 PuglHandle
849 puglGetHandle(PuglView* view);
850 
851 /**
852    Set the graphics backend to use for a view.
853 
854    This must be called once to set the graphics backend before calling
855    puglRealize().
856 
857    Pugl includes the following backends:
858 
859    - puglCairoBackend()
860    - puglGlBackend()
861    - puglVulkanBackend()
862 
863    Note that backends are modular and not compiled into the main Pugl library
864    to avoid unnecessary dependencies.  To use a particular backend,
865    applications must link against the appropriate backend library, or be sure
866    to compile in the appropriate code if using a local copy of Pugl.
867 */
868 PUGL_API
869 PuglStatus
870 puglSetBackend(PuglView* view, const PuglBackend* backend);
871 
872 /// Set the function to call when an event occurs
873 PUGL_API
874 PuglStatus
875 puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc);
876 
877 /**
878    Set a hint to configure view properties.
879 
880    This only has an effect when called before puglRealize().
881 */
882 PUGL_API
883 PuglStatus
884 puglSetViewHint(PuglView* view, PuglViewHint hint, int value);
885 
886 /**
887    Get the value for a view hint.
888 
889    If the view has been realized, this can be used to get the actual value of a
890    hint which was initially set to PUGL_DONT_CARE, or has been adjusted from
891    the suggested value.
892 */
893 PUGL_API
894 int
895 puglGetViewHint(const PuglView* view, PuglViewHint hint);
896 
897 /**
898    @}
899    @defgroup frame Frame
900    Functions for working with the position and size of a view.
901    @{
902 */
903 
904 /**
905    Get the current position and size of the view.
906 
907    The position is in screen coordinates with an upper left origin.
908 */
909 PUGL_API
910 PuglRect
911 puglGetFrame(const PuglView* view);
912 
913 /**
914    Set the current position and size of the view.
915 
916    The position is in screen coordinates with an upper left origin.
917 
918    @return #PUGL_UNKNOWN_ERROR on failure, in which case the view frame is
919    unchanged.
920 */
921 PUGL_API
922 PuglStatus
923 puglSetFrame(PuglView* view, PuglRect frame);
924 
925 /**
926    Set the default size of the view.
927 
928    This should be called before puglResize() to set the default size of the
929    view, which will be the initial size of the window if this is a top level
930    view.
931 
932    @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
933    not yet realized.
934 */
935 PUGL_API
936 PuglStatus
937 puglSetDefaultSize(PuglView* view, int width, int height);
938 
939 /**
940    Set the minimum size of the view.
941 
942    If an initial minimum size is known, this should be called before
943    puglRealize() to avoid stutter, though it can be called afterwards as well.
944 
945    @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
946    not yet realized.
947 */
948 PUGL_API
949 PuglStatus
950 puglSetMinSize(PuglView* view, int width, int height);
951 
952 /**
953    Set the maximum size of the view.
954 
955    If an initial maximum size is known, this should be called before
956    puglRealize() to avoid stutter, though it can be called afterwards as well.
957 
958    @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
959    not yet realized.
960 */
961 PUGL_API
962 PuglStatus
963 puglSetMaxSize(PuglView* view, int width, int height);
964 
965 /**
966    Set the view aspect ratio range.
967 
968    The x and y values here represent a ratio of width to height.  To set a
969    fixed aspect ratio, set the minimum and maximum values to the same ratio.
970 
971    Note that setting different minimum and maximum constraints does not
972    currenty work on MacOS (the minimum is used), so only setting a fixed aspect
973    ratio works properly across all platforms.
974 
975    If an initial aspect ratio is known, this should be called before
976    puglRealize() to avoid stutter, though it can be called afterwards as well.
977 
978    @return #PUGL_UNKNOWN_ERROR on failure, but always succeeds if the view is
979    not yet realized.
980 */
981 PUGL_API
982 PuglStatus
983 puglSetAspectRatio(PuglView* view, int minX, int minY, int maxX, int maxY);
984 
985 /**
986    @}
987    @defgroup window Window
988    Functions to control the top-level window of a view.
989    @{
990 */
991 
992 /**
993    Set the title of the window.
994 
995    This only makes sense for non-embedded views that will have a corresponding
996    top-level window, and sets the title, typically displayed in the title bar
997    or in window switchers.
998 */
999 PUGL_API
1000 PuglStatus
1001 puglSetWindowTitle(PuglView* view, const char* title);
1002 
1003 /**
1004    Set the parent window for embedding a view in an existing window.
1005 
1006    This must be called before puglRealize(), reparenting is not supported.
1007 */
1008 PUGL_API
1009 PuglStatus
1010 puglSetParentWindow(PuglView* view, PuglNativeView parent);
1011 
1012 /**
1013    Set the transient parent of the window.
1014 
1015    Set this for transient children like dialogs, to have them properly
1016    associated with their parent window.  This should be called before
1017    puglRealize().
1018 
1019    A view can either have a parent (for embedding) or a transient parent (for
1020    top-level windows like dialogs), but not both.
1021 */
1022 PUGL_API
1023 PuglStatus
1024 puglSetTransientFor(PuglView* view, PuglNativeView parent);
1025 
1026 /**
1027    Realize a view by creating a corresponding system view or window.
1028 
1029    After this call, the (initially invisible) underlying system view exists and
1030    can be accessed with puglGetNativeWindow().  There is currently no
1031    corresponding unrealize function, the system view will be destroyed along
1032    with the view when puglFreeView() is called.
1033 
1034    The view should be fully configured using the above functions before this is
1035    called.  This function may only be called once per view.
1036 */
1037 PUGL_API
1038 PuglStatus
1039 puglRealize(PuglView* view);
1040 
1041 /**
1042    Show the view.
1043 
1044    If the view has not yet been realized, the first call to this function will
1045    do so automatically.
1046 
1047    If the view is currently hidden, it will be shown and possibly raised to the
1048    top depending on the platform.
1049 */
1050 PUGL_API
1051 PuglStatus
1052 puglShow(PuglView* view);
1053 
1054 /// Hide the current window
1055 PUGL_API
1056 PuglStatus
1057 puglHide(PuglView* view);
1058 
1059 /// Return true iff the view is currently visible
1060 PUGL_API
1061 bool
1062 puglGetVisible(const PuglView* view);
1063 
1064 /// Return the native window handle
1065 PUGL_API
1066 PuglNativeView
1067 puglGetNativeWindow(PuglView* view);
1068 
1069 /**
1070    @}
1071    @defgroup graphics Graphics
1072    Functions for working with the graphics context and scheduling redisplays.
1073    @{
1074 */
1075 
1076 /**
1077    Get the graphics context.
1078 
1079    This is a backend-specific context used for drawing if the backend graphics
1080    API requires one.  It is only available during an expose.
1081 
1082    Cairo: Returns a pointer to a
1083    [cairo_t](http://www.cairographics.org/manual/cairo-cairo-t.html).
1084 
1085    All other backends: returns null.
1086 */
1087 PUGL_API
1088 void*
1089 puglGetContext(PuglView* view);
1090 
1091 /**
1092    Request a redisplay for the entire view.
1093 
1094    This will cause an expose event to be dispatched later.  If called from
1095    within the event handler, the expose should arrive at the end of the current
1096    event loop iteration, though this is not strictly guaranteed on all
1097    platforms.  If called elsewhere, an expose will be enqueued to be processed
1098    in the next event loop iteration.
1099 */
1100 PUGL_API
1101 PuglStatus
1102 puglPostRedisplay(PuglView* view);
1103 
1104 /**
1105    Request a redisplay of the given rectangle within the view.
1106 
1107    This has the same semantics as puglPostRedisplay(), but allows giving a
1108    precise region for redrawing only a portion of the view.
1109 */
1110 PUGL_API
1111 PuglStatus
1112 puglPostRedisplayRect(PuglView* view, PuglRect rect);
1113 
1114 /**
1115    @}
1116    @defgroup interaction Interaction
1117    Functions for interacting with the user and window system.
1118    @{
1119 */
1120 
1121 /**
1122    A mouse cursor type.
1123 
1124    This is a portable subset of mouse cursors that exist on X11, MacOS, and
1125    Windows.
1126 */
1127 typedef enum {
1128   PUGL_CURSOR_ARROW,      ///< Default pointing arrow
1129   PUGL_CURSOR_CARET,      ///< Caret (I-Beam) for text entry
1130   PUGL_CURSOR_CROSSHAIR,  ///< Cross-hair
1131   PUGL_CURSOR_HAND,       ///< Hand with a pointing finger
1132   PUGL_CURSOR_NO,         ///< Operation not allowed
1133   PUGL_CURSOR_LEFT_RIGHT, ///< Left/right arrow for horizontal resize
1134   PUGL_CURSOR_UP_DOWN,    ///< Up/down arrow for vertical resize
1135 } PuglCursor;
1136 
1137 /// Grab the keyboard input focus
1138 PUGL_API
1139 PuglStatus
1140 puglGrabFocus(PuglView* view);
1141 
1142 /// Return whether `view` has the keyboard input focus
1143 PUGL_API
1144 bool
1145 puglHasFocus(const PuglView* view);
1146 
1147 /**
1148    Set the clipboard contents.
1149 
1150    This sets the system clipboard contents, which can be retrieved with
1151    puglGetClipboard() or pasted into other applications.
1152 
1153    @param view The view.
1154    @param type The MIME type of the data, "text/plain" is assumed if `NULL`.
1155    @param data The data to copy to the clipboard.
1156    @param len The length of data in bytes (including terminator if necessary).
1157 */
1158 PUGL_API
1159 PuglStatus
1160 puglSetClipboard(PuglView*   view,
1161                  const char* type,
1162                  const void* data,
1163                  size_t      len);
1164 
1165 /**
1166    Get the clipboard contents.
1167 
1168    This gets the system clipboard contents, which may have been set with
1169    puglSetClipboard() or copied from another application.
1170 
1171    @param view The view.
1172    @param[out] type Set to the MIME type of the data.
1173    @param[out] len Set to the length of the data in bytes.
1174    @return The clipboard contents, or null.
1175 */
1176 PUGL_API
1177 const void*
1178 puglGetClipboard(PuglView* view, const char** type, size_t* len);
1179 
1180 /**
1181    Set the mouse cursor.
1182 
1183    This changes the system cursor that is displayed when the pointer is inside
1184    the view.  May fail if setting the cursor is not supported on this system,
1185    for example if compiled on X11 without Xcursor support.
1186 
1187    @return #PUGL_BAD_PARAMETER if the given cursor is invalid,
1188    #PUGL_FAILURE if the cursor is known but loading it system fails.
1189 */
1190 PUGL_API
1191 PuglStatus
1192 puglSetCursor(PuglView* view, PuglCursor cursor);
1193 
1194 /**
1195    Request user attention.
1196 
1197    This hints to the system that the window or application requires attention
1198    from the user.  The exact effect depends on the platform, but is usually
1199    something like a flashing task bar entry or bouncing application icon.
1200 */
1201 PUGL_API
1202 PuglStatus
1203 puglRequestAttention(PuglView* view);
1204 
1205 /**
1206    Activate a repeating timer event.
1207 
1208    This starts a timer which will send a #PuglEventTimer to `view` every
1209    `timeout` seconds.  This can be used to perform some action in a view at a
1210    regular interval with relatively low frequency.  Note that the frequency of
1211    timer events may be limited by how often puglUpdate() is called.
1212 
1213    If the given timer already exists, it is replaced.
1214 
1215    @param view The view to begin sending #PUGL_TIMER events to.
1216 
1217    @param id The identifier for this timer.  This is an application-specific ID
1218    that should be a low number, typically the value of a constant or `enum`
1219    that starts from 0.  There is a platform-specific limit to the number of
1220    supported timers, and overhead associated with each, so applications should
1221    create only a few timers and perform several tasks in one if necessary.
1222 
1223    @param timeout The period, in seconds, of this timer.  This is not
1224    guaranteed to have a resolution better than 10ms (the maximum timer
1225    resolution on Windows) and may be rounded up if it is too short.  On X11 and
1226    MacOS, a resolution of about 1ms can usually be relied on.
1227 
1228    @return #PUGL_FAILURE if timers are not supported by the system,
1229    #PUGL_UNKNOWN_ERROR if setting the timer failed.
1230 */
1231 PUGL_API
1232 PuglStatus
1233 puglStartTimer(PuglView* view, uintptr_t id, double timeout);
1234 
1235 /**
1236    Stop an active timer.
1237 
1238    @param view The view that the timer is set for.
1239    @param id The ID previously passed to puglStartTimer().
1240 
1241    @return #PUGL_FAILURE if timers are not supported by this system,
1242    #PUGL_UNKNOWN_ERROR if stopping the timer failed.
1243 */
1244 PUGL_API
1245 PuglStatus
1246 puglStopTimer(PuglView* view, uintptr_t id);
1247 
1248 /**
1249    Send an event to a view via the window system.
1250 
1251    If supported, the event will be delivered to the view via the event loop
1252    like other events.  Note that this function only works for certain event
1253    types.
1254 
1255    Currently, only #PUGL_CLIENT events are supported on all platforms.
1256 
1257    X11: A #PUGL_EXPOSE event can be sent, which is similar to calling
1258    puglPostRedisplayRect(), but will always send a message to the X server,
1259    even when called in an event handler.
1260 
1261    @return #PUGL_UNSUPPORTED_TYPE if sending events of this type is not supported,
1262    #PUGL_UNKNOWN_ERROR if sending the event failed.
1263 */
1264 PUGL_API
1265 PuglStatus
1266 puglSendEvent(PuglView* view, const PuglEvent* event);
1267 
1268 /**
1269    @}
1270 */
1271 
1272 #ifndef PUGL_DISABLE_DEPRECATED
1273 
1274 /**
1275    @}
1276    @defgroup deprecated Deprecated API
1277    @{
1278 */
1279 
1280 /**
1281    A native window handle.
1282 
1283    X11: This is a `Window`.
1284 
1285    MacOS: This is a pointer to an `NSView*`.
1286 
1287    Windows: This is a `HWND`.
1288 */
1289 typedef uintptr_t PuglNativeWindow;
1290 
1291 /**
1292    Create a Pugl application and view.
1293 
1294    To create a window, call the various puglInit* functions as necessary, then
1295    call puglRealize().
1296 
1297    @deprecated Use puglNewApp() and puglNewView().
1298 
1299    @param pargc Pointer to argument count (currently unused).
1300    @param argv  Arguments (currently unused).
1301    @return A newly created view.
1302 */
1303 static inline PUGL_DEPRECATED_BY("puglNewView")
1304 PuglView*
puglInit(const int * pargc,char ** argv)1305 puglInit(const int* pargc, char** argv)
1306 {
1307   (void)pargc;
1308   (void)argv;
1309 
1310   return puglNewView(puglNewWorld(PUGL_MODULE, 0));
1311 }
1312 
1313 /**
1314    Destroy an app and view created with `puglInit()`.
1315 
1316    @deprecated Use puglFreeApp() and puglFreeView().
1317 */
1318 static inline PUGL_DEPRECATED_BY("puglFreeView")
1319 void
puglDestroy(PuglView * view)1320 puglDestroy(PuglView* view)
1321 {
1322   PuglWorld* const world = puglGetWorld(view);
1323 
1324   puglFreeView(view);
1325   puglFreeWorld(world);
1326 }
1327 
1328 /**
1329    Set the window class name before creating a window.
1330 */
1331 static inline PUGL_DEPRECATED_BY("puglSetClassName")
1332 void
puglInitWindowClass(PuglView * view,const char * name)1333 puglInitWindowClass(PuglView* view, const char* name)
1334 {
1335   puglSetClassName(puglGetWorld(view), name);
1336 }
1337 
1338 /**
1339    Set the window size before creating a window.
1340 
1341    @deprecated Use puglSetFrame().
1342 */
1343 static inline PUGL_DEPRECATED_BY("puglSetFrame")
1344 void
puglInitWindowSize(PuglView * view,int width,int height)1345 puglInitWindowSize(PuglView* view, int width, int height)
1346 {
1347   PuglRect frame = puglGetFrame(view);
1348 
1349   frame.width  = width;
1350   frame.height = height;
1351 
1352   puglSetFrame(view, frame);
1353 }
1354 
1355 /**
1356    Set the minimum window size before creating a window.
1357 */
1358 static inline PUGL_DEPRECATED_BY("puglSetMinSize")
1359 void
puglInitWindowMinSize(PuglView * view,int width,int height)1360 puglInitWindowMinSize(PuglView* view, int width, int height)
1361 {
1362   puglSetMinSize(view, width, height);
1363 }
1364 
1365 /**
1366    Set the window aspect ratio range before creating a window.
1367 
1368    The x and y values here represent a ratio of width to height.  To set a
1369    fixed aspect ratio, set the minimum and maximum values to the same ratio.
1370 
1371    Note that setting different minimum and maximum constraints does not
1372    currenty work on MacOS (the minimum is used), so only setting a fixed aspect
1373    ratio works properly across all platforms.
1374 */
1375 static inline PUGL_DEPRECATED_BY("puglSetAspectRatio")
1376 void
puglInitWindowAspectRatio(PuglView * view,int minX,int minY,int maxX,int maxY)1377 puglInitWindowAspectRatio(PuglView* view,
1378                           int       minX,
1379                           int       minY,
1380                           int       maxX,
1381                           int       maxY)
1382 {
1383   puglSetAspectRatio(view, minX, minY, maxX, maxY);
1384 }
1385 
1386 /**
1387    Set transient parent before creating a window.
1388 
1389    On X11, parent must be a Window.
1390    On OSX, parent must be an NSView*.
1391 */
1392 static inline PUGL_DEPRECATED_BY("puglSetTransientFor")
1393 void
puglInitTransientFor(PuglView * view,uintptr_t parent)1394 puglInitTransientFor(PuglView* view, uintptr_t parent)
1395 {
1396   puglSetTransientFor(view, (PuglNativeWindow)parent);
1397 }
1398 
1399 /**
1400    Enable or disable resizing before creating a window.
1401 
1402    @deprecated Use puglSetViewHint() with #PUGL_RESIZABLE.
1403 */
1404 static inline PUGL_DEPRECATED_BY("puglSetViewHint")
1405 void
puglInitResizable(PuglView * view,bool resizable)1406 puglInitResizable(PuglView* view, bool resizable)
1407 {
1408   puglSetViewHint(view, PUGL_RESIZABLE, resizable);
1409 }
1410 
1411 /**
1412    Get the current size of the view.
1413 
1414    @deprecated Use puglGetFrame().
1415 
1416 */
1417 static inline PUGL_DEPRECATED_BY("puglGetFrame")
1418 void
puglGetSize(PuglView * view,int * width,int * height)1419 puglGetSize(PuglView* view, int* width, int* height)
1420 {
1421   const PuglRect frame = puglGetFrame(view);
1422 
1423   *width  = (int)frame.width;
1424   *height = (int)frame.height;
1425 }
1426 
1427 /**
1428    Ignore synthetic repeated key events.
1429 
1430    @deprecated Use puglSetViewHint() with #PUGL_IGNORE_KEY_REPEAT.
1431 */
1432 static inline PUGL_DEPRECATED_BY("puglSetViewHint")
1433 void
puglIgnoreKeyRepeat(PuglView * view,bool ignore)1434 puglIgnoreKeyRepeat(PuglView* view, bool ignore)
1435 {
1436   puglSetViewHint(view, PUGL_IGNORE_KEY_REPEAT, ignore);
1437 }
1438 
1439 /**
1440    Set a hint before creating a window.
1441 
1442    @deprecated Use puglSetWindowHint().
1443 */
1444 static inline PUGL_DEPRECATED_BY("puglSetViewHint")
1445 void
puglInitWindowHint(PuglView * view,PuglViewHint hint,int value)1446 puglInitWindowHint(PuglView* view, PuglViewHint hint, int value)
1447 {
1448   puglSetViewHint(view, hint, value);
1449 }
1450 
1451 /**
1452    Set the parent window before creating a window (for embedding).
1453 
1454    @deprecated Use puglSetWindowParent().
1455 */
1456 static inline PUGL_DEPRECATED_BY("puglSetParentWindow")
1457 void
puglInitWindowParent(PuglView * view,PuglNativeWindow parent)1458 puglInitWindowParent(PuglView* view, PuglNativeWindow parent)
1459 {
1460   puglSetParentWindow(view, parent);
1461 }
1462 
1463 /**
1464    Set the graphics backend to use.
1465 
1466    @deprecated Use puglSetBackend().
1467 */
1468 static inline PUGL_DEPRECATED_BY("puglSetBackend")
1469 int
puglInitBackend(PuglView * view,const PuglBackend * backend)1470 puglInitBackend(PuglView* view, const PuglBackend* backend)
1471 {
1472   return (int)puglSetBackend(view, backend);
1473 }
1474 
1475 /**
1476    Realize a view by creating a corresponding system view or window.
1477 
1478    The view should be fully configured using the above functions before this is
1479    called.  This function may only be called once per view.
1480 
1481    @deprecated Use puglRealize(), or just show the view.
1482 */
1483 static inline PUGL_DEPRECATED_BY("puglRealize")
1484 PuglStatus
puglCreateWindow(PuglView * view,const char * title)1485 puglCreateWindow(PuglView* view, const char* title)
1486 {
1487   puglSetWindowTitle(view, title);
1488   return puglRealize(view);
1489 }
1490 
1491 /**
1492    Block and wait for an event to be ready.
1493 
1494    This can be used in a loop to only process events via puglProcessEvents when
1495    necessary.  This function will block indefinitely if no events are
1496    available, so is not appropriate for use in programs that need to perform
1497    regular updates (e.g. animation).
1498 
1499    @deprecated Use puglPollEvents().
1500 */
1501 PUGL_API
1502 PUGL_DEPRECATED_BY("puglPollEvents")
1503 PuglStatus
1504 puglWaitForEvent(PuglView* view);
1505 
1506 /**
1507    Process all pending window events.
1508 
1509    This handles input events as well as rendering, so it should be called
1510    regularly and rapidly enough to keep the UI responsive.  This function does
1511    not block if no events are pending.
1512 
1513    @deprecated Use puglDispatchEvents().
1514 */
1515 PUGL_API
1516 PUGL_DEPRECATED_BY("puglDispatchEvents")
1517 PuglStatus
1518 puglProcessEvents(PuglView* view);
1519 
1520 /**
1521    Poll for events that are ready to be processed.
1522 
1523    This polls for events that are ready for any view in the world, potentially
1524    blocking depending on `timeout`.
1525 
1526    @param world The world to poll for events.
1527 
1528    @param timeout Maximum time to wait, in seconds.  If zero, the call returns
1529    immediately, if negative, the call blocks indefinitely.
1530 
1531    @return #PUGL_SUCCESS if events are read, #PUGL_FAILURE if not, or an error.
1532 
1533    @deprecated Use puglUpdate().
1534 */
1535 PUGL_API
1536 PUGL_DEPRECATED_BY("puglUpdate")
1537 PuglStatus
1538 puglPollEvents(PuglWorld* world, double timeout);
1539 
1540 /**
1541    Dispatch any pending events to views.
1542 
1543    This processes all pending events, dispatching them to the appropriate
1544    views.  View event handlers will be called in the scope of this call.  This
1545    function does not block, if no events are pending then it will return
1546    immediately.
1547 
1548    @deprecated Use puglUpdate().
1549 */
1550 PUGL_API
1551 PUGL_DEPRECATED_BY("puglUpdate")
1552 PuglStatus
1553 puglDispatchEvents(PuglWorld* world);
1554 
1555 PUGL_API
1556 PUGL_DEPRECATED_BY("puglShow")
1557 PuglStatus
1558 puglShowWindow(PuglView* view);
1559 
1560 PUGL_API
1561 PUGL_DEPRECATED_BY("puglHide")
1562 PuglStatus
1563 puglHideWindow(PuglView* view);
1564 
1565 #endif // PUGL_DISABLE_DEPRECATED
1566 
1567 /**
1568    @}
1569    @}
1570 */
1571 
1572 PUGL_END_DECLS
1573 
1574 #endif // PUGL_PUGL_H
1575