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