mirror of https://github.com/snes9xgit/snes9x.git
Rework XRandR support to list all modes and refresh rates.
This commit is contained in:
parent
363fdc9848
commit
c48f212a8a
|
@ -162,8 +162,6 @@ Snes9xConfig::load_defaults (void)
|
|||
full_screen_on_open = 0;
|
||||
change_display_resolution = 0;
|
||||
xrr_index = 0;
|
||||
xrr_width = 0;
|
||||
xrr_height = 0;
|
||||
scale_to_fit = 1;
|
||||
maintain_aspect_ratio = 0;
|
||||
aspect_ratio = 0;
|
||||
|
@ -324,8 +322,6 @@ Snes9xConfig::save_config_file (void)
|
|||
xml_out_int (xml, "full_screen_on_open", full_screen_on_open);
|
||||
xml_out_int (xml, "change_display_resolution", change_display_resolution);
|
||||
xml_out_int (xml, "video_mode", xrr_index);
|
||||
xml_out_int (xml, "video_mode_width", xrr_width);
|
||||
xml_out_int (xml, "video_mode_height", xrr_height);
|
||||
xml_out_int (xml, "scale_to_fit", scale_to_fit);
|
||||
xml_out_int (xml, "maintain_aspect_ratio", maintain_aspect_ratio);
|
||||
xml_out_int (xml, "aspect_ratio", aspect_ratio);
|
||||
|
@ -498,14 +494,7 @@ Snes9xConfig::set_option (const char *name, const char *value)
|
|||
}
|
||||
else if (!strcasecmp (name, "video_mode"))
|
||||
{
|
||||
}
|
||||
else if (!strcasecmp (name, "video_mode_width"))
|
||||
{
|
||||
xrr_width = atoi (value);
|
||||
}
|
||||
else if (!strcasecmp (name, "video_mode_height"))
|
||||
{
|
||||
xrr_height = atoi (value);
|
||||
xrr_index = atoi (value);
|
||||
}
|
||||
else if (!strcasecmp (name, "scale_to_fit"))
|
||||
{
|
||||
|
|
|
@ -58,9 +58,7 @@ class Snes9xConfig
|
|||
unsigned char statusbar_visible;
|
||||
unsigned char default_esc_behavior;
|
||||
unsigned char prevent_screensaver;
|
||||
unsigned int xrr_index;
|
||||
int xrr_width;
|
||||
int xrr_height;
|
||||
int xrr_index;
|
||||
unsigned char scale_to_fit;
|
||||
unsigned char maintain_aspect_ratio;
|
||||
int aspect_ratio;
|
||||
|
@ -138,14 +136,12 @@ class Snes9xConfig
|
|||
unsigned int rewind_buffer_size;
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
XRRScreenConfiguration *xrr_config;
|
||||
XRRScreenSize *xrr_sizes;
|
||||
int xrr_num_sizes;
|
||||
Rotation xrr_rotation;
|
||||
SizeID xrr_original_size;
|
||||
XRRScreenResources *xrr_screen_resources;
|
||||
XRROutputInfo *xrr_output_info;
|
||||
XRRCrtcInfo *xrr_crtc_info;
|
||||
RROutput xrr_output;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_OPENGL
|
||||
unsigned char sync_to_vblank;
|
||||
unsigned char opengl_activated;
|
||||
|
|
|
@ -1703,30 +1703,35 @@ S9xQueryDrivers (void)
|
|||
gui_config->allow_opengl = 0;
|
||||
#endif
|
||||
|
||||
gui_config->allow_xrandr = 0;
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
int error_base_p, event_base_p;
|
||||
Display *display = GDK_DISPLAY_XDISPLAY (gdk_display_get_default ());
|
||||
int major_version, minor_version;
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (gtk_widget_get_display (GTK_WIDGET (top_level->get_window())));
|
||||
Window xid = gdk_x11_window_get_xid (gtk_widget_get_window (GTK_WIDGET (top_level->get_window())));
|
||||
|
||||
if (!XRRQueryExtension (dpy, &event_base_p, &error_base_p))
|
||||
{
|
||||
gui_config->change_display_resolution = FALSE;
|
||||
return;
|
||||
}
|
||||
if (!XRRQueryVersion (dpy, &major_version, &minor_version))
|
||||
{
|
||||
gui_config->change_display_resolution = FALSE;
|
||||
return;
|
||||
}
|
||||
if (minor_version < 3)
|
||||
{
|
||||
gui_config->change_display_resolution = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
gui_config->allow_xrandr = 1;
|
||||
|
||||
if (!XRRQueryExtension (display, &event_base_p, &error_base_p))
|
||||
{
|
||||
gui_config->allow_xrandr = 0;
|
||||
gui_config->change_display_resolution = FALSE;
|
||||
}
|
||||
|
||||
if (gui_config->allow_xrandr)
|
||||
{
|
||||
gui_config->xrr_config = XRRGetScreenInfo (display,
|
||||
DefaultRootWindow (display));
|
||||
gui_config->xrr_original_size =
|
||||
XRRConfigCurrentConfiguration (gui_config->xrr_config,
|
||||
&(gui_config->xrr_rotation));
|
||||
gui_config->xrr_sizes = XRRConfigSizes (gui_config->xrr_config,
|
||||
&(gui_config->xrr_num_sizes));
|
||||
}
|
||||
#else
|
||||
gui_config->allow_xrandr = 0;
|
||||
gui_config->xrr_screen_resources = XRRGetScreenResources (dpy, xid);
|
||||
gui_config->xrr_output = XRRGetOutputPrimary (dpy, xid);
|
||||
gui_config->xrr_output_info = XRRGetOutputInfo (dpy, gui_config->xrr_screen_resources, gui_config->xrr_output);
|
||||
gui_config->xrr_crtc_info = XRRGetCrtcInfo (dpy, gui_config->xrr_screen_resources, gui_config->xrr_output_info->crtc);
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
|
|
@ -497,6 +497,10 @@ static double XRRGetExactRefreshRate (Display *dpy, Window window)
|
|||
XRRModeInfo *m = &resources->modes[i];
|
||||
|
||||
refresh_rate = (double) m->dotClock / m->hTotal / m->vTotal;
|
||||
refresh_rate /= m->modeFlags & RR_DoubleScan ? 2 : 1;
|
||||
refresh_rate /= m->modeFlags & RR_ClockDivideBy2 ? 2 : 1;
|
||||
refresh_rate *= m->modeFlags & RR_DoubleClock ? 2 : 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -633,6 +637,10 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) :
|
|||
last_toggled = NULL;
|
||||
this->config = config;
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
mode_indices = NULL;
|
||||
#endif
|
||||
|
||||
gtk_widget_realize (window);
|
||||
|
||||
signal_connect (callbacks);
|
||||
|
@ -649,6 +657,10 @@ Snes9xPreferences::Snes9xPreferences (Snes9xConfig *config) :
|
|||
|
||||
Snes9xPreferences::~Snes9xPreferences (void)
|
||||
{
|
||||
#ifdef USE_XRANDR
|
||||
delete[] mode_indices;
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -847,16 +859,12 @@ Snes9xPreferences::get_settings_from_dialog (void)
|
|||
{
|
||||
top_level->leave_fullscreen_mode ();
|
||||
config->xrr_index = get_combo ("resolution_combo");
|
||||
config->xrr_width = config->xrr_sizes[config->xrr_index].width;
|
||||
config->xrr_height = config->xrr_sizes[config->xrr_index].height;
|
||||
config->change_display_resolution = get_check ("change_display_resolution");
|
||||
top_level->enter_fullscreen_mode ();
|
||||
}
|
||||
else
|
||||
{
|
||||
config->xrr_index = get_combo ("resolution_combo");
|
||||
config->xrr_width = config->xrr_sizes[config->xrr_index].width;
|
||||
config->xrr_height = config->xrr_sizes[config->xrr_index].height;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1102,22 +1110,38 @@ Snes9xPreferences::show (void)
|
|||
|
||||
combo = get_widget ("resolution_combo");
|
||||
|
||||
config->xrr_index = 0;
|
||||
|
||||
for (int i = 0; i < config->xrr_num_sizes; i++)
|
||||
mode_indices = new unsigned int[config->xrr_output_info->nmode];
|
||||
for (int i = 0; i < config->xrr_output_info->nmode; i++)
|
||||
{
|
||||
if (config->xrr_width == config->xrr_sizes[i].width &&
|
||||
config->xrr_height == config->xrr_sizes[i].height)
|
||||
config->xrr_index = i;
|
||||
for (int j = 0; j < config->xrr_screen_resources->nmode; j++)
|
||||
{
|
||||
if (config->xrr_screen_resources->modes[j].id == config->xrr_output_info->modes[i])
|
||||
{
|
||||
mode_indices[i] = j;
|
||||
}
|
||||
}
|
||||
|
||||
XRRModeInfo *m = &config->xrr_screen_resources->modes[mode_indices[i]];
|
||||
unsigned long dotClock = m->dotClock;
|
||||
if (m->modeFlags & RR_ClockDivideBy2)
|
||||
dotClock /= 2;
|
||||
if (m->modeFlags & RR_DoubleScan)
|
||||
dotClock /= 2;
|
||||
if (m->modeFlags & RR_DoubleClock)
|
||||
dotClock *= 2;
|
||||
|
||||
snprintf (size_string,
|
||||
256,
|
||||
"%dx%d",
|
||||
config->xrr_sizes[i].width,
|
||||
config->xrr_sizes[i].height);
|
||||
"%dx%d @ %.3fHz",
|
||||
m->width,
|
||||
m->height,
|
||||
(double) dotClock / m->hTotal / m->vTotal);
|
||||
|
||||
combo_box_append (GTK_COMBO_BOX (combo), size_string);
|
||||
}
|
||||
|
||||
if (config->xrr_index > config->xrr_output_info->nmode)
|
||||
config->xrr_index = 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
|
|
|
@ -40,6 +40,10 @@ class Snes9xPreferences : public GtkBuilderWindow
|
|||
private:
|
||||
void get_settings_from_dialog (void);
|
||||
void move_settings_to_dialog (void);
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
unsigned int *mode_indices;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* __GTK_PREFERENCES_H */
|
||||
|
|
|
@ -1550,53 +1550,40 @@ Snes9xWindow::enter_fullscreen_mode (void)
|
|||
|
||||
gtk_window_get_position (GTK_WINDOW (window), &nfs_x, &nfs_y);
|
||||
|
||||
/* Make sure everything is done synchronously */
|
||||
gdk_display_sync (gdk_display_get_default ());
|
||||
gtk_window_fullscreen (GTK_WINDOW (window));
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
if (config->change_display_resolution)
|
||||
{
|
||||
int mode = -1;
|
||||
GdkDisplay *gdk_display = gtk_widget_get_display (window);
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
|
||||
for (int i = 0; i < config->xrr_num_sizes; i++)
|
||||
{
|
||||
if (config->xrr_sizes[i].width == config->xrr_width &&
|
||||
config->xrr_sizes[i].height == config->xrr_height)
|
||||
{
|
||||
mode = i;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode < 0)
|
||||
gdk_display_sync (gdk_display);
|
||||
if (XRRSetCrtcConfig (dpy,
|
||||
config->xrr_screen_resources,
|
||||
config->xrr_output_info->crtc,
|
||||
CurrentTime,
|
||||
config->xrr_crtc_info->x,
|
||||
config->xrr_crtc_info->y,
|
||||
config->xrr_output_info->modes[config->xrr_index],
|
||||
config->xrr_crtc_info->rotation,
|
||||
&config->xrr_output,
|
||||
1) != 0)
|
||||
{
|
||||
config->change_display_resolution = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
GdkDisplay *gdk_display = gtk_widget_get_display (window);
|
||||
Display *display = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
GdkScreen *screen = gtk_widget_get_screen (window);
|
||||
GdkWindow *root = gdk_screen_get_root_window (screen);
|
||||
|
||||
gdk_display_sync (gdk_display_get_default ());
|
||||
XRRSetScreenConfig (display,
|
||||
config->xrr_config,
|
||||
GDK_COMPAT_WINDOW_XID (root),
|
||||
(SizeID) mode,
|
||||
config->xrr_rotation,
|
||||
CurrentTime);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
set_bypass_compositor (gdk_x11_display_get_xdisplay (gtk_widget_get_display (window)),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (window)),
|
||||
1);
|
||||
/* Make sure everything is done synchronously */
|
||||
gdk_display_sync (gdk_display_get_default ());
|
||||
gtk_window_fullscreen (GTK_WINDOW (window));
|
||||
|
||||
gdk_display_sync (gdk_display_get_default ());
|
||||
gtk_window_present (GTK_WINDOW (window));
|
||||
|
||||
set_bypass_compositor (gdk_x11_display_get_xdisplay (gtk_widget_get_display (window)),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (window)),
|
||||
1);
|
||||
|
||||
config->fullscreen = 1;
|
||||
config->rom_loaded = rom_loaded;
|
||||
|
||||
|
@ -1619,37 +1606,34 @@ Snes9xWindow::leave_fullscreen_mode (void)
|
|||
|
||||
config->rom_loaded = 0;
|
||||
|
||||
set_bypass_compositor (gdk_x11_display_get_xdisplay (gtk_widget_get_display (window)),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (window)),
|
||||
0);
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
if (config->change_display_resolution)
|
||||
{
|
||||
gtk_widget_hide (window);
|
||||
|
||||
GdkDisplay *gdk_display = gtk_widget_get_display (window);
|
||||
Display *display = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
GdkScreen *screen = gtk_widget_get_screen (window);
|
||||
GdkWindow *root = gdk_screen_get_root_window (screen);
|
||||
Display *dpy = gdk_x11_display_get_xdisplay (gdk_display);
|
||||
|
||||
XRRSetScreenConfig (display,
|
||||
config->xrr_config,
|
||||
GDK_COMPAT_WINDOW_XID (root),
|
||||
(SizeID) config->xrr_original_size,
|
||||
config->xrr_rotation,
|
||||
CurrentTime);
|
||||
if (config->xrr_index > config->xrr_output_info->nmode)
|
||||
config->xrr_index = 0;
|
||||
|
||||
gdk_display_sync (gdk_display);
|
||||
XRRSetCrtcConfig (dpy,
|
||||
config->xrr_screen_resources,
|
||||
config->xrr_output_info->crtc,
|
||||
CurrentTime,
|
||||
config->xrr_crtc_info->x,
|
||||
config->xrr_crtc_info->y,
|
||||
config->xrr_crtc_info->mode,
|
||||
config->xrr_crtc_info->rotation,
|
||||
&config->xrr_output,
|
||||
1);
|
||||
}
|
||||
#endif
|
||||
|
||||
gtk_window_unfullscreen (GTK_WINDOW (window));
|
||||
|
||||
#ifdef USE_XRANDR
|
||||
if (config->change_display_resolution)
|
||||
{
|
||||
gtk_widget_show (window);
|
||||
}
|
||||
#endif
|
||||
set_bypass_compositor (gdk_x11_display_get_xdisplay (gtk_widget_get_display (window)),
|
||||
gdk_x11_window_get_xid (gtk_widget_get_window (window)),
|
||||
0);
|
||||
|
||||
resize (nfs_width, nfs_height);
|
||||
gtk_window_move (GTK_WINDOW (window), nfs_x, nfs_y);
|
||||
|
|
Loading…
Reference in New Issue