WARNING: REDESIGN: InitPlatform() to initialize all platform data #3313
`InitGraphicsDevice()` could be confusing because the function actually initialized many things: window, graphics, inputs, callbacks, timming, storage... restructured it.
This commit is contained in:
parent
4521a142c3
commit
b34c2ecbcb
1 changed files with 505 additions and 547 deletions
354
src/rcore_drm.c
354
src/rcore_drm.c
|
|
@ -140,21 +140,22 @@ static PlatformData platform = { 0 }; // Platform specific data
|
|||
//----------------------------------------------------------------------------------
|
||||
// Module Internal Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool InitGraphicsDevice(int width, int height); // Initialize graphics device
|
||||
static int InitPlatform(void); // Initialize platform (graphics, inputs and more)
|
||||
static void ClosePlatform(void); // Close platform
|
||||
|
||||
static void InitKeyboard(void); // Initialize raw keyboard system
|
||||
static void RestoreKeyboard(void); // Restore keyboard system
|
||||
static void InitKeyboard(void); // Initialize raw keyboard system
|
||||
static void RestoreKeyboard(void); // Restore keyboard system
|
||||
#if defined(SUPPORT_SSH_KEYBOARD_RPI)
|
||||
static void ProcessKeyboard(void); // Process keyboard events
|
||||
static void ProcessKeyboard(void); // Process keyboard events
|
||||
#endif
|
||||
|
||||
static void InitEvdevInput(void); // Initialize evdev inputs
|
||||
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
||||
static void *EventThread(void *arg); // Input device events reading thread
|
||||
static void InitEvdevInput(void); // Initialize evdev inputs
|
||||
static void ConfigureEvdevDevice(char *device); // Identifies a input device and configures it for use if appropriate
|
||||
static void PollKeyboardEvents(void); // Process evdev keyboard events
|
||||
static void *EventThread(void *arg); // Input device events reading thread
|
||||
|
||||
static void InitGamepad(void); // Initialize raw gamepad input
|
||||
static void *GamepadThread(void *arg); // Mouse reading thread
|
||||
static void InitGamepad(void); // Initialize raw gamepad input
|
||||
static void *GamepadThread(void *arg); // Mouse reading thread
|
||||
|
||||
static int FindMatchingConnectorMode(const drmModeConnector *connector, const drmModeModeInfo *mode); // Search matching DRM mode in connector's mode list
|
||||
static int FindExactConnectorMode(const drmModeConnector *connector, uint width, uint height, uint fps, bool allowInterlaced); // Search exactly matching DRM connector mode in connector's list
|
||||
|
|
@ -204,49 +205,31 @@ void InitWindow(int width, int height, const char *title)
|
|||
TRACELOG(LOG_INFO, " > raudio:.... not loaded (optional)");
|
||||
#endif
|
||||
|
||||
// NOTE: Keep internal pointer to input title string (no copy)
|
||||
// Initialize window data
|
||||
CORE.Window.screen.width = width;
|
||||
CORE.Window.screen.height = height;
|
||||
CORE.Window.eventWaiting = false;
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
if ((title != NULL) && (title[0] != 0)) CORE.Window.title = title;
|
||||
|
||||
// Initialize global input state
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input));
|
||||
memset(&CORE.Input, 0, sizeof(CORE.Input)); // Reset CORE.Input structure to 0
|
||||
CORE.Input.Keyboard.exitKey = KEY_ESCAPE;
|
||||
CORE.Input.Mouse.scale = (Vector2){1.0f, 1.0f};
|
||||
CORE.Input.Mouse.scale = (Vector2){ 1.0f, 1.0f };
|
||||
CORE.Input.Mouse.cursor = MOUSE_CURSOR_ARROW;
|
||||
CORE.Input.Gamepad.lastButtonPressed = 0; // GAMEPAD_BUTTON_UNKNOWN
|
||||
CORE.Window.eventWaiting = false;
|
||||
|
||||
|
||||
// Platform specific init window
|
||||
CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
|
||||
|
||||
// Initialize platform
|
||||
//--------------------------------------------------------------
|
||||
InitPlatform();
|
||||
//--------------------------------------------------------------
|
||||
// Initialize graphics device (display device and OpenGL context)
|
||||
// NOTE: returns true if window and graphic device has been initialized successfully
|
||||
CORE.Window.ready = InitGraphicsDevice(width, height);
|
||||
|
||||
// Initialize rlgl default data (buffers and shaders)
|
||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
|
||||
|
||||
// Set some default window flags
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
// Initialize raw input system
|
||||
InitEvdevInput(); // Evdev inputs initialization
|
||||
InitGamepad(); // Gamepad init
|
||||
InitKeyboard(); // Keyboard init (stdin)
|
||||
//--------------------------------------------------------------
|
||||
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
// Setup default viewport
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
#if defined(SUPPORT_MODULE_RTEXT) && defined(SUPPORT_DEFAULT_FONT)
|
||||
// Load default font
|
||||
|
|
@ -289,7 +272,10 @@ void InitWindow(int width, int height, const char *title)
|
|||
events = (AutomationEvent *)RL_CALLOC(MAX_CODE_AUTOMATION_EVENTS, sizeof(AutomationEvent));
|
||||
CORE.Time.frameCounter = 0;
|
||||
#endif
|
||||
|
||||
|
||||
// Initialize random seed
|
||||
SetRandomSeed((unsigned int)time(NULL));
|
||||
|
||||
TRACELOG(LOG_INFO, "PLATFORM: DRM: Application initialized successfully");
|
||||
}
|
||||
|
||||
|
|
@ -315,93 +301,9 @@ void CloseWindow(void)
|
|||
timeEndPeriod(1); // Restore time period
|
||||
#endif
|
||||
|
||||
// Platform specific close window
|
||||
//--------------------------------------------------------------
|
||||
if (platform.prevFB)
|
||||
{
|
||||
drmModeRmFB(platform.fd, platform.prevFB);
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
platform.prevBO = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmSurface)
|
||||
{
|
||||
gbm_surface_destroy(platform.gbmSurface);
|
||||
platform.gbmSurface = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmDevice)
|
||||
{
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
if (platform.connector)
|
||||
{
|
||||
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(platform.crtc);
|
||||
platform.crtc = NULL;
|
||||
}
|
||||
|
||||
if (platform.fd != -1)
|
||||
{
|
||||
close(platform.fd);
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
if (platform.surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(platform.device, platform.surface);
|
||||
platform.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (platform.context != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(platform.device, platform.context);
|
||||
platform.context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
// Wait for mouse and gamepad threads to finish before closing
|
||||
// NOTE: Those threads should already have finished at this point
|
||||
// because they are controlled by CORE.Window.shouldClose variable
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
// Close the evdev keyboard
|
||||
if (platform.keyboardFd != -1)
|
||||
{
|
||||
close(platform.keyboardFd);
|
||||
platform.keyboardFd = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (platform.eventWorker[i].threadId)
|
||||
{
|
||||
pthread_join(platform.eventWorker[i].threadId, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
||||
// De-initialize platform
|
||||
//--------------------------------------------------------------
|
||||
ClosePlatform();
|
||||
//--------------------------------------------------------------
|
||||
|
||||
#if defined(SUPPORT_EVENTS_AUTOMATION)
|
||||
|
|
@ -808,28 +710,9 @@ void PollInputEvents(void)
|
|||
// Module Internal Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Initialize display device and framebuffer
|
||||
// NOTE: width and height represent the screen (framebuffer) desired size, not actual display size
|
||||
// If width or height are 0, default display size will be used for framebuffer size
|
||||
// NOTE: returns false in case graphic device could not be created
|
||||
static bool InitGraphicsDevice(int width, int height)
|
||||
// Initialize platform: graphics, inputs and more
|
||||
static int InitPlatform(void)
|
||||
{
|
||||
CORE.Window.screen.width = width; // User desired width
|
||||
CORE.Window.screen.height = height; // User desired height
|
||||
CORE.Window.screenScale = MatrixIdentity(); // No draw scaling required by default
|
||||
|
||||
// Set the window minimum and maximum default values to 0
|
||||
CORE.Window.screenMin.width = 0;
|
||||
CORE.Window.screenMin.height = 0;
|
||||
CORE.Window.screenMax.width = 0;
|
||||
CORE.Window.screenMax.height = 0;
|
||||
|
||||
// NOTE: Framebuffer (render area - CORE.Window.render.width, CORE.Window.render.height) could include black bars...
|
||||
// ...in top-down or left-right to match display aspect ratio (no weird scaling)
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
platform.fd = -1;
|
||||
platform.connector = NULL;
|
||||
platform.modeIndex = -1;
|
||||
|
|
@ -838,6 +721,9 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
platform.gbmSurface = NULL;
|
||||
platform.prevBO = NULL;
|
||||
platform.prevFB = 0;
|
||||
|
||||
CORE.Window.fullscreen = true;
|
||||
CORE.Window.flags |= FLAG_FULLSCREEN_MODE;
|
||||
|
||||
#if defined(DEFAULT_GRAPHIC_DEVICE_DRM)
|
||||
platform.fd = open(DEFAULT_GRAPHIC_DEVICE_DRM, O_RDWR);
|
||||
|
|
@ -861,14 +747,14 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.fd == -1)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to open graphic card");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
drmModeRes *res = drmModeGetResources(platform.fd);
|
||||
if (!res)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed get DRM resources");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: Connectors found: %i", res->count_connectors);
|
||||
|
|
@ -897,7 +783,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: No suitable DRM connector found");
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
drmModeEncoder *enc = drmModeGetEncoder(platform.fd, platform.connector->encoder_id);
|
||||
|
|
@ -905,7 +791,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode encoder");
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
platform.crtc = drmModeGetCrtc(platform.fd, enc->crtc_id);
|
||||
|
|
@ -914,7 +800,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get DRM mode crtc");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// If InitWindow should use the current mode find it in the connector's mode list
|
||||
|
|
@ -929,7 +815,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: No matching DRM connector mode found");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CORE.Window.screen.width = CORE.Window.display.width;
|
||||
|
|
@ -957,7 +843,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable DRM connector mode");
|
||||
drmModeFreeEncoder(enc);
|
||||
drmModeFreeResources(res);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
CORE.Window.display.width = platform.connector->modes[platform.modeIndex].hdisplay;
|
||||
|
|
@ -982,7 +868,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!platform.gbmDevice)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM device");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
platform.gbmSurface = gbm_surface_create(platform.gbmDevice, platform.connector->modes[platform.modeIndex].hdisplay,
|
||||
|
|
@ -990,7 +876,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!platform.gbmSurface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create GBM surface");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EGLint samples = 0;
|
||||
|
|
@ -1030,7 +916,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.device == EGL_NO_DISPLAY)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to initialize EGL device");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Initialize the EGL device connection
|
||||
|
|
@ -1038,13 +924,13 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
// 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;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!eglChooseConfig(platform.device, NULL, NULL, 0, &numConfigs))
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get EGL config count: 0x%x", eglGetError());
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: EGL configs available: %d", numConfigs);
|
||||
|
|
@ -1053,7 +939,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!configs)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to get memory for EGL configs");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
EGLint matchingNumConfigs = 0;
|
||||
|
|
@ -1061,7 +947,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to choose EGL config: 0x%x", eglGetError());
|
||||
free(configs);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
TRACELOG(LOG_TRACE, "DISPLAY: EGL matching configs available: %d", matchingNumConfigs);
|
||||
|
|
@ -1091,7 +977,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (!found)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to find a suitable EGL config");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set rendering API
|
||||
|
|
@ -1102,7 +988,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (platform.context == EGL_NO_CONTEXT)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL context");
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Create an EGL window surface
|
||||
|
|
@ -1111,7 +997,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
if (EGL_NO_SURFACE == platform.surface)
|
||||
{
|
||||
TRACELOG(LOG_WARNING, "DISPLAY: Failed to create EGL window surface: 0x%04x", eglGetError());
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// At this point we need to manage render size vs screen size
|
||||
|
|
@ -1127,7 +1013,7 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
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;
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1147,19 +1033,123 @@ static bool InitGraphicsDevice(int width, int height)
|
|||
// NOTE: GL procedures address loader is required to load extensions
|
||||
rlLoadExtensions(eglGetProcAddress);
|
||||
|
||||
// Initialize OpenGL context (states and resources)
|
||||
// NOTE: CORE.Window.currentFbo.width and CORE.Window.currentFbo.height not used, just stored as globals in rlgl
|
||||
rlglInit(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
// Setup default viewport
|
||||
// NOTE: It updated CORE.Window.render.width and CORE.Window.render.height
|
||||
SetupViewport(CORE.Window.currentFbo.width, CORE.Window.currentFbo.height);
|
||||
|
||||
if ((CORE.Window.flags & FLAG_WINDOW_MINIMIZED) > 0) MinimizeWindow();
|
||||
|
||||
// If graphic device is no properly initialized, we end program
|
||||
if (!CORE.Window.ready) { TRACELOG(LOG_FATAL, "PLATFORM: Failed to initialize graphic device"); return -1; }
|
||||
else SetWindowPosition(GetMonitorWidth(GetCurrentMonitor()) / 2 - CORE.Window.screen.width / 2, GetMonitorHeight(GetCurrentMonitor()) / 2 - CORE.Window.screen.height / 2);
|
||||
|
||||
return true;
|
||||
// Set some default window flags
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_HIDDEN; // false
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_MINIMIZED; // false
|
||||
CORE.Window.flags |= FLAG_WINDOW_MAXIMIZED; // true
|
||||
CORE.Window.flags &= ~FLAG_WINDOW_UNFOCUSED; // false
|
||||
|
||||
// Initialize hi-res timer
|
||||
InitTimer();
|
||||
|
||||
// Initialize base path for storage
|
||||
CORE.Storage.basePath = GetWorkingDirectory();
|
||||
|
||||
// Initialize raw input system
|
||||
InitEvdevInput(); // Evdev inputs initialization
|
||||
InitGamepad(); // Gamepad init
|
||||
InitKeyboard(); // Keyboard init (stdin)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Close platform
|
||||
static void ClosePlatform(void)
|
||||
{
|
||||
if (platform.prevFB)
|
||||
{
|
||||
drmModeRmFB(platform.fd, platform.prevFB);
|
||||
platform.prevFB = 0;
|
||||
}
|
||||
|
||||
if (platform.prevBO)
|
||||
{
|
||||
gbm_surface_release_buffer(platform.gbmSurface, platform.prevBO);
|
||||
platform.prevBO = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmSurface)
|
||||
{
|
||||
gbm_surface_destroy(platform.gbmSurface);
|
||||
platform.gbmSurface = NULL;
|
||||
}
|
||||
|
||||
if (platform.gbmDevice)
|
||||
{
|
||||
gbm_device_destroy(platform.gbmDevice);
|
||||
platform.gbmDevice = NULL;
|
||||
}
|
||||
|
||||
if (platform.crtc)
|
||||
{
|
||||
if (platform.connector)
|
||||
{
|
||||
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(platform.crtc);
|
||||
platform.crtc = NULL;
|
||||
}
|
||||
|
||||
if (platform.fd != -1)
|
||||
{
|
||||
close(platform.fd);
|
||||
platform.fd = -1;
|
||||
}
|
||||
|
||||
// Close surface, context and display
|
||||
if (platform.device != EGL_NO_DISPLAY)
|
||||
{
|
||||
if (platform.surface != EGL_NO_SURFACE)
|
||||
{
|
||||
eglDestroySurface(platform.device, platform.surface);
|
||||
platform.surface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (platform.context != EGL_NO_CONTEXT)
|
||||
{
|
||||
eglDestroyContext(platform.device, platform.context);
|
||||
platform.context = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
eglTerminate(platform.device);
|
||||
platform.device = EGL_NO_DISPLAY;
|
||||
}
|
||||
|
||||
// Wait for mouse and gamepad threads to finish before closing
|
||||
// NOTE: Those threads should already have finished at this point
|
||||
// because they are controlled by CORE.Window.shouldClose variable
|
||||
|
||||
CORE.Window.shouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
// Close the evdev keyboard
|
||||
if (platform.keyboardFd != -1)
|
||||
{
|
||||
close(platform.keyboardFd);
|
||||
platform.keyboardFd = -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < sizeof(platform.eventWorker)/sizeof(InputEventWorker); ++i)
|
||||
{
|
||||
if (platform.eventWorker[i].threadId)
|
||||
{
|
||||
pthread_join(platform.eventWorker[i].threadId, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (platform.gamepadThreadId) pthread_join(platform.gamepadThreadId, NULL);
|
||||
}
|
||||
|
||||
|
||||
// Initialize Keyboard system (using standard input)
|
||||
static void InitKeyboard(void)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue