mirror of
https://github.com/libretro/snes9x.git
synced 2024-11-23 16:29:41 +00:00
Merge pull request #196 from Francesco149/xinerama
Add xinerama multi-monitor support and position window hints
This commit is contained in:
commit
4dcf4ddc74
26
unix/configure
vendored
26
unix/configure
vendored
@ -719,6 +719,7 @@ enable_jma
|
||||
enable_screenshot
|
||||
with_x
|
||||
enable_xvideo
|
||||
enable_xinerama
|
||||
enable_sound
|
||||
'
|
||||
ac_precious_vars='build_alias
|
||||
@ -1370,6 +1371,7 @@ Optional Features:
|
||||
--enable-screenshot enable screenshot support through libpng (default:
|
||||
yes)
|
||||
--enable-xvideo enable Xvideo if available (default: yes)
|
||||
--enable-xinerama enable Xinerama if available (default: yes)
|
||||
--enable-sound enable sound if available (default: yes)
|
||||
|
||||
Optional Packages:
|
||||
@ -6253,6 +6255,29 @@ if test "x$ac_cv_header_X11_extensions_Xv_h" = xyes; then :
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# Check if we can build with Xinerama multi-monitor support
|
||||
# Check whether --enable-xinerama was given.
|
||||
if test "${enable_xinerama+set}" = set; then :
|
||||
enableval=$enable_xinerama;
|
||||
else
|
||||
enable_xinerama="yes"
|
||||
fi
|
||||
|
||||
|
||||
if test "x$enable_xinerama" = "xyes"; then
|
||||
enable_xinerama="no"
|
||||
ac_fn_cxx_check_header_mongrel "$LINENO" "X11/extensions/Xinerama.h" "ac_cv_header_X11_extensions_Xinerama_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_X11_extensions_Xinerama_h" = xyes; then :
|
||||
|
||||
enable_xinerama="yes"
|
||||
S9XLIBS="$S9XLIBS -lXinerama"
|
||||
S9XDEFS="$S9XDEFS -DUSE_XINERAMA"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
fi
|
||||
|
||||
# Check if we have sound code for this platform.
|
||||
@ -6333,6 +6358,7 @@ libs................. $S9XLIBS
|
||||
|
||||
features:
|
||||
Xvideo support....... $enable_xvideo
|
||||
Xinerama support..... $enable_xinerama
|
||||
sound support........ $enable_sound
|
||||
screenshot support... $enable_screenshot
|
||||
netplay support...... $enable_netplay
|
||||
|
@ -406,6 +406,22 @@ if test "x$enable_xvideo" = "xyes"; then
|
||||
])
|
||||
fi
|
||||
|
||||
# Check if we can build with Xinerama multi-monitor support
|
||||
AC_ARG_ENABLE([xinerama],
|
||||
[AS_HELP_STRING([--enable-xinerama],
|
||||
[enable Xinerama if available (default: yes)])],
|
||||
[], [enable_xinerama="yes"])
|
||||
|
||||
if test "x$enable_xinerama" = "xyes"; then
|
||||
enable_xinerama="no"
|
||||
AC_CHECK_HEADER([X11/extensions/Xinerama.h],
|
||||
[
|
||||
enable_xinerama="yes"
|
||||
S9XLIBS="$S9XLIBS -lXinerama"
|
||||
S9XDEFS="$S9XDEFS -DUSE_XINERAMA"
|
||||
])
|
||||
fi
|
||||
|
||||
# Check if we have sound code for this platform.
|
||||
|
||||
AC_ARG_ENABLE([sound],
|
||||
@ -473,6 +489,7 @@ libs................. $S9XLIBS
|
||||
|
||||
features:
|
||||
Xvideo support....... $enable_xvideo
|
||||
Xinerama support..... $enable_xinerama
|
||||
sound support........ $enable_sound
|
||||
screenshot support... $enable_screenshot
|
||||
netplay support...... $enable_netplay
|
||||
|
110
unix/x11.cpp
110
unix/x11.cpp
@ -214,6 +214,10 @@
|
||||
#define FOURCC_YUY2 0x32595559
|
||||
#endif
|
||||
|
||||
#ifdef USE_XINERAMA
|
||||
#include <X11/extensions/Xinerama.h>
|
||||
#endif
|
||||
|
||||
#ifdef MITSHM
|
||||
#include <sys/ipc.h>
|
||||
#include <sys/shm.h>
|
||||
@ -299,6 +303,9 @@ struct GUIData
|
||||
unsigned char u_table[1 << 15];
|
||||
unsigned char v_table[1 << 15];
|
||||
#endif
|
||||
#ifdef USE_XINERAMA
|
||||
uint32 xinerama_head;
|
||||
#endif
|
||||
#ifdef MITSHM
|
||||
XShmSegmentInfo sm_info;
|
||||
bool8 use_shared_memory;
|
||||
@ -363,6 +370,9 @@ void S9xExtraDisplayUsage (void)
|
||||
#ifdef USE_XVIDEO
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-xvideo Hardware accelerated scaling");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-maxaspect Try to fill the display, in fullscreen");
|
||||
#endif
|
||||
#ifdef USE_XINERAMA
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-xineramahead Xinerama head number for multi-monitor setups");
|
||||
#endif
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
||||
S9xMessage(S9X_INFO, S9X_USAGE, "-v1 Video mode: Blocky (default)");
|
||||
@ -391,6 +401,16 @@ void S9xParseDisplayArg (char **argv, int &i, int argc)
|
||||
if (!strcasecmp(argv[i], "-maxaspect"))
|
||||
GUI.maxaspect = TRUE;
|
||||
else
|
||||
#endif
|
||||
#ifdef USE_XINERAMA
|
||||
if (!strcasecmp(argv[i], "-xineramahead"))
|
||||
{
|
||||
if (i + 1 < argc)
|
||||
GUI.xinerama_head = atoi(argv[++i]);
|
||||
else
|
||||
S9xUsage();
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!strncasecmp(argv[i], "-v", 2))
|
||||
{
|
||||
@ -555,6 +575,9 @@ const char * S9xParseDisplayConfig (ConfigFile &conf, int pass)
|
||||
GUI.use_xvideo = conf.GetBool("Unix/X11::Xvideo", FALSE);
|
||||
GUI.maxaspect = conf.GetBool("Unix/X11::MaxAspect", FALSE);
|
||||
#endif
|
||||
#ifdef USE_XINERAMA
|
||||
GUI.xinerama_head = conf.GetUInt("Unix/X11::XineramaHead", 0);
|
||||
#endif
|
||||
|
||||
if (conf.Exists("Unix/X11::VideoMode"))
|
||||
{
|
||||
@ -855,13 +878,60 @@ void S9xInitDisplay (int argc, char **argv)
|
||||
attrib.background_pixel = BlackPixelOfScreen(GUI.screen);
|
||||
attrib.colormap = XCreateColormap(GUI.display, RootWindowOfScreen(GUI.screen), GUI.visual, AllocNone);
|
||||
|
||||
int screen_left = 0, screen_top = 0;
|
||||
int screen_w = WidthOfScreen(GUI.screen), screen_h = HeightOfScreen(GUI.screen);
|
||||
|
||||
#ifdef USE_XINERAMA
|
||||
int heads = 0;
|
||||
XineramaScreenInfo* si = 0;
|
||||
|
||||
int useless1, useless2;
|
||||
if (!XineramaQueryExtension(GUI.display, &useless1, &useless2)) {
|
||||
puts("Xinerama is not available");
|
||||
goto xinerama_end;
|
||||
}
|
||||
|
||||
if (!XineramaIsActive(GUI.display)) {
|
||||
puts("Xinerama is not active");
|
||||
goto xinerama_end;
|
||||
}
|
||||
|
||||
si = XineramaQueryScreens(GUI.display, &heads);
|
||||
if (!si) {
|
||||
puts("XineramaQueryScreens failed");
|
||||
goto xinerama_end;
|
||||
}
|
||||
|
||||
if (GUI.xinerama_head >= heads) {
|
||||
printf("Invalid xinerama head id (expected 0-%d, got %u)\n", heads - 1, GUI.xinerama_head);
|
||||
goto xinerama_end;
|
||||
}
|
||||
|
||||
si = &si[GUI.xinerama_head];
|
||||
screen_left = si->x_org;
|
||||
screen_top = si->y_org;
|
||||
screen_w = si->width;
|
||||
screen_h = si->height;
|
||||
|
||||
printf("Selected xinerama head %u (%d,%d %dx%d)\n", GUI.xinerama_head, screen_left, screen_top, screen_w, screen_h);
|
||||
|
||||
xinerama_end:
|
||||
#endif
|
||||
|
||||
XSizeHints Hints;
|
||||
memset((void *) &Hints, 0, sizeof(XSizeHints));
|
||||
|
||||
/* Try to switch to Fullscreen. */
|
||||
if (GUI.fullscreen == TRUE)
|
||||
{
|
||||
Hints.flags = PPosition;
|
||||
Hints.x = screen_left;
|
||||
Hints.y = screen_top;
|
||||
|
||||
/* Create the window with maximum screen width,height positioned at 0,0. */
|
||||
GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen),
|
||||
0, 0,
|
||||
WidthOfScreen(GUI.screen), HeightOfScreen(GUI.screen), 0,
|
||||
Hints.x, Hints.y,
|
||||
screen_w, screen_h, 0,
|
||||
GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib);
|
||||
|
||||
/* Try to tell the Window Manager not to decorate this window. */
|
||||
@ -874,20 +944,20 @@ void S9xInitDisplay (int argc, char **argv)
|
||||
if (GUI.use_xvideo)
|
||||
{
|
||||
// Set some defaults
|
||||
GUI.scale_w = WidthOfScreen(GUI.screen);
|
||||
GUI.scale_h = HeightOfScreen(GUI.screen);
|
||||
GUI.scale_w = screen_w;
|
||||
GUI.scale_h = screen_h;
|
||||
|
||||
GUI.imageHeight = SNES_HEIGHT_EXTENDED * 2;
|
||||
|
||||
if (! GUI.maxaspect)
|
||||
{
|
||||
// Compute the maximum screen size for scaling xvideo window.
|
||||
double screenAspect = (double)WidthOfScreen(GUI.screen) / HeightOfScreen(GUI.screen);
|
||||
double screenAspect = (double)screen_w / screen_h;
|
||||
double snesAspect = (double)SNES_WIDTH / SNES_HEIGHT_EXTENDED;
|
||||
double ratio = screenAspect / snesAspect;
|
||||
|
||||
printf("\tScreen (%dx%d) aspect %f vs SNES (%dx%d) aspect %f (ratio: %f)\n",
|
||||
WidthOfScreen(GUI.screen),HeightOfScreen(GUI.screen),screenAspect,
|
||||
screen_w,screen_h,screenAspect,
|
||||
SNES_WIDTH,SNES_HEIGHT_EXTENDED,snesAspect,
|
||||
ratio);
|
||||
|
||||
@ -897,12 +967,12 @@ void S9xInitDisplay (int argc, char **argv)
|
||||
// widescreen monitor, 4:3 snes
|
||||
// match height, scale width
|
||||
GUI.scale_w /= ratio;
|
||||
GUI.x_offset = (WidthOfScreen(GUI.screen) - GUI.scale_w) / 2;
|
||||
GUI.x_offset = (screen_w - GUI.scale_w) / 2;
|
||||
} else {
|
||||
// narrow monitor, 4:3 snes
|
||||
// match width, scale height
|
||||
GUI.scale_h *= ratio;
|
||||
GUI.y_offset = (HeightOfScreen(GUI.screen) - GUI.scale_h) / 2;
|
||||
GUI.y_offset = (screen_h - GUI.scale_h) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -912,23 +982,21 @@ void S9xInitDisplay (int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
/* Last: position the output window in the center of the screen. */
|
||||
GUI.x_offset = (WidthOfScreen(GUI.screen) - SNES_WIDTH * 2) / 2;
|
||||
GUI.y_offset = (HeightOfScreen(GUI.screen) - SNES_HEIGHT_EXTENDED * 2) / 2;
|
||||
GUI.x_offset = (screen_w - SNES_WIDTH * 2) / 2;
|
||||
GUI.y_offset = (screen_h - SNES_HEIGHT_EXTENDED * 2) / 2;
|
||||
}
|
||||
} else {
|
||||
/* Create the window. */
|
||||
GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen),
|
||||
(WidthOfScreen(GUI.screen) - SNES_WIDTH * 2) / 2, (HeightOfScreen(GUI.screen) - SNES_HEIGHT_EXTENDED * 2) / 2,
|
||||
SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, 0, GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib);
|
||||
|
||||
/* Tell the Window Manager that we do not wish to be resizable */
|
||||
XSizeHints Hints;
|
||||
memset((void *) &Hints, 0, sizeof(XSizeHints));
|
||||
|
||||
Hints.flags = PSize | PMinSize | PMaxSize;
|
||||
Hints.flags = PSize | PMinSize | PMaxSize | PPosition;
|
||||
Hints.x = screen_left + (screen_w - SNES_WIDTH * 2) / 2;
|
||||
Hints.y = screen_top + (screen_h - SNES_HEIGHT_EXTENDED * 2) / 2;
|
||||
Hints.min_width = Hints.max_width = Hints.base_width = SNES_WIDTH * 2;
|
||||
Hints.min_height = Hints.max_height = Hints.base_height = SNES_HEIGHT_EXTENDED * 2;
|
||||
XSetWMNormalHints(GUI.display, GUI.window, &Hints);
|
||||
|
||||
/* Create the window. */
|
||||
GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen),
|
||||
Hints.x, Hints.y,
|
||||
SNES_WIDTH * 2, SNES_HEIGHT_EXTENDED * 2, 0, GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib);
|
||||
|
||||
/* Last: Windowed SNES is not drawn with any offsets. */
|
||||
GUI.x_offset = GUI.y_offset = 0;
|
||||
@ -938,6 +1006,8 @@ void S9xInitDisplay (int argc, char **argv)
|
||||
#endif
|
||||
}
|
||||
|
||||
XSetWMNormalHints(GUI.display, GUI.window, &Hints);
|
||||
|
||||
/* Load UI cursors */
|
||||
static XColor bg, fg;
|
||||
static char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
Loading…
Reference in New Issue
Block a user