#include <cerrno>
#include <cstddef>
#include <cstdio>
#include <cstring>
#include <dlfcn.h>
#include <memory>
#include <string>
#include <vector>
#include <wayland-client.h>
#include "outputs.h"
#include "unity.h"
static std::vector<const char*> quality_levels = {"Low", "High"};
static int latest_display = 0;
static void *handle = nullptr;
PFN_SetupUnityCallbacks SetupUnityCallbacks = nullptr;
PFN_LoadScreenSelectorWindow LoadScreenSelectorWindow = nullptr;
int GetAxisDescription(int axis, char *control, char *primary, char *secondary)
{
printf("GetAxisDescription(%d)\n", axis);
switch (axis) {
case 0:
strncpy(control, "Horizontal (+)", 8192);
strncpy(primary, "right", 8192);
strncpy(secondary, "d", 8192);
break;
case 1:
strncpy(control, "Horizontal (-)", 8192);
strncpy(primary, "left", 8192);
strncpy(secondary, "a", 8192);
break;
case 2:
strncpy(control, "Vertical (+)", 8192);
strncpy(primary, "up", 8192);
strncpy(secondary, "w", 8192);
break;
case 3:
strncpy(control, "Vertical (-)", 8192);
strncpy(primary, "down", 8192);
strncpy(secondary, "s", 8192);
break;
default:
control[0] = '\0';
primary[0] = '\0';
secondary[0] = '\0';
return 1;
}
return 0;
}
char ConfigureAxis(int axis, int enabled)
{
printf("ConfigureAxis(%d, %d) -> %d\n", axis, enabled, 1);
return 1;
}
std::vector<struct resolution>* GetResolutions(int display)
{
printf("GetResolutions(display=%d)\n", display);
latest_display = display;
return &outputs[display]->resolutions;
}
void GetSelectedResolution(int *width, int *height, bool *windowed)
{
const struct output_info *info = outputs[latest_display].get();
*width = info->resolutions[info->default_resolution].width;
*height = info->resolutions[info->default_resolution].height;
*windowed = false;
printf("GetSelectedResolution() -> (%d×%d, windowed=%d)\n", *width, *height, *windowed);
}
void SetSelectedResolution(int width, int height, bool windowed)
{
printf("SetSelectedResolution(width=%d, height=%d, windowed=%d)\n", width, height, windowed);
}
std::vector<const char *>* GetQualityLevels()
{
printf("GetQualityLevels()\n");
return &quality_levels;
}
int GetSelectedQualityLevel()
{
printf("GetSelectedQualityLevel() -> %d\n", 1);
return 1;
}
void SetSelectedQualityLevel(int quality)
{
printf("SetSelectedQualityLevel(quality=%d)\n", quality);
}
std::vector<const char *>* GetDisplays()
{
static std::vector<const char*> displays;
displays.clear();
for (const auto& output : outputs)
displays.push_back(output->model.c_str());
printf("GetDisplays()\n");
return &displays;
}
int GetSelectedDisplay()
{
int ret = 0;
printf("GetSelectedDisplay() -> %d\n", ret);
return ret;
}
void SetSelectedDisplay(int display)
{
printf("SetSelectedDisplay(display=%d)\n", display);
}
int load_screen_selector()
{
handle = dlopen("./ScreenSelector.so", RTLD_NOW);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
return -1;
}
SetupUnityCallbacks = reinterpret_cast<PFN_SetupUnityCallbacks>(dlsym(handle, "SetupUnityCallbacks"));
if (!SetupUnityCallbacks) {
fprintf(stderr, "%s\n", dlerror());
return -1;
}
LoadScreenSelectorWindow = reinterpret_cast<PFN_LoadScreenSelectorWindow>(dlsym(handle, "LoadScreenSelectorWindow"));
if (!LoadScreenSelectorWindow) {
fprintf(stderr, "%s\n", dlerror());
return -1;
}
return 0;
}
int unload_screen_selector()
{
int ret = dlclose(handle);
if (ret) {
fprintf(stderr, "Failed to close ScreenSelector.so: %s\n", dlerror());
return -1;
}
return 0;
}