mcpe-1.1-linux/src/linux_app_platform.cpp
2026-01-19 20:18:08 +02:00

203 lines
8.8 KiB
C++

#include "linux_app_platform.h"
#include <cstring>
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <png.h>
#include <uuid/uuid.h>
#include <sys/types.h>
#include <sys/sysinfo.h>
#include "../mcpe/ImagePickingCallback.h"
#include "../mcpe/FilePickerSettings.h"
#include "../hybris/src/jb/linker.h"
extern "C" {
#ifndef SERVER
#include <eglut.h>
#endif
#include "../hybris/include/hybris/dlfcn.h"
}
void** LinuxAppPlatform::myVtable = nullptr;
bool LinuxAppPlatform::mousePointerHidden = false;
bool enablePocketGuis = false;
LinuxAppPlatform::LinuxAppPlatform() : AppPlatform() {
this->vtable = myVtable;
internalStorage = getRootPath() + "data/private/";
externalStorage = getRootPath() + "data/public/";
currentStorage = getRootPath() + "data/current/";
userdata = getRootPath() + "data/user/";
userdataPathForLevels = getRootPath() + "data/user/";
region = "0xdeadbeef";
tmpPath = getRootPath() + "tmp/";
}
#include <execinfo.h>
#include <cxxabi.h>
#include <dlfcn.h>
void LinuxAppPlatform::replaceVtableEntry(void* lib, void** vtable, const char* sym, void* nw) {
void* sm = hybris_dlsym(lib, sym);
for (int i = 0; ; i++) {
if (vtable[i] == nullptr)
break;
if (vtable[i] == sm) {
myVtable[i] = nw;
return;
}
}
}
void LinuxAppPlatform::initVtable(void* lib) {
void** vt = AppPlatform::myVtable;
void** vta = &((void**) hybris_dlsym(lib, "_ZTV19AppPlatform_android"))[2];
// get vtable size
int size;
for (size = 2; ; size++) {
if (vt[size] == nullptr)
break;
}
printf("AppPlatform size = %i\n", size);
myVtable = (void**) ::operator new(size * sizeof(void*));
memcpy(&myVtable[0], &vt[2], (size - 2) * sizeof(void*));
replaceVtableEntry(lib, vta, "_ZNK19AppPlatform_android10getDataUrlEv", (void*) &LinuxAppPlatform::getDataUrl);
replaceVtableEntry(lib, vta, "_ZNK19AppPlatform_android14getUserDataUrlEv", (void*) &LinuxAppPlatform::getUserDataUrl);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android14getPackagePathEv", (void*) &LinuxAppPlatform::getPackagePath);
replaceVtableEntry(lib, vta, "_ZN11AppPlatform16hideMousePointerEv", (void*) &LinuxAppPlatform::hideMousePointer);
replaceVtableEntry(lib, vta, "_ZN11AppPlatform16showMousePointerEv", (void*) &LinuxAppPlatform::showMousePointer);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android11swapBuffersEv", (void*) &LinuxAppPlatform::swapBuffers);
replaceVtableEntry(lib, vta, "_ZNK19AppPlatform_android15getSystemRegionEv", (void*) &LinuxAppPlatform::getSystemRegion);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android25getGraphicsTearingSupportEv", (void*) &LinuxAppPlatform::getGraphicsTearingSupport);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android9pickImageER20ImagePickingCallback", (void*) &LinuxAppPlatform::pickImage);
replaceVtableEntry(lib, vta, "_ZN11AppPlatform8pickFileER18FilePickerSettings", (void*) &LinuxAppPlatform::pickFile);
replaceVtableEntry(lib, vta, "_ZNK11AppPlatform19supportsFilePickingEv", (void*) &LinuxAppPlatform::supportsFilePicking);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android22getExternalStoragePathEv", (void*) &LinuxAppPlatform::getExternalStoragePath);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android22getInternalStoragePathEv", (void*) &LinuxAppPlatform::getInternalStoragePath);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android21getCurrentStoragePathEv", (void*) &LinuxAppPlatform::getCurrentStoragePath);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android15getUserdataPathEv", (void*) &LinuxAppPlatform::getUserdataPath);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android24getUserdataPathForLevelsEv", (void*) &LinuxAppPlatform::getUserdataPathForLevels);
replaceVtableEntry(lib, vta, "_ZN11AppPlatform20getAssetFileFullPathERKSs", (void*) &LinuxAppPlatform::getAssetFileFullPath);
replaceVtableEntry(lib, vta, "_ZNK11AppPlatform14useCenteredGUIEv", (void*) &LinuxAppPlatform::useCenteredGUI);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android16getApplicationIdEv", (void*) &LinuxAppPlatform::getApplicationId);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android18getAvailableMemoryEv", (void*) &LinuxAppPlatform::getAvailableMemory);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android11getDeviceIdEv", (void*) &LinuxAppPlatform::getDeviceId);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android10createUUIDEv", (void*) &LinuxAppPlatform::createUUID);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android18isFirstSnoopLaunchEv", (void*) &LinuxAppPlatform::isFirstSnoopLaunch);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android29hasHardwareInformationChangedEv", (void*) &LinuxAppPlatform::hasHardwareInformationChanged);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android8isTabletEv", (void*) &LinuxAppPlatform::isTablet);
replaceVtableEntry(lib, vta, "_ZN11AppPlatform17setFullscreenModeE14FullscreenMode", (void*) &LinuxAppPlatform::setFullscreenMode);
replaceVtableEntry(lib, vta, "_ZNK11AppPlatform10getEditionEv", (void*) &LinuxAppPlatform::getEdition);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android31calculateAvailableDiskFreeSpaceERKSs", (void*) &LinuxAppPlatform::calculateAvailableDiskFreeSpace);
replaceVtableEntry(lib, vta, "_ZNK19AppPlatform_android25getPlatformUIScalingRulesEv", (void*) &LinuxAppPlatform::getPlatformUIScalingRules);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android19getPlatformTempPathEv", (void*) &LinuxAppPlatform::getPlatformTempPath);
replaceVtableEntry(lib, vta, "_ZN19AppPlatform_android14createDeviceIDEv", (void*) &LinuxAppPlatform::createDeviceID);
}
void LinuxAppPlatform::hideMousePointer() {
mousePointerHidden = true;
#ifndef SERVER
moveMouseToCenter = true;
eglutSetMousePointerVisiblity(EGLUT_POINTER_INVISIBLE);
#endif
}
void LinuxAppPlatform::showMousePointer() {
mousePointerHidden = false;
#ifndef SERVER
eglutSetMousePointerVisiblity(EGLUT_POINTER_VISIBLE);
#endif
}
std::string LinuxAppPlatform::_pickFile(std::string commandLine) {
std::cout << "Launching file picker with args: " << commandLine << "\n";
char file[1024];
FILE *f = popen(commandLine.c_str(), "r");
if (fgets(file, 1024, f) == nullptr) {
std::cout << "No file selected\n";
return "";
}
file[strlen(file) - 1] = '\0';
std::cout << "Selected file: " << file << "\n";
return std::string(file);
}
void LinuxAppPlatform::pickImage(ImagePickingCallback &callback) {
std::cout << "pickImage\n";
std::string file = _pickFile("zenity --file-selection --title 'Select image' --file-filter *.png");
if (file.empty()) {
callback.onImagePickingCanceled();
} else {
callback.onImagePickingSuccess(file);
}
}
std::string replaceAll(std::string s, std::string a, std::string b) {
while (true) {
size_t p = s.find(a);
if (p == std::string::npos)
break;
s.replace(p, a.length(), b);
}
return s;
}
void LinuxAppPlatform::pickFile(FilePickerSettings &settings) {
std::cout << "pickFile\n";
std::cout << "- title: " << settings.pickerTitle << "\n";
std::cout << "- type: " << (int) settings.type << "\n";
std::cout << "- file descriptions:\n";
for (FilePickerSettings::FileDescription &d : settings.fileDescriptions) {
std::cout << " - " << d.ext << " " << d.desc << "\n";
}
std::stringstream ss;
//ss << "zenity --file-selection --title '" << replaceAll(settings.pickerTitle, "'", "\\'") << "'";
if (settings.type == FilePickerSettings::PickerType::SAVE)
ss << " --save";
if (settings.fileDescriptions.size() > 0) {
ss << " --file-filter '";
bool first = true;
for (FilePickerSettings::FileDescription &d : settings.fileDescriptions) {
if (first)
first = false;
else
ss << "|";
ss << "*." << d.ext;
}
ss << "'";
}
std::string file = _pickFile(ss.str());
settings.pickedCallback(settings, file);
}
void LinuxAppPlatform::setFullscreenMode(int mode) {
std::cout << "set fullscreen mode: " << mode << "\n";
#ifndef SERVER
int newMode = mode == 1 ? EGLUT_FULLSCREEN : EGLUT_WINDOWED;
if (eglutGet(EGLUT_FULLSCREEN_MODE) != newMode)
eglutToggleFullscreen();
#endif
}
std::string LinuxAppPlatform::createUUID() {
srand(time(NULL));
uuid_t id;
uuid_generate(id);
char out [256];
uuid_unparse(id, out);
printf("uuid: %s\n", out);
return std::string(out);
}
long long LinuxAppPlatform::getAvailableMemory() {
struct sysinfo memInfo;
sysinfo (&memInfo);
long long totalVirtualMem = memInfo.totalram;
totalVirtualMem += memInfo.totalswap;
totalVirtualMem *= memInfo.mem_unit;
return totalVirtualMem;
}