1 /* 2 Copyright 2012-2016 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 <stdbool.h> 25 #include <stdint.h> 26 27 #ifdef PUGL_SHARED 28 # ifdef _WIN32 29 # define PUGL_LIB_IMPORT __declspec(dllimport) 30 # define PUGL_LIB_EXPORT __declspec(dllexport) 31 # else 32 # define PUGL_LIB_IMPORT __attribute__((visibility("default"))) 33 # define PUGL_LIB_EXPORT __attribute__((visibility("default"))) 34 # endif 35 # ifdef PUGL_INTERNAL 36 # define PUGL_API PUGL_LIB_EXPORT 37 # else 38 # define PUGL_API PUGL_LIB_IMPORT 39 # endif 40 #else 41 # define PUGL_API 42 #endif 43 44 #ifdef __cplusplus 45 extern "C" { 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 Handle for opaque user data. 70 */ 71 typedef void* PuglHandle; 72 73 /** 74 Return status code. 75 */ 76 typedef enum { 77 PUGL_SUCCESS = 0 78 } PuglStatus; 79 80 /** 81 Drawing context type. 82 */ 83 typedef enum { 84 PUGL_GL = 1 << 0, /**< OpenGL (3D) */ 85 PUGL_CAIRO = 1 << 1 /**< Cairo (2D) */ 86 } PuglContextType; 87 88 /** 89 Window hint. 90 */ 91 typedef enum { 92 PUGL_USE_COMPAT_PROFILE, /**< Use compatible (not core) OpenGL profile */ 93 PUGL_CONTEXT_VERSION_MAJOR, /**< OpenGL context major version */ 94 PUGL_CONTEXT_VERSION_MINOR, /**< OpenGL context minor version */ 95 PUGL_RED_BITS, /**< Number of bits for red channel */ 96 PUGL_GREEN_BITS, /**< Number of bits for green channel */ 97 PUGL_BLUE_BITS, /**< Number of bits for blue channel */ 98 PUGL_ALPHA_BITS, /**< Number of bits for alpha channel */ 99 PUGL_DEPTH_BITS, /**< Number of bits for depth buffer */ 100 PUGL_STENCIL_BITS, /**< Number of bits for stencil buffer */ 101 PUGL_SAMPLES, /**< Number of samples per pixel (AA) */ 102 PUGL_DOUBLE_BUFFER, /**< True if double buffering should be used */ 103 PUGL_RESIZABLE, /**< True if window should be resizable */ 104 } PuglWindowHint; 105 106 /** 107 Special window hint value. 108 */ 109 typedef enum { 110 PUGL_DONT_CARE = -1, /**< Use best available value */ 111 PUGL_FALSE = 0, /**< Explicitly false */ 112 PUGL_TRUE = 1 /**< Explicitly true */ 113 } PuglWindowHintValue; 114 115 /** 116 Convenience symbols for ASCII control characters. 117 */ 118 typedef enum { 119 PUGL_CHAR_BACKSPACE = 0x08, 120 PUGL_CHAR_ESCAPE = 0x1B, 121 PUGL_CHAR_DELETE = 0x7F 122 } PuglChar; 123 124 /** 125 Keyboard modifier flags. 126 */ 127 typedef enum { 128 PUGL_MOD_SHIFT = 1, /**< Shift key */ 129 PUGL_MOD_CTRL = 1 << 1, /**< Control key */ 130 PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */ 131 PUGL_MOD_SUPER = 1 << 3 /**< Mod4/Command/Windows key */ 132 } PuglMod; 133 134 /** 135 Special (non-Unicode) keyboard keys. 136 137 The numerical values of these symbols occupy a reserved range of Unicode 138 points, so it is possible to express either a PuglKey value or a Unicode 139 character in the same variable. This is sometimes useful for interfacing 140 with APIs that do not make this distinction. 141 */ 142 typedef enum { 143 PUGL_KEY_F1 = 0xE000, 144 PUGL_KEY_F2, 145 PUGL_KEY_F3, 146 PUGL_KEY_F4, 147 PUGL_KEY_F5, 148 PUGL_KEY_F6, 149 PUGL_KEY_F7, 150 PUGL_KEY_F8, 151 PUGL_KEY_F9, 152 PUGL_KEY_F10, 153 PUGL_KEY_F11, 154 PUGL_KEY_F12, 155 PUGL_KEY_LEFT, 156 PUGL_KEY_UP, 157 PUGL_KEY_RIGHT, 158 PUGL_KEY_DOWN, 159 PUGL_KEY_PAGE_UP, 160 PUGL_KEY_PAGE_DOWN, 161 PUGL_KEY_HOME, 162 PUGL_KEY_END, 163 PUGL_KEY_INSERT, 164 PUGL_KEY_SHIFT, 165 PUGL_KEY_CTRL, 166 PUGL_KEY_ALT, 167 PUGL_KEY_SUPER 168 } PuglKey; 169 170 /** 171 The type of a PuglEvent. 172 */ 173 typedef enum { 174 PUGL_NOTHING, /**< No event */ 175 PUGL_BUTTON_PRESS, /**< Mouse button press */ 176 PUGL_BUTTON_RELEASE, /**< Mouse button release */ 177 PUGL_CONFIGURE, /**< View moved and/or resized */ 178 PUGL_EXPOSE, /**< View exposed, redraw required */ 179 PUGL_CLOSE, /**< Close view */ 180 PUGL_KEY_PRESS, /**< Key press */ 181 PUGL_KEY_RELEASE, /**< Key release */ 182 PUGL_ENTER_NOTIFY, /**< Pointer entered view */ 183 PUGL_LEAVE_NOTIFY, /**< Pointer left view */ 184 PUGL_MOTION_NOTIFY, /**< Pointer motion */ 185 PUGL_SCROLL, /**< Scroll */ 186 PUGL_FOCUS_IN, /**< Keyboard focus entered view */ 187 PUGL_FOCUS_OUT /**< Keyboard focus left view */ 188 } PuglEventType; 189 190 typedef enum { 191 PUGL_IS_SEND_EVENT = 1 192 } PuglEventFlag; 193 194 /** 195 Reason for a PuglEventCrossing. 196 */ 197 typedef enum { 198 PUGL_CROSSING_NORMAL, /**< Crossing due to pointer motion. */ 199 PUGL_CROSSING_GRAB, /**< Crossing due to a grab. */ 200 PUGL_CROSSING_UNGRAB /**< Crossing due to a grab release. */ 201 } PuglCrossingMode; 202 203 /** 204 Common header for all event structs. 205 */ 206 typedef struct { 207 PuglEventType type; /**< Event type. */ 208 PuglView* view; /**< View that received this event. */ 209 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 210 } PuglEventAny; 211 212 /** 213 Button press or release event. 214 215 For event types PUGL_BUTTON_PRESS and PUGL_BUTTON_RELEASE. 216 */ 217 typedef struct { 218 PuglEventType type; /**< PUGL_BUTTON_PRESS or PUGL_BUTTON_RELEASE. */ 219 PuglView* view; /**< View that received this event. */ 220 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 221 uint32_t time; /**< Time in milliseconds. */ 222 double x; /**< View-relative X coordinate. */ 223 double y; /**< View-relative Y coordinate. */ 224 double x_root; /**< Root-relative X coordinate. */ 225 double y_root; /**< Root-relative Y coordinate. */ 226 unsigned state; /**< Bitwise OR of PuglMod flags. */ 227 unsigned button; /**< 1-relative button number. */ 228 } PuglEventButton; 229 230 /** 231 Configure event for when window size or position has changed. 232 */ 233 typedef struct { 234 PuglEventType type; /**< PUGL_CONFIGURE. */ 235 PuglView* view; /**< View that received this event. */ 236 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 237 double x; /**< New parent-relative X coordinate. */ 238 double y; /**< New parent-relative Y coordinate. */ 239 double width; /**< New width. */ 240 double height; /**< New height. */ 241 } PuglEventConfigure; 242 243 /** 244 Expose event for when a region must be redrawn. 245 */ 246 typedef struct { 247 PuglEventType type; /**< PUGL_EXPOSE. */ 248 PuglView* view; /**< View that received this event. */ 249 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 250 double x; /**< View-relative X coordinate. */ 251 double y; /**< View-relative Y coordinate. */ 252 double width; /**< Width of exposed region. */ 253 double height; /**< Height of exposed region. */ 254 int count; /**< Number of expose events to follow. */ 255 } PuglEventExpose; 256 257 /** 258 Window close event. 259 */ 260 typedef struct { 261 PuglEventType type; /**< PUGL_CLOSE. */ 262 PuglView* view; /**< View that received this event. */ 263 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 264 } PuglEventClose; 265 266 /** 267 Key press/release event. 268 269 Keys that correspond to a Unicode character have `character` and `utf8` set. 270 Other keys will have `character` 0, but `special` may be set if this is a 271 known special key. 272 273 A key press may be part of a multi-key sequence to generate a wide 274 character. If `filter` is set, this event is part of a multi-key sequence 275 and should be ignored if the application is reading textual input. 276 Following the series of filtered press events, a press event with 277 `character` and `utf8` (but `keycode` 0) will be sent. This event will have 278 no corresponding release event. 279 280 Generally, an application should either work with raw keyboard press/release 281 events based on `keycode` (ignoring events with `keycode` 0), or 282 read textual input based on `character` or `utf8` (ignoring releases and 283 events with `filter` 1). Note that blindly appending `utf8` will yield 284 incorrect text, since press events are sent for both individually composed 285 keys and the resulting synthetic multi-byte press. 286 */ 287 typedef struct { 288 PuglEventType type; /**< PUGL_KEY_PRESS or PUGL_KEY_RELEASE. */ 289 PuglView* view; /**< View that received this event. */ 290 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 291 uint32_t time; /**< Time in milliseconds. */ 292 double x; /**< View-relative X coordinate. */ 293 double y; /**< View-relative Y coordinate. */ 294 double x_root; /**< Root-relative X coordinate. */ 295 double y_root; /**< Root-relative Y coordinate. */ 296 unsigned state; /**< Bitwise OR of PuglMod flags. */ 297 unsigned keycode; /**< Raw key code. */ 298 uint32_t character; /**< Unicode character code, or 0. */ 299 PuglKey special; /**< Special key, or 0. */ 300 uint8_t utf8[8]; /**< UTF-8 string. */ 301 bool filter; /**< True if part of a multi-key sequence. */ 302 } PuglEventKey; 303 304 /** 305 Pointer crossing event (enter and leave). 306 */ 307 typedef struct { 308 PuglEventType type; /**< PUGL_ENTER_NOTIFY or PUGL_LEAVE_NOTIFY. */ 309 PuglView* view; /**< View that received this event. */ 310 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 311 uint32_t time; /**< Time in milliseconds. */ 312 double x; /**< View-relative X coordinate. */ 313 double y; /**< View-relative Y coordinate. */ 314 double x_root; /**< Root-relative X coordinate. */ 315 double y_root; /**< Root-relative Y coordinate. */ 316 unsigned state; /**< Bitwise OR of PuglMod flags. */ 317 PuglCrossingMode mode; /**< Reason for crossing. */ 318 } PuglEventCrossing; 319 320 /** 321 Pointer motion event. 322 */ 323 typedef struct { 324 PuglEventType type; /**< PUGL_MOTION_NOTIFY. */ 325 PuglView* view; /**< View that received this event. */ 326 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 327 uint32_t time; /**< Time in milliseconds. */ 328 double x; /**< View-relative X coordinate. */ 329 double y; /**< View-relative Y coordinate. */ 330 double x_root; /**< Root-relative X coordinate. */ 331 double y_root; /**< Root-relative Y coordinate. */ 332 unsigned state; /**< Bitwise OR of PuglMod flags. */ 333 bool is_hint; /**< True iff this event is a motion hint. */ 334 bool focus; /**< True iff this is the focused window. */ 335 } PuglEventMotion; 336 337 /** 338 Scroll event. 339 340 The scroll distance is expressed in "lines", an arbitrary unit that 341 corresponds to a single tick of a detented mouse wheel. For example, `dy` = 342 1.0 scrolls 1 line up. Some systems and devices support finer resolution 343 and/or higher values for fast scrolls, so programs should handle any value 344 gracefully. 345 */ 346 typedef struct { 347 PuglEventType type; /**< PUGL_SCROLL. */ 348 PuglView* view; /**< View that received this event. */ 349 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 350 uint32_t time; /**< Time in milliseconds. */ 351 double x; /**< View-relative X coordinate. */ 352 double y; /**< View-relative Y coordinate. */ 353 double x_root; /**< Root-relative X coordinate. */ 354 double y_root; /**< Root-relative Y coordinate. */ 355 unsigned state; /**< Bitwise OR of PuglMod flags. */ 356 double dx; /**< Scroll X distance in lines. */ 357 double dy; /**< Scroll Y distance in lines. */ 358 } PuglEventScroll; 359 360 /** 361 Keyboard focus event. 362 */ 363 typedef struct { 364 PuglEventType type; /**< PUGL_FOCUS_IN or PUGL_FOCUS_OUT. */ 365 PuglView* view; /**< View that received this event. */ 366 uint32_t flags; /**< Bitwise OR of PuglEventFlag values. */ 367 bool grab; /**< True iff this is a grab/ungrab event. */ 368 } PuglEventFocus; 369 370 /** 371 Interface event. 372 373 This is a union of all event structs. The `type` must be checked to 374 determine which fields are safe to access. A pointer to PuglEvent can 375 either be cast to the appropriate type, or the union members used. 376 */ 377 typedef union { 378 PuglEventType type; /**< Event type. */ 379 PuglEventAny any; /**< Valid for all event types. */ 380 PuglEventButton button; /**< PUGL_BUTTON_PRESS, PUGL_BUTTON_RELEASE. */ 381 PuglEventConfigure configure; /**< PUGL_CONFIGURE. */ 382 PuglEventExpose expose; /**< PUGL_EXPOSE. */ 383 PuglEventClose close; /**< PUGL_CLOSE. */ 384 PuglEventKey key; /**< PUGL_KEY_PRESS, PUGL_KEY_RELEASE. */ 385 PuglEventCrossing crossing; /**< PUGL_ENTER_NOTIFY, PUGL_LEAVE_NOTIFY. */ 386 PuglEventMotion motion; /**< PUGL_MOTION_NOTIFY. */ 387 PuglEventScroll scroll; /**< PUGL_SCROLL. */ 388 PuglEventFocus focus; /**< PUGL_FOCUS_IN, PUGL_FOCUS_OUT. */ 389 } PuglEvent; 390 391 /** 392 @name Initialization 393 Configuration functions which must be called before creating a window. 394 @{ 395 */ 396 397 /** 398 Create a Pugl view. 399 400 To create a window, call the various puglInit* functions as necessary, then 401 call puglCreateWindow(). 402 403 @param pargc Pointer to argument count (currently unused). 404 @param argv Arguments (currently unused). 405 @return A newly created view. 406 */ 407 PUGL_API PuglView* 408 puglInit(int* pargc, char** argv); 409 410 /** 411 Set a hint before creating a window. 412 */ 413 PUGL_API void 414 puglInitWindowHint(PuglView* view, PuglWindowHint hint, int value); 415 416 /** 417 Set the window class name before creating a window. 418 */ 419 PUGL_API void 420 puglInitWindowClass(PuglView* view, const char* name); 421 422 /** 423 Set the parent window before creating a window (for embedding). 424 */ 425 PUGL_API void 426 puglInitWindowParent(PuglView* view, PuglNativeWindow parent); 427 428 /** 429 Set the window size before creating a window. 430 */ 431 PUGL_API void 432 puglInitWindowSize(PuglView* view, int width, int height); 433 434 /** 435 Set the minimum window size before creating a window. 436 */ 437 PUGL_API void 438 puglInitWindowMinSize(PuglView* view, int width, int height); 439 440 /** 441 Set the window aspect ratio range before creating a window. 442 443 The x and y values here represent a ratio of width to height. To set a 444 fixed aspect ratio, set the minimum and maximum values to the same ratio. 445 */ 446 PUGL_API void 447 puglInitWindowAspectRatio(PuglView* view, 448 int min_x, 449 int min_y, 450 int max_x, 451 int max_y); 452 453 /** 454 Enable or disable resizing before creating a window. 455 */ 456 PUGL_API void 457 puglInitResizable(PuglView* view, bool resizable); 458 459 /** 460 Set transient parent before creating a window. 461 462 On X11, parent must be a Window. 463 On OSX, parent must be an NSView*. 464 */ 465 PUGL_API void 466 puglInitTransientFor(PuglView* view, uintptr_t parent); 467 468 /** 469 Set the context type before creating a window. 470 */ 471 PUGL_API void 472 puglInitContextType(PuglView* view, PuglContextType type); 473 474 /** 475 @} 476 */ 477 478 /** 479 @name Windows 480 Functions for creating and managing a visible window for a view. 481 @{ 482 */ 483 484 /** 485 Create a window with the settings given by the various puglInit functions. 486 487 @return 1 (pugl does not currently support multiple windows). 488 */ 489 PUGL_API int 490 puglCreateWindow(PuglView* view, const char* title); 491 492 /** 493 Show the current window. 494 */ 495 PUGL_API void 496 puglShowWindow(PuglView* view); 497 498 /** 499 Hide the current window. 500 */ 501 PUGL_API void 502 puglHideWindow(PuglView* view); 503 504 /** 505 Return the native window handle. 506 */ 507 PUGL_API PuglNativeWindow 508 puglGetNativeWindow(PuglView* view); 509 510 /** 511 @} 512 */ 513 514 /** 515 Set the handle to be passed to all callbacks. 516 517 This is generally a pointer to a struct which contains all necessary state. 518 Everything needed in callbacks should be here, not in static variables. 519 */ 520 PUGL_API void 521 puglSetHandle(PuglView* view, PuglHandle handle); 522 523 /** 524 Get the handle to be passed to all callbacks. 525 */ 526 PUGL_API PuglHandle 527 puglGetHandle(PuglView* view); 528 529 /** 530 Return true iff the view is currently visible. 531 */ 532 PUGL_API bool 533 puglGetVisible(PuglView* view); 534 535 /** 536 Get the current size of the view. 537 */ 538 PUGL_API void 539 puglGetSize(PuglView* view, int* width, int* height); 540 541 /** 542 @name Context 543 Functions for accessing the drawing context. 544 @{ 545 */ 546 547 /** 548 Get the drawing context. 549 550 For PUGL_GL contexts, this is unused and returns NULL. 551 For PUGL_CAIRO contexts, this returns a pointer to a cairo_t. 552 */ 553 PUGL_API void* 554 puglGetContext(PuglView* view); 555 556 /** 557 Enter the drawing context. 558 559 This must be called before any code that accesses the drawing context, 560 including any GL functions. This is only necessary for code that does so 561 outside the usual draw callback or handling of an expose event. 562 */ 563 PUGL_API void 564 puglEnterContext(PuglView* view); 565 566 /** 567 Leave the drawing context. 568 569 This must be called after puglEnterContext and applies the results of the 570 drawing code (for example, by swapping buffers). 571 */ 572 PUGL_API void 573 puglLeaveContext(PuglView* view, bool flush); 574 575 /** 576 @} 577 */ 578 579 /** 580 @name Event Handling 581 @{ 582 */ 583 584 /** 585 A function called when an event occurs. 586 */ 587 typedef void (*PuglEventFunc)(PuglView* view, const PuglEvent* event); 588 589 /** 590 Set the function to call when an event occurs. 591 */ 592 PUGL_API void 593 puglSetEventFunc(PuglView* view, PuglEventFunc eventFunc); 594 595 /** 596 Ignore synthetic repeated key events. 597 */ 598 PUGL_API void 599 puglIgnoreKeyRepeat(PuglView* view, bool ignore); 600 601 /** 602 Grab the input focus. 603 */ 604 PUGL_API void 605 puglGrabFocus(PuglView* view); 606 607 /** 608 Block and wait for an event to be ready. 609 610 This can be used in a loop to only process events via puglProcessEvents when 611 necessary. This function will block indefinitely if no events are 612 available, so is not appropriate for use in programs that need to perform 613 regular updates (e.g. animation). 614 */ 615 PUGL_API PuglStatus 616 puglWaitForEvent(PuglView* view); 617 618 /** 619 Process all pending window events. 620 621 This handles input events as well as rendering, so it should be called 622 regularly and rapidly enough to keep the UI responsive. This function does 623 not block if no events are pending. 624 */ 625 PUGL_API PuglStatus 626 puglProcessEvents(PuglView* view); 627 628 /** 629 @} 630 */ 631 632 /** 633 OpenGL extension function. 634 */ 635 typedef void (*PuglGlFunc)(); 636 637 /** 638 Return the address of an OpenGL extension function. 639 */ 640 PUGL_API PuglGlFunc 641 puglGetProcAddress(const char* name); 642 643 /** 644 Request a redisplay on the next call to puglProcessEvents(). 645 */ 646 PUGL_API void 647 puglPostRedisplay(PuglView* view); 648 649 /** 650 Destroy a GL window. 651 */ 652 PUGL_API void 653 puglDestroy(PuglView* view); 654 655 /** 656 @} 657 */ 658 659 #ifdef __cplusplus 660 } /* extern "C" */ 661 #endif 662 663 #endif /* PUGL_H_INCLUDED */ 664