Split Headless And Server Mode Code

This commit is contained in:
TheBrokenRail 2021-08-26 22:52:18 -04:00
parent 4aeb2fd95b
commit a762654e35
17 changed files with 97 additions and 73 deletions

View File

@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.13.0)
# Specify Options # Specify Options
option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" FALSE) option(MCPI_USE_MEDIA_LAYER_PROXY "Whether To Enable The Media Layer Proxy" FALSE)
option(MCPI_SERVER_MODE "Server Mode" FALSE) option(MCPI_SERVER_MODE "Server Mode" FALSE)
option(MCPI_HEADLESS_MODE "Headless Mode" ${MCPI_SERVER_MODE})
set(MCPI_BUILD_MODE "both" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code; \"both\" = Build All Code As ARM") set(MCPI_BUILD_MODE "both" CACHE STRING "\"arm\" = Build Only Code That Must Be ARM; \"native\" = Build Architecture-Independent Code; \"both\" = Build All Code As ARM")
set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "both" "arm" "native") set_property(CACHE MCPI_BUILD_MODE PROPERTY STRINGS "both" "arm" "native")
@ -95,6 +96,9 @@ set(CMAKE_CXX_STANDARD 11)
if(MCPI_SERVER_MODE) if(MCPI_SERVER_MODE)
add_definitions(-DMCPI_SERVER_MODE) add_definitions(-DMCPI_SERVER_MODE)
endif() endif()
if(MCPI_HEADLESS_MODE)
add_definitions(-DMCPI_HEADLESS_MODE)
endif()
# Version # Version
file(STRINGS VERSION VERSION) file(STRINGS VERSION VERSION)

View File

@ -8,6 +8,9 @@
* ``MCPI_SERVER_MODE`` * ``MCPI_SERVER_MODE``
* ``ON``: Enable Server Mode * ``ON``: Enable Server Mode
* ``OFF`` (Default): Disable Server Mode * ``OFF`` (Default): Disable Server Mode
* ``MCPI_HEADLESS_MODE``
* ``ON`` (Default In Server Mode): Enable Headless Mode
* ``OFF`` (Default In Client Mode): Disable Headless Mode
* ``MCPI_USE_MEDIA_LAYER_PROXY`` * ``MCPI_USE_MEDIA_LAYER_PROXY``
* ``ON``: Enable The Media Layer Proxy * ``ON``: Enable The Media Layer Proxy
* ``OFF`` (Default): Disable The Media Layer Proxy * ``OFF`` (Default): Disable The Media Layer Proxy

View File

@ -7,3 +7,4 @@
#define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); } #define INFO(format, ...) { fprintf(stderr, "[INFO]: " format "\n", __VA_ARGS__); }
#define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); } #define WARN(format, ...) { fprintf(stderr, "[WARN]: " format "\n", __VA_ARGS__); }
#define ERR(format, ...) { fprintf(stderr, "[ERR]: " format "\n", __VA_ARGS__); exit(EXIT_FAILURE); } #define ERR(format, ...) { fprintf(stderr, "[ERR]: " format "\n", __VA_ARGS__); exit(EXIT_FAILURE); }
#define IMPOSSIBLE() ERR("(%s:%i) This Should Never Be Called", __FILE__, __LINE__)

View File

@ -2,8 +2,8 @@ project(media-layer)
# Check Options # Check Options
if(MCPI_USE_MEDIA_LAYER_PROXY) if(MCPI_USE_MEDIA_LAYER_PROXY)
if(MCPI_SERVER_MODE) if(MCPI_HEADLESS_MODE)
message(FATAL_ERROR "Server Mode With Media Layer Proxy Configuration Is Redundant") message(FATAL_ERROR "Headless Mode With Media Layer Proxy Configuration Is Redundant")
endif() endif()
if(MCPI_BUILD_MODE STREQUAL "both") if(MCPI_BUILD_MODE STREQUAL "both")
message(FATAL_ERROR "Media Layer Proxy Is Redundant When Building ARM And Native Components In The Same Build") message(FATAL_ERROR "Media Layer Proxy Is Redundant When Building ARM And Native Components In The Same Build")

View File

