From 569702e75ad7ba316e833119e54815100ffdb70d Mon Sep 17 00:00:00 2001 From: Brandon Wright Date: Sat, 14 Apr 2018 16:21:13 -0500 Subject: [PATCH] Add automatic input rate selection by polling XRandR. --- gtk/src/gtk_preferences.cpp | 63 +++++++++++++++++++++++++++++++++++++ gtk/src/snes9x.ui | 53 ++++++++++++++++++++----------- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/gtk/src/gtk_preferences.cpp b/gtk/src/gtk_preferences.cpp index 85794c85..9831f3b0 100644 --- a/gtk/src/gtk_preferences.cpp +++ b/gtk/src/gtk_preferences.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #ifdef USE_GTK3 #include #endif @@ -463,6 +464,66 @@ event_input_rate_changed (GtkRange *range, gpointer data) return; } +#ifdef USE_XRANDR +static double XRRGetExactRefreshRate (Display *dpy, Window window) +{ + XRRScreenResources *resources = NULL; + XRROutputInfo *output_info = NULL; + XRRCrtcInfo *crtc_info = NULL; + RROutput output; + int event_base; + int error_base; + int version_major; + int version_minor; + double refresh_rate = 0.0; + int i; + + if (!XRRQueryExtension (dpy, &event_base, &error_base) || + !XRRQueryVersion (dpy, &version_major, &version_minor)) + { + return refresh_rate; + } + + resources = XRRGetScreenResources (dpy, window); + output = XRRGetOutputPrimary (dpy, window); + output_info = XRRGetOutputInfo (dpy, resources, output); + crtc_info = XRRGetCrtcInfo (dpy, resources, output_info->crtc); + + for (i = 0; i < resources->nmode; i++) + { + if (resources->modes[i].id == crtc_info->mode) + { + XRRModeInfo *m = &resources->modes[i]; + + refresh_rate = (double) m->dotClock / m->hTotal / m->vTotal; + break; + } + } + + XRRFreeCrtcInfo (crtc_info); + XRRFreeOutputInfo (output_info); + XRRFreeScreenResources (resources); + + return refresh_rate; +} +#endif + +static void +event_set_input_rate (GtkButton *widget, gpointer data) +{ +#ifdef USE_XRANDR + Snes9xPreferences *preferences = (Snes9xPreferences *) data; + GdkWindow *gdk_window = gtk_widget_get_window (GTK_WIDGET(top_level->get_window())); + Display *dpy = GDK_DISPLAY_XDISPLAY (gdk_window_get_display (gdk_window)); + Window window = GDK_COMPAT_WINDOW_XID (gdk_window); + double rate = XRRGetExactRefreshRate(dpy, window); + + if (rate != 0.0) + preferences->set_slider("sound_input_rate", (int) (rate * 32040 / 60.09881389744051 + 0.5)); +#endif +} + + static void event_about_clicked (GtkButton *widget, gpointer data) { @@ -561,6 +622,7 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) : { "game_data_browse", G_CALLBACK (event_game_data_browse) }, { "game_data_clear", G_CALLBACK (event_game_data_clear) }, { "about_clicked", G_CALLBACK (event_about_clicked) }, + { "set_input_rate", G_CALLBACK (event_set_input_rate) }, #ifdef USE_JOYSTICK { "calibrate", G_CALLBACK (event_calibrate) }, #endif @@ -1060,6 +1122,7 @@ Snes9xPreferences::show (void) else { gtk_widget_hide (get_widget ("resolution_box")); + gtk_widget_hide (get_widget ("set_input_rate_button")); } #ifdef USE_HQ2X diff --git a/gtk/src/snes9x.ui b/gtk/src/snes9x.ui index a4c038bb..90722835 100644 --- a/gtk/src/snes9x.ui +++ b/gtk/src/snes9x.ui @@ -4023,7 +4023,7 @@ True True False - Adjust input rate automatically + Smoothes out slight hiccups in sound input rate True @@ -4085,7 +4085,7 @@ True False - 5 + 6 2 10 5 @@ -4140,8 +4140,8 @@ 1 2 - 3 - 4 + 4 + 5 GTK_FILL GTK_FILL @@ -4154,8 +4154,8 @@ Buffer size: - 3 - 4 + 4 + 5 GTK_FILL GTK_FILL @@ -4168,8 +4168,8 @@ Dynamic rate limit: - 4 - 5 + 5 + 6 GTK_FILL GTK_FILL @@ -4198,8 +4198,8 @@ 1 - 4 - 5 + 5 + 6 GTK_FILL GTK_FILL @@ -4212,8 +4212,8 @@ Input rate: - 1 - 2 + 2 + 3 GTK_FILL GTK_FILL @@ -4231,8 +4231,8 @@ 1 2 - 1 - 2 + 2 + 3 GTK_FILL @@ -4266,6 +4266,23 @@ GTK_FILL + + + Automatically Set Input Rate + True + True + True + + + + 1 + 2 + 1 + 2 + GTK_FILL + GTK_FILL + + True @@ -4274,8 +4291,8 @@ Video rate: - 2 - 3 + 3 + 4 GTK_FILL GTK_FILL @@ -4289,8 +4306,8 @@ 1 2 - 2 - 3 + 3 + 4 GTK_FILL