rcore_desktop_rgfw.c (49130B)
1 /********************************************************************************************** 2 * 3 * rcore_desktop_rgfw - Functions to manage window, graphics device and inputs 4 * 5 * PLATFORM: RGFW 6 * - Windows (Win32, Win64) 7 * - Linux (X11/Wayland desktop mode) 8 * - MacOS (Cocoa) 9 * 10 * LIMITATIONS: 11 * - TODO 12 * 13 * POSSIBLE IMPROVEMENTS: 14 * - TODO 15 * 16 * ADDITIONAL NOTES: 17 * - TRACELOG() function is located in raylib [utils] module 18 * 19 * CONFIGURATION: 20 * #define RCORE_PLATFORM_RGFW 21 * Custom flag for rcore on target platform RGFW 22 * 23 * DEPENDENCIES: 24 * - RGFW.h (main library): Windowing and inputs management 25 * - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs) 26 * 27 * 28 * LICENSE: zlib/libpng 29 * 30 * Copyright (c) 2013-2024 Ramon Santamaria (@raysan5), Colleague Riley and contributors 31 * 32 * This software is provided "as-is", without any express or implied warranty. In no event 33 * will the authors be held liable for any damages arising from the use of this software. 34 * 35 * Permission is granted to anyone to use this software for any purpose, including commercial 36 * applications, and to alter it and redistribute it freely, subject to the following restrictions: 37 * 38 * 1. The origin of this software must not be misrepresented; you must not claim that you 39 * wrote the original software. If you use this software in a product, an acknowledgment 40 * in the product documentation would be appreciated but is not required. 41 * 42 * 2. Altered source versions must be plainly marked as such, and must not be misrepresented 43 * as being the original software. 44 * 45 * 3. This notice may not be removed or altered from any source distribution. 46 * 47 **********************************************************************************************/ 48 49 #if defined(GRAPHICS_API_OPENGL_ES2) 50 #define RGFW_OPENGL_ES2 51 #endif 52 53 void ShowCursor(void); 54 void CloseWindow(void); 55 56 #if defined(__linux__) 57 #define _INPUT_EVENT_CODES_H 58 #endif 59 60 #if defined(__unix__) || defined(__linux__) 61 #define _XTYPEDEF_FONT 62 #endif 63 64 #define RGFW_IMPLEMENTATION 65 66 #if defined(_WIN32) || defined(_WIN64) 67 #define WIN32_LEAN_AND_MEAN 68 #define Rectangle rectangle_win32 69 #define CloseWindow CloseWindow_win32 70 #define ShowCursor __imp_ShowCursor 71 #define _APISETSTRING_ 72 73 #undef MAX_PATH 74 75 __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int CodePage, unsigned long dwFlags, const char *lpMultiByteStr, int cbMultiByte, wchar_t *lpWideCharStr, int cchWideChar); 76 #endif 77 78 #if defined(__APPLE__) 79 #define Point NSPOINT 80 #define Size NSSIZE 81 #endif 82 83 #include "../external/RGFW.h" 84 85 #if defined(_WIN32) || defined(_WIN64) 86 #undef DrawText 87 #undef ShowCursor 88 #undef CloseWindow 89 #undef Rectangle 90 91 #undef MAX_PATH 92 #define MAX_PATH 1025 93 #endif 94 95 #if defined(__APPLE__) 96 #undef Point 97 #undef Size 98 #endif 99 100 #include <stdbool.h> 101 #include <string.h> // Required for: strcmp() 102 103 //---------------------------------------------------------------------------------- 104 // Types and Structures Definition 105 //---------------------------------------------------------------------------------- 106 typedef struct { 107 RGFW_window *window; // Native display device (physical screen connection) 108 } PlatformData; 109 110 //---------------------------------------------------------------------------------- 111 // Global Variables Definition 112 //---------------------------------------------------------------------------------- 113 extern CoreData CORE; // Global CORE state context 114 115 static PlatformData platform = { NULL }; // Platform specific 116 117 static bool RGFW_disableCursor = false; 118 119 static const unsigned short keyMappingRGFW[] = { 120 [RGFW_KEY_NULL] = KEY_NULL, 121 [RGFW_Quote] = KEY_APOSTROPHE, 122 [RGFW_Comma] = KEY_COMMA, 123 [RGFW_Minus] = KEY_MINUS, 124 [RGFW_Period] = KEY_PERIOD, 125 [RGFW_Slash] = KEY_SLASH, 126 [RGFW_Escape] = KEY_ESCAPE, 127 [RGFW_F1] = KEY_F1, 128 [RGFW_F2] = KEY_F2, 129 [RGFW_F3] = KEY_F3, 130 [RGFW_F4] = KEY_F4, 131 [RGFW_F5] = KEY_F5, 132 [RGFW_F6] = KEY_F6, 133 [RGFW_F7] = KEY_F7, 134 [RGFW_F8] = KEY_F8, 135 [RGFW_F9] = KEY_F9, 136 [RGFW_F10] = KEY_F10, 137 [RGFW_F11] = KEY_F11, 138 [RGFW_F12] = KEY_F12, 139 [RGFW_Backtick] = KEY_GRAVE, 140 [RGFW_0] = KEY_ZERO, 141 [RGFW_1] = KEY_ONE, 142 [RGFW_2] = KEY_TWO, 143 [RGFW_3] = KEY_THREE, 144 [RGFW_4] = KEY_FOUR, 145 [RGFW_5] = KEY_FIVE, 146 [RGFW_6] = KEY_SIX, 147 [RGFW_7] = KEY_SEVEN, 148 [RGFW_8] = KEY_EIGHT, 149 [RGFW_9] = KEY_NINE, 150 [RGFW_Equals] = KEY_EQUAL, 151 [RGFW_BackSpace] = KEY_BACKSPACE, 152 [RGFW_Tab] = KEY_TAB, 153 [RGFW_CapsLock] = KEY_CAPS_LOCK, 154 [RGFW_ShiftL] = KEY_LEFT_SHIFT, 155 [RGFW_ControlL] = KEY_LEFT_CONTROL, 156 [RGFW_AltL] = KEY_LEFT_ALT, 157 [RGFW_SuperL] = KEY_LEFT_SUPER, 158 #ifndef RGFW_MACOS 159 [RGFW_ShiftR] = KEY_RIGHT_SHIFT, 160 161 [RGFW_AltR] = KEY_RIGHT_ALT, 162 #endif 163 [RGFW_Space] = KEY_SPACE, 164 165 [RGFW_a] = KEY_A, 166 [RGFW_b] = KEY_B, 167 [RGFW_c] = KEY_C, 168 [RGFW_d] = KEY_D, 169 [RGFW_e] = KEY_E, 170 [RGFW_f] = KEY_F, 171 [RGFW_g] = KEY_G, 172 [RGFW_h] = KEY_H, 173 [RGFW_i] = KEY_I, 174 [RGFW_j] = KEY_J, 175 [RGFW_k] = KEY_K, 176 [RGFW_l] = KEY_L, 177 [RGFW_m] = KEY_M, 178 [RGFW_n] = KEY_N, 179 [RGFW_o] = KEY_O, 180 [RGFW_p] = KEY_P, 181 [RGFW_q] = KEY_Q, 182 [RGFW_r] = KEY_R, 183 [RGFW_s] = KEY_S, 184 [RGFW_t] = KEY_T, 185 [RGFW_u] = KEY_U, 186 [RGFW_v] = KEY_V, 187 [RGFW_w] = KEY_W, 188 [RGFW_x] = KEY_X, 189 [RGFW_y] = KEY_Y, 190 [RGFW_z] = KEY_Z, 191 [RGFW_Bracket] = KEY_LEFT_BRACKET, 192 [RGFW_BackSlash] = KEY_BACKSLASH, 193 [RGFW_CloseBracket] = KEY_RIGHT_BRACKET, 194 [RGFW_Semicolon] = KEY_SEMICOLON, 195 [RGFW_Insert] = KEY_INSERT, 196 [RGFW_Home] = KEY_HOME, 197 [RGFW_PageUp] = KEY_PAGE_UP, 198 [RGFW_Delete] = KEY_DELETE, 199 [RGFW_End] = KEY_END, 200 [RGFW_PageDown] = KEY_PAGE_DOWN, 201 [RGFW_Right] = KEY_RIGHT, 202 [RGFW_Left] = KEY_LEFT, 203 [RGFW_Down] = KEY_DOWN, 204 [RGFW_Up] = KEY_UP, 205 [RGFW_Numlock] = KEY_NUM_LOCK, 206 [RGFW_KP_Slash] = KEY_KP_DIVIDE, 207 [RGFW_Multiply] = KEY_KP_MULTIPLY, 208 [RGFW_KP_Minus] = KEY_KP_SUBTRACT, 209 [RGFW_KP_Return] = KEY_KP_ENTER, 210 [RGFW_KP_1] = KEY_KP_1, 211 [RGFW_KP_2] = KEY_KP_2, 212 [RGFW_KP_3] = KEY_KP_3, 213 [RGFW_KP_4] = KEY_KP_4, 214 [RGFW_KP_5] = KEY_KP_5, 215 [RGFW_KP_6] = KEY_KP_6, 216 [RGFW_KP_7] = KEY_KP_7, 217 [RGFW_KP_8] = KEY_KP_8, 218 [RGFW_KP_9] = KEY_KP_9, 219 [RGFW_KP_0] = KEY_KP_0, 220 [RGFW_KP_Period] = KEY_KP_DECIMAL 221 }; 222 223 //---------------------------------------------------------------------------------- 224 // Module Internal Functions Declaration 225 //---------------------------------------------------------------------------------- 226 int InitPlatform(void); // Initialize platform (graphics, inputs and more) 227 bool InitGraphicsDevice(void); // Initialize graphics device 228 229 //---------------------------------------------------------------------------------- 230 // Module Functions Declaration 231 //---------------------------------------------------------------------------------- 232 // NOTE: Functions declaration is provided by raylib.h 233 234 //---------------------------------------------------------------------------------- 235 // Module Functions Definition: Window and Graphics Device 236 //---------------------------------------------------------------------------------- 237 238 // Check if application should close 239 bool WindowShouldClose(void) 240 { 241 if (CORE.Window.shouldClose == false) 242 CORE.Window.shouldClose = RGFW_window_shouldClose(platform.window); 243 if (CORE.Window.ready) return CORE.Window.shouldClose; 244 else return true; 245 } 246 247 // Toggle fullscreen mode 248 void ToggleFullscreen(void) 249 { 250 RGFW_window_maximize(platform.window); 251 ToggleBorderlessWindowed(); 252 } 253 254 // Toggle borderless windowed mode 255 void ToggleBorderlessWindowed(void) 256 { 257 if (platform.window != NULL) 258 { 259 RGFW_window_setBorder(platform.window, CORE.Window.flags & FLAG_WINDOW_UNDECORATED); 260 } 261 } 262 263 // Set window state: maximized, if resizable 264 void MaximizeWindow(void) 265 { 266 RGFW_window_maximize(platform.window); 267 } 268 269 // Set window state: minimized 270 void MinimizeWindow(void) 271 { 272 RGFW_window_minimize(platform.window); 273 } 274 275 // Set window state: not minimized/maximized 276 void RestoreWindow(void) 277 { 278 RGFW_window_restore(platform.window); 279 } 280 281 // Set window configuration state using flags 282 void SetWindowState(unsigned int flags) 283 { 284 CORE.Window.flags |= flags; 285 286 if (flags & FLAG_VSYNC_HINT) 287 { 288 RGFW_window_swapInterval(platform.window, 1); 289 } 290 if (flags & FLAG_FULLSCREEN_MODE) 291 { 292 RGFW_window_maximize(platform.window); 293 ToggleBorderlessWindowed(); 294 } 295 if (flags & FLAG_WINDOW_RESIZABLE) 296 { 297 RGFW_window_setMaxSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); 298 RGFW_window_setMinSize(platform.window, RGFW_AREA(platform.window->r.w, platform.window->r.h)); 299 } 300 if (flags & FLAG_WINDOW_UNDECORATED) 301 { 302 ToggleBorderlessWindowed(); 303 } 304 if (flags & FLAG_WINDOW_HIDDEN) 305 { 306 RGFW_window_hide(platform.window); 307 } 308 if (flags & FLAG_WINDOW_MINIMIZED) 309 { 310 RGFW_window_minimize(platform.window); 311 } 312 if (flags & FLAG_WINDOW_MAXIMIZED) 313 { 314 RGFW_window_maximize(platform.window); 315 } 316 if (flags & FLAG_WINDOW_UNFOCUSED) 317 { 318 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW"); 319 } 320 if (flags & FLAG_WINDOW_TOPMOST) 321 { 322 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW"); 323 } 324 if (flags & FLAG_WINDOW_ALWAYS_RUN) 325 { 326 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW"); 327 } 328 if (flags & FLAG_WINDOW_TRANSPARENT) 329 { 330 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_TRANSPARENT post window creation post window creation is not supported on PLATFORM_DESKTOP_RGFW"); 331 } 332 if (flags & FLAG_WINDOW_HIGHDPI) 333 { 334 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW"); 335 } 336 if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) 337 { 338 RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH); 339 } 340 if (flags & FLAG_BORDERLESS_WINDOWED_MODE) 341 { 342 ToggleBorderlessWindowed(); 343 } 344 if (flags & FLAG_MSAA_4X_HINT) 345 { 346 RGFW_setGLSamples(4); 347 } 348 if (flags & FLAG_INTERLACED_HINT) 349 { 350 TRACELOG(LOG_WARNING, "SetWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW"); 351 } 352 } 353 354 // Clear window configuration state flags 355 void ClearWindowState(unsigned int flags) 356 { 357 CORE.Window.flags &= ~flags; 358 359 if (flags & FLAG_VSYNC_HINT) 360 { 361 RGFW_window_swapInterval(platform.window, 0); 362 } 363 if (flags & FLAG_FULLSCREEN_MODE) 364 { 365 ToggleBorderlessWindowed(); 366 RGFW_window_restore(platform.window); 367 CORE.Window.fullscreen = false; 368 } 369 if (flags & FLAG_WINDOW_RESIZABLE) 370 { 371 RGFW_window_setMaxSize(platform.window, RGFW_AREA(0, 0)); 372 RGFW_window_setMinSize(platform.window, RGFW_AREA(0, 0)); 373 } 374 if (flags & FLAG_WINDOW_UNDECORATED) 375 { 376 ToggleBorderlessWindowed(); 377 } 378 if (flags & FLAG_WINDOW_HIDDEN) 379 { 380 RGFW_window_show(platform.window); 381 } 382 if (flags & FLAG_WINDOW_MINIMIZED) 383 { 384 RGFW_window_restore(platform.window); 385 } 386 if (flags & FLAG_WINDOW_MAXIMIZED) 387 { 388 RGFW_window_restore(platform.window); 389 } 390 if (flags & FLAG_WINDOW_UNFOCUSED) 391 { 392 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_UNFOCUSED is not supported on PLATFORM_DESKTOP_RGFW"); 393 } 394 if (flags & FLAG_WINDOW_TOPMOST) 395 { 396 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TOPMOST is not supported on PLATFORM_DESKTOP_RGFW"); 397 } 398 if (flags & FLAG_WINDOW_ALWAYS_RUN) 399 { 400 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_ALWAYS_RUN is not supported on PLATFORM_DESKTOP_RGFW"); 401 } 402 if (flags & FLAG_WINDOW_TRANSPARENT) 403 { 404 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_TRANSPARENT is not supported on PLATFORM_DESKTOP_RGFW"); 405 } 406 if (flags & FLAG_WINDOW_HIGHDPI) 407 { 408 // NOTE: There also doesn't seem to be a feature to disable high DPI once enabled 409 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_HIGHDPI is not supported on PLATFORM_DESKTOP_RGFW"); 410 } 411 if (flags & FLAG_WINDOW_MOUSE_PASSTHROUGH) 412 { 413 RGFW_window_setMousePassthrough(platform.window, flags & FLAG_WINDOW_MOUSE_PASSTHROUGH); 414 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_WINDOW_MOUSE_PASSTHROUGH is not supported on PLATFORM_DESKTOP_RGFW"); 415 } 416 if (flags & FLAG_BORDERLESS_WINDOWED_MODE) 417 { 418 ToggleFullscreen(); 419 } 420 if (flags & FLAG_MSAA_4X_HINT) 421 { 422 RGFW_setGLSamples(0); 423 } 424 if (flags & FLAG_INTERLACED_HINT) 425 { 426 TRACELOG(LOG_WARNING, "ClearWindowState() - FLAG_INTERLACED_HINT is not supported on PLATFORM_DESKTOP_RGFW"); 427 } 428 } 429 430 // Set icon for window 431 void SetWindowIcon(Image image) 432 { 433 i32 channels = 4; 434 435 switch (image.format) 436 { 437 case PIXELFORMAT_UNCOMPRESSED_GRAYSCALE: 438 case PIXELFORMAT_UNCOMPRESSED_R16: // 16 bpp (1 channel - half float) 439 case PIXELFORMAT_UNCOMPRESSED_R32: // 32 bpp (1 channel - float) 440 { 441 channels = 1; 442 } break; 443 case PIXELFORMAT_UNCOMPRESSED_GRAY_ALPHA: // 8*2 bpp (2 channels) 444 case PIXELFORMAT_UNCOMPRESSED_R5G6B5: // 16 bpp 445 case PIXELFORMAT_UNCOMPRESSED_R8G8B8: // 24 bpp 446 case PIXELFORMAT_UNCOMPRESSED_R5G5B5A1: // 16 bpp (1 bit alpha) 447 case PIXELFORMAT_UNCOMPRESSED_R4G4B4A4: // 16 bpp (4 bit alpha) 448 case PIXELFORMAT_UNCOMPRESSED_R8G8B8A8: // 32 bpp 449 { 450 channels = 2; 451 } break; 452 case PIXELFORMAT_UNCOMPRESSED_R32G32B32: // 32*3 bpp (3 channels - float) 453 case PIXELFORMAT_UNCOMPRESSED_R16G16B16: // 16*3 bpp (3 channels - half float) 454 case PIXELFORMAT_COMPRESSED_DXT1_RGB: // 4 bpp (no alpha) 455 case PIXELFORMAT_COMPRESSED_ETC1_RGB: // 4 bpp 456 case PIXELFORMAT_COMPRESSED_ETC2_RGB: // 4 bpp 457 case PIXELFORMAT_COMPRESSED_PVRT_RGB: // 4 bpp 458 { 459 channels = 3; 460 } break; 461 case PIXELFORMAT_UNCOMPRESSED_R32G32B32A32: // 32*4 bpp (4 channels - float) 462 case PIXELFORMAT_UNCOMPRESSED_R16G16B16A16: // 16*4 bpp (4 channels - half float) 463 case PIXELFORMAT_COMPRESSED_DXT1_RGBA: // 4 bpp (1 bit alpha) 464 case PIXELFORMAT_COMPRESSED_DXT3_RGBA: // 8 bpp 465 case PIXELFORMAT_COMPRESSED_DXT5_RGBA: // 8 bpp 466 case PIXELFORMAT_COMPRESSED_ETC2_EAC_RGBA: // 8 bpp 467 case PIXELFORMAT_COMPRESSED_PVRT_RGBA: // 4 bpp 468 case PIXELFORMAT_COMPRESSED_ASTC_4x4_RGBA: // 8 bpp 469 case PIXELFORMAT_COMPRESSED_ASTC_8x8_RGBA: // 2 bpp 470 { 471 channels = 4; 472 } break; 473 default: break; 474 } 475 476 RGFW_window_setIcon(platform.window, image.data, RGFW_AREA(image.width, image.height), channels); 477 } 478 479 // Set icon for window 480 void SetWindowIcons(Image *images, int count) 481 { 482 TRACELOG(LOG_WARNING, "SetWindowIcons() not available on target platform"); 483 } 484 485 // Set title for window 486 void SetWindowTitle(const char *title) 487 { 488 RGFW_window_setName(platform.window, (char*)title); 489 CORE.Window.title = title; 490 } 491 492 // Set window position on screen (windowed mode) 493 void SetWindowPosition(int x, int y) 494 { 495 RGFW_window_move(platform.window, RGFW_POINT(x, y)); 496 } 497 498 // Set monitor for the current window 499 void SetWindowMonitor(int monitor) 500 { 501 RGFW_window_moveToMonitor(platform.window, RGFW_getMonitors()[monitor]); 502 } 503 504 // Set window minimum dimensions (FLAG_WINDOW_RESIZABLE) 505 void SetWindowMinSize(int width, int height) 506 { 507 RGFW_window_setMinSize(platform.window, RGFW_AREA(width, height)); 508 CORE.Window.screenMin.width = width; 509 CORE.Window.screenMin.height = height; 510 } 511 512 // Set window maximum dimensions (FLAG_WINDOW_RESIZABLE) 513 void SetWindowMaxSize(int width, int height) 514 { 515 RGFW_window_setMaxSize(platform.window, RGFW_AREA(width, height)); 516 CORE.Window.screenMax.width = width; 517 CORE.Window.screenMax.height = height; 518 } 519 520 // Set window dimensions 521 void SetWindowSize(int width, int height) 522 { 523 CORE.Window.screen.width = width; 524 CORE.Window.screen.height = height; 525 526 RGFW_window_resize(platform.window, RGFW_AREA(width, height)); 527 } 528 529 // Set window opacity, value opacity is between 0.0 and 1.0 530 void SetWindowOpacity(float opacity) 531 { 532 TRACELOG(LOG_WARNING, "SetWindowOpacity() not available on target platform"); 533 } 534 535 // Set window focused 536 void SetWindowFocused(void) 537 { 538 RGFW_window_show(platform.window); 539 } 540 541 // Get native window handle 542 void *GetWindowHandle(void) 543 { 544 #ifdef RGFW_WEBASM 545 return (void*)platform.window->src.ctx; 546 #else 547 return (void*)platform.window->src.window; 548 #endif 549 } 550 551 // Get number of monitors 552 int GetMonitorCount(void) 553 { 554 #define MAX_MONITORS_SUPPORTED 6 555 556 int count = MAX_MONITORS_SUPPORTED; 557 RGFW_monitor *mons = RGFW_getMonitors(); 558 559 for (int i = 0; i < 6; i++) 560 { 561 if (!mons[i].rect.x && !mons[i].rect.y && !mons[i].rect.w && mons[i].rect.h) 562 { 563 count = i; 564 break; 565 } 566 } 567 568 return count; 569 } 570 571 // Get number of monitors 572 int GetCurrentMonitor(void) 573 { 574 RGFW_monitor *mons = RGFW_getMonitors(); 575 RGFW_monitor mon = RGFW_window_getMonitor(platform.window); 576 577 for (int i = 0; i < 6; i++) 578 { 579 if ((mons[i].rect.x == mon.rect.x) && (mons[i].rect.y == mon.rect.y)) return i; 580 } 581 582 return 0; 583 } 584 585 // Get selected monitor position 586 Vector2 GetMonitorPosition(int monitor) 587 { 588 RGFW_monitor *mons = RGFW_getMonitors(); 589 590 return (Vector2){mons[monitor].rect.x, mons[monitor].rect.y}; 591 } 592 593 // Get selected monitor width (currently used by monitor) 594 int GetMonitorWidth(int monitor) 595 { 596 RGFW_monitor *mons = RGFW_getMonitors(); 597 598 return mons[monitor].rect.w; 599 } 600 601 // Get selected monitor height (currently used by monitor) 602 int GetMonitorHeight(int monitor) 603 { 604 RGFW_monitor *mons = RGFW_getMonitors(); 605 606 return mons[monitor].rect.h; 607 } 608 609 // Get selected monitor physical width in millimetres 610 int GetMonitorPhysicalWidth(int monitor) 611 { 612 RGFW_monitor* mons = RGFW_getMonitors(); 613 614 return mons[monitor].physW; 615 } 616 617 // Get selected monitor physical height in millimetres 618 int GetMonitorPhysicalHeight(int monitor) 619 { 620 RGFW_monitor *mons = RGFW_getMonitors(); 621 622 return mons[monitor].physH; 623 } 624 625 // Get selected monitor refresh rate 626 int GetMonitorRefreshRate(int monitor) 627 { 628 TRACELOG(LOG_WARNING, "GetMonitorRefreshRate() not implemented on target platform"); 629 return 0; 630 } 631 632 // Get the human-readable, UTF-8 encoded name of the selected monitor 633 const char *GetMonitorName(int monitor) 634 { 635 RGFW_monitor *mons = RGFW_getMonitors(); 636 637 return mons[monitor].name; 638 } 639 640 // Get window position XY on monitor 641 Vector2 GetWindowPosition(void) 642 { 643 return (Vector2){ platform.window->r.x, platform.window->r.y }; 644 } 645 646 // Get window scale DPI factor for current monitor 647 Vector2 GetWindowScaleDPI(void) 648 { 649 RGFW_monitor monitor = RGFW_window_getMonitor(platform.window); 650 651 return (Vector2){monitor.scaleX, monitor.scaleX}; 652 } 653 654 // Set clipboard text content 655 void SetClipboardText(const char *text) 656 { 657 RGFW_writeClipboard(text, strlen(text)); 658 } 659 660 // Get clipboard text content 661 // NOTE: returned string is allocated and freed by GLFW 662 const char *GetClipboardText(void) 663 { 664 return RGFW_readClipboard(NULL); 665 } 666 667 668 #if defined(SUPPORT_CLIPBOARD_IMAGE) 669 670 #ifdef _WIN32 671 # define WIN32_CLIPBOARD_IMPLEMENTATION 672 # define WINUSER_ALREADY_INCLUDED 673 # define WINBASE_ALREADY_INCLUDED 674 # define WINGDI_ALREADY_INCLUDED 675 # include "../external/win32_clipboard.h" 676 #endif 677 678 // Get clipboard image 679 Image GetClipboardImage(void) 680 { 681 Image image = {0}; 682 unsigned long long int dataSize = 0; 683 void* fileData = NULL; 684 685 #ifdef _WIN32 686 int width, height; 687 fileData = (void*)Win32GetClipboardImageData(&width, &height, &dataSize); 688 #else 689 TRACELOG(LOG_WARNING, "Clipboard image: PLATFORM_DESKTOP_RGFW doesn't implement `GetClipboardImage` for this OS"); 690 #endif 691 692 if (fileData == NULL) 693 { 694 TRACELOG(LOG_WARNING, "Clipboard image: Couldn't get clipboard data."); 695 } 696 else 697 { 698 image = LoadImageFromMemory(".bmp", fileData, dataSize); 699 } 700 return image; 701 } 702 #endif // SUPPORT_CLIPBOARD_IMAGE 703 704 // Show mouse cursor 705 void ShowCursor(void) 706 { 707 RGFW_window_showMouse(platform.window, true); 708 CORE.Input.Mouse.cursorHidden = false; 709 } 710 711 // Hides mouse cursor 712 void HideCursor(void) 713 { 714 RGFW_window_showMouse(platform.window, false); 715 CORE.Input.Mouse.cursorHidden = true; 716 } 717 718 // Enables cursor (unlock cursor) 719 void EnableCursor(void) 720 { 721 RGFW_disableCursor = false; 722 RGFW_window_mouseUnhold(platform.window); 723 724 // Set cursor position in the middle 725 SetMousePosition(CORE.Window.screen.width/2, CORE.Window.screen.height/2); 726 RGFW_window_showMouse(platform.window, true); 727 CORE.Input.Mouse.cursorHidden = false; 728 } 729 730 // Disables cursor (lock cursor) 731 void DisableCursor(void) 732 { 733 RGFW_disableCursor = true; 734 735 RGFW_window_mouseHold(platform.window, RGFW_AREA(0, 0)); 736 737 HideCursor(); 738 } 739 740 // Swap back buffer with front buffer (screen drawing) 741 void SwapScreenBuffer(void) 742 { 743 RGFW_window_swapBuffers(platform.window); 744 } 745 746 //---------------------------------------------------------------------------------- 747 // Module Functions Definition: Misc 748 //---------------------------------------------------------------------------------- 749 750 // Get elapsed time measure in seconds since InitTimer() 751 double GetTime(void) 752 { 753 double time = 0.0; 754 unsigned long long int nanoSeconds = RGFW_getTimeNS(); 755 time = (double)(nanoSeconds - CORE.Time.base)*1e-9; // Elapsed time since InitTimer() 756 757 return time; 758 } 759 760 // Open URL with default system browser (if available) 761 // NOTE: This function is only safe to use if you control the URL given. 762 // A user could craft a malicious string performing another action. 763 // Only call this function yourself not with user input or make sure to check the string yourself. 764 // Ref: https://github.com/raysan5/raylib/issues/686 765 void OpenURL(const char *url) 766 { 767 // Security check to (partially) avoid malicious code on target platform 768 if (strchr(url, '\'') != NULL) TRACELOG(LOG_WARNING, "SYSTEM: Provided URL could be potentially malicious, avoid [\'] character"); 769 else 770 { 771 // TODO: Open URL implementation 772 } 773 } 774 775 //---------------------------------------------------------------------------------- 776 // Module Functions Definition: Inputs 777 //---------------------------------------------------------------------------------- 778 779 // Set internal gamepad mappings 780 int SetGamepadMappings(const char *mappings) 781 { 782 TRACELOG(LOG_WARNING, "SetGamepadMappings() not implemented on target platform"); 783 return 0; 784 } 785 786 // Set mouse position XY 787 void SetMousePosition(int x, int y) 788 { 789 RGFW_window_moveMouse(platform.window, RGFW_POINT(x, y)); 790 CORE.Input.Mouse.currentPosition = (Vector2){ (float)x, (float)y }; 791 CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; 792 } 793 794 // Set mouse cursor 795 void SetMouseCursor(int cursor) 796 { 797 RGFW_window_setMouseStandard(platform.window, cursor); 798 } 799 800 // Get physical key name. 801 const char *GetKeyName(int key) 802 { 803 TRACELOG(LOG_WARNING, "GetKeyName() not implemented on target platform"); 804 return ""; 805 } 806 807 static KeyboardKey ConvertScancodeToKey(u32 keycode); 808 809 // TODO: Review function to avoid duplicate with RSGL 810 char RSGL_keystrToChar(const char *str) 811 { 812 if (str[1] == 0) return str[0]; 813 814 static const char *map[] = { 815 "asciitilde", "`", 816 "grave", "~", 817 "exclam", "!", 818 "at", "@", 819 "numbersign", "#", 820 "dollar", "$", 821 "percent", "%%", 822 "asciicircum", "^", 823 "ampersand", "&", 824 "asterisk", "*", 825 "parenleft", "(", 826 "parenright", ")", 827 "underscore", "_", 828 "minus", "-", 829 "plus", "+", 830 "equal", "=", 831 "braceleft", "{", 832 "bracketleft", "[", 833 "bracketright", "]", 834 "braceright", "}", 835 "colon", ":", 836 "semicolon", ";", 837 "quotedbl", "\"", 838 "apostrophe", "'", 839 "bar", "|", 840 "backslash", "\'", 841 "less", "<", 842 "comma", ",", 843 "greater", ">", 844 "period", ".", 845 "question", "?", 846 "slash", "/", 847 "space", " ", 848 "Return", "\n", 849 "Enter", "\n", 850 "enter", "\n", 851 }; 852 853 for (unsigned char i = 0; i < (sizeof(map)/sizeof(char *)); i += 2) 854 { 855 if (strcmp(map[i], str) == 0) return *map[i + 1]; 856 } 857 858 return '\0'; 859 } 860 861 // Register all input events 862 void PollInputEvents(void) 863 { 864 #if defined(SUPPORT_GESTURES_SYSTEM) 865 // NOTE: Gestures update must be called every frame to reset gestures correctly 866 // because ProcessGestureEvent() is just called on an event, not every frame 867 UpdateGestures(); 868 #endif 869 870 // Reset keys/chars pressed registered 871 CORE.Input.Keyboard.keyPressedQueueCount = 0; 872 CORE.Input.Keyboard.charPressedQueueCount = 0; 873 874 // Reset mouse wheel 875 CORE.Input.Mouse.currentWheelMove.x = 0; 876 CORE.Input.Mouse.currentWheelMove.y = 0; 877 878 // Register previous mouse position 879 880 // Reset last gamepad button/axis registered state 881 882 for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) 883 { 884 // Check if gamepad is available 885 if (CORE.Input.Gamepad.ready[i]) 886 { 887 // Register previous gamepad button states 888 for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) 889 { 890 CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k]; 891 } 892 } 893 } 894 895 // Register previous touch states 896 for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i]; 897 898 // Map touch position to mouse position for convenience 899 CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; 900 901 int touchAction = -1; // 0-TOUCH_ACTION_UP, 1-TOUCH_ACTION_DOWN, 2-TOUCH_ACTION_MOVE 902 bool realTouch = false; // Flag to differentiate real touch gestures from mouse ones 903 904 // Register previous keys states 905 // NOTE: Android supports up to 260 keys 906 for (int i = 0; i < MAX_KEYBOARD_KEYS; i++) 907 { 908 CORE.Input.Keyboard.previousKeyState[i] = CORE.Input.Keyboard.currentKeyState[i]; 909 CORE.Input.Keyboard.keyRepeatInFrame[i] = 0; 910 } 911 912 // Register previous mouse states 913 for (int i = 0; i < MAX_MOUSE_BUTTONS; i++) CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i]; 914 915 // Poll input events for current platform 916 //----------------------------------------------------------------------------- 917 CORE.Window.resizedLastFrame = false; 918 919 CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; 920 #define RGFW_HOLD_MOUSE (1L<<2) 921 if (platform.window->_winArgs & RGFW_HOLD_MOUSE) 922 { 923 CORE.Input.Mouse.previousPosition = (Vector2){ 0.0f, 0.0f }; 924 CORE.Input.Mouse.currentPosition = (Vector2){ 0.0f, 0.0f }; 925 } 926 else 927 { 928 CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; 929 } 930 931 while (RGFW_window_checkEvent(platform.window)) 932 { 933 if ((platform.window->event.type >= RGFW_jsButtonPressed) && (platform.window->event.type <= RGFW_jsAxisMove)) 934 { 935 if (!CORE.Input.Gamepad.ready[platform.window->event.joystick]) 936 { 937 CORE.Input.Gamepad.ready[platform.window->event.joystick] = true; 938 CORE.Input.Gamepad.axisCount[platform.window->event.joystick] = platform.window->event.axisesCount; 939 CORE.Input.Gamepad.name[platform.window->event.joystick][0] = '\0'; 940 CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f; 941 CORE.Input.Gamepad.axisState[platform.window->event.joystick][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f; 942 } 943 } 944 945 RGFW_Event *event = &platform.window->event; 946 947 // All input events can be processed after polling 948 switch (event->type) 949 { 950 case RGFW_quit: CORE.Window.shouldClose = true; break; 951 case RGFW_dnd: // Dropped file 952 { 953 for (int i = 0; i < event->droppedFilesCount; i++) 954 { 955 if (CORE.Window.dropFileCount == 0) 956 { 957 // When a new file is dropped, we reserve a fixed number of slots for all possible dropped files 958 // at the moment we limit the number of drops at once to 1024 files but this behaviour should probably be reviewed 959 // TODO: Pointers should probably be reallocated for any new file added... 960 CORE.Window.dropFilepaths = (char **)RL_CALLOC(1024, sizeof(char *)); 961 962 CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); 963 strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); 964 965 CORE.Window.dropFileCount++; 966 } 967 else if (CORE.Window.dropFileCount < 1024) 968 { 969 CORE.Window.dropFilepaths[CORE.Window.dropFileCount] = (char *)RL_CALLOC(MAX_FILEPATH_LENGTH, sizeof(char)); 970 strcpy(CORE.Window.dropFilepaths[CORE.Window.dropFileCount], event->droppedFiles[i]); 971 972 CORE.Window.dropFileCount++; 973 } 974 else TRACELOG(LOG_WARNING, "FILE: Maximum drag and drop files at once is limited to 1024 files!"); 975 } 976 } break; 977 978 // Window events are also polled (Minimized, maximized, close...) 979 case RGFW_windowResized: 980 { 981 SetupViewport(platform.window->r.w, platform.window->r.h); 982 CORE.Window.screen.width = platform.window->r.w; 983 CORE.Window.screen.height = platform.window->r.h; 984 CORE.Window.currentFbo.width = platform.window->r.w; 985 CORE.Window.currentFbo.height = platform.window->r.h; 986 CORE.Window.resizedLastFrame = true; 987 } break; 988 case RGFW_windowMoved: 989 { 990 CORE.Window.position.x = platform.window->r.x; 991 CORE.Window.position.y = platform.window->r.x; 992 } break; 993 994 // Keyboard events 995 case RGFW_keyPressed: 996 { 997 KeyboardKey key = ConvertScancodeToKey(event->keyCode); 998 999 if (key != KEY_NULL) 1000 { 1001 // If key was up, add it to the key pressed queue 1002 if ((CORE.Input.Keyboard.currentKeyState[key] == 0) && (CORE.Input.Keyboard.keyPressedQueueCount < MAX_KEY_PRESSED_QUEUE)) 1003 { 1004 CORE.Input.Keyboard.keyPressedQueue[CORE.Input.Keyboard.keyPressedQueueCount] = key; 1005 CORE.Input.Keyboard.keyPressedQueueCount++; 1006 } 1007 1008 CORE.Input.Keyboard.currentKeyState[key] = 1; 1009 } 1010 1011 // TODO: Put exitKey verification outside the switch? 1012 if (CORE.Input.Keyboard.currentKeyState[CORE.Input.Keyboard.exitKey]) 1013 { 1014 CORE.Window.shouldClose = true; 1015 } 1016 1017 // NOTE: event.text.text data comes an UTF-8 text sequence but we register codepoints (int) 1018 // Check if there is space available in the queue 1019 if (CORE.Input.Keyboard.charPressedQueueCount < MAX_CHAR_PRESSED_QUEUE) 1020 { 1021 // Add character (codepoint) to the queue 1022 CORE.Input.Keyboard.charPressedQueue[CORE.Input.Keyboard.charPressedQueueCount] = RSGL_keystrToChar(event->keyName); 1023 CORE.Input.Keyboard.charPressedQueueCount++; 1024 } 1025 } break; 1026 case RGFW_keyReleased: 1027 { 1028 KeyboardKey key = ConvertScancodeToKey(event->keyCode); 1029 if (key != KEY_NULL) CORE.Input.Keyboard.currentKeyState[key] = 0; 1030 } break; 1031 1032 // Check mouse events 1033 case RGFW_mouseButtonPressed: 1034 { 1035 if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown)) 1036 { 1037 CORE.Input.Mouse.currentWheelMove.y = event->scroll; 1038 break; 1039 } 1040 1041 int btn = event->button; 1042 if (btn == RGFW_mouseLeft) btn = 1; 1043 else if (btn == RGFW_mouseRight) btn = 2; 1044 else if (btn == RGFW_mouseMiddle) btn = 3; 1045 1046 CORE.Input.Mouse.currentButtonState[btn - 1] = 1; 1047 CORE.Input.Touch.currentTouchState[btn - 1] = 1; 1048 1049 touchAction = 1; 1050 } break; 1051 case RGFW_mouseButtonReleased: 1052 { 1053 1054 if ((event->button == RGFW_mouseScrollUp) || (event->button == RGFW_mouseScrollDown)) 1055 { 1056 CORE.Input.Mouse.currentWheelMove.y = event->scroll; 1057 break; 1058 } 1059 1060 int btn = event->button; 1061 if (btn == RGFW_mouseLeft) btn = 1; 1062 else if (btn == RGFW_mouseRight) btn = 2; 1063 else if (btn == RGFW_mouseMiddle) btn = 3; 1064 1065 CORE.Input.Mouse.currentButtonState[btn - 1] = 0; 1066 CORE.Input.Touch.currentTouchState[btn - 1] = 0; 1067 1068 touchAction = 0; 1069 } break; 1070 case RGFW_mousePosChanged: 1071 { 1072 if (platform.window->_winArgs & RGFW_HOLD_MOUSE) 1073 { 1074 CORE.Input.Mouse.currentPosition.x += (float)event->point.x; 1075 CORE.Input.Mouse.currentPosition.y += (float)event->point.y; 1076 } 1077 else 1078 { 1079 CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition; 1080 CORE.Input.Mouse.currentPosition.x = (float)event->point.x; 1081 CORE.Input.Mouse.currentPosition.y = (float)event->point.y; 1082 } 1083 1084 CORE.Input.Touch.position[0] = CORE.Input.Mouse.currentPosition; 1085 touchAction = 2; 1086 } break; 1087 case RGFW_jsButtonPressed: 1088 { 1089 int button = -1; 1090 1091 switch (event->button) 1092 { 1093 case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; 1094 case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; 1095 case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; 1096 case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; 1097 1098 case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; 1099 case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; 1100 1101 case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break; 1102 case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break; 1103 1104 case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; 1105 case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break; 1106 case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; 1107 1108 case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; 1109 case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; 1110 case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; 1111 case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; 1112 1113 default: break; 1114 } 1115 1116 if (button >= 0) 1117 { 1118 CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 1; 1119 CORE.Input.Gamepad.lastButtonPressed = button; 1120 } 1121 } break; 1122 case RGFW_jsButtonReleased: 1123 { 1124 int button = -1; 1125 switch (event->button) 1126 { 1127 case RGFW_JS_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break; 1128 case RGFW_JS_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break; 1129 case RGFW_JS_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break; 1130 case RGFW_JS_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break; 1131 1132 case RGFW_JS_L1: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break; 1133 case RGFW_JS_R1: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break; 1134 1135 case RGFW_JS_L2: button = GAMEPAD_BUTTON_LEFT_TRIGGER_2; break; 1136 case RGFW_JS_R2: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_2; break; 1137 1138 case RGFW_JS_SELECT: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break; 1139 case RGFW_JS_HOME: button = GAMEPAD_BUTTON_MIDDLE; break; 1140 case RGFW_JS_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break; 1141 1142 case RGFW_JS_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break; 1143 case RGFW_JS_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break; 1144 case RGFW_JS_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break; 1145 case RGFW_JS_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break; 1146 default: break; 1147 } 1148 1149 if (button >= 0) 1150 { 1151 CORE.Input.Gamepad.currentButtonState[event->joystick][button] = 0; 1152 if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; 1153 } 1154 } break; 1155 case RGFW_jsAxisMove: 1156 { 1157 int axis = -1; 1158 for (int i = 0; i < event->axisesCount; i++) 1159 { 1160 switch(i) 1161 { 1162 case 0: 1163 { 1164 if (abs(event->axis[i].x) > abs(event->axis[i].y)) 1165 { 1166 axis = GAMEPAD_AXIS_LEFT_X; 1167 break; 1168 } 1169 1170 axis = GAMEPAD_AXIS_LEFT_Y; 1171 } break; 1172 case 1: 1173 { 1174 if (abs(event->axis[i].x) > abs(event->axis[i].y)) 1175 { 1176 axis = GAMEPAD_AXIS_RIGHT_X; 1177 break; 1178 } 1179 1180 axis = GAMEPAD_AXIS_RIGHT_Y; 1181 } break; 1182 case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break; 1183 case 3: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break; 1184 default: break; 1185 } 1186 1187 #ifdef __linux__ 1188 float value = (event->axis[i].x + event->axis[i].y)/(float)32767; 1189 #else 1190 float value = (event->axis[i].x + -event->axis[i].y)/(float)32767; 1191 #endif 1192 CORE.Input.Gamepad.axisState[event->joystick][axis] = value; 1193 1194 // Register button state for triggers in addition to their axes 1195 if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER)) 1196 { 1197 int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER)? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2; 1198 int pressed = (value > 0.1f); 1199 CORE.Input.Gamepad.currentButtonState[event->joystick][button] = pressed; 1200 1201 if (pressed) CORE.Input.Gamepad.lastButtonPressed = button; 1202 else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0; 1203 } 1204 } 1205 } break; 1206 default: break; 1207 } 1208 1209 #if defined(SUPPORT_GESTURES_SYSTEM) 1210 if (touchAction > -1) 1211 { 1212 // Process mouse events as touches to be able to use mouse-gestures 1213 GestureEvent gestureEvent = { 0 }; 1214 1215 // Register touch actions 1216 gestureEvent.touchAction = touchAction; 1217 1218 // Assign a pointer ID 1219 gestureEvent.pointId[0] = 0; 1220 1221 // Register touch points count 1222 gestureEvent.pointCount = 1; 1223 1224 // Register touch points position, only one point registered 1225 if (touchAction == 2 || realTouch) gestureEvent.position[0] = CORE.Input.Touch.position[0]; 1226 else gestureEvent.position[0] = GetMousePosition(); 1227 1228 // Normalize gestureEvent.position[0] for CORE.Window.screen.width and CORE.Window.screen.height 1229 gestureEvent.position[0].x /= (float)GetScreenWidth(); 1230 gestureEvent.position[0].y /= (float)GetScreenHeight(); 1231 1232 // Gesture data is sent to gestures-system for processing 1233 ProcessGestureEvent(gestureEvent); 1234 1235 touchAction = -1; 1236 } 1237 #endif 1238 } 1239 //----------------------------------------------------------------------------- 1240 } 1241 1242 //---------------------------------------------------------------------------------- 1243 // Module Internal Functions Definition 1244 //---------------------------------------------------------------------------------- 1245 1246 // Initialize platform: graphics, inputs and more 1247 int InitPlatform(void) 1248 { 1249 // Initialize RGFW internal global state, only required systems 1250 unsigned int flags = RGFW_CENTER | RGFW_ALLOW_DND; 1251 1252 // Check window creation flags 1253 if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) 1254 { 1255 CORE.Window.fullscreen = true; 1256 flags |= RGFW_FULLSCREEN; 1257 } 1258 1259 if ((CORE.Window.flags & FLAG_WINDOW_UNDECORATED) > 0) flags |= RGFW_NO_BORDER; 1260 if ((CORE.Window.flags & FLAG_WINDOW_RESIZABLE) == 0) flags |= RGFW_NO_RESIZE; 1261 1262 if ((CORE.Window.flags & FLAG_WINDOW_TRANSPARENT) > 0) flags |= RGFW_TRANSPARENT_WINDOW; 1263 1264 if ((CORE.Window.flags & FLAG_FULLSCREEN_MODE) > 0) flags |= RGFW_FULLSCREEN; 1265 1266 // NOTE: Some OpenGL context attributes must be set before window creation 1267 1268 // Check selection OpenGL version 1269 if (rlGetVersion() == RL_OPENGL_21) 1270 { 1271 RGFW_setGLVersion(RGFW_GL_CORE, 2, 1); 1272 } 1273 else if (rlGetVersion() == RL_OPENGL_33) 1274 { 1275 RGFW_setGLVersion(RGFW_GL_CORE, 3, 3); 1276 } 1277 else if (rlGetVersion() == RL_OPENGL_43) 1278 { 1279 RGFW_setGLVersion(RGFW_GL_CORE, 4, 1); 1280 } 1281 1282 if (CORE.Window.flags & FLAG_MSAA_4X_HINT) 1283 { 1284 RGFW_setGLSamples(4); 1285 } 1286 1287 platform.window = RGFW_createWindow(CORE.Window.title, RGFW_RECT(0, 0, CORE.Window.screen.width, CORE.Window.screen.height), flags); 1288 1289 RGFW_area screenSize = RGFW_getScreenSize(); 1290 CORE.Window.display.width = screenSize.w; 1291 CORE.Window.display.height = screenSize.h; 1292 /* 1293 I think this is needed by Raylib now ? 1294 If so, rcore_destkop_sdl should be updated too 1295 */ 1296 SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height); 1297 1298 if (CORE.Window.flags & FLAG_VSYNC_HINT) RGFW_window_swapInterval(platform.window, 1); 1299 1300 RGFW_window_makeCurrent(platform.window); 1301 1302 // Check surface and context activation 1303 if (platform.window != NULL) 1304 { 1305 CORE.Window.ready = true; 1306 1307 CORE.Window.render.width = CORE.Window.screen.width; 1308 CORE.Window.render.height = CORE.Window.screen.height; 1309 CORE.Window.currentFbo.width = CORE.Window.render.width; 1310 CORE.Window.currentFbo.height = CORE.Window.render.height; 1311 1312 TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); 1313 TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); 1314 TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); 1315 TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); 1316 TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); 1317 } 1318 else 1319 { 1320 TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphics device"); 1321 return -1; 1322 } 1323 //---------------------------------------------------------------------------- 1324 1325 // If everything work as expected, we can continue 1326 CORE.Window.position.x = platform.window->r.x; 1327 CORE.Window.position.y = platform.window->r.y; 1328 CORE.Window.render.width = CORE.Window.screen.width; 1329 CORE.Window.render.height = CORE.Window.screen.height; 1330 CORE.Window.currentFbo.width = CORE.Window.render.width; 1331 CORE.Window.currentFbo.height = CORE.Window.render.height; 1332 1333 TRACELOG(LOG_INFO, "DISPLAY: Device initialized successfully"); 1334 TRACELOG(LOG_INFO, " > Display size: %i x %i", CORE.Window.display.width, CORE.Window.display.height); 1335 TRACELOG(LOG_INFO, " > Screen size: %i x %i", CORE.Window.screen.width, CORE.Window.screen.height); 1336 TRACELOG(LOG_INFO, " > Render size: %i x %i", CORE.Window.render.width, CORE.Window.render.height); 1337 TRACELOG(LOG_INFO, " > Viewport offsets: %i, %i", CORE.Window.renderOffset.x, CORE.Window.renderOffset.y); 1338 1339 // Load OpenGL extensions 1340 // NOTE: GL procedures address loader is required to load extensions 1341 //---------------------------------------------------------------------------- 1342 rlLoadExtensions((void*)RGFW_getProcAddress); 1343 //---------------------------------------------------------------------------- 1344 1345 // TODO: Initialize input events system 1346 // It could imply keyboard, mouse, gamepad, touch... 1347 // Depending on the platform libraries/SDK it could use a callback mechanism 1348 // For system events and inputs evens polling on a per-frame basis, use PollInputEvents() 1349 //---------------------------------------------------------------------------- 1350 // ... 1351 //---------------------------------------------------------------------------- 1352 1353 // Initialize timing system 1354 //---------------------------------------------------------------------------- 1355 InitTimer(); 1356 //---------------------------------------------------------------------------- 1357 1358 // Initialize storage system 1359 //---------------------------------------------------------------------------- 1360 CORE.Storage.basePath = GetWorkingDirectory(); 1361 //---------------------------------------------------------------------------- 1362 1363 #ifdef RGFW_X11 1364 for (int i = 0; (i < 4) && (i < MAX_GAMEPADS); i++) 1365 { 1366 RGFW_registerJoystick(platform.window, i); 1367 } 1368 #endif 1369 1370 TRACELOG(LOG_INFO, "PLATFORM: CUSTOM: Initialized successfully"); 1371 1372 return 0; 1373 } 1374 1375 // Close platform 1376 void ClosePlatform(void) 1377 { 1378 RGFW_window_close(platform.window); 1379 } 1380 1381 // Keycode mapping 1382 static KeyboardKey ConvertScancodeToKey(u32 keycode) 1383 { 1384 if (keycode > sizeof(keyMappingRGFW)/sizeof(unsigned short)) return 0; 1385 1386 return keyMappingRGFW[keycode]; 1387 }