1 /*
2   Copyright 2012 David Robillard <http://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 /**
18    @file pugl.h API for Pugl, a minimal portable API for OpenGL.
19 */
20 
21 #ifndef PUGL_H_INCLUDED
22 #define PUGL_H_INCLUDED
23 
24 #include <stdint.h>
25 
26 /*
27   This API is pure portable C and contains no platform specific elements, or
28   even a GL dependency.  However, unfortunately GL includes vary across
29   platforms so they are included here to allow for pure portable programs.
30 */
31 #ifdef __APPLE__
32 #    include "OpenGL/gl.h"
33 #else
34 #    ifdef _WIN32
35 #        include <windows.h>  /* Broken Windows GL headers require this */
36 #    endif
37 #    include "GL/gl.h"
38 #endif
39 
40 #ifdef _WIN32
41 #define PUGL_API
42 #else
43 #define PUGL_API __attribute__((visibility("hidden")))
44 #endif
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #else
49 #    include <stdbool.h>
50 #endif
51 
52 /**
53    @defgroup pugl Pugl
54    A minimal portable API for OpenGL.
55    @{
56 */
57 
58 /**
59    An OpenGL view.
60 */
61 typedef struct PuglViewImpl PuglView;
62 
63 /**
64    A native window handle.
65 
66    On X11, this is a Window.
67    On OSX, this is an NSView*.
68    On Windows, this is a HWND.
69 */
70 typedef intptr_t PuglNativeWindow;
71 
72 /**
73    Return status code.
74 */
75 typedef enum {
76 	PUGL_SUCCESS = 0
77 } PuglStatus;
78 
79 /**
80    Convenience symbols for ASCII control characters.
81 */
82 typedef enum {
83 	PUGL_CHAR_BACKSPACE = 0x08,
84 	PUGL_CHAR_ESCAPE    = 0x1B,
85 	PUGL_CHAR_DELETE    = 0x7F
86 } PuglChar;
87 
88 /**
89    Special (non-Unicode) keyboard keys.
90 */
91 typedef enum {
92 	PUGL_KEY_F1 = 1,
93 	PUGL_KEY_F2,
94 	PUGL_KEY_F3,
95 	PUGL_KEY_F4,
96 	PUGL_KEY_F5,
97 	PUGL_KEY_F6,
98 	PUGL_KEY_F7,
99 	PUGL_KEY_F8,
100 	PUGL_KEY_F9,
101 	PUGL_KEY_F10,
102 	PUGL_KEY_F11,
103 	PUGL_KEY_F12,
104 	PUGL_KEY_LEFT,
105 	PUGL_KEY_UP,
106 	PUGL_KEY_RIGHT,
107 	PUGL_KEY_DOWN,
108 	PUGL_KEY_PAGE_UP,
109 	PUGL_KEY_PAGE_DOWN,
110 	PUGL_KEY_HOME,
111 	PUGL_KEY_END,
112 	PUGL_KEY_INSERT,
113 	PUGL_KEY_SHIFT,
114 	PUGL_KEY_CTRL,
115 	PUGL_KEY_ALT,
116 	PUGL_KEY_SUPER,
117 } PuglKey;
118 
119 /**
120    Keyboard modifier flags.
121 */
122 typedef enum {
123 	PUGL_MOD_SHIFT = 1,       /**< Shift key */
124 	PUGL_MOD_CTRL  = 1 << 1,  /**< Control key */
125 	PUGL_MOD_ALT   = 1 << 2,  /**< Alt/Option key */
126 	PUGL_MOD_SUPER = 1 << 3,  /**< Mod4/Command/Windows key */
127 } PuglMod;
128 
129 /**
130    Handle for opaque user data.
131 */
132 typedef void* PuglHandle;
133 
134 /**
135    A function called when the window is closed.
136 */
137 typedef void (*PuglCloseFunc)(PuglView* view);
138 
139 /**
140    A function called to draw the view contents with OpenGL.
141 */
142 typedef void (*PuglDisplayFunc)(PuglView* view);
143 
144 /**
145    A function called when a key is pressed or released.
146    @param view The view the event occured in.
147    @param press True if the key was pressed, false if released.
148    @param key Unicode point of the key pressed.
149 */
150 typedef void (*PuglKeyboardFunc)(PuglView* view, bool press, uint32_t key);
151 
152 /**
153    A function called when the pointer moves.
154    @param view The view the event occured in.
155    @param x The window-relative x coordinate of the pointer.
156    @param y The window-relative y coordinate of the pointer.
157 */
158 typedef void (*PuglMotionFunc)(PuglView* view, int x, int y);
159 
160 /**
161    A function called when a mouse button is pressed or released.
162    @param view The view the event occured in.
163    @param button The button number (1 = left, 2 = middle, 3 = right).
164    @param press True if the key was pressed, false if released.
165    @param x The window-relative x coordinate of the pointer.
166    @param y The window-relative y coordinate of the pointer.
167 */
168 typedef void (*PuglMouseFunc)(
169 	PuglView* view, int button, bool press, int x, int y);
170 
171 /**
172    A function called when the view is resized.
173    @param view The view being resized.
174    @param width The new view width.
175    @param height The new view height.
176 */
177 typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height);
178 
179 /**
180    Called outside glx-context when the plugin schedules a resize via puglPostResize.
181 
182    @param view The view being resized.
183    @param width view width to resize to (variable is initialized to current size)
184    @param height view height to resize to (variable is initialized to current size)
185    @param set_hints if non-zero set window-hints
186  */
187 typedef void (*PuglResizeFunc)(PuglView* view, int *width, int *height, int *set_hints);
188 
189 /**
190    A function called on scrolling (e.g. mouse wheel or track pad).
191 
192    The distances used here are in "lines", a single tick of a clicking mouse
193    wheel.  For example, @p dy = 1.0 scrolls 1 line up.  Some systems and
194    devices support finer resolution and/or higher values for fast scrolls,
195    so programs should handle any value gracefully.
196 
197    @param view The view being scrolled.
198    @param x The window-relative x coordinate of the pointer.
199    @param y The window-relative y coordinate of the pointer.
200    @param dx The scroll x distance.
201    @param dx The scroll y distance.
202 */
203 typedef void (*PuglScrollFunc)(PuglView* view, int x, int y, float dx, float dy);
204 
205 /**
206    A function called when a special key is pressed or released.
207 
208    This callback allows the use of keys that do not have unicode points.  Note
209    that some non-printable keys
210    @param view The view the event occured in.
211    @param press True if the key was pressed, false if released.
212    @param key The key pressed.
213 */
214 typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key);
215 
216 /**
217    A function called when a filename is selected via file-browser.
218 
219    @param view The view the event occured in.
220    @param filename The selected file name or NULL if the dialog was canceled.
221 */
222 typedef void (*PuglFileSelectedFunc)(PuglView* view, const char* filename);
223 
224 /**
225    A function called when a the main window's focus changed
226 
227    @param view The view the event occured in.
228    @param enter True when focus is recevied, false when focus is lost
229 */
230 typedef void (*PuglFocusFunc)(PuglView* view, bool enter);
231 
232 
233 /**
234    Create a new GL window.
235    @param parent Parent window, or 0 for top level.
236    @param title Window title, or NULL.
237    @param width Window width in pixels.
238    @param height Window height in pixels.
239    @param resizable Whether window should be user resizable.
240 */
241 PUGL_API PuglView*
242 puglCreate(PuglNativeWindow parent,
243            const char*      title,
244            int              min_width,
245            int              min_height,
246            int              width,
247            int              height,
248            bool             resizable,
249            bool             ontop,
250            unsigned long    transientId);
251 
252 /**
253    Set the handle to be passed to all callbacks.
254 
255    This is generally a pointer to a struct which contains all necessary state.
256    Everything needed in callbacks should be here, not in static variables.
257 
258    Note the lack of this facility makes GLUT unsuitable for plugins or
259    non-trivial programs; this mistake is largely why Pugl exists.
260 */
261 PUGL_API void
262 puglSetHandle(PuglView* view, PuglHandle handle);
263 
264 /**
265    Get the handle to be passed to all callbacks.
266 */
267 PUGL_API PuglHandle
268 puglGetHandle(PuglView* view);
269 
270 /**
271    Return the timestamp (if any) of the currently-processing event.
272 */
273 PUGL_API uint32_t
274 puglGetEventTimestamp(PuglView* view);
275 
276 /**
277    Get the currently active modifiers (PuglMod flags).
278 
279    This should only be called from an event handler.
280 */
281 PUGL_API int
282 puglGetModifiers(PuglView* view);
283 
284 /**
285    Ignore synthetic repeated key events.
286 */
287 PUGL_API void
288 puglIgnoreKeyRepeat(PuglView* view, bool ignore);
289 
290 /**
291    Set the function to call when the window is closed.
292 */
293 PUGL_API void
294 puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc);
295 
296 /**
297    Set the display function which should draw the UI using GL.
298 */
299 PUGL_API void
300 puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc);
301 
302 /**
303    Set the function to call on keyboard events.
304 */
305 PUGL_API void
306 puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc);
307 
308 /**
309    Set the function to call on mouse motion.
310 */
311 PUGL_API void
312 puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc);
313 
314 /**
315    Set the function to call on mouse button events.
316 */
317 PUGL_API void
318 puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc);
319 
320 /**
321    Set the function to call on scroll events.
322 */
323 PUGL_API void
324 puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc);
325 
326 /**
327    Set the function to call on special events.
328 */
329 PUGL_API void
330 puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);
331 
332 /**
333    Set the function to call when the window size changes.
334 */
335 PUGL_API void
336 puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
337 
338 /**
339    Set the function to call on file-browser selections.
340 */
341 PUGL_API void
342 puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
343 
344 /**
345    Set the function to call on when windows focus changes
346 */
347 PUGL_API void
348 puglSetFocusFunc(PuglView* view, PuglFocusFunc focusFunc);
349 
350 PUGL_API int
351 puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect);
352 
353 /**
354    Open a file dialog window.
355  */
356 PUGL_API int
357 puglOpenFileDialog(PuglView* view, const char *title);
358 
359 /**
360    Return the native window handle.
361 */
362 PUGL_API PuglNativeWindow
363 puglGetNativeWindow(PuglView* view);
364 
365 /**
366    Process all pending window events.
367 
368    This handles input events as well as rendering, so it should be called
369    regularly and rapidly enough to keep the UI responsive.
370 */
371 PUGL_API PuglStatus
372 puglProcessEvents(PuglView* view);
373 
374 /**
375    Request a redisplay on the next call to puglProcessEvents().
376 */
377 PUGL_API void
378 puglPostRedisplay(PuglView* view);
379 
380 /**
381    Destroy a GL window.
382 */
383 PUGL_API void
384 puglDestroy(PuglView* view);
385 
386 /**
387    Set callback function to change window size.
388 */
389 PUGL_API void
390 puglSetResizeFunc(PuglView* view, PuglResizeFunc resizeFunc);
391 
392 /**
393    Request a resize on the next call to puglProcessEvents().
394 */
395 PUGL_API void
396 puglPostResize(PuglView* view);
397 
398 /**
399    Show Window (external ui)
400  */
401 PUGL_API void
402 puglHideWindow(PuglView* view);
403 
404 /**
405    Hide Window (external ui)
406  */
407 PUGL_API void
408 puglShowWindow(PuglView* view);
409 
410 /**
411    @}
412 */
413 
414 #ifdef __cplusplus
415 }  /* extern "C" */
416 #endif
417 
418 #endif  /* PUGL_H_INCLUDED */
419