1 /*
2   Copyright 2012-2014 David Robillard <http://drobilla.net>
3   Copyright 2012-2019 Filipe Coelho <falktx@falktx.com>
4 
5   Permission to use, copy, modify, and/or distribute this software for any
6   purpose with or without fee is hereby granted, provided that the above
7   copyright notice and this permission notice appear in all copies.
8 
9   THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10   WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11   MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12   ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13   WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14   ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17 
18 /**
19    @file pugl.h API for Pugl, a minimal portable API for OpenGL.
20 */
21 
22 #ifndef PUGL_H_INCLUDED
23 #define PUGL_H_INCLUDED
24 
25 #include <stdint.h>
26 
27 /*
28   This API is pure portable C and contains no platform specific elements, or
29   even a GL dependency.  However, unfortunately GL includes vary across
30   platforms so they are included here to allow for pure portable programs.
31 */
32 #ifdef __APPLE__
33 #    include <OpenGL/gl.h>
34 #else
35 #    ifdef _WIN32
36 #        include <winsock2.h>
37 #        include <windows.h>  /* Broken Windows GL headers require this */
38 #    endif
39 #    include <GL/gl.h>
40 #endif
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #else
45 #    include <stdbool.h>
46 #endif
47 
48 /**
49    @defgroup pugl Pugl
50    A minimal portable API for OpenGL.
51    @{
52 */
53 
54 /**
55    A Pugl view.
56 */
57 typedef struct PuglViewImpl PuglView;
58 
59 /**
60    A native window handle.
61 
62    On X11, this is a Window.
63    On OSX, this is an NSView*.
64    On Windows, this is a HWND.
65 */
66 typedef intptr_t PuglNativeWindow;
67 
68 /**
69    Return status code.
70 */
71 typedef enum {
72 	PUGL_SUCCESS = 0
73 } PuglStatus;
74 
75 /**
76    Convenience symbols for ASCII control characters.
77 */
78 typedef enum {
79 	PUGL_CHAR_BACKSPACE = 0x08,
80 	PUGL_CHAR_ESCAPE    = 0x1B,
81 	PUGL_CHAR_DELETE    = 0x7F
82 } PuglChar;
83 
84 /**
85    Special (non-Unicode) keyboard keys.
86 */
87 typedef enum {
88 	PUGL_KEY_F1 = 1,
89 	PUGL_KEY_F2,
90 	PUGL_KEY_F3,
91 	PUGL_KEY_F4,
92 	PUGL_KEY_F5,
93 	PUGL_KEY_F6,
94 	PUGL_KEY_F7,
95 	PUGL_KEY_F8,
96 	PUGL_KEY_F9,
97 	PUGL_KEY_F10,
98 	PUGL_KEY_F11,
99 	PUGL_KEY_F12,
100 	PUGL_KEY_LEFT,
101 	PUGL_KEY_UP,
102 	PUGL_KEY_RIGHT,
103 	PUGL_KEY_DOWN,
104 	PUGL_KEY_PAGE_UP,
105 	PUGL_KEY_PAGE_DOWN,
106 	PUGL_KEY_HOME,
107 	PUGL_KEY_END,
108 	PUGL_KEY_INSERT,
109 	PUGL_KEY_SHIFT,
110 	PUGL_KEY_CTRL,
111 	PUGL_KEY_ALT,
112 	PUGL_KEY_SUPER
113 } PuglKey;
114 
115 /**
116    Keyboard modifier flags.
117 */
118 typedef enum {
119 	PUGL_MOD_SHIFT = 1 << 0,  /**< Shift key */
120 	PUGL_MOD_CTRL  = 1 << 1,  /**< Control key */
121 	PUGL_MOD_ALT   = 1 << 2,  /**< Alt/Option key */
122 	PUGL_MOD_SUPER = 1 << 3   /**< Mod4/Command/Windows key */
123 } PuglMod;
124 
125 /**
126    Handle for opaque user data.
127 */
128 typedef void* PuglHandle;
129 
130 /**
131    A function called when the window is closed.
132 */
133 typedef void (*PuglCloseFunc)(PuglView* view);
134 
135 /**
136    A function called to draw the view contents with OpenGL.
137 */
138 typedef void (*PuglDisplayFunc)(PuglView* view);
139 
140 /**
141    A function called when a key is pressed or released.
142    @param view The view the event occured in.
143    @param press True if the key was pressed, false if released.
144    @param key Unicode point of the key pressed.
145    @return 0 if event was handled, otherwise send event to parent window.
146 */
147 typedef int (*PuglKeyboardFunc)(PuglView* view, bool press, uint32_t key);
148 
149 /**
150    A function called when the pointer moves.
151    @param view The view the event occured in.
152    @param x The window-relative x coordinate of the pointer.
153    @param y The window-relative y coordinate of the pointer.
154 */
155 typedef void (*PuglMotionFunc)(PuglView* view, int x, int y);
156 
157 /**
158    A function called when a mouse button is pressed or released.
159    @param view The view the event occured in.
160    @param button The button number (1 = left, 2 = middle, 3 = right).
161    @param press True if the key was pressed, false if released.
162    @param x The window-relative x coordinate of the pointer.
163    @param y The window-relative y coordinate of the pointer.
164 */
165 typedef void (*PuglMouseFunc)(
166 	PuglView* view, int button, bool press, int x, int y);
167 
168 /**
169    A function called when the view is resized.
170    @param view The view being resized.
171    @param width The new view width.
172    @param height The new view height.
173 */
174 typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height);
175 
176 /**
177    A function called outside of gl-context when the plugin schedules a resize via puglPostResize.
178 
179    @param view The view being resized.
180    @param width The new width to resize to (variable is initialized to current size)
181    @param height The new height to resize to (variable is initialized to current size)
182    @param set_hints If not null, set window-hints
183  */
184 typedef void (*PuglResizeFunc)(PuglView* view, int *width, int *height, int *set_hints);
185 
186 /**
187    A function called on scrolling (e.g. mouse wheel or track pad).
188 
189    The distances used here are in "lines", a single tick of a clicking mouse
190    wheel.  For example, @p dy = 1.0 scrolls 1 line up.  Some systems and
191    devices support finer resolution and/or higher values for fast scrolls,
192    so programs should handle any value gracefully.
193 
194    @param view The view being scrolled.
195    @param x The window-relative x coordinate of the pointer.
196    @param y The window-relative y coordinate of the pointer.
197    @param dx The scroll x distance.
198    @param dx The scroll y distance.
199 */
200 typedef void (*PuglScrollFunc)(PuglView* view, int x, int y, float dx, float dy);
201 
202 /**
203    A function called when a special key is pressed or released.
204 
205    This callback allows the use of keys that do not have unicode points.
206    Note that some are non-printable keys.
207 
208    @param view The view the event occured in.
209    @param press True if the key was pressed, false if released.
210    @param key The key pressed.
211    @return 0 if event was handled, otherwise send event to parent window.
212 */
213 typedef int (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key);
214 
215 /**
216    A function called when a filename is selected via file-browser.
217 
218    @param view The view the event occured in.
219    @param filename The selected file name or NULL if the dialog was canceled.
220 */
221 typedef void (*PuglFileSelectedFunc)(PuglView* view, const char* filename);
222 
223 /**
224    @name Initialization
225    Configuration functions which must be called before creating a window.
226    @{
227 */
228 
229 /**
230    Create a Pugl context.
231 
232    To create a window, call the various puglInit* functions as necessary, then
233    call puglCreateWindow().
234 */
235 PuglView*
236 puglInit(void);
237 
238 /**
239    Set the parent window before creating a window (for embedding).
240 */
241 void
242 puglInitWindowParent(PuglView* view, PuglNativeWindow parent);
243 
244 /**
245    Set the window size before creating a window.
246 */
247 void
248 puglInitWindowSize(PuglView* view, int width, int height);
249 
250 /**
251    Set the minimum window size before creating a window.
252 */
253 void
254 puglInitWindowMinSize(PuglView* view, int width, int height);
255 
256 /**
257    Enable or disable resizing before creating a window.
258 */
259 void
260 puglInitUserResizable(PuglView* view, bool resizable);
261 
262 /**
263    Set transient parent before creating a window.
264 
265    On X11, parent_id must be a Window.
266    On OSX, parent_id must be an NSView*.
267 */
268 void
269 puglInitTransientFor(PuglView* view, uintptr_t parent);
270 
271 /**
272    @}
273 */
274 
275 /**
276    @name Windows
277    Window management functions.
278    @{
279 */
280 
281 /**
282    Create a window with the settings given by the various puglInit functions.
283 
284    @return 1 (pugl does not currently support multiple windows).
285 */
286 int
287 puglCreateWindow(PuglView* view, const char* title);
288 
289 /**
290    Create a new GL window.
291    @param parent Parent window, or 0 for top level.
292    @param title Window title, or NULL.
293    @param width Window width in pixels.
294    @param height Window height in pixels.
295    @param resizable Whether window should be user resizable.
296 */
297 PuglView*
298 puglCreate(PuglNativeWindow parent,
299            const char*      title,
300            int              min_width,
301            int              min_height,
302            int              width,
303            int              height,
304            bool             resizable,
305            unsigned long    transientId);
306 
307 /**
308    Show Window (external ui)
309 */
310 void
311 puglShowWindow(PuglView* view);
312 
313 /**
314    Hide Window (external ui)
315 */
316 void
317 puglHideWindow(PuglView* view);
318 
319 /**
320    Return the native window handle.
321 */
322 PuglNativeWindow
323 puglGetNativeWindow(PuglView* view);
324 
325 /**
326    @}
327 */
328 
329 /**
330    Set the handle to be passed to all callbacks.
331 
332    This is generally a pointer to a struct which contains all necessary state.
333    Everything needed in callbacks should be here, not in static variables.
334 
335    Note the lack of this facility makes GLUT unsuitable for plugins or
336    non-trivial programs; this mistake is largely why Pugl exists.
337 */
338 void
339 puglSetHandle(PuglView* view, PuglHandle handle);
340 
341 /**
342    Get the handle to be passed to all callbacks.
343 */
344 PuglHandle
345 puglGetHandle(PuglView* view);
346 
347 /**
348    Get the drawing context.
349    For Cairo contexts, this returns a pointer to a cairo_t.
350    For everything else, this is unused and returns NULL.
351 */
352 void*
353 puglGetContext(PuglView* view);
354 
355 /**
356    Return the timestamp (if any) of the currently-processing event.
357 */
358 uint32_t
359 puglGetEventTimestamp(PuglView* view);
360 
361 /**
362    Get the currently active modifiers (PuglMod flags).
363 
364    This should only be called from an event handler.
365 */
366 int
367 puglGetModifiers(PuglView* view);
368 
369 /**
370    Ignore synthetic repeated key events.
371 */
372 void
373 puglIgnoreKeyRepeat(PuglView* view, bool ignore);
374 
375 /**
376    @name Event Callbacks
377    Functions to set event callbacks for handling user input.
378    @{
379 */
380 
381 /**
382    Set the function to call when the window is closed.
383 */
384 void
385 puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc);
386 
387 /**
388    Set the display function which should draw the UI using GL.
389 */
390 void
391 puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc);
392 
393 /**
394    Set the function to call on keyboard events.
395 */
396 void
397 puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc);
398 
399 /**
400    Set the function to call on mouse motion.
401 */
402 void
403 puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc);
404 
405 /**
406    Set the function to call on mouse button events.
407 */
408 void
409 puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc);
410 
411 /**
412    Set the function to call on scroll events.
413 */
414 void
415 puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc);
416 
417 /**
418    Set the function to call on special events.
419 */
420 void
421 puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);
422 
423 /**
424    Set the function to call when the window size changes.
425 */
426 void
427 puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
428 
429 /**
430    Set callback function to change window size.
431 */
432 void
433 puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc);
434 
435 /**
436    Set the function to call on file-browser selections.
437 */
438 void
439 puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
440 
441 /**
442    @}
443 */
444 
445 /**
446    TODO document this.
447  */
448 int
449 puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect);
450 
451 /**
452    Grab the input focus.
453 */
454 void
455 puglGrabFocus(PuglView* view);
456 
457 /**
458    Process all pending window events.
459 
460    This handles input events as well as rendering, so it should be called
461    regularly and rapidly enough to keep the UI responsive.
462 */
463 PuglStatus
464 puglProcessEvents(PuglView* view);
465 
466 /**
467    Request a redisplay on the next call to puglProcessEvents().
468 */
469 void
470 puglPostRedisplay(PuglView* view);
471 
472 /**
473    Request a resize on the next call to puglProcessEvents().
474 */
475 void
476 puglPostResize(PuglView* view);
477 
478 /**
479    Destroy a GL window.
480 */
481 void
482 puglDestroy(PuglView* view);
483 
484 /**
485    @}
486 */
487 
488 #ifdef __cplusplus
489 }  /* extern "C" */
490 #endif
491 
492 #endif  /* PUGL_H_INCLUDED */
493