@ -18,7 +18,7 @@ endif()
if(TARGET media-layer-core) if(TARGET media-layer-core)
# Link # Link
target_link_libraries(media-layer-core media-layer-headers reborn-headers pthread dl) target_link_libraries(media-layer-core media-layer-headers reborn-headers pthread dl)
if(NOT MCPI_SERVER_MODE) if(NOT MCPI_HEADLESS_MODE)
# Find GLFW # Find GLFW
find_package(glfw3 3.3 REQUIRED) find_package(glfw3 3.3 REQUIRED)
# Find FreeImage # Find FreeImage

View File

@ -3,17 +3,17 @@
#include <SDL/SDL.h> #include <SDL/SDL.h>
#include <GLES/gl.h> #include <GLES/gl.h>
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
#define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_NONE
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include <libreborn/media-layer/core.h> #include <libreborn/media-layer/core.h>
#include <libreborn/media-layer/internal.h> #include <libreborn/media-layer/internal.h>
// GLFW Code Not Needed In Server Mode // GLFW Code Not Needed In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
static GLFWwindow *glfw_window; static GLFWwindow *glfw_window;
@ -194,12 +194,12 @@ static void glfw_scroll(__attribute__((unused)) GLFWwindow *window, __attribute_
} }
} }
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
// Init GLFW // Init GLFW
void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) { void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *icon) {
// Don't Enable GLFW In Server Mode // Don't Enable GLFW In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
glfwSetErrorCallback(glfw_error); glfwSetErrorCallback(glfw_error);
if (!glfwInit()) { if (!glfwInit()) {
@ -229,20 +229,20 @@ void SDL_WM_SetCaption(const char *title, __attribute__((unused)) const char *ic
glfwSetScrollCallback(glfw_window, glfw_scroll); glfwSetScrollCallback(glfw_window, glfw_scroll);
glfwMakeContextCurrent(glfw_window); glfwMakeContextCurrent(glfw_window);
#else // #ifndef MCPI_SERVER_MODE #else // #ifndef MCPI_HEADLESS_MODE
(void) title; // Mark As Used (void) title; // Mark As Used
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
} }
void media_swap_buffers() { void media_swap_buffers() {
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
// Don't Swap Buffers In A Context-Less Window // Don't Swap Buffers In A Context-Less Window
glfwSwapBuffers(glfw_window); glfwSwapBuffers(glfw_window);
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
} }
// Fullscreen Not Needed In Server Mode // Fullscreen Not Needed In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
static int is_fullscreen = 0; static int is_fullscreen = 0;
// Old Size And Position To Use When Exiting Fullscreen // Old Size And Position To Use When Exiting Fullscreen
@ -271,15 +271,15 @@ void media_toggle_fullscreen() {
} }
is_fullscreen = !is_fullscreen; is_fullscreen = !is_fullscreen;
} }
#else // #ifndef MCPI_SERVER_MODE #else // #ifndef MCPI_HEADLESS_MODE
void media_toggle_fullscreen() { void media_toggle_fullscreen() {
} }
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
// Intercept SDL Events // Intercept SDL Events
void _media_handle_SDL_PollEvent() { void _media_handle_SDL_PollEvent() {
// GLFW Is Disabled In Server Mode // GLFW Is Disabled In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
// Process GLFW Events // Process GLFW Events
glfwPollEvents(); glfwPollEvents();
@ -290,16 +290,16 @@ void _media_handle_SDL_PollEvent() {
SDL_PushEvent(&event); SDL_PushEvent(&event);
glfwSetWindowShouldClose(glfw_window, GLFW_FALSE); glfwSetWindowShouldClose(glfw_window, GLFW_FALSE);
} }
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
} }
// Terminate GLFW // Terminate GLFW
void media_cleanup() { void media_cleanup() {
// GLFW Is Disabled In Server Mode // GLFW Is Disabled In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
glfwDestroyWindow(glfw_window); glfwDestroyWindow(glfw_window);
glfwTerminate(); glfwTerminate();
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
} }
// Store Cursor State // Store Cursor State
@ -307,7 +307,7 @@ static int cursor_grabbed = 0;
static int cursor_visible = 1; static int cursor_visible = 1;
// Update GLFW Cursor State (Client Only) // Update GLFW Cursor State (Client Only)
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
static void update_glfw_cursor() { static void update_glfw_cursor() {
// Store Old Mode // Store Old Mode
int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR); int old_mode = glfwGetInputMode(glfw_window, GLFW_CURSOR);
@ -352,7 +352,7 @@ SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) {
cursor_grabbed = 0; cursor_grabbed = 0;
} }
// Update Cursor GLFW State (Client Only) // Update Cursor GLFW State (Client Only)
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
update_glfw_cursor(); update_glfw_cursor();
#endif #endif
// Return // Return
@ -372,7 +372,7 @@ int SDL_ShowCursor(int toggle) {
cursor_visible = 0; cursor_visible = 0;
} }
// Update Cursor GLFW State (Client Only) // Update Cursor GLFW State (Client Only)
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
update_glfw_cursor(); update_glfw_cursor();
#endif #endif
// Return // Return
@ -381,12 +381,12 @@ int SDL_ShowCursor(int toggle) {
// Get Framebuffer Size // Get Framebuffer Size
void media_get_framebuffer_size(int *width, int *height) { void media_get_framebuffer_size(int *width, int *height) {
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
if (glfw_window != NULL) { if (glfw_window != NULL) {
glfwGetFramebufferSize(glfw_window, width, height); glfwGetFramebufferSize(glfw_window, width, height);
return; return;
} }
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE
*width = DEFAULT_WIDTH; *width = DEFAULT_WIDTH;
*height = DEFAULT_HEIGHT; *height = DEFAULT_HEIGHT;
} }

View File

@ -1,5 +1,5 @@
// Screenshot Code Is Useless In Server Mode // Screenshot Code Is Useless In Server Mode
#ifndef MCPI_SERVER_MODE #ifndef MCPI_HEADLESS_MODE
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
@ -16,22 +16,41 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#include <libreborn/media-layer/core.h> #include <libreborn/media-layer/core.h>
// Ensure Screenshots Folder Exists
static void ensure_screenshots_folder(char *screenshots) {
// Check Screenshots Folder
struct stat obj;
if (stat(screenshots, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
// Create Screenshots Folder
int ret = mkdir(screenshots, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
ERR("Error Creating Directory: %s: %s", screenshots, strerror(errno));
}
}
}
// 4 (Year) + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Null Terminator) // 4 (Year) + 1 (Hyphen) + 2 (Month) + 1 (Hyphen) + 2 (Day) + 1 (Underscore) + 2 (Hour) + 1 (Period) + 2 (Minute) + 1 (Period) + 2 (Second) + 1 (Null Terminator)
#define TIME_SIZE 20 #define TIME_SIZE 20
// Take Screenshot // Take Screenshot
void media_take_screenshot() { void media_take_screenshot(char *home) {
// Get Directory
char *screenshots = NULL;
safe_asprintf(&screenshots, "%s/screenshots", home);
// Get Timestamp
time_t rawtime; time_t rawtime;
struct tm *timeinfo; struct tm *timeinfo;
time(&rawtime); time(&rawtime);
timeinfo = localtime(&rawtime); timeinfo = localtime(&rawtime);
char time[TIME_SIZE]; char time[TIME_SIZE];
strftime(time, TIME_SIZE, "%Y-%m-%d_%H.%M.%S", timeinfo); strftime(time, TIME_SIZE, "%Y-%m-%d_%H.%M.%S", timeinfo);
char *screenshots = NULL; // Ensure Screenshots Folder Exists
safe_asprintf(&screenshots, "%s/.minecraft-pi/screenshots", getenv("HOME")); ensure_screenshots_folder(screenshots);
// Prevent Overwriting Screenshots
int num = 1; int num = 1;
char *file = NULL; char *file = NULL;
safe_asprintf(&file, "%s/%s.png", screenshots, time); safe_asprintf(&file, "%s/%s.png", screenshots, time);
@ -42,6 +61,7 @@ void media_take_screenshot() {
num++; num++;
} }
// Get Image Size
GLint viewport[4]; GLint viewport[4];
glGetIntegerv(GL_VIEWPORT, viewport); glGetIntegerv(GL_VIEWPORT, viewport);
int x = viewport[0]; int x = viewport[0];
@ -49,12 +69,15 @@ void media_take_screenshot() {
int width = viewport[2]; int width = viewport[2];
int height = viewport[3]; int height = viewport[3];
// Get Line Size
int line_size = width * 3; int line_size = width * 3;
int size = height * line_size; int size = height * line_size;
// Read Pixels
unsigned char pixels[size]; unsigned char pixels[size];
glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); glReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels);
// Handle Little Endian Systems
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
// Swap Red And Blue // Swap Red And Blue
for (int i = 0; i < (size / 3); i++) { for (int i = 0; i < (size / 3); i++) {
@ -66,6 +89,7 @@ void media_take_screenshot() {
} }
#endif #endif
// Save Image
FIBITMAP *image = FreeImage_ConvertFromRawBits(pixels, width, height, line_size, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0); FIBITMAP *image = FreeImage_ConvertFromRawBits(pixels, width, height, line_size, 24, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, 0);
if (!FreeImage_Save(FIF_PNG, image, file, 0)) { if (!FreeImage_Save(FIF_PNG, image, file, 0)) {
INFO("Screenshot Failed: %s", file); INFO("Screenshot Failed: %s", file);
@ -74,6 +98,7 @@ void media_take_screenshot() {
} }
FreeImage_Unload(image); FreeImage_Unload(image);
// Free
free(file); free(file);
free(screenshots); free(screenshots);
} }
@ -82,27 +107,10 @@ void media_take_screenshot() {
__attribute__((constructor)) static void init() { __attribute__((constructor)) static void init() {
// Init FreeImage // Init FreeImage
FreeImage_Initialise(0); FreeImage_Initialise(0);
// Screenshots Folder
char *screenshots_folder = NULL;
safe_asprintf(&screenshots_folder, "%s/.minecraft-pi/screenshots", getenv("HOME"));
{
// Check Screenshots Folder
struct stat obj;
if (stat(screenshots_folder, &obj) != 0 || !S_ISDIR(obj.st_mode)) {
// Create Screenshots Folder
int ret = mkdir(screenshots_folder, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
if (ret != 0) {
// Unable To Create Folder
ERR("Error Creating Directory: %s: %s", screenshots_folder, strerror(errno));
}
}
}
free(screenshots_folder);
} }
#else // #ifndef MCPI_SERVER_MODE #else // #ifndef MCPI_HEADLESS_MODE
void media_take_screenshot() { void media_take_screenshot() {
// NOP // NOP
} }
#endif // #ifndef MCPI_SERVER_MODE #endif // #ifndef MCPI_HEADLESS_MODE

View File

@ -8,7 +8,7 @@ extern "C" {
#define DEFAULT_WIDTH 840 #define DEFAULT_WIDTH 840
#define DEFAULT_HEIGHT 480 #define DEFAULT_HEIGHT 480
void media_take_screenshot(); void media_take_screenshot(char *home);
void media_toggle_fullscreen(); void media_toggle_fullscreen();
void media_swap_buffers(); void media_swap_buffers();
void media_cleanup(); void media_cleanup();

View File

@ -1,9 +1,3 @@
# Component Details:
# Media Layer Proxy
#
# This components proxies multi-media calls from the ARM
# MCPI to the native architecture by using a UNIX socket.
project(media-layer-proxy) project(media-layer-proxy)
# Configuration # Configuration

View File

@ -284,15 +284,22 @@ CALL(6, SDL_ShowCursor, int, (int32_t toggle)) {
#endif #endif
} }
CALL(7, media_take_screenshot, void, ()) { CALL(7, media_take_screenshot, void, (char *home)) {
#if defined(MEDIA_LAYER_PROXY_SERVER) #if defined(MEDIA_LAYER_PROXY_SERVER)
// Lock Proxy // Lock Proxy
start_proxy_call(); start_proxy_call();
// Arguments
write_string(home);
// Release Proxy // Release Proxy
end_proxy_call(); end_proxy_call();
#else #else
char *home = read_string();
// Run // Run
media_take_screenshot(); media_take_screenshot(home);
// Free
free(home);
#endif #endif
} }

View File

@ -21,21 +21,21 @@ if(BUILD_ARM_COMPONENTS)
target_link_libraries(X11 reborn-headers media-layer-headers) target_link_libraries(X11 reborn-headers media-layer-headers)
set_target_properties(X11 PROPERTIES SOVERSION "6") set_target_properties(X11 PROPERTIES SOVERSION "6")
# Install # Install
if(MCPI_SERVER_MODE OR MCPI_USE_MEDIA_LAYER_PROXY) if(MCPI_HEADLESS_MODE OR MCPI_USE_MEDIA_LAYER_PROXY)
install(TARGETS EGL X11 DESTINATION "${MCPI_LIB_DIR}") install(TARGETS EGL X11 DESTINATION "${MCPI_LIB_DIR}")
else() else()
install(TARGETS EGL X11 DESTINATION "${MCPI_FALLBACK_LIB_DIR}") # Place At The End Of LD_LIBRARY_PATH install(TARGETS EGL X11 DESTINATION "${MCPI_FALLBACK_LIB_DIR}") # Place At The End Of LD_LIBRARY_PATH
endif() endif()
# Install GLESv1_CM Stubs In Server Mode # Install GLESv1_CM Stubs In Server Mode
if(MCPI_SERVER_MODE) if(MCPI_HEADLESS_MODE)
install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}") install(TARGETS GLESv1_CM DESTINATION "${MCPI_LIB_DIR}")
endif() endif()
# MCPI Depends On GLESv2, But Uses GLESv1_CM # MCPI Depends On GLESv2, But Uses GLESv1_CM
install_symlink("libGLESv1_CM.so.1" "${MCPI_LIB_DIR}/libGLESv2.so") install_symlink("libGLESv1_CM.so.1" "${MCPI_LIB_DIR}/libGLESv2.so")
# Prevent MCPI From Linking To The Legacy GL Driver When Directly Linking To GL # Prevent MCPI From Linking To The Legacy GL Driver When Directly Linking To GL
if(NOT MCPI_SERVER_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY) if(NOT MCPI_HEADLESS_MODE AND NOT MCPI_USE_MEDIA_LAYER_PROXY)
# Symlinks # Symlinks
install_symlink("/usr/lib/arm-linux-gnueabihf/libEGL.so.1" "${MCPI_LIB_DIR}/libEGL.so") install_symlink("/usr/lib/arm-linux-gnueabihf/libEGL.so.1" "${MCPI_LIB_DIR}/libEGL.so")
install_symlink("/usr/lib/arm-linux-gnueabihf/libGLESv1_CM.so.1" "${MCPI_LIB_DIR}/libGLESv1_CM.so.1") install_symlink("/usr/lib/arm-linux-gnueabihf/libGLESv1_CM.so.1" "${MCPI_LIB_DIR}/libGLESv1_CM.so.1")

View File

@ -2,8 +2,6 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#define IMPOSSIBLE() ERR("(%s:%i) This Should Never Be Called", __FILE__, __LINE__)
// EGL Is Replaced With GLFW // EGL Is Replaced With GLFW
EGLDisplay eglGetDisplay(__attribute__((unused)) NativeDisplayType native_display) { EGLDisplay eglGetDisplay(__attribute__((unused)) NativeDisplayType native_display) {

View File

@ -2,8 +2,6 @@
#include <libreborn/libreborn.h> #include <libreborn/libreborn.h>
#define IMPOSSIBLE() ERR("(%s:%i) This Should Never Be Called", __FILE__, __LINE__)
// Raw X11 Is Replaced With GLFW // Raw X11 Is Replaced With GLFW
int XTranslateCoordinates(__attribute__((unused)) void *display, __attribute__((unused)) XID src_w, __attribute__((unused)) XID dest_w, __attribute__((unused)) int src_x, __attribute__((unused)) int src_y, __attribute__((unused)) int *dest_x_return, __attribute__((unused)) int *dest_y_return, __attribute__((unused)) XID *child_return) { int XTranslateCoordinates(__attribute__((unused)) void *display, __attribute__((unused)) XID src_w, __attribute__((unused)) XID dest_w, __attribute__((unused)) int src_x, __attribute__((unused)) int src_y, __attribute__((unused)) int *dest_x_return, __attribute__((unused)) int *dest_y_return, __attribute__((unused)) XID *child_return) {

View File

@ -8,7 +8,7 @@ add_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)
## Mods ## Mods
add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c) add_library(compat SHARED src/compat/compat.c src/compat/egl.c src/compat/x11.c)
target_link_libraries(compat feature input chat sign media-layer-core dl) target_link_libraries(compat feature input chat sign media-layer-core home dl)
add_library(readdir SHARED src/readdir/readdir.c) add_library(readdir SHARED src/readdir/readdir.c)
@ -27,7 +27,7 @@ else()
endif() endif()
add_library(camera SHARED src/camera/camera.cpp) add_library(camera SHARED src/camera/camera.cpp)
target_link_libraries(camera reborn media-layer-core feature) target_link_libraries(camera reborn media-layer-core feature home)
add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp) add_library(game-mode SHARED src/game-mode/game-mode.c src/game-mode/game-mode.cpp)
target_link_libraries(game-mode reborn feature) target_link_libraries(game-mode reborn feature)

View File

@ -2,12 +2,13 @@
#include <libreborn/media-layer/core.h> #include <libreborn/media-layer/core.h>
#include <libreborn/minecraft.h> #include <libreborn/minecraft.h>
#include "../init/init.h"
#include "../feature/feature.h" #include "../feature/feature.h"
#include "../home/home.h"
#include "../init/init.h"
// Take Screenshot Using TripodCamera // Take Screenshot Using TripodCamera
static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) unsigned char *app_platform, __attribute__((unused)) std::string const& path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) { static void AppPlatform_linux_saveScreenshot_injection(__attribute__((unused)) unsigned char *app_platform, __attribute__((unused)) std::string const& path, __attribute__((unused)) int32_t width, __attribute__((unused)) int32_t height) {
media_take_screenshot(); media_take_screenshot(home_get());
} }
// Enable TripodCameraRenderer // Enable TripodCameraRenderer

View File

@ -9,6 +9,7 @@
#include "../input/input.h" #include "../input/input.h"
#include "../sign/sign.h" #include "../sign/sign.h"
#include "../chat/chat.h" #include "../chat/chat.h"
#include "../home/home.h"
#include "../init/init.h" #include "../init/init.h"
#include "compat.h" #include "compat.h"
@ -53,7 +54,7 @@ HOOK(SDL_PollEvent, int, (SDL_Event *event)) {
media_toggle_fullscreen(); media_toggle_fullscreen();
handled = 1; handled = 1;
} else if (event->key.keysym.sym == SDLK_F2) { } else if (event->key.keysym.sym == SDLK_F2) {
media_take_screenshot(); media_take_screenshot(home_get());
handled = 1; handled = 1;
} else if (event->key.keysym.sym == SDLK_F1) { } else if (event->key.keysym.sym == SDLK_F1) {
input_hide_gui(); input_hide_gui();

View File

@ -13,15 +13,24 @@
#define NEW_PATH "" #define NEW_PATH ""
// Store Launch Directory // Store Launch Directory
static char *get_launch_directory() {
static char *launch_directory = NULL; static char *launch_directory = NULL;
__attribute__((constructor)) static void init_launch_directory() { if (launch_directory == NULL) {
launch_directory = getcwd(NULL, 0); launch_directory = getcwd(NULL, 0);
} }
return launch_directory;
}
__attribute__((constructor)) static void init_launch_directory() {
get_launch_directory();
}
__attribute__((destructor)) static void free_launch_directory() {
free(get_launch_directory());
}
// Pretend $HOME Is Launch Directory // Pretend $HOME Is Launch Directory
HOOK(getenv, char *, (const char *name)) { HOOK(getenv, char *, (const char *name)) {
if (strcmp(name, "HOME") == 0) { if (strcmp(name, "HOME") == 0) {
return launch_directory; return get_launch_directory();
} else { } else {
ensure_getenv(); ensure_getenv();
return (*real_getenv)(name); return (*real_getenv)(name);
@ -34,7 +43,7 @@ char *home_get() {
static char *dir = NULL; static char *dir = NULL;
// Load // Load
if (dir == NULL) { if (dir == NULL) {
safe_asprintf(&dir, "%s/" NEW_PATH, getenv("HOME")); safe_asprintf(&dir, "%s" NEW_PATH, getenv("HOME"));
} }
// Return // Return
return dir; return dir;