|
@@ -17,8 +17,10 @@
|
|
|
* - TRACELOG() function is located in raylib [utils] module
|
|
|
*
|
|
|
* CONFIGURATION:
|
|
|
-* #define RCORE_DRM_CUSTOM_FLAG
|
|
|
-* Custom flag for rcore on PLATFORM_DRM -not used-
|
|
|
+* #define SUPPORT_SSH_KEYBOARD_RPI (Raspberry Pi only)
|
|
|
+* Reconfigure standard input to receive key inputs, works with SSH connection.
|
|
|
+* WARNING: Reconfiguring standard input could lead to undesired effects, like breaking other
|
|
|
+* running processes orblocking the device if not restored properly. Use with care.
|
|
|
*
|
|
|
* DEPENDENCIES:
|
|
|
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
|
|
@@ -47,15 +49,93 @@
|
|
|
|
|
|
#include "rcore.h"
|
|
|
|
|
|
+#include <fcntl.h> // POSIX file control definitions - open(), creat(), fcntl()
|
|
|
+#include <unistd.h> // POSIX standard function definitions - read(), close(), STDIN_FILENO
|
|
|
+#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
|
|
+#include <pthread.h> // POSIX threads management (inputs reading)
|
|
|
+#include <dirent.h> // POSIX directory browsing
|
|
|
+
|
|
|
+#include <sys/ioctl.h> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
|
|
+#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
|
|
|
+#include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
|
|
|
+#include <linux/joystick.h> // Linux: Joystick support library
|
|
|
+
|
|
|
+#include <gbm.h> // Generic Buffer Management (native platform for EGL on DRM)
|
|
|
+#include <xf86drm.h> // Direct Rendering Manager user-level library interface
|
|
|
+#include <xf86drmMode.h> // Direct Rendering Manager mode setting (KMS) interface
|
|
|
+
|
|
|
+#include "EGL/egl.h" // Native platform windowing system interface
|
|
|
+#include "EGL/eglext.h" // EGL extensions
|
|
|
+
|
|
|
+//----------------------------------------------------------------------------------
|
|
|
+// Defines and Macros
|
|
|
+//----------------------------------------------------------------------------------
|
|
|
+#define USE_LAST_TOUCH_DEVICE // When multiple touchscreens are connected, only use the one with the highest event<N> number
|
|
|
+
|
|
|
+#define DEFAULT_GAMEPAD_DEV "/dev/input/js" // Gamepad input (base dev for all gamepads: js0, js1, ...)
|
|
|
+#define DEFAULT_EVDEV_PATH "/dev/input/" // Path to the linux input events
|
|
|
+
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Types and Structures Definition
|
|
|
//----------------------------------------------------------------------------------
|
|
|
-//...
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ pthread_t threadId; // Event reading thread id
|
|
|
+
|
|
|
+ int fd; // File descriptor to the device it is assigned to
|
|
|
+ int eventNum; // Number of 'event<N>' device
|
|
|
+ Rectangle absRange; // Range of values for absolute pointing devices (touchscreens)
|
|
|
+ int touchSlot; // Hold the touch slot number of the currently being sent multitouch block
|
|
|
+ bool isMouse; // True if device supports relative X Y movements
|
|
|
+ bool isTouch; // True if device supports absolute X Y movements and has BTN_TOUCH
|
|
|
+ bool isMultitouch; // True if device supports multiple absolute movevents and has BTN_TOUCH
|
|
|
+ bool isKeyboard; // True if device has letter keycodes
|
|
|
+ bool isGamepad; // True if device has gamepad buttons
|
|
|
+} InputEventWorker;
|
|
|
+
|
|
|
+typedef struct {
|
|
|
+ // Display data
|
|
|
+ int fd; // File descriptor for /dev/dri/...
|
|
|
+ drmModeConnector *connector; // Direct Rendering Manager (DRM) mode connector
|
|
|
+ drmModeCrtc *crtc; // CRT Controller
|
|
|
+ int modeIndex; // Index of the used mode of connector->modes
|
|
|
+ struct gbm_device *gbmDevice; // GBM device
|
|
|
+ struct gbm_surface *gbmSurface; // GBM surface
|
|
|
+ struct gbm_bo *prevBO; // Previous GBM buffer object (during frame swapping)
|
|
|
+ uint32_t prevFB; // Previous GBM framebufer (during frame swapping)
|
|
|
+
|
|
|
+ EGLDisplay device; // Native display device (physical screen connection)
|
|
|
+ EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
|
|
|
+ EGLContext context; // Graphic context, mode in which drawing can be done
|
|
|
+ EGLConfig config; // Graphic config
|
|
|
+
|
|
|
+ // Input data
|
|
|
+ InputEventWorker eventWorker[10]; // List of worker threads for every monitored "/dev/input/event<N>"
|
|
|
+
|
|
|
+ // Keyboard data
|
|
|
+ int defaultKeyboardMode; // Default keyboard mode
|
|
|
+ bool eventKeyboardMode; // Keyboard in event mode
|
|
|
+ int defaultFileFlags; // Default IO file flags
|
|
|
+ struct termios defaultSettings; // Default keyboard settings
|
|
|
+ int keyboardFd; // File descriptor for the evdev keyboard
|
|
|
+
|
|
|
+ // Mouse data
|
|
|
+ Vector2 eventWheelMove; // Registers the event mouse wheel variation
|
|
|
+ // NOTE: currentButtonState[] can't be written directly due to multithreading, app could miss the update
|
|
|
+ char currentButtonStateEvdev[MAX_MOUSE_BUTTONS]; // Holds the new mouse state for the next polling event to grab
|
|
|
+
|
|
|
+ // Gamepad data
|
|
|
+ pthread_t gamepadThreadId; // Gamepad reading thread id
|
|
|
+ int gamepadStreamFd[MAX_GAMEPADS]; // Gamepad device file descriptor
|
|
|
+
|
|
|
+} PlatformData;
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Global Variables Definition
|
|
|
//----------------------------------------------------------------------------------
|
|
|
-extern CoreData CORE; // Global CORE state context
|
|
|
+extern CoreData CORE; // Global CORE state context
|
|
|
+
|
|
|
+static PlatformData platform = { 0 }; // Platform specific data
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
// Module Internal Functions Declaration
|
|
@@ -227,67 +307,67 @@ void CloseWindow(void)
|
|
|
timeEndPeriod(1); // Restore time period
|
|
|
#endif
|
|
|
|
|
|
- if (CORE.Window.prevFB)
|
|
|
+ if (platform.prevFB)
|
|
|
{
|
|
|
- drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
|
|
- CORE.Window.prevFB = 0;
|
|
|
+ drmModeRmFB(platform.fd, platform.prevFB);
|
|
|
+ platform.prevFB = 0;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.prevBO)
|
|
|
+ if (platform.prevBO)
|
|
|
{
|
|
|
- gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
|
|
- CORE.Window.prevBO = NULL;
|
|
|
+ gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
|
|
+ platform.prevBO = NULL;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.gbmSurface)
|
|
|
+ if (platform.gbmSurface)
|
|
|
{
|
|
|
- gbm_surface_destroy(CORE.Window.gbmSurface);
|
|
|
- CORE.Window.gbmSurface = NULL;
|
|
|
+ gbm_surface_destroy(platform.gbmSurface);
|
|
|
+ platform.gbmSurface = NULL;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.gbmDevice)
|
|
|
+ if (platform.gbmDevice)
|
|
|
{
|
|
|
- gbm_device_destroy(CORE.Window.gbmDevice);
|
|
|
- CORE.Window.gbmDevice = NULL;
|
|
|
+ gbm_device_destroy(platform.gbmDevice);
|
|
|
+ platform.gbmDevice = NULL;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.crtc)
|
|
|
+ if (platform.crtc)
|
|
|
{
|
|
|
- if (CORE.Window.connector)
|
|
|
+ if (platform.connector)
|
|
|
{
|
|
|
- drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, CORE.Window.crtc->buffer_id,
|
|
|
- CORE.Window.crtc->x, CORE.Window.crtc->y, &CORE.Window.connector->connector_id, 1, &CORE.Window.crtc->mode);
|
|
|
- drmModeFreeConnector(CORE.Window.connector);
|
|
|
- CORE.Window.connector = NULL;
|
|
|
+ drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, platform.crtc->buffer_id,
|
|
|
+ platform.crtc->x, platform.crtc->y, &platform.connector->connector_id, 1, &platform.crtc->mode);
|
|
|
+ drmModeFreeConnector(platform.connector);
|
|
|
+ platform.connector = NULL;
|
|
|
}
|
|
|
|
|
|
- drmModeFreeCrtc(CORE.Window.crtc);
|
|
|
- CORE.Window.crtc = NULL;
|
|
|
+ drmModeFreeCrtc(platform.crtc);
|
|
|
+ platform.crtc = NULL;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.fd != -1)
|
|
|
+ if (platform.fd != -1)
|
|
|
{
|
|
|
- close(CORE.Window.fd);
|
|
|
- CORE.Window.fd = -1;
|
|
|
+ close(platform.fd);
|
|
|
+ platform.fd = -1;
|
|
|
}
|
|
|
|
|
|
// Close surface, context and display
|
|
|
- if (CORE.Window.device != EGL_NO_DISPLAY)
|
|
|
+ if (platform.device != EGL_NO_DISPLAY)
|
|
|
{
|
|
|
- if (CORE.Window.surface != EGL_NO_SURFACE)
|
|
|
+ if (platform.surface != EGL_NO_SURFACE)
|
|
|
{
|
|
|
- eglDestroySurface(CORE.Window.device, CORE.Window.surface);
|
|
|
- CORE.Window.surface = EGL_NO_SURFACE;
|
|
|
+ eglDestroySurface(platform.device, platform.surface);
|
|
|
+ platform.surface = EGL_NO_SURFACE;
|
|
|
}
|
|
|
|
|
|
- if (CORE.Window.context != EGL_NO_CONTEXT)
|
|
|
+ if (platform.context != EGL_NO_CONTEXT)
|
|
|
{
|
|
|
- eglDestroyContext(CORE.Window.device, CORE.Window.context);
|
|
|
- CORE.Window.context = EGL_NO_CONTEXT;
|
|
|
+ eglDestroyContext(platform.device, platform.context);
|
|
|
+ platform.context = EGL_NO_CONTEXT;
|
|
|
}
|
|
|
|
|
|
- eglTerminate(CORE.Window.device);
|
|
|
- CORE.Window.device = EGL_NO_DISPLAY;
|
|
|
+ eglTerminate(platform.device);
|
|
|
+ platform.device = EGL_NO_DISPLAY;
|
|
|
}
|
|
|
|
|
|
// Wait for mouse and gamepad threads to finish before closing
|
|
@@ -297,21 +377,21 @@ void CloseWindow(void)
|
|
|
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
|
|
|
|
|
// Close the evdev keyboard
|
|
|
- if (CORE.Input.Keyboard.fd != -1)
|
|
|
+ if (platform.keyboardFd != -1)
|
|
|
{
|
|
|
- close(CORE.Input.Keyboard.fd);
|
|
|
- CORE.Input.Keyboard.fd = -1;
|
|
|
+ close(platform.keyboardFd);
|
|
|
+ platform.keyboardFd = -1;
|
|
|
}
|
|
|
|
|
|
- for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
+ for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
{
|
|
|
- if (CORE.Input.eventWorker[i].threadId)
|
|
|
+ if (platform.eventWorker[i].threadId)
|
|
|
{
|
|
|
- pthread_join(CORE.Input.eventWorker[i].threadId, NULL);
|
|
|
+ pthread_join(platform.eventWorker[i].threadId, NULL);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (CORE.Input.Gamepad.threadId) pthread_join(CORE.Input.Gamepad.threadId, NULL);
|
|
|
+ if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
|
|
|
|
|
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
|
|
RL_FREE(events);
|
|
@@ -524,9 +604,9 @@ int GetMonitorRefreshRate(int monitor)
|
|
|
{
|
|
|
int refresh = 0;
|
|
|
|
|
|
- if ((CORE.Window.connector) && (CORE.Window.modeIndex >= 0))
|
|
|
+ if ((platform.connector) && (platform.modeIndex >= 0))
|
|
|
{
|
|
|
- refresh = CORE.Window.connector->modes[CORE.Window.modeIndex].vrefresh;
|
|
|
+ refresh = platform.connector->modes[platform.modeIndex].vrefresh;
|
|
|
}
|
|
|
|
|
|
return refresh;
|
|
@@ -659,7 +739,7 @@ const char *GetGamepadName(int gamepad)
|
|
|
|
|
|
if (CORE.Input.Gamepad.ready[gamepad])
|
|
|
{
|
|
|
- ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]);
|
|
|
+ ioctl(platform.gamepadStreamFd[gamepad], JSIOCGNAME(64), &CORE.Input.Gamepad.name[gamepad]);
|
|
|
name = CORE.Input.Gamepad.name[gamepad];
|
|
|
}
|
|
|
|
|
@@ -670,7 +750,7 @@ const char *GetGamepadName(int gamepad)
|
|
|
int GetGamepadAxisCount(int gamepad)
|
|
|
{
|
|
|
int axisCount = 0;
|
|
|
- if (CORE.Input.Gamepad.ready[gamepad]) ioctl(CORE.Input.Gamepad.streamId[gamepad], JSIOCGAXES, &axisCount);
|
|
|
+ if (CORE.Input.Gamepad.ready[gamepad]) ioctl(platform.gamepadStreamFd[gamepad], JSIOCGAXES, &axisCount);
|
|
|
CORE.Input.Gamepad.axisCount = axisCount;
|
|
|
|
|
|
return CORE.Input.Gamepad.axisCount;
|
|
@@ -756,31 +836,31 @@ Vector2 GetTouchPosition(int index)
|
|
|
// Swap back buffer with front buffer (screen drawing)
|
|
|
void SwapScreenBuffer(void)
|
|
|
{
|
|
|
- eglSwapBuffers(CORE.Window.device, CORE.Window.surface);
|
|
|
+ eglSwapBuffers(platform.device, platform.surface);
|
|
|
|
|
|
- if (!CORE.Window.gbmSurface || (-1 == CORE.Window.fd) || !CORE.Window.connector || !CORE.Window.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
|
|
+ if (!platform.gbmSurface || (-1 == platform.fd) || !platform.connector || !platform.crtc) TRACELOG(LOG_ERROR, "DISPLAY: DRM initialization failed to swap");
|
|
|
|
|
|
- struct gbm_bo *bo = gbm_surface_lock_front_buffer(CORE.Window.gbmSurface);
|
|
|
+ struct gbm_bo *bo = gbm_surface_lock_front_buffer(platform.gbmSurface);
|
|
|
if (!bo) TRACELOG(LOG_ERROR, "DISPLAY: Failed GBM to lock front buffer");
|
|
|
|
|
|
uint32_t fb = 0;
|
|
|
- int result = drmModeAddFB(CORE.Window.fd, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
|
|
+ int result = drmModeAddFB(platform.fd, platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay, 24, 32, gbm_bo_get_stride(bo), gbm_bo_get_handle(bo).u32, &fb);
|
|
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeAddFB() failed with result: %d", result);
|
|
|
|
|
|
- result = drmModeSetCrtc(CORE.Window.fd, CORE.Window.crtc->crtc_id, fb, 0, 0, &CORE.Window.connector->connector_id, 1, &CORE.Window.connector->modes[CORE.Window.modeIndex]);
|
|
|
+ result = drmModeSetCrtc(platform.fd, platform.crtc->crtc_id, fb, 0, 0, &platform.connector->connector_id, 1, &platform.connector->modes[platform.modeIndex]);
|
|
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeSetCrtc() failed with result: %d", result);
|
|
|
|
|
|
- if (CORE.Window.prevFB)
|
|
|
+ if (platform.prevFB)
|
|
|
{
|
|
|
- result = drmModeRmFB(CORE.Window.fd, CORE.Window.prevFB);
|
|
|
+ result = drmModeRmFB(platform.fd, platform.prevFB);
|
|
|
if (result != 0) TRACELOG(LOG_ERROR, "DISPLAY: drmModeRmFB() failed with result: %d", result);
|
|
|
}
|
|
|
|
|
|
- CORE.Window.prevFB = fb;
|
|
|
+ platform.prevFB = fb;
|
|
|
|
|
|
- if (CORE.Window.prevBO) gbm_surface_release_buffer(CORE.Window.gbmSurface, CORE.Window.prevBO);
|
|
|
+ if (platform.prevBO) gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
|
|
|
|
|
- CORE.Window.prevBO = bo;
|
|
|
+ platform.prevBO = bo;
|
|
|
}
|
|
|
|
|
|
// Register all input events
|
|
@@ -814,12 +894,12 @@ void PollInputEvents(void)
|
|
|
|
|
|
// Register previous mouse states
|
|
|
CORE.Input.Mouse.previousWheelMove = CORE.Input.Mouse.currentWheelMove;
|
|
|
- CORE.Input.Mouse.currentWheelMove = CORE.Input.Mouse.eventWheelMove;
|
|
|
- CORE.Input.Mouse.eventWheelMove = (Vector2){ 0.0f, 0.0f };
|
|
|
+ CORE.Input.Mouse.currentWheelMove = platform.eventWheelMove;
|
|
|
+ platform.eventWheelMove = (Vector2){ 0.0f, 0.0f };
|
|
|
for (int i = 0; i < MAX_MOUSE_BUTTONS; i++)
|
|
|
{
|
|
|
CORE.Input.Mouse.previousButtonState[i] = CORE.Input.Mouse.currentButtonState[i];
|
|
|
- CORE.Input.Mouse.currentButtonState[i] = CORE.Input.Mouse.currentButtonStateEvdev[i];
|
|
|
+ CORE.Input.Mouse.currentButtonState[i] = platform.currentButtonStateEvdev[i];
|
|
|
}
|
|
|
|
|
|
// Register gamepads buttons events
|
|
@@ -844,7 +924,7 @@ void PollInputEvents(void)
|
|
|
// NOTE: Keyboard reading could be done using input_event(s) or just read from stdin, both methods are used here.
|
|
|
// stdin reading is still used for legacy purposes, it allows keyboard input trough SSH console
|
|
|
|
|
|
- if (!CORE.Input.Keyboard.evtMode) ProcessKeyboard();
|
|
|
+ if (!platform.eventKeyboardMode) ProcessKeyboard();
|
|
|
|
|
|
// NOTE: Mouse input events polling is done asynchronously in another pthread - EventThread()
|
|
|
// NOTE: Gamepad (Joystick) input events polling is done asynchonously in another pthread - GamepadThread()
|
|
@@ -877,41 +957,41 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
CORE.Window.fullscreen = true;
|
|
|
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
|
|
|
|
|
- CORE.Window.fd = -1;
|
|
|
- CORE.Window.connector = NULL;
|
|
|
- CORE.Window.modeIndex = -1;
|
|
|
- CORE.Window.crtc = NULL;
|
|
|
- CORE.Window.gbmDevice = NULL;
|
|
|
- CORE.Window.gbmSurface = NULL;
|
|
|
- CORE.Window.prevBO = NULL;
|
|
|
- CORE.Window.prevFB = 0;
|
|
|
+ platform.fd = -1;
|
|
|
+ platform.connector = NULL;
|
|
|
+ platform.modeIndex = -1;
|
|
|
+ platform.crtc = NULL;
|
|
|
+ platform.gbmDevice = NULL;
|
|
|
+ platform.gbmSurface = NULL;
|
|
|
+ platform.prevBO = NULL;
|
|
|
+ platform.prevFB = 0;
|
|
|
|
|
|
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
|
|
- CORE.Window.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
|
|
+ platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
|
|
#else
|
|
|
TRACELOG(LOG_INFO, "DISPLAY: No graphic card set, trying platform-gpu-card");
|
|
|
- CORE.Window.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
|
|
+ platform.fd = open("/dev/dri/by-path/platform-gpu-card", O_RDWR); // VideoCore VI (Raspberry Pi 4)
|
|
|
|
|
|
- if ((CORE.Window.fd == -1) || (drmModeGetResources(CORE.Window.fd) == NULL))
|
|
|
+ if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
|
|
{
|
|
|
TRACELOG(LOG_INFO, "DISPLAY: Failed to open platform-gpu-card, trying card1");
|
|
|
- CORE.Window.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
|
|
+ platform.fd = open("/dev/dri/card1", O_RDWR); // Other Embedded
|
|
|
}
|
|
|
|
|
|
- if ((CORE.Window.fd == -1) || (drmModeGetResources(CORE.Window.fd) == NULL))
|
|
|
+ if ((platform.fd == -1) || (drmModeGetResources(platform.fd) == NULL))
|
|
|
{
|
|
|
TRACELOG(LOG_INFO, "DISPLAY: Failed to open graphic card1, trying card0");
|
|
|
- CORE.Window.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
|
|
+ platform.fd = open("/dev/dri/card0", O_RDWR); // VideoCore IV (Raspberry Pi 1-3)
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
- if (CORE.Window.fd == -1)
|
|
|
+ if (platform.fd == -1)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- drmModeRes *res = drmModeGetResources(CORE.Window.fd);
|
|
|
+ drmModeRes *res = drmModeGetResources(platform.fd);
|
|
|
if (!res)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
|
@@ -924,13 +1004,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
{
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector index %i", i);
|
|
|
|
|
|
- drmModeConnector *con = drmModeGetConnector(CORE.Window.fd, res->connectors[i]);
|
|
|
+ drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]);
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes);
|
|
|
|
|
|
if ((con->connection == DRM_MODE_CONNECTED) && (con->encoder_id))
|
|
|
{
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode connected");
|
|
|
- CORE.Window.connector = con;
|
|
|
+ platform.connector = con;
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
@@ -940,14 +1020,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (!CORE.Window.connector)
|
|
|
+ if (!platform.connector)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
|
|
drmModeFreeResources(res);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- drmModeEncoder *enc = drmModeGetEncoder(CORE.Window.fd, CORE.Window.connector->encoder_id);
|
|
|
+ drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
|
|
if (!enc)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
|
@@ -955,8 +1035,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- CORE.Window.crtc = drmModeGetCrtc(CORE.Window.fd, enc->crtc_id);
|
|
|
- if (!CORE.Window.crtc)
|
|
|
+ platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
|
|
|
+ if (!platform.crtc)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
|
|
drmModeFreeEncoder(enc);
|
|
@@ -969,9 +1049,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
{
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: Selecting DRM connector mode for current used mode...");
|
|
|
|
|
|
- CORE.Window.modeIndex = FindMatchingConnectorMode(CORE.Window.connector, &CORE.Window.crtc->mode);
|
|
|
+ platform.modeIndex = FindMatchingConnectorMode(platform.connector, &platform.crtc->mode);
|
|
|
|
|
|
- if (CORE.Window.modeIndex < 0)
|
|
|
+ if (platform.modeIndex < 0)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
|
|
drmModeFreeEncoder(enc);
|
|
@@ -987,19 +1067,19 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
const int fps = (CORE.Time.target > 0)? (1.0/CORE.Time.target) : 60;
|
|
|
|
|
|
// Try to find an exact matching mode
|
|
|
- CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
|
|
+ platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
|
|
|
|
|
// If nothing found, try to find a nearly matching mode
|
|
|
- if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
|
|
+ if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, allowInterlaced);
|
|
|
|
|
|
// If nothing found, try to find an exactly matching mode including interlaced
|
|
|
- if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindExactConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
|
|
+ if (platform.modeIndex < 0) platform.modeIndex = FindExactConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
|
|
|
|
|
// If nothing found, try to find a nearly matching mode including interlaced
|
|
|
- if (CORE.Window.modeIndex < 0) CORE.Window.modeIndex = FindNearestConnectorMode(CORE.Window.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
|
|
+ if (platform.modeIndex < 0) platform.modeIndex = FindNearestConnectorMode(platform.connector, CORE.Window.screen.width, CORE.Window.screen.height, fps, true);
|
|
|
|
|
|
// If nothing found, there is no suitable mode
|
|
|
- if (CORE.Window.modeIndex < 0)
|
|
|
+ if (platform.modeIndex < 0)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
|
|
drmModeFreeEncoder(enc);
|
|
@@ -1007,13 +1087,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- CORE.Window.display.width = CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay;
|
|
|
- CORE.Window.display.height = CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay;
|
|
|
+ CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
|
|
+ CORE.Window.display.height = platform.connector->modes[platform.modeIndex].vdisplay;
|
|
|
|
|
|
- TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", CORE.Window.connector->modes[CORE.Window.modeIndex].name,
|
|
|
- CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay, CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay,
|
|
|
- (CORE.Window.connector->modes[CORE.Window.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
|
|
- CORE.Window.connector->modes[CORE.Window.modeIndex].vrefresh);
|
|
|
+ TRACELOG(LOG_INFO, "DISPLAY: Selected DRM connector mode %s (%ux%u%c@%u)", platform.connector->modes[platform.modeIndex].name,
|
|
|
+ platform.connector->modes[platform.modeIndex].hdisplay, platform.connector->modes[platform.modeIndex].vdisplay,
|
|
|
+ (platform.connector->modes[platform.modeIndex].flags & DRM_MODE_FLAG_INTERLACE)? 'i' : 'p',
|
|
|
+ platform.connector->modes[platform.modeIndex].vrefresh);
|
|
|
|
|
|
// Use the width and height of the surface for render
|
|
|
CORE.Window.render.width = CORE.Window.screen.width;
|
|
@@ -1025,16 +1105,16 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
drmModeFreeResources(res);
|
|
|
res = NULL;
|
|
|
|
|
|
- CORE.Window.gbmDevice = gbm_create_device(CORE.Window.fd);
|
|
|
- if (!CORE.Window.gbmDevice)
|
|
|
+ platform.gbmDevice = gbm_create_device(platform.fd);
|
|
|
+ if (!platform.gbmDevice)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- CORE.Window.gbmSurface = gbm_surface_create(CORE.Window.gbmDevice, CORE.Window.connector->modes[CORE.Window.modeIndex].hdisplay,
|
|
|
- CORE.Window.connector->modes[CORE.Window.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
|
|
- if (!CORE.Window.gbmSurface)
|
|
|
+ platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,
|
|
|
+ platform.connector->modes[platform.modeIndex].vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING);
|
|
|
+ if (!platform.gbmSurface)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
|
|
return false;
|
|
@@ -1073,22 +1153,22 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
EGLint numConfigs = 0;
|
|
|
|
|
|
// Get an EGL device connection
|
|
|
- CORE.Window.device = eglGetDisplay((EGLNativeDisplayType)CORE.Window.gbmDevice);
|
|
|
- if (CORE.Window.device == EGL_NO_DISPLAY)
|
|
|
+ platform.device = eglGetDisplay((EGLNativeDisplayType)platform.gbmDevice);
|
|
|
+ if (platform.device == EGL_NO_DISPLAY)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// Initialize the EGL device connection
|
|
|
- if (eglInitialize(CORE.Window.device, NULL, NULL) == EGL_FALSE)
|
|
|
+ if (eglInitialize(platform.device, NULL, NULL) == EGL_FALSE)
|
|
|
{
|
|
|
// If all of the calls to eglInitialize returned EGL_FALSE then an error has occurred.
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
- if (!eglChooseConfig(CORE.Window.device, NULL, NULL, 0, &numConfigs))
|
|
|
+ if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
|
|
|
return false;
|
|
@@ -1104,7 +1184,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
}
|
|
|
|
|
|
EGLint matchingNumConfigs = 0;
|
|
|
- if (!eglChooseConfig(CORE.Window.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
|
|
+ if (!eglChooseConfig(platform.device, framebufferAttribs, configs, numConfigs, &matchingNumConfigs))
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
|
|
free(configs);
|
|
@@ -1118,7 +1198,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
for (EGLint i = 0; i < matchingNumConfigs; ++i)
|
|
|
{
|
|
|
EGLint id = 0;
|
|
|
- if (!eglGetConfigAttrib(CORE.Window.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))
|
|
|
+ if (!eglGetConfigAttrib(platform.device, configs[i], EGL_NATIVE_VISUAL_ID, &id))
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config attribute: 0x%x", eglGetError());
|
|
|
continue;
|
|
@@ -1127,7 +1207,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
if (GBM_FORMAT_ARGB8888 == id)
|
|
|
{
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: Using EGL config: %d", i);
|
|
|
- CORE.Window.config = configs[i];
|
|
|
+ platform.config = configs[i];
|
|
|
found = 1;
|
|
|
break;
|
|
|
}
|
|
@@ -1145,8 +1225,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
eglBindAPI(EGL_OPENGL_ES_API);
|
|
|
|
|
|
// Create an EGL rendering context
|
|
|
- CORE.Window.context = eglCreateContext(CORE.Window.device, CORE.Window.config, EGL_NO_CONTEXT, contextAttribs);
|
|
|
- if (CORE.Window.context == EGL_NO_CONTEXT)
|
|
|
+ platform.context = eglCreateContext(platform.device, platform.config, EGL_NO_CONTEXT, contextAttribs);
|
|
|
+ if (platform.context == EGL_NO_CONTEXT)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
|
|
return false;
|
|
@@ -1154,8 +1234,8 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
|
|
|
// Create an EGL window surface
|
|
|
//---------------------------------------------------------------------------------
|
|
|
- CORE.Window.surface = eglCreateWindowSurface(CORE.Window.device, CORE.Window.config, (EGLNativeWindowType)CORE.Window.gbmSurface, NULL);
|
|
|
- if (EGL_NO_SURFACE == CORE.Window.surface)
|
|
|
+ platform.surface = eglCreateWindowSurface(platform.device, platform.config, (EGLNativeWindowType)platform.gbmSurface, NULL);
|
|
|
+ if (EGL_NO_SURFACE == platform.surface)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
|
|
|
return false;
|
|
@@ -1169,9 +1249,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|
|
SetupFramebuffer(CORE.Window.display.width, CORE.Window.display.height);
|
|
|
|
|
|
// There must be at least one frame displayed before the buffers are swapped
|
|
|
- //eglSwapInterval(CORE.Window.device, 1);
|
|
|
+ //eglSwapInterval(platform.device, 1);
|
|
|
|
|
|
- if (eglMakeCurrent(CORE.Window.device, CORE.Window.surface, CORE.Window.surface, CORE.Window.context) == EGL_FALSE)
|
|
|
+ if (eglMakeCurrent(platform.device, platform.surface, platform.surface, platform.context) == EGL_FALSE)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "DISPLAY: Failed to attach EGL rendering context to EGL surface");
|
|
|
return false;
|
|
@@ -1214,11 +1294,11 @@ static void InitKeyboard(void)
|
|
|
// Reading directly from stdin will give chars already key-mapped by kernel to ASCII or UNICODE
|
|
|
|
|
|
// Save terminal keyboard settings
|
|
|
- tcgetattr(STDIN_FILENO, &CORE.Input.Keyboard.defaultSettings);
|
|
|
+ tcgetattr(STDIN_FILENO, &platform.defaultSettings);
|
|
|
|
|
|
// Reconfigure terminal with new settings
|
|
|
struct termios keyboardNewSettings = { 0 };
|
|
|
- keyboardNewSettings = CORE.Input.Keyboard.defaultSettings;
|
|
|
+ keyboardNewSettings = platform.defaultSettings;
|
|
|
|
|
|
// New terminal settings for keyboard: turn off buffering (non-canonical mode), echo and key processing
|
|
|
// NOTE: ISIG controls if ^C and ^Z generate break signals or not
|
|
@@ -1231,11 +1311,11 @@ static void InitKeyboard(void)
|
|
|
tcsetattr(STDIN_FILENO, TCSANOW, &keyboardNewSettings);
|
|
|
|
|
|
// Save old keyboard mode to restore it at the end
|
|
|
- CORE.Input.Keyboard.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags
|
|
|
- fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified
|
|
|
+ platform.defaultFileFlags = fcntl(STDIN_FILENO, F_GETFL, 0); // F_GETFL: Get the file access mode and the file status flags
|
|
|
+ fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags | O_NONBLOCK); // F_SETFL: Set the file status flags to the value specified
|
|
|
|
|
|
// NOTE: If ioctl() returns -1, it means the call failed for some reason (error code set in errno)
|
|
|
- int result = ioctl(STDIN_FILENO, KDGKBMODE, &CORE.Input.Keyboard.defaultMode);
|
|
|
+ int result = ioctl(STDIN_FILENO, KDGKBMODE, &platform.defaultKeyboardMode);
|
|
|
|
|
|
// In case of failure, it could mean a remote keyboard is used (SSH)
|
|
|
if (result < 0) TRACELOG(LOG_WARNING, "RPI: Failed to change keyboard mode, an SSH keyboard is probably used");
|
|
@@ -1257,11 +1337,11 @@ static void InitKeyboard(void)
|
|
|
static void RestoreKeyboard(void)
|
|
|
{
|
|
|
// Reset to default keyboard settings
|
|
|
- tcsetattr(STDIN_FILENO, TCSANOW, &CORE.Input.Keyboard.defaultSettings);
|
|
|
+ tcsetattr(STDIN_FILENO, TCSANOW, &platform.defaultSettings);
|
|
|
|
|
|
// Reconfigure keyboard to default mode
|
|
|
- fcntl(STDIN_FILENO, F_SETFL, CORE.Input.Keyboard.defaultFileFlags);
|
|
|
- ioctl(STDIN_FILENO, KDSKBMODE, CORE.Input.Keyboard.defaultMode);
|
|
|
+ fcntl(STDIN_FILENO, F_SETFL, platform.defaultFileFlags);
|
|
|
+ ioctl(STDIN_FILENO, KDSKBMODE, platform.defaultKeyboardMode);
|
|
|
}
|
|
|
|
|
|
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
|
@@ -1389,7 +1469,7 @@ static void InitEvdevInput(void)
|
|
|
struct dirent *entity = NULL;
|
|
|
|
|
|
// Initialise keyboard file descriptor
|
|
|
- CORE.Input.Keyboard.fd = -1;
|
|
|
+ platform.keyboardFd = -1;
|
|
|
|
|
|
// Reset variables
|
|
|
for (int i = 0; i < MAX_TOUCH_POINTS; ++i)
|
|
@@ -1451,9 +1531,9 @@ static void ConfigureEvdevDevice(char *device)
|
|
|
// Open the device and allocate worker
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
|
// Find a free spot in the workers array
|
|
|
- for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
+ for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
{
|
|
|
- if (CORE.Input.eventWorker[i].threadId == 0)
|
|
|
+ if (platform.eventWorker[i].threadId == 0)
|
|
|
{
|
|
|
freeWorkerId = i;
|
|
|
break;
|
|
@@ -1463,7 +1543,7 @@ static void ConfigureEvdevDevice(char *device)
|
|
|
// Select the free worker from array
|
|
|
if (freeWorkerId >= 0)
|
|
|
{
|
|
|
- worker = &(CORE.Input.eventWorker[freeWorkerId]); // Grab a pointer to the worker
|
|
|
+ worker = &(platform.eventWorker[freeWorkerId]); // Grab a pointer to the worker
|
|
|
memset(worker, 0, sizeof(InputEventWorker)); // Clear the worker
|
|
|
}
|
|
|
else
|
|
@@ -1574,13 +1654,13 @@ static void ConfigureEvdevDevice(char *device)
|
|
|
|
|
|
// Decide what to do with the device
|
|
|
//-------------------------------------------------------------------------------------------------------
|
|
|
- if (worker->isKeyboard && (CORE.Input.Keyboard.fd == -1))
|
|
|
+ if (worker->isKeyboard && (platform.keyboardFd == -1))
|
|
|
{
|
|
|
// Use the first keyboard encountered. This assumes that a device that says it's a keyboard is just a
|
|
|
// keyboard. The keyboard is polled synchronously, whereas other input devices are polled in separate
|
|
|
// threads so that they don't drop events when the frame rate is slow.
|
|
|
TRACELOG(LOG_INFO, "RPI: Opening keyboard device: %s", device);
|
|
|
- CORE.Input.Keyboard.fd = worker->fd;
|
|
|
+ platform.keyboardFd = worker->fd;
|
|
|
}
|
|
|
else if (worker->isTouch || worker->isMouse)
|
|
|
{
|
|
@@ -1604,21 +1684,21 @@ static void ConfigureEvdevDevice(char *device)
|
|
|
// Find touchscreen with the highest index
|
|
|
int maxTouchNumber = -1;
|
|
|
|
|
|
- for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
+ for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
{
|
|
|
- if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = CORE.Input.eventWorker[i].eventNum;
|
|
|
+ if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum > maxTouchNumber)) maxTouchNumber = platform.eventWorker[i].eventNum;
|
|
|
}
|
|
|
|
|
|
// Find touchscreens with lower indexes
|
|
|
- for (int i = 0; i < sizeof(CORE.Input.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
+ for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
|
|
{
|
|
|
- if (CORE.Input.eventWorker[i].isTouch && (CORE.Input.eventWorker[i].eventNum < maxTouchNumber))
|
|
|
+ if (platform.eventWorker[i].isTouch && (platform.eventWorker[i].eventNum < maxTouchNumber))
|
|
|
{
|
|
|
- if (CORE.Input.eventWorker[i].threadId != 0)
|
|
|
+ if (platform.eventWorker[i].threadId != 0)
|
|
|
{
|
|
|
TRACELOG(LOG_WARNING, "RPI: Found duplicate touchscreen, killing touchscreen on event: %d", i);
|
|
|
- pthread_cancel(CORE.Input.eventWorker[i].threadId);
|
|
|
- close(CORE.Input.eventWorker[i].fd);
|
|
|
+ pthread_cancel(platform.eventWorker[i].threadId);
|
|
|
+ close(platform.eventWorker[i].fd);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -1652,7 +1732,7 @@ static void PollKeyboardEvents(void)
|
|
|
243, 244, 245, 246, 247, 248, 0, 0, 0, 0, 0, 0, 0
|
|
|
};
|
|
|
|
|
|
- int fd = CORE.Input.Keyboard.fd;
|
|
|
+ int fd = platform.keyboardFd;
|
|
|
if (fd == -1) return;
|
|
|
|
|
|
struct input_event event = { 0 };
|
|
@@ -1666,7 +1746,7 @@ static void PollKeyboardEvents(void)
|
|
|
{
|
|
|
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
|
|
// Change keyboard mode to events
|
|
|
- CORE.Input.Keyboard.evtMode = true;
|
|
|
+ platform.eventKeyboardMode = true;
|
|
|
#endif
|
|
|
// Keyboard button parsing
|
|
|
if ((event.code >= 1) && (event.code <= 255)) //Keyboard keys appear for codes 1 to 255
|
|
@@ -1739,7 +1819,7 @@ static void *EventThread(void *arg)
|
|
|
gestureUpdate = true;
|
|
|
}
|
|
|
|
|
|
- if (event.code == REL_WHEEL) CORE.Input.Mouse.eventWheelMove.y += event.value;
|
|
|
+ if (event.code == REL_WHEEL) platform.eventWheelMove.y += event.value;
|
|
|
}
|
|
|
|
|
|
// Absolute movement parsing
|
|
@@ -1790,11 +1870,11 @@ static void *EventThread(void *arg)
|
|
|
// Touchscreen tap
|
|
|
if (event.code == ABS_PRESSURE)
|
|
|
{
|
|
|
- int previousMouseLeftButtonState = CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];
|
|
|
+ int previousMouseLeftButtonState = platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT];
|
|
|
|
|
|
if (!event.value && previousMouseLeftButtonState)
|
|
|
{
|
|
|
- CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
|
|
|
+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 0;
|
|
|
|
|
|
touchAction = 0; // TOUCH_ACTION_UP
|
|
|
gestureUpdate = true;
|
|
@@ -1802,7 +1882,7 @@ static void *EventThread(void *arg)
|
|
|
|
|
|
if (event.value && !previousMouseLeftButtonState)
|
|
|
{
|
|
|
- CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
|
|
|
+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = 1;
|
|
|
|
|
|
touchAction = 1; // TOUCH_ACTION_DOWN
|
|
|
gestureUpdate = true;
|
|
@@ -1817,19 +1897,19 @@ static void *EventThread(void *arg)
|
|
|
// Mouse button parsing
|
|
|
if ((event.code == BTN_TOUCH) || (event.code == BTN_LEFT))
|
|
|
{
|
|
|
- CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
|
|
|
+ platform.currentButtonStateEvdev[MOUSE_BUTTON_LEFT] = event.value;
|
|
|
|
|
|
if (event.value > 0) touchAction = 1; // TOUCH_ACTION_DOWN
|
|
|
else touchAction = 0; // TOUCH_ACTION_UP
|
|
|
gestureUpdate = true;
|
|
|
}
|
|
|
|
|
|
- if (event.code == BTN_RIGHT) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
|
|
|
- if (event.code == BTN_MIDDLE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;
|
|
|
- if (event.code == BTN_SIDE) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;
|
|
|
- if (event.code == BTN_EXTRA) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;
|
|
|
- if (event.code == BTN_FORWARD) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;
|
|
|
- if (event.code == BTN_BACK) CORE.Input.Mouse.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;
|
|
|
+ if (event.code == BTN_RIGHT) platform.currentButtonStateEvdev[MOUSE_BUTTON_RIGHT] = event.value;
|
|
|
+ if (event.code == BTN_MIDDLE) platform.currentButtonStateEvdev[MOUSE_BUTTON_MIDDLE] = event.value;
|
|
|
+ if (event.code == BTN_SIDE) platform.currentButtonStateEvdev[MOUSE_BUTTON_SIDE] = event.value;
|
|
|
+ if (event.code == BTN_EXTRA) platform.currentButtonStateEvdev[MOUSE_BUTTON_EXTRA] = event.value;
|
|
|
+ if (event.code == BTN_FORWARD) platform.currentButtonStateEvdev[MOUSE_BUTTON_FORWARD] = event.value;
|
|
|
+ if (event.code == BTN_BACK) platform.currentButtonStateEvdev[MOUSE_BUTTON_BACK] = event.value;
|
|
|
}
|
|
|
|
|
|
// Screen confinement
|
|
@@ -1885,7 +1965,7 @@ static void InitGamepad(void)
|
|
|
{
|
|
|
sprintf(gamepadDev, "%s%i", DEFAULT_GAMEPAD_DEV, i);
|
|
|
|
|
|
- if ((CORE.Input.Gamepad.streamId[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
|
|
|
+ if ((platform.gamepadStreamFd[i] = open(gamepadDev, O_RDONLY | O_NONBLOCK)) < 0)
|
|
|
{
|
|
|
// NOTE: Only show message for first gamepad
|
|
|
if (i == 0) TRACELOG(LOG_WARNING, "RPI: Failed to open Gamepad device, no gamepad available");
|
|
@@ -1897,7 +1977,7 @@ static void InitGamepad(void)
|
|
|
// NOTE: Only create one thread
|
|
|
if (i == 0)
|
|
|
{
|
|
|
- int error = pthread_create(&CORE.Input.Gamepad.threadId, NULL, &GamepadThread, NULL);
|
|
|
+ int error = pthread_create(&platform.gamepadThreadId, NULL, &GamepadThread, NULL);
|
|
|
|
|
|
if (error != 0) TRACELOG(LOG_WARNING, "RPI: Failed to create gamepad input event thread");
|
|
|
else TRACELOG(LOG_INFO, "RPI: Gamepad device initialized successfully");
|
|
@@ -1927,7 +2007,7 @@ static void *GamepadThread(void *arg)
|
|
|
{
|
|
|
for (int i = 0; i < MAX_GAMEPADS; i++)
|
|
|
{
|
|
|
- if (read(CORE.Input.Gamepad.streamId[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
|
|
|
+ if (read(platform.gamepadStreamFd[i], &gamepadEvent, sizeof(struct js_event)) == (int)sizeof(struct js_event))
|
|
|
{
|
|
|
gamepadEvent.type &= ~JS_EVENT_INIT; // Ignore synthetic events
|
|
|
|
|
@@ -1977,7 +2057,7 @@ static int FindMatchingConnectorMode(const drmModeConnector *connector, const dr
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, connector->modes[i].hdisplay, connector->modes[i].vdisplay,
|
|
|
connector->modes[i].vrefresh, (connector->modes[i].flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
|
|
|
|
|
- if (0 == BINCMP(&CORE.Window.crtc->mode, &CORE.Window.connector->modes[i])) return i;
|
|
|
+ if (0 == BINCMP(&platform.crtc->mode, &platform.connector->modes[i])) return i;
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
@@ -1992,9 +2072,9 @@ static int FindExactConnectorMode(const drmModeConnector *connector, uint width,
|
|
|
|
|
|
if (NULL == connector) return -1;
|
|
|
|
|
|
- for (int i = 0; i < CORE.Window.connector->count_modes; i++)
|
|
|
+ for (int i = 0; i < platform.connector->count_modes; i++)
|
|
|
{
|
|
|
- const drmModeModeInfo *const mode = &CORE.Window.connector->modes[i];
|
|
|
+ const drmModeModeInfo *const mode = &platform.connector->modes[i];
|
|
|
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM Mode %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh, (mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
|
|
|
|
@@ -2015,9 +2095,9 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|
|
if (NULL == connector) return -1;
|
|
|
|
|
|
int nearestIndex = -1;
|
|
|
- for (int i = 0; i < CORE.Window.connector->count_modes; i++)
|
|
|
+ for (int i = 0; i < platform.connector->count_modes; i++)
|
|
|
{
|
|
|
- const drmModeModeInfo *const mode = &CORE.Window.connector->modes[i];
|
|
|
+ const drmModeModeInfo *const mode = &platform.connector->modes[i];
|
|
|
|
|
|
TRACELOG(LOG_TRACE, "DISPLAY: DRM mode: %d %ux%u@%u %s", i, mode->hdisplay, mode->vdisplay, mode->vrefresh,
|
|
|
(mode->flags & DRM_MODE_FLAG_INTERLACE)? "interlaced" : "progressive");
|
|
@@ -2044,9 +2124,9 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|
|
const int heightDiff = abs(mode->vdisplay - height);
|
|
|
const int fpsDiff = abs(mode->vrefresh - fps);
|
|
|
|
|
|
- const int nearestWidthDiff = abs(CORE.Window.connector->modes[nearestIndex].hdisplay - width);
|
|
|
- const int nearestHeightDiff = abs(CORE.Window.connector->modes[nearestIndex].vdisplay - height);
|
|
|
- const int nearestFpsDiff = abs(CORE.Window.connector->modes[nearestIndex].vrefresh - fps);
|
|
|
+ const int nearestWidthDiff = abs(platform.connector->modes[nearestIndex].hdisplay - width);
|
|
|
+ const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
|
|
|
+ const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
|
|
|
|
|
|
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) {
|
|
|
nearestIndex = i;
|