mirror of
https://github.com/libretro/RetroArch
synced 2025-02-21 00:40:09 +00:00
Bump switchres to 2.2.1 (#16782)
* Remove switchres before bump * Squashed 'deps/switchres/' content from commit 725e4d484a git-subtree-dir: deps/switchres git-subtree-split: 725e4d484a33632618dd44cdc2a61948dd833282
This commit is contained in:
parent
bd69602686
commit
f1a37f7c75
39
deps/switchres/.github/workflows/build.yml
vendored
39
deps/switchres/.github/workflows/build.yml
vendored
@ -9,16 +9,16 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform:
|
platform:
|
||||||
- { name: Linux GCC }
|
- { name: linux_gcc }
|
||||||
- { name: Windows MINGW, make_opts: PLATFORM=NT CROSS_COMPILE=x86_64-w64-mingw32- }
|
- { name: windows_mingw, make_opts: PLATFORM=NT CROSS_COMPILE=x86_64-w64-mingw32- }
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Install Linux dependencies
|
- name: Install Linux dependencies
|
||||||
if: matrix.platform.name == 'Linux GCC'
|
if: matrix.platform.name == 'linux_gcc'
|
||||||
run: sudo apt-get install libxrandr-dev libdrm-dev libsdl2-dev
|
run: sudo apt-get install libxrandr-dev libdrm-dev libsdl2-dev
|
||||||
- name: Install Windows dependencies
|
- name: Install Windows dependencies
|
||||||
if: matrix.platform.name == 'Windows MINGW'
|
if: matrix.platform.name == 'windows_mingw'
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install mingw-w64 wget tar
|
sudo apt-get install mingw-w64 wget tar
|
||||||
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
|
sudo update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
|
||||||
@ -33,7 +33,7 @@ jobs:
|
|||||||
make libswitchres ${{matrix.platform.make_opts}}
|
make libswitchres ${{matrix.platform.make_opts}}
|
||||||
make ${{matrix.platform.make_opts}}
|
make ${{matrix.platform.make_opts}}
|
||||||
- name: Build grid.exe (Windows only)
|
- name: Build grid.exe (Windows only)
|
||||||
if: matrix.platform.name == 'Windows MINGW'
|
if: matrix.platform.name == 'windows_mingw'
|
||||||
run: |
|
run: |
|
||||||
make ${{matrix.platform.make_opts}} clean
|
make ${{matrix.platform.make_opts}} clean
|
||||||
make ${{matrix.platform.make_opts}} grid
|
make ${{matrix.platform.make_opts}} grid
|
||||||
@ -62,3 +62,32 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: geometry-win32-x86_64
|
name: geometry-win32-x86_64
|
||||||
path: dist/
|
path: dist/
|
||||||
|
|
||||||
|
release:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: [buildx86_64, win32-build-x86_64-geometry]
|
||||||
|
if: startsWith(github.ref, 'refs/tags/v')
|
||||||
|
steps:
|
||||||
|
- name: Get version
|
||||||
|
id: get_version
|
||||||
|
run: echo ::set-output name=VERSION::${GITHUB_REF#refs/tags/}
|
||||||
|
- name: Download artifacts
|
||||||
|
uses: actions/download-artifact@v2.0.5
|
||||||
|
- name: Make packages
|
||||||
|
run: |
|
||||||
|
tag="${GITHUB_REF#refs/tags/}"
|
||||||
|
mv ./geometry-win32-x86_64/geometry.exe ./switchres-windows_mingw-x86_64
|
||||||
|
7z a "switchres-${tag}-windows_mingw-x86_64.7z" ./switchres-windows_mingw-x86_64
|
||||||
|
tar cvjf switchres-${tag}-linux_gcc-x86_64.tar.bz2 ./switchres-linux_gcc-x86_64
|
||||||
|
- name: Create release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
name: Switchres ${{ steps.get_version.outputs.VERSION }}
|
||||||
|
draft: true
|
||||||
|
prerelease: false
|
||||||
|
files: |
|
||||||
|
./*.bz2
|
||||||
|
./*.7z
|
||||||
|
15
deps/switchres/README.md
vendored
15
deps/switchres/README.md
vendored
@ -1,4 +1,4 @@
|
|||||||
# What is Switchres 2.0
|
# What is Switchres
|
||||||
Switchres is a modeline generation engine for emulation.
|
Switchres is a modeline generation engine for emulation.
|
||||||
|
|
||||||
Its purpose is on-the-fly creation of fully customized video modes that accurately reproduce those of the emulated systems. Based on a monitor profile, it will provide the best video mode for a given width, height, and refresh rate.
|
Its purpose is on-the-fly creation of fully customized video modes that accurately reproduce those of the emulated systems. Based on a monitor profile, it will provide the best video mode for a given width, height, and refresh rate.
|
||||||
@ -7,7 +7,7 @@ Switchres features the most versatile modeline generation ever, ranging from 15-
|
|||||||
|
|
||||||
Switchres can be integrated into open-source emulators either as a library, or used as a standalone emulator launcher. It's written in C++ and a C wrapper is also available.
|
Switchres can be integrated into open-source emulators either as a library, or used as a standalone emulator launcher. It's written in C++ and a C wrapper is also available.
|
||||||
|
|
||||||
Switchres 2.0 is a rewrite of the original Switchres code used in GroovyMAME. It currently supports mode switching on the following platforms, with their respective backends:
|
Switchres is a rewrite of the original Switchres code used in GroovyMAME. It currently supports mode switching on the following platforms, with their respective backends:
|
||||||
- **Windows**:
|
- **Windows**:
|
||||||
- AMD ADL (AMD Radeon HD 5000+)
|
- AMD ADL (AMD Radeon HD 5000+)
|
||||||
- ATI legacy (ATI Radeon pre-HD 5000)
|
- ATI legacy (ATI Radeon pre-HD 5000)
|
||||||
@ -37,12 +37,17 @@ Options:
|
|||||||
-l, --launch <command> Launch <command>
|
-l, --launch <command> Launch <command>
|
||||||
-m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)
|
-m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)
|
||||||
-a --aspect <num:den> Monitor aspect ratio
|
-a --aspect <num:den> Monitor aspect ratio
|
||||||
-r --rotated Original mode's native orientation is rotated
|
-r --rotated Rotate axes, preserving aspect ratio
|
||||||
-d, --display <OS_display_name> Use target display (Windows: \\\\.\\DISPLAY1, ... Linux: VGA-0, ...)
|
-d, --display <display_index> Use target display (index = 0, 1, 2...)
|
||||||
-f, --force <w>x<h>@<r> Force a specific video mode from display mode list
|
-f, --force <w>x<h>@<r> Force a specific video mode from display mode list
|
||||||
-i, --ini <file.ini> Specify an ini file
|
-i, --ini <file.ini> Specify an ini file
|
||||||
-b, --backend <api_name> Specify the api name
|
|
||||||
-k, --keep Keep changes on exit (warning: this disables cleanup)
|
-k, --keep Keep changes on exit (warning: this disables cleanup)
|
||||||
|
-g, --geometry <adjustment> Adjust geometry of generated modeline
|
||||||
|
adjustment = <h_size>:<h_shift>:<v_shift>
|
||||||
|
e.g. switchres 640 480 60 -c -g 1.1:-1:2
|
||||||
|
|
||||||
|
For more options, refer to switchres.ini. All options in switchres.ini can be applied in
|
||||||
|
command line as long options, e.g.: switchres 256 224 57.55 -c --dotclock_min 8.0
|
||||||
```
|
```
|
||||||
|
|
||||||
A default `switchres.ini` file will be searched in the current working directory, then in `.\ini` on Windows, `./ini` then `/etc` on Linux. The repo has a switchres.ini example.
|
A default `switchres.ini` file will be searched in the current working directory, then in `.\ini` on Windows, `./ini` then `/etc` on Linux. The repo has a switchres.ini example.
|
||||||
|
86
deps/switchres/custom_video_drmkms.cpp
vendored
86
deps/switchres/custom_video_drmkms.cpp
vendored
@ -47,11 +47,22 @@
|
|||||||
#define drmModeFreePlaneResources p_drmModeFreePlaneResources
|
#define drmModeFreePlaneResources p_drmModeFreePlaneResources
|
||||||
#define drmIoctl p_drmIoctl
|
#define drmIoctl p_drmIoctl
|
||||||
#define drmGetCap p_drmGetCap
|
#define drmGetCap p_drmGetCap
|
||||||
|
#define drmGetDevices2 p_drmGetDevices2
|
||||||
#define drmIsMaster p_drmIsMaster
|
#define drmIsMaster p_drmIsMaster
|
||||||
#define drmSetMaster p_drmSetMaster
|
#define drmSetMaster p_drmSetMaster
|
||||||
#define drmDropMaster p_drmDropMaster
|
#define drmDropMaster p_drmDropMaster
|
||||||
|
|
||||||
# define MAX_CARD_ID 10
|
# define MAX_CARD_ID 10
|
||||||
|
# define MAX_DRM_DEVICES 16
|
||||||
|
|
||||||
|
// To enable libdrmhook: make SR_WITH_DRMHOOK=1
|
||||||
|
#ifdef SR_WITH_DRMHOOK
|
||||||
|
#define hook_handle RTLD_DEFAULT
|
||||||
|
#define hook_log " (will attempt hook)"
|
||||||
|
#else
|
||||||
|
#define hook_handle mp_drm_handle
|
||||||
|
#define hook_log ""
|
||||||
|
#endif
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// shared the privileges of the master fd
|
// shared the privileges of the master fd
|
||||||
@ -212,6 +223,13 @@ bool drmkms_timing::test_kernel_user_modes()
|
|||||||
// Count the number of existing modes, so it should be +1 when attaching
|
// Count the number of existing modes, so it should be +1 when attaching
|
||||||
// a new mode. Could also check the mode name, still better
|
// a new mode. Could also check the mode name, still better
|
||||||
conn = drmModeGetConnector(fd, m_desktop_output);
|
conn = drmModeGetConnector(fd, m_desktop_output);
|
||||||
|
if (!conn)
|
||||||
|
{
|
||||||
|
log_verbose("DRM/KMS: <%d> (%s) Cannot get connector\n", m_id, __FUNCTION__);
|
||||||
|
m_kernel_user_modes = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
first_modes_count = conn->count_modes;
|
first_modes_count = conn->count_modes;
|
||||||
ret = drmModeAttachMode(fd, m_desktop_output, &mode);
|
ret = drmModeAttachMode(fd, m_desktop_output, &mode);
|
||||||
drmModeFreeConnector(conn);
|
drmModeFreeConnector(conn);
|
||||||
@ -329,7 +347,7 @@ drmkms_timing::~drmkms_timing()
|
|||||||
|
|
||||||
bool drmkms_timing::init()
|
bool drmkms_timing::init()
|
||||||
{
|
{
|
||||||
log_verbose("DRM/KMS: <%d> (init) loading DRM/KMS library\n", m_id);
|
log_verbose("DRM/KMS: <%d> (init) loading DRM/KMS library%s\n", m_id, hook_log);
|
||||||
mp_drm_handle = dlopen("libdrm.so", RTLD_NOW);
|
mp_drm_handle = dlopen("libdrm.so", RTLD_NOW);
|
||||||
if (mp_drm_handle)
|
if (mp_drm_handle)
|
||||||
{
|
{
|
||||||
@ -354,21 +372,21 @@ bool drmkms_timing::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_drmModeGetConnector = (__typeof__(drmModeGetConnector)) dlsym(RTLD_DEFAULT, "drmModeGetConnector");
|
p_drmModeGetConnector = (__typeof__(drmModeGetConnector)) dlsym(hook_handle, "drmModeGetConnector");
|
||||||
if (p_drmModeGetConnector == NULL)
|
if (p_drmModeGetConnector == NULL)
|
||||||
{
|
{
|
||||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnector", "DRM_LIBRARY");
|
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnector", "DRM_LIBRARY");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_drmModeGetConnectorCurrent = (__typeof__(drmModeGetConnectorCurrent)) dlsym(RTLD_DEFAULT, "drmModeGetConnectorCurrent");
|
p_drmModeGetConnectorCurrent = (__typeof__(drmModeGetConnectorCurrent)) dlsym(hook_handle, "drmModeGetConnectorCurrent");
|
||||||
if (p_drmModeGetConnectorCurrent == NULL)
|
if (p_drmModeGetConnectorCurrent == NULL)
|
||||||
{
|
{
|
||||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnectorCurrent", "DRM_LIBRARY");
|
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeGetConnectorCurrent", "DRM_LIBRARY");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
p_drmModeFreeConnector = (__typeof__(drmModeFreeConnector)) dlsym(RTLD_DEFAULT, "drmModeFreeConnector");
|
p_drmModeFreeConnector = (__typeof__(drmModeFreeConnector)) dlsym(hook_handle, "drmModeFreeConnector");
|
||||||
if (p_drmModeFreeConnector == NULL)
|
if (p_drmModeFreeConnector == NULL)
|
||||||
{
|
{
|
||||||
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeFreeConnector", "DRM_LIBRARY");
|
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmModeFreeConnector", "DRM_LIBRARY");
|
||||||
@ -494,6 +512,13 @@ bool drmkms_timing::init()
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p_drmGetDevices2 = (__typeof__(drmGetDevices2)) dlsym(mp_drm_handle, "drmGetDevices2");
|
||||||
|
if (p_drmGetDevices2 == NULL)
|
||||||
|
{
|
||||||
|
log_error("DRM/KMS: <%d> (init) [ERROR] missing func %s in %s", m_id, "drmGetDevices2", "DRM_LIBRARY");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
p_drmIsMaster = (__typeof__(drmIsMaster)) dlsym(mp_drm_handle, "drmIsMaster");
|
p_drmIsMaster = (__typeof__(drmIsMaster)) dlsym(mp_drm_handle, "drmIsMaster");
|
||||||
if (p_drmIsMaster == NULL)
|
if (p_drmIsMaster == NULL)
|
||||||
{
|
{
|
||||||
@ -529,14 +554,31 @@ bool drmkms_timing::init()
|
|||||||
else if (strlen(m_device_name) == 1 && m_device_name[0] >= '0' && m_device_name[0] <= '9')
|
else if (strlen(m_device_name) == 1 && m_device_name[0] >= '0' && m_device_name[0] <= '9')
|
||||||
screen_pos = m_device_name[0] - '0';
|
screen_pos = m_device_name[0] - '0';
|
||||||
|
|
||||||
char drm_name[15] = "/dev/dri/card_";
|
// Get an array of drm devices to check
|
||||||
|
drmDevicePtr devices[MAX_DRM_DEVICES];
|
||||||
|
int num_devices = drmGetDevices2(0, NULL, 0);
|
||||||
|
|
||||||
|
if (num_devices > MAX_DRM_DEVICES)
|
||||||
|
num_devices = MAX_DRM_DEVICES;
|
||||||
|
|
||||||
|
int ret = drmGetDevices2(0, devices, num_devices);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
log_error("DRM/KMS: drmGetDevices2() returned an error %d\n", ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *drm_name;
|
||||||
drmModeRes *p_res;
|
drmModeRes *p_res;
|
||||||
drmModeConnector *p_connector;
|
drmModeConnector *p_connector;
|
||||||
|
|
||||||
int output_position = 0;
|
int output_position = 0;
|
||||||
for (int num = 0; !m_desktop_output && num < MAX_CARD_ID; num++)
|
for (int num = 0; num < num_devices; num++)
|
||||||
{
|
{
|
||||||
drm_name[13] = '0' + num;
|
// Skip non-primary nodes
|
||||||
|
if (devices[num]->available_nodes & (1 << DRM_NODE_PRIMARY))
|
||||||
|
drm_name = devices[num]->nodes[DRM_NODE_PRIMARY];
|
||||||
|
else continue;
|
||||||
|
|
||||||
if (!access(drm_name, F_OK) == 0)
|
if (!access(drm_name, F_OK) == 0)
|
||||||
{
|
{
|
||||||
@ -554,7 +596,10 @@ bool drmkms_timing::init()
|
|||||||
log_error("DRM/KMS: <%d> (init) [ERROR] ioctl DRM_CAP_DUMB_BUFFER\n", m_id);
|
log_error("DRM/KMS: <%d> (init) [ERROR] ioctl DRM_CAP_DUMB_BUFFER\n", m_id);
|
||||||
|
|
||||||
if (!check_dumb)
|
if (!check_dumb)
|
||||||
|
{
|
||||||
log_error("DRM/KMS: <%d> (init) [ERROR] dumb buffer not supported\n", m_id);
|
log_error("DRM/KMS: <%d> (init) [ERROR] dumb buffer not supported\n", m_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
p_res = drmModeGetResources(m_drm_fd);
|
p_res = drmModeGetResources(m_drm_fd);
|
||||||
|
|
||||||
@ -582,6 +627,7 @@ bool drmkms_timing::init()
|
|||||||
}
|
}
|
||||||
m_desktop_output = p_connector->connector_id;
|
m_desktop_output = p_connector->connector_id;
|
||||||
m_card_id = num;
|
m_card_id = num;
|
||||||
|
strcpy(m_drm_name, drm_name);
|
||||||
log_verbose("DRM/KMS: <%d> (init) card %d connector %d id %d name %s selected as primary output\n", m_id, num, i, m_desktop_output, connector_name);
|
log_verbose("DRM/KMS: <%d> (init) card %d connector %d id %d name %s selected as primary output\n", m_id, num, i, m_desktop_output, connector_name);
|
||||||
|
|
||||||
drmModeEncoder *p_encoder = drmModeGetEncoder(m_drm_fd, p_connector->encoder_id);
|
drmModeEncoder *p_encoder = drmModeGetEncoder(m_drm_fd, p_connector->encoder_id);
|
||||||
@ -601,7 +647,10 @@ bool drmkms_timing::init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mp_crtc_desktop)
|
if (!mp_crtc_desktop)
|
||||||
|
{
|
||||||
|
m_desktop_output = 0;
|
||||||
log_error("DRM/KMS: <%d> (init) [ERROR] no crtc found\n", m_id);
|
log_error("DRM/KMS: <%d> (init) [ERROR] no crtc found\n", m_id);
|
||||||
|
}
|
||||||
drmModeFreeEncoder(p_encoder);
|
drmModeFreeEncoder(p_encoder);
|
||||||
}
|
}
|
||||||
output_position++;
|
output_position++;
|
||||||
@ -649,9 +698,14 @@ bool drmkms_timing::init()
|
|||||||
s_shared_count[m_card_id] = 2;
|
s_shared_count[m_card_id] = 2;
|
||||||
}
|
}
|
||||||
if (!drmIsMaster(m_drm_fd))
|
if (!drmIsMaster(m_drm_fd))
|
||||||
|
{
|
||||||
|
m_desktop_output = 0;
|
||||||
log_error("DRM/KMS: <%d> (%s) [ERROR] limited DRM rights on this screen\n", m_id, __FUNCTION__);
|
log_error("DRM/KMS: <%d> (%s) [ERROR] limited DRM rights on this screen\n", m_id, __FUNCTION__);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// If we're here and we have a valid output, we're done.
|
||||||
|
if (m_desktop_output) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -697,9 +751,8 @@ bool drmkms_timing::init()
|
|||||||
|
|
||||||
int drmkms_timing::get_master_fd()
|
int drmkms_timing::get_master_fd()
|
||||||
{
|
{
|
||||||
const size_t path_length = 15;
|
const size_t path_length = 20;
|
||||||
char dev_path[path_length];
|
char procpath[path_length];
|
||||||
char procpath[50];
|
|
||||||
char fullpath[512];
|
char fullpath[512];
|
||||||
char* actualpath;
|
char* actualpath;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
@ -721,10 +774,9 @@ int drmkms_timing::get_master_fd()
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
snprintf(dev_path, path_length, "/dev/dri/card%d", m_card_id);
|
if (!access(m_drm_name, F_OK) == 0)
|
||||||
if (!access(dev_path, F_OK) == 0)
|
|
||||||
{
|
{
|
||||||
log_error("DRM/KMS: <%d> (%s) [ERROR] Device %s doesn't exist\n", m_id, __FUNCTION__, dev_path);
|
log_error("DRM/KMS: <%d> (%s) [ERROR] Device %s doesn't exist\n", m_id, __FUNCTION__, m_drm_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -749,7 +801,7 @@ int drmkms_timing::get_master_fd()
|
|||||||
continue;
|
continue;
|
||||||
actualpath = realpath(fullpath, NULL);
|
actualpath = realpath(fullpath, NULL);
|
||||||
// Only check the device we expect
|
// Only check the device we expect
|
||||||
if (strncmp(dev_path, actualpath, path_length) != 0)
|
if (strncmp(m_drm_name, actualpath, path_length) != 0)
|
||||||
{
|
{
|
||||||
free(actualpath);
|
free(actualpath);
|
||||||
continue;
|
continue;
|
||||||
@ -770,16 +822,16 @@ int drmkms_timing::get_master_fd()
|
|||||||
|
|
||||||
// CASE 3: m_drm_fd is not a master (and probably not even a valid FD), the currend pid doesn't have master rights
|
// CASE 3: m_drm_fd is not a master (and probably not even a valid FD), the currend pid doesn't have master rights
|
||||||
// Or master is owned by a 3rd party app (like a frontend ...)
|
// Or master is owned by a 3rd party app (like a frontend ...)
|
||||||
log_verbose("DRM/KMS: <%d> (%s) Couldn't find a master FD, opening default /dev/dri/card%d\n", m_id, __FUNCTION__, m_card_id);
|
log_verbose("DRM/KMS: <%d> (%s) Couldn't find a master FD, opening default %s\n", m_id, __FUNCTION__, m_drm_name);
|
||||||
|
|
||||||
// mark our former hook as invalid
|
// mark our former hook as invalid
|
||||||
m_hook_fd = -1;
|
m_hook_fd = -1;
|
||||||
|
|
||||||
fd = open(dev_path, O_RDWR | O_CLOEXEC);
|
fd = open(m_drm_name, O_RDWR | O_CLOEXEC);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
// Oh, we're totally screwed here, worst possible scenario
|
// Oh, we're totally screwed here, worst possible scenario
|
||||||
log_error("DRM/KMS: <%d> (%s) Can't open /dev/dri/card%d, can't get master rights\n", m_id, __FUNCTION__, m_card_id);
|
log_error("DRM/KMS: <%d> (%s) Can't open %s, can't get master rights\n", m_id, __FUNCTION__, m_drm_name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
deps/switchres/custom_video_drmkms.h
vendored
2
deps/switchres/custom_video_drmkms.h
vendored
@ -53,6 +53,7 @@ class drmkms_timing : public custom_video
|
|||||||
int m_caps = 0;
|
int m_caps = 0;
|
||||||
|
|
||||||
char m_device_name[32];
|
char m_device_name[32];
|
||||||
|
char m_drm_name[32];
|
||||||
unsigned int m_desktop_output = 0;
|
unsigned int m_desktop_output = 0;
|
||||||
int m_video_modes_position = 0;
|
int m_video_modes_position = 0;
|
||||||
|
|
||||||
@ -83,6 +84,7 @@ class drmkms_timing : public custom_video
|
|||||||
__typeof__(drmModeFreePlaneResources) *p_drmModeFreePlaneResources;
|
__typeof__(drmModeFreePlaneResources) *p_drmModeFreePlaneResources;
|
||||||
__typeof__(drmIoctl) *p_drmIoctl;
|
__typeof__(drmIoctl) *p_drmIoctl;
|
||||||
__typeof__(drmGetCap) *p_drmGetCap;
|
__typeof__(drmGetCap) *p_drmGetCap;
|
||||||
|
__typeof__(drmGetDevices2) *p_drmGetDevices2;
|
||||||
__typeof__(drmIsMaster) *p_drmIsMaster;
|
__typeof__(drmIsMaster) *p_drmIsMaster;
|
||||||
__typeof__(drmSetMaster) *p_drmSetMaster;
|
__typeof__(drmSetMaster) *p_drmSetMaster;
|
||||||
__typeof__(drmDropMaster) *p_drmDropMaster;
|
__typeof__(drmDropMaster) *p_drmDropMaster;
|
||||||
|
1
deps/switchres/display.cpp
vendored
1
deps/switchres/display.cpp
vendored
@ -104,7 +104,6 @@ void display_manager::parse_options()
|
|||||||
|
|
||||||
void display_manager::set_preset(const char *preset)
|
void display_manager::set_preset(const char *preset)
|
||||||
{
|
{
|
||||||
strncpy(m_ds.monitor, preset, sizeof(m_ds.monitor)-1);
|
|
||||||
for (size_t i = 0; i < strlen(m_ds.monitor); i++) m_ds.monitor[i] = tolower(m_ds.monitor[i]);
|
for (size_t i = 0; i < strlen(m_ds.monitor); i++) m_ds.monitor[i] = tolower(m_ds.monitor[i]);
|
||||||
|
|
||||||
memset(&range[0], 0, sizeof(struct monitor_range) * MAX_RANGES);
|
memset(&range[0], 0, sizeof(struct monitor_range) * MAX_RANGES);
|
||||||
|
4
deps/switchres/display.h
vendored
4
deps/switchres/display.h
vendored
@ -97,6 +97,7 @@ public:
|
|||||||
int v_shift_correct() { return m_ds.gs.v_shift_correct; }
|
int v_shift_correct() { return m_ds.gs.v_shift_correct; }
|
||||||
int pixel_precision() { return m_ds.gs.pixel_precision; }
|
int pixel_precision() { return m_ds.gs.pixel_precision; }
|
||||||
int interlace_force_even() { return m_ds.gs.interlace_force_even; }
|
int interlace_force_even() { return m_ds.gs.interlace_force_even; }
|
||||||
|
int scale_proportional() { return m_ds.gs.scale_proportional; }
|
||||||
|
|
||||||
// getters (modeline result)
|
// getters (modeline result)
|
||||||
bool got_mode() { return (m_selected_mode != nullptr); }
|
bool got_mode() { return (m_selected_mode != nullptr); }
|
||||||
@ -134,7 +135,7 @@ public:
|
|||||||
void set_current_mode(modeline *mode) { m_current_mode = mode; }
|
void set_current_mode(modeline *mode) { m_current_mode = mode; }
|
||||||
|
|
||||||
// setters (display_manager)
|
// setters (display_manager)
|
||||||
void set_monitor(const char *preset) { set_preset(preset); }
|
void set_monitor(const char *preset) { strncpy(m_ds.monitor, preset, sizeof(m_ds.monitor)-1); set_preset(preset); }
|
||||||
void set_modeline(const char *modeline) { strncpy(m_ds.user_modeline, modeline, sizeof(m_ds.user_modeline)-1); }
|
void set_modeline(const char *modeline) { strncpy(m_ds.user_modeline, modeline, sizeof(m_ds.user_modeline)-1); }
|
||||||
void set_crt_range(int i, const char *range) { strncpy(m_ds.crt_range[i], range, sizeof(m_ds.crt_range[i])-1); }
|
void set_crt_range(int i, const char *range) { strncpy(m_ds.crt_range[i], range, sizeof(m_ds.crt_range[i])-1); }
|
||||||
void set_lcd_range(const char *range) { strncpy(m_ds.lcd_range, range, sizeof(m_ds.lcd_range)-1); }
|
void set_lcd_range(const char *range) { strncpy(m_ds.lcd_range, range, sizeof(m_ds.lcd_range)-1); }
|
||||||
@ -161,6 +162,7 @@ public:
|
|||||||
void set_v_shift_correct(int value) { m_ds.gs.v_shift_correct = value; }
|
void set_v_shift_correct(int value) { m_ds.gs.v_shift_correct = value; }
|
||||||
void set_pixel_precision(int value) { m_ds.gs.pixel_precision = value; }
|
void set_pixel_precision(int value) { m_ds.gs.pixel_precision = value; }
|
||||||
void set_interlace_force_even(int value) { m_ds.gs.interlace_force_even = value; }
|
void set_interlace_force_even(int value) { m_ds.gs.interlace_force_even = value; }
|
||||||
|
void set_scale_proportional(int value) { m_ds.gs.scale_proportional = value; }
|
||||||
|
|
||||||
// setters (custom_video backend)
|
// setters (custom_video backend)
|
||||||
void set_screen_compositing(bool value) { m_ds.vs.screen_compositing = value; }
|
void set_screen_compositing(bool value) { m_ds.vs.screen_compositing = value; }
|
||||||
|
67
deps/switchres/display_sdl2.cpp
vendored
67
deps/switchres/display_sdl2.cpp
vendored
@ -19,65 +19,6 @@
|
|||||||
#include "display_sdl2.h"
|
#include "display_sdl2.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
//============================================================
|
|
||||||
// custom_video::get_sdl_hwinfo_from_sdl_window
|
|
||||||
//============================================================
|
|
||||||
void get_sdl_hwinfo_from_sdl_window(SDL_Window* window)
|
|
||||||
{
|
|
||||||
SDL_SysWMinfo m_sdlwminfo;
|
|
||||||
|
|
||||||
SDL_VERSION(&m_sdlwminfo.version);
|
|
||||||
if(! SDL_GetWindowWMInfo(window, &m_sdlwminfo))
|
|
||||||
{
|
|
||||||
log_error("Couldn't get the SDL WMInfo\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const char *subsystem = "an unsupported or unknown system!";
|
|
||||||
switch((int)m_sdlwminfo.subsystem)
|
|
||||||
{
|
|
||||||
case SDL_SYSWM_UNKNOWN:
|
|
||||||
case SDL_SYSWM_COCOA:
|
|
||||||
case SDL_SYSWM_UIKIT:
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 2)
|
|
||||||
case SDL_SYSWM_WAYLAND:
|
|
||||||
#endif
|
|
||||||
case SDL_SYSWM_MIR:
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 3)
|
|
||||||
case SDL_SYSWM_WINRT:
|
|
||||||
#endif
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 4)
|
|
||||||
case SDL_SYSWM_ANDROID:
|
|
||||||
#endif
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
|
||||||
case SDL_SYSWM_VIVANTE:
|
|
||||||
#endif
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 6)
|
|
||||||
case SDL_SYSWM_OS2:
|
|
||||||
#endif
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 12)
|
|
||||||
case SDL_SYSWM_HAIKU:
|
|
||||||
#endif
|
|
||||||
case SDL_SYSWM_DIRECTFB:
|
|
||||||
break;
|
|
||||||
case SDL_SYSWM_WINDOWS:
|
|
||||||
subsystem = "Microsoft Windows(TM)";
|
|
||||||
break;
|
|
||||||
case SDL_SYSWM_X11:
|
|
||||||
subsystem = "X Window System";
|
|
||||||
break;
|
|
||||||
#if SDL_VERSION_ATLEAST(2, 0, 16)
|
|
||||||
case SDL_SYSWM_KMSDRM:
|
|
||||||
subsystem = "KMSDRM";
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
log_info("Switchres/SDL2: Detected SDL version %d.%d.%d on %s\n",
|
|
||||||
(int)m_sdlwminfo.version.major,
|
|
||||||
(int)m_sdlwminfo.version.minor,
|
|
||||||
(int)m_sdlwminfo.version.patch,
|
|
||||||
subsystem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
// sdl2_display::sdl2_display
|
// sdl2_display::sdl2_display
|
||||||
@ -147,6 +88,11 @@ bool sdl2_display::init(void* pf_data)
|
|||||||
|
|
||||||
//SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
//SDL_LogSetAllPriority(SDL_LOG_PRIORITY_DEBUG);
|
||||||
|
|
||||||
|
// Get SDL version information
|
||||||
|
SDL_version version;
|
||||||
|
SDL_GetVersion(&version);
|
||||||
|
log_info("Switchres/SDL2: Detected SDL version %d.%d.%d\n", (int)version.major, (int)version.minor, (int)version.patch);
|
||||||
|
|
||||||
SDL_Window* window = NULL;
|
SDL_Window* window = NULL;
|
||||||
Uint32 id = 0;
|
Uint32 id = 0;
|
||||||
|
|
||||||
@ -185,9 +131,6 @@ bool sdl2_display::init(void* pf_data)
|
|||||||
log_verbose("Switchres/SDL2: (%s:%d) No SDL2 window found, don't expect things to work good\n", __FUNCTION__, __LINE__);
|
log_verbose("Switchres/SDL2: (%s:%d) No SDL2 window found, don't expect things to work good\n", __FUNCTION__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(m_sdlwindow)
|
|
||||||
get_sdl_hwinfo_from_sdl_window(m_sdlwindow);
|
|
||||||
|
|
||||||
// Need a check to see if SDL2 can refresh the modelist
|
// Need a check to see if SDL2 can refresh the modelist
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
48
deps/switchres/examples/switch_refresh.cpp
vendored
Normal file
48
deps/switchres/examples/switch_refresh.cpp
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Test switching of refresh rate only
|
||||||
|
// Requires working update method
|
||||||
|
//
|
||||||
|
// Build: g++ -o switch_refresh switch_refresh.cpp -I ../ -L ../ -ldl -lswitchres -lSDL2 -lSDL2_ttf -ldrm
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <switchres/switchres_wrapper.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
sr_mode srm;
|
||||||
|
|
||||||
|
sr_set_log_level(3);
|
||||||
|
sr_init();
|
||||||
|
sr_set_disp(-1);
|
||||||
|
sr_set_monitor("arcade_31");
|
||||||
|
sr_init_disp("1", NULL);
|
||||||
|
|
||||||
|
printf("Testing first refresh (50Hz). Press any key...\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
if (!sr_add_mode(648, 480, 50, 0, &srm))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!sr_set_mode(srm.id))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
printf("Testing second refresh (60Hz). Press any key...\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
if(!sr_add_mode(648, 480, 60, 0, &srm))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if(!sr_set_mode(srm.id))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
printf("Success. Press any key to quit.\n");
|
||||||
|
getchar();
|
||||||
|
|
||||||
|
sr_deinit();
|
||||||
|
exit(0);
|
||||||
|
|
||||||
|
error:
|
||||||
|
printf("ERROR: Exiting!\n");
|
||||||
|
sr_deinit();
|
||||||
|
exit(1);
|
||||||
|
}
|
7
deps/switchres/makefile
vendored
7
deps/switchres/makefile
vendored
@ -64,6 +64,9 @@ else
|
|||||||
CPPFLAGS += -DSR_WITH_KMSDRM
|
CPPFLAGS += -DSR_WITH_KMSDRM
|
||||||
EXTRA_LIBS = libdrm
|
EXTRA_LIBS = libdrm
|
||||||
SRC += custom_video_drmkms.cpp
|
SRC += custom_video_drmkms.cpp
|
||||||
|
ifeq ($(SR_WITH_DRMHOOK),1)
|
||||||
|
CPPFLAGS += -DSR_WITH_DRMHOOK
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# SDL2 misses a test for drm as drm.h is required
|
# SDL2 misses a test for drm as drm.h is required
|
||||||
@ -150,8 +153,8 @@ install:
|
|||||||
$(INSTALL) -Dm644 switchres.h $(INCDIR)/switchres/switchres.h
|
$(INSTALL) -Dm644 switchres.h $(INCDIR)/switchres/switchres.h
|
||||||
$(INSTALL) -Dm644 switchres.pc $(PKGDIR)/switchres.pc
|
$(INSTALL) -Dm644 switchres.pc $(PKGDIR)/switchres.pc
|
||||||
ifneq ($(SO_NAME),)
|
ifneq ($(SO_NAME),)
|
||||||
$(LN) -s $(REAL_SO_NAME) $(LIBDIR)/$(SO_NAME)
|
$(LN) -s -f $(REAL_SO_NAME) $(LIBDIR)/$(SO_NAME)
|
||||||
$(LN) -s $(SO_NAME) $(LIBDIR)/$(LINKER_NAME)
|
$(LN) -s -f $(SO_NAME) $(LIBDIR)/$(LINKER_NAME)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
|
6
deps/switchres/modeline.cpp
vendored
6
deps/switchres/modeline.cpp
vendored
@ -168,9 +168,9 @@ int modeline_create(modeline *s_mode, modeline *t_mode, monitor_range *range, ge
|
|||||||
// if we can, let's apply the same scaling to both directions
|
// if we can, let's apply the same scaling to both directions
|
||||||
if (t_mode->type & X_RES_EDITABLE)
|
if (t_mode->type & X_RES_EDITABLE)
|
||||||
{
|
{
|
||||||
x_scale = y_scale;
|
x_scale = cs->scale_proportional? y_scale : 1;
|
||||||
double aspect_corrector = max(1.0f, cs->monitor_aspect / source_aspect);
|
double aspect_corrector = max(1.0f, cs->monitor_aspect / source_aspect);
|
||||||
t_mode->hactive = normalize(double(t_mode->hactive) * double(x_scale) * aspect_corrector, 8);
|
t_mode->hactive = normalize(double(t_mode->hactive) * double(x_scale) * aspect_corrector, cs->pixel_precision? 1 : 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// otherwise, try to get the best out of our current xres
|
// otherwise, try to get the best out of our current xres
|
||||||
@ -204,7 +204,7 @@ int modeline_create(modeline *s_mode, modeline *t_mode, monitor_range *range, ge
|
|||||||
|
|
||||||
// check if we can create a normal aspect resolution
|
// check if we can create a normal aspect resolution
|
||||||
if (t_mode->type & X_RES_EDITABLE)
|
if (t_mode->type & X_RES_EDITABLE)
|
||||||
t_mode->hactive = max(t_mode->hactive, normalize(STANDARD_CRT_ASPECT * t_mode->vactive, 8));
|
t_mode->hactive = max(t_mode->hactive, normalize(STANDARD_CRT_ASPECT * t_mode->vactive, cs->pixel_precision? 1 : 8));
|
||||||
|
|
||||||
// calculate integer scale for prescaling
|
// calculate integer scale for prescaling
|
||||||
x_scale = max(1, scale_into_aspect(s_mode->hactive, t_mode->hactive, source_aspect, cs->monitor_aspect, &x_diff));
|
x_scale = max(1, scale_into_aspect(s_mode->hactive, t_mode->hactive, source_aspect, cs->monitor_aspect, &x_diff));
|
||||||
|
1
deps/switchres/modeline.h
vendored
1
deps/switchres/modeline.h
vendored
@ -117,6 +117,7 @@ typedef struct generator_settings
|
|||||||
int v_shift_correct;
|
int v_shift_correct;
|
||||||
int pixel_precision;
|
int pixel_precision;
|
||||||
int interlace_force_even;
|
int interlace_force_even;
|
||||||
|
int scale_proportional;
|
||||||
} generator_settings;
|
} generator_settings;
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
|
7
deps/switchres/switchres.cpp
vendored
7
deps/switchres/switchres.cpp
vendored
@ -89,7 +89,7 @@ switchres_manager::switchres_manager()
|
|||||||
display()->set_monitor("generic_15");
|
display()->set_monitor("generic_15");
|
||||||
display()->set_modeline("auto");
|
display()->set_modeline("auto");
|
||||||
display()->set_lcd_range("auto");
|
display()->set_lcd_range("auto");
|
||||||
for (int i = 0; i++ < MAX_RANGES;) display()->set_crt_range(i, "auto");
|
for (int i = 0; i < MAX_RANGES; i++) display()->set_crt_range(i, "auto");
|
||||||
display()->set_screen("auto");
|
display()->set_screen("auto");
|
||||||
display()->set_modeline_generation(true);
|
display()->set_modeline_generation(true);
|
||||||
display()->set_lock_unsupported_modes(true);
|
display()->set_lock_unsupported_modes(true);
|
||||||
@ -109,6 +109,7 @@ switchres_manager::switchres_manager()
|
|||||||
display()->set_v_shift_correct(0);
|
display()->set_v_shift_correct(0);
|
||||||
display()->set_pixel_precision(1);
|
display()->set_pixel_precision(1);
|
||||||
display()->set_interlace_force_even(0);
|
display()->set_interlace_force_even(0);
|
||||||
|
display()->set_scale_proportional(1);
|
||||||
|
|
||||||
// Set logger properties
|
// Set logger properties
|
||||||
set_log_info_fn((void*)printf);
|
set_log_info_fn((void*)printf);
|
||||||
@ -359,6 +360,10 @@ void switchres_manager::set_option(const char* key, const char* value)
|
|||||||
display()->set_interlace_force_even(atoi(value));
|
display()->set_interlace_force_even(atoi(value));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case s2i("scale_proportional"):
|
||||||
|
display()->set_scale_proportional(atoi(value));
|
||||||
|
break;
|
||||||
|
|
||||||
// Custom video backend options
|
// Custom video backend options
|
||||||
case s2i("screen_compositing"):
|
case s2i("screen_compositing"):
|
||||||
display()->set_screen_compositing(atoi(value));
|
display()->set_screen_compositing(atoi(value));
|
||||||
|
2
deps/switchres/switchres.h
vendored
2
deps/switchres/switchres.h
vendored
@ -27,7 +27,7 @@
|
|||||||
//============================================================
|
//============================================================
|
||||||
|
|
||||||
#ifndef SWITCHRES_VERSION
|
#ifndef SWITCHRES_VERSION
|
||||||
#define SWITCHRES_VERSION "2.1.0"
|
#define SWITCHRES_VERSION "2.2.1"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
3
deps/switchres/switchres.ini
vendored
3
deps/switchres/switchres.ini
vendored
@ -122,6 +122,9 @@
|
|||||||
# Calculate all vertical values of interlaced modes as even numbers. Required by AMD APU hardware on Linux
|
# Calculate all vertical values of interlaced modes as even numbers. Required by AMD APU hardware on Linux
|
||||||
interlace_force_even 0
|
interlace_force_even 0
|
||||||
|
|
||||||
|
# Scale both axes by the same factor, when integer scaling is applied
|
||||||
|
scale_proportional 1
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Custom video backend config
|
# Custom video backend config
|
||||||
|
1
deps/switchres/switchres_defines.h
vendored
1
deps/switchres/switchres_defines.h
vendored
@ -33,6 +33,7 @@
|
|||||||
#define SR_OPT_V_SHIFT "v_shift"
|
#define SR_OPT_V_SHIFT "v_shift"
|
||||||
#define SR_OPT_PIXEL_PRECISION "pixel_precision"
|
#define SR_OPT_PIXEL_PRECISION "pixel_precision"
|
||||||
#define SR_OPT_INTERLACE_FORCE_EVEN "interlace_force_even"
|
#define SR_OPT_INTERLACE_FORCE_EVEN "interlace_force_even"
|
||||||
|
#define SR_OPT_SCALE_PROPORTIONAL "scale_proportional"
|
||||||
#define SR_OPT_SCREEN_COMPOSITING "screen_compositing"
|
#define SR_OPT_SCREEN_COMPOSITING "screen_compositing"
|
||||||
#define SR_OPT_SCREEN_REORDERING "screen_reordering"
|
#define SR_OPT_SCREEN_REORDERING "screen_reordering"
|
||||||
#define SR_OPT_ALLOW_HARDWARE_REFRESH "allow_hardware_refresh"
|
#define SR_OPT_ALLOW_HARDWARE_REFRESH "allow_hardware_refresh"
|
||||||
|
158
deps/switchres/switchres_main.cpp
vendored
158
deps/switchres/switchres_main.cpp
vendored
@ -16,6 +16,7 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include "switchres.h"
|
#include "switchres.h"
|
||||||
|
#include "switchres_defines.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -25,7 +26,42 @@ int show_usage();
|
|||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
OPT_MODELINE = 128
|
OPT_CRT_RANGE0 = 128,
|
||||||
|
OPT_CRT_RANGE1,
|
||||||
|
OPT_CRT_RANGE2,
|
||||||
|
OPT_CRT_RANGE3,
|
||||||
|
OPT_CRT_RANGE4,
|
||||||
|
OPT_CRT_RANGE5,
|
||||||
|
OPT_CRT_RANGE6,
|
||||||
|
OPT_CRT_RANGE7,
|
||||||
|
OPT_CRT_RANGE8,
|
||||||
|
OPT_CRT_RANGE9,
|
||||||
|
OPT_LCD_RANGE,
|
||||||
|
OPT_MODELINE,
|
||||||
|
OPT_USER_MODE,
|
||||||
|
OPT_API,
|
||||||
|
OPT_LOCK_UNSUPPORTED_MODES,
|
||||||
|
OPT_LOCK_SYSTEM_MODES,
|
||||||
|
OPT_REFRESH_DONT_CARE,
|
||||||
|
OPT_KEEP_CHANGES,
|
||||||
|
OPT_MODELINE_GENERATION,
|
||||||
|
OPT_INTERLACE,
|
||||||
|
OPT_DOUBLESCAN,
|
||||||
|
OPT_DOTCLOCK_MIN,
|
||||||
|
OPT_SYNC_REFRESH_TOLERANCE,
|
||||||
|
OPT_SUPER_WIDTH,
|
||||||
|
OPT_V_SHIFT_CORRECT,
|
||||||
|
OPT_H_SIZE,
|
||||||
|
OPT_H_SHIFT,
|
||||||
|
OPT_V_SHIFT,
|
||||||
|
OPT_PIXEL_PRECISION,
|
||||||
|
OPT_INTERLACE_FORCE_EVEN,
|
||||||
|
OPT_SCALE_PROPORTIONAL,
|
||||||
|
OPT_SCREEN_COMPOSITING,
|
||||||
|
OPT_SCREEN_REORDERING,
|
||||||
|
OPT_ALLOW_HARDWARE_REFRESH,
|
||||||
|
OPT_CUSTOM_TIMING,
|
||||||
|
OPT_VERBOSITY
|
||||||
};
|
};
|
||||||
|
|
||||||
//============================================================
|
//============================================================
|
||||||
@ -68,28 +104,65 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
|
// Options unique to standalone Switchres
|
||||||
{"version", no_argument, &version_flag, '1'},
|
{"version", no_argument, &version_flag, '1'},
|
||||||
{"help", no_argument, 0, 'h'},
|
{"help", no_argument, 0, 'h'},
|
||||||
{"calc", no_argument, 0, 'c'},
|
{"calc", no_argument, 0, 'c'},
|
||||||
{"switch", no_argument, 0, 's'},
|
{"switch", no_argument, 0, 's'},
|
||||||
{"launch", required_argument, 0, 'l'},
|
{"launch", required_argument, 0, 'l'},
|
||||||
{"monitor", required_argument, 0, 'm'},
|
|
||||||
{"aspect", required_argument, 0, 'a'},
|
|
||||||
{"edid", no_argument, 0, 'e'},
|
{"edid", no_argument, 0, 'e'},
|
||||||
{"rotated", no_argument, 0, 'r'},
|
{"rotated", no_argument, 0, 'r'},
|
||||||
{"display", required_argument, 0, 'd'},
|
{"force", required_argument, 0, 'f'}, // equ. --user_mode
|
||||||
{"force", required_argument, 0, 'f'},
|
|
||||||
{"ini", required_argument, 0, 'i'},
|
{"ini", required_argument, 0, 'i'},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"keep", no_argument, 0, 'k'}, // equ. --keep_changes
|
||||||
{"backend", required_argument, 0, 'b'},
|
|
||||||
{"keep", no_argument, 0, 'k'},
|
|
||||||
{"geometry", required_argument, 0, 'g'},
|
{"geometry", required_argument, 0, 'g'},
|
||||||
{"modeline", required_argument, 0, OPT_MODELINE},
|
// Options available in short and long forms
|
||||||
|
{SR_OPT_VERBOSE, no_argument, 0, 'v'},
|
||||||
|
{SR_OPT_DISPLAY, required_argument, 0, 'd'},
|
||||||
|
{SR_OPT_MONITOR, required_argument, 0, 'm'},
|
||||||
|
{SR_OPT_ASPECT, required_argument, 0, 'a'},
|
||||||
|
// Long options, from switchres.ini
|
||||||
|
{SR_OPT_CRT_RANGE0, required_argument, 0, OPT_CRT_RANGE0},
|
||||||
|
{SR_OPT_CRT_RANGE1, required_argument, 0, OPT_CRT_RANGE1},
|
||||||
|
{SR_OPT_CRT_RANGE2, required_argument, 0, OPT_CRT_RANGE2},
|
||||||
|
{SR_OPT_CRT_RANGE3, required_argument, 0, OPT_CRT_RANGE3},
|
||||||
|
{SR_OPT_CRT_RANGE4, required_argument, 0, OPT_CRT_RANGE4},
|
||||||
|
{SR_OPT_CRT_RANGE5, required_argument, 0, OPT_CRT_RANGE5},
|
||||||
|
{SR_OPT_CRT_RANGE6, required_argument, 0, OPT_CRT_RANGE6},
|
||||||
|
{SR_OPT_CRT_RANGE7, required_argument, 0, OPT_CRT_RANGE7},
|
||||||
|
{SR_OPT_CRT_RANGE8, required_argument, 0, OPT_CRT_RANGE8},
|
||||||
|
{SR_OPT_CRT_RANGE9, required_argument, 0, OPT_CRT_RANGE9},
|
||||||
|
{SR_OPT_LCD_RANGE, required_argument, 0, OPT_LCD_RANGE},
|
||||||
|
{SR_OPT_MODELINE, required_argument, 0, OPT_MODELINE},
|
||||||
|
{SR_OPT_USER_MODE, required_argument, 0, OPT_USER_MODE},
|
||||||
|
{SR_OPT_API, required_argument, 0, OPT_API},
|
||||||
|
{SR_OPT_LOCK_UNSUPPORTED_MODES, required_argument, 0, OPT_LOCK_UNSUPPORTED_MODES},
|
||||||
|
{SR_OPT_LOCK_SYSTEM_MODES, required_argument, 0, OPT_LOCK_SYSTEM_MODES},
|
||||||
|
{SR_OPT_REFRESH_DONT_CARE, required_argument, 0, OPT_REFRESH_DONT_CARE},
|
||||||
|
{SR_OPT_KEEP_CHANGES, required_argument, 0, OPT_KEEP_CHANGES},
|
||||||
|
{SR_OPT_MODELINE_GENERATION, required_argument, 0, OPT_MODELINE_GENERATION},
|
||||||
|
{SR_OPT_INTERLACE, required_argument, 0, OPT_INTERLACE},
|
||||||
|
{SR_OPT_DOUBLESCAN, required_argument, 0, OPT_DOUBLESCAN},
|
||||||
|
{SR_OPT_DOTCLOCK_MIN, required_argument, 0, OPT_DOTCLOCK_MIN},
|
||||||
|
{SR_OPT_SYNC_REFRESH_TOLERANCE, required_argument, 0, OPT_SYNC_REFRESH_TOLERANCE},
|
||||||
|
{SR_OPT_SUPER_WIDTH, required_argument, 0, OPT_SUPER_WIDTH},
|
||||||
|
{SR_OPT_V_SHIFT_CORRECT, required_argument, 0, OPT_V_SHIFT_CORRECT},
|
||||||
|
{SR_OPT_H_SIZE, required_argument, 0, OPT_H_SIZE},
|
||||||
|
{SR_OPT_H_SHIFT, required_argument, 0, OPT_H_SHIFT},
|
||||||
|
{SR_OPT_V_SHIFT, required_argument, 0, OPT_V_SHIFT},
|
||||||
|
{SR_OPT_PIXEL_PRECISION, required_argument, 0, OPT_PIXEL_PRECISION},
|
||||||
|
{SR_OPT_INTERLACE_FORCE_EVEN, required_argument, 0, OPT_INTERLACE_FORCE_EVEN},
|
||||||
|
{SR_OPT_SCALE_PROPORTIONAL, required_argument, 0, OPT_SCALE_PROPORTIONAL},
|
||||||
|
{SR_OPT_SCREEN_COMPOSITING, required_argument, 0, OPT_SCREEN_COMPOSITING},
|
||||||
|
{SR_OPT_SCREEN_REORDERING, required_argument, 0, OPT_SCREEN_REORDERING},
|
||||||
|
{SR_OPT_ALLOW_HARDWARE_REFRESH, required_argument, 0, OPT_ALLOW_HARDWARE_REFRESH},
|
||||||
|
{SR_OPT_CUSTOM_TIMING, required_argument, 0, OPT_CUSTOM_TIMING},
|
||||||
|
{SR_OPT_VERBOSITY, required_argument, 0, OPT_VERBOSITY},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
int c = getopt_long(argc, argv, "vhcsl:m:a:erd:f:i:b:kg:", long_options, &option_index);
|
int c = getopt_long(argc, argv, "vhcsl:m:a:erd:f:i:kg:", long_options, &option_index);
|
||||||
|
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
@ -102,10 +175,6 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case OPT_MODELINE:
|
|
||||||
df->set_modeline(optarg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
case 'v':
|
||||||
switchres.set_log_level(3);
|
switchres.set_log_level(3);
|
||||||
switchres.set_log_error_fn((void*)printf);
|
switchres.set_log_error_fn((void*)printf);
|
||||||
@ -142,7 +211,8 @@ int main(int argc, char **argv)
|
|||||||
// Add new display in multi-monitor case
|
// Add new display in multi-monitor case
|
||||||
if (index > 0) switchres.add_display();
|
if (index > 0) switchres.add_display();
|
||||||
index ++;
|
index ++;
|
||||||
df->set_screen(optarg);
|
switchres.set_current_display(-1);
|
||||||
|
switchres.set_option(SR_OPT_DISPLAY, optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a':
|
case 'a':
|
||||||
@ -154,9 +224,10 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
case OPT_USER_MODE:
|
||||||
force_flag = true;
|
force_flag = true;
|
||||||
if (sscanf(optarg, "%dx%d@%d", &user_mode.width, &user_mode.height, &user_mode.refresh) < 1)
|
if (sscanf(optarg, "%dx%d@%d", &user_mode.width, &user_mode.height, &user_mode.refresh) < 1)
|
||||||
log_error("Error: use format --force <w>x<h>@<r>\n");
|
log_error("Error: use format <w>x<h>@<r>\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
@ -183,6 +254,45 @@ int main(int argc, char **argv)
|
|||||||
df->set_v_shift(v_shift);
|
df->set_v_shift(v_shift);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Long options
|
||||||
|
case OPT_CRT_RANGE0:
|
||||||
|
case OPT_CRT_RANGE1:
|
||||||
|
case OPT_CRT_RANGE2:
|
||||||
|
case OPT_CRT_RANGE3:
|
||||||
|
case OPT_CRT_RANGE4:
|
||||||
|
case OPT_CRT_RANGE5:
|
||||||
|
case OPT_CRT_RANGE6:
|
||||||
|
case OPT_CRT_RANGE7:
|
||||||
|
case OPT_CRT_RANGE8:
|
||||||
|
case OPT_CRT_RANGE9:
|
||||||
|
case OPT_LCD_RANGE:
|
||||||
|
case OPT_MODELINE:
|
||||||
|
case OPT_API:
|
||||||
|
case OPT_LOCK_UNSUPPORTED_MODES:
|
||||||
|
case OPT_LOCK_SYSTEM_MODES:
|
||||||
|
case OPT_REFRESH_DONT_CARE:
|
||||||
|
case OPT_KEEP_CHANGES:
|
||||||
|
case OPT_MODELINE_GENERATION:
|
||||||
|
case OPT_INTERLACE:
|
||||||
|
case OPT_DOUBLESCAN:
|
||||||
|
case OPT_DOTCLOCK_MIN:
|
||||||
|
case OPT_SYNC_REFRESH_TOLERANCE:
|
||||||
|
case OPT_SUPER_WIDTH:
|
||||||
|
case OPT_V_SHIFT_CORRECT:
|
||||||
|
case OPT_H_SIZE:
|
||||||
|
case OPT_H_SHIFT:
|
||||||
|
case OPT_V_SHIFT:
|
||||||
|
case OPT_PIXEL_PRECISION:
|
||||||
|
case OPT_INTERLACE_FORCE_EVEN:
|
||||||
|
case OPT_SCALE_PROPORTIONAL:
|
||||||
|
case OPT_SCREEN_COMPOSITING:
|
||||||
|
case OPT_SCREEN_REORDERING:
|
||||||
|
case OPT_ALLOW_HARDWARE_REFRESH:
|
||||||
|
case OPT_CUSTOM_TIMING:
|
||||||
|
case OPT_VERBOSITY:
|
||||||
|
switchres.set_option(long_options[option_index].name, optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -265,7 +375,7 @@ int main(int argc, char **argv)
|
|||||||
monitor_range *range = &switchres.display()->range[mode->range];
|
monitor_range *range = &switchres.display()->range[mode->range];
|
||||||
edid_from_modeline(mode, range, switchres.display()->monitor(), &edid);
|
edid_from_modeline(mode, range, switchres.display()->monitor(), &edid);
|
||||||
|
|
||||||
char file_name[strlen(switchres.display()->monitor()) + 4];
|
char file_name[strlen(switchres.display()->monitor()) + 5];
|
||||||
sprintf(file_name, "%s.bin", switchres.display()->monitor());
|
sprintf(file_name, "%s.bin", switchres.display()->monitor());
|
||||||
|
|
||||||
FILE *file = fopen(file_name, "wb");
|
FILE *file = fopen(file_name, "wb");
|
||||||
@ -313,7 +423,7 @@ int show_version()
|
|||||||
{
|
{
|
||||||
"Switchres " SWITCHRES_VERSION "\n"
|
"Switchres " SWITCHRES_VERSION "\n"
|
||||||
"Modeline generation engine for emulation\n"
|
"Modeline generation engine for emulation\n"
|
||||||
"Copyright (C) 2010-2021 - Chris Kennedy, Antonio Giner, Alexandre Wodarczyk, Gil Delescluse\n"
|
"Copyright (C) 2010-2024 - Chris Kennedy, Antonio Giner, Alexandre Wodarczyk, Gil Delescluse\n"
|
||||||
"License GPL-2.0+\n"
|
"License GPL-2.0+\n"
|
||||||
"This is free software: you are free to change and redistribute it.\n"
|
"This is free software: you are free to change and redistribute it.\n"
|
||||||
"There is NO WARRANTY, to the extent permitted by law.\n"
|
"There is NO WARRANTY, to the extent permitted by law.\n"
|
||||||
@ -338,15 +448,17 @@ int show_usage()
|
|||||||
" -l, --launch <command> Launch <command>\n"
|
" -l, --launch <command> Launch <command>\n"
|
||||||
" -m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)\n"
|
" -m, --monitor <preset> Monitor preset (generic_15, arcade_15, pal, ntsc, etc.)\n"
|
||||||
" -a, --aspect <num:den> Monitor aspect ratio\n"
|
" -a, --aspect <num:den> Monitor aspect ratio\n"
|
||||||
" -r, --rotated Original mode's native orientation is rotated\n"
|
" -r, --rotated Rotate axes, preserving aspect ratio.\n"
|
||||||
" -d, --display <OS_display_name> Use target display (Windows: \\\\.\\DISPLAY1, ... Linux: VGA-0, ...)\n"
|
" -d, --display <display_index> Use target display (index = 0, 1, 2...)\n"
|
||||||
" -f, --force <w>x<h>@<r> Force a specific video mode from display mode list\n"
|
" -f, --force <w>x<h>@<r> Force a specific video mode from display mode list\n"
|
||||||
" -i, --ini <file.ini> Specify an ini file\n"
|
" -i, --ini <file.ini> Specify an ini file\n"
|
||||||
" -b, --backend <api_name> Specify the api name\n"
|
|
||||||
" -e, --edid Create an EDID binary with calculated video modes\n"
|
" -e, --edid Create an EDID binary with calculated video modes\n"
|
||||||
" -k, --keep Keep changes on exit (warning: this disables cleanup)\n"
|
" -k, --keep Keep changes on exit (warning: this disables cleanup)\n"
|
||||||
" -g, --geometry <h_size>:<h_shift>:<v_shift> Adjust geometry of generated modeline\n"
|
" -g, --geometry <adjustment> Adjust geometry of generated modeline\n"
|
||||||
" --modeline <\"pclk hdisp hsst hsend htot vdisp vsst vsend vtot flags\"> Force an XFree86 modeline\n"
|
" adjustment = <h_size>:<h_shift>:<v_shift>\n"
|
||||||
|
" e.g. switchres 640 480 60 -c -g 1.1:-1:2\n\n"
|
||||||
|
"For more options, refer to switchres.ini. All options in switchres.ini can be applied in\n"
|
||||||
|
"command line as long options, e.g.: switchres 256 224 57.55 -c --dotclock_min 8.0\n\n"
|
||||||
};
|
};
|
||||||
|
|
||||||
log_info("%s", usage);
|
log_info("%s", usage);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user