mirror of https://github.com/snes9xgit/snes9x.git
add xinerama multi-monitor support and position window hints
This commit is contained in:
parent
1188fa2a1e
commit
81694ae8f9
|
@ -719,6 +719,7 @@ enable_jma
|
||||||
enable_screenshot
|
enable_screenshot
|
||||||
with_x
|
with_x
|
||||||
enable_xvideo
|
enable_xvideo
|
||||||
|
enable_xinerama
|
||||||
enable_sound
|
enable_sound
|
||||||
'
|
'
|
||||||
ac_precious_vars='build_alias
|
ac_precious_vars='build_alias
|
||||||
|
@ -1370,6 +1371,7 @@ Optional Features:
|
||||||
--enable-screenshot enable screenshot support through libpng (default:
|
--enable-screenshot enable screenshot support through libpng (default:
|
||||||
yes)
|
yes)
|
||||||
--enable-xvideo enable Xvideo if available (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)
|
--enable-sound enable sound if available (default: yes)
|
||||||
|
|
||||||
Optional Packages:
|
Optional Packages:
|
||||||
|
@ -6265,6 +6267,29 @@ if test "x$ac_cv_header_X11_extensions_Xv_h" = xyes; then :
|
||||||
fi
|
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
|
fi
|
||||||
|
|
||||||
# Check if we have sound code for this platform.
|
# Check if we have sound code for this platform.
|
||||||
|
@ -6343,6 +6368,7 @@ libs................. $S9XLIBS
|
||||||
|
|
||||||
features:
|
features:
|
||||||
Xvideo support....... $enable_xvideo
|
Xvideo support....... $enable_xvideo
|
||||||
|
Xinerama support..... $enable_xinerama
|
||||||
sound support........ $enable_sound
|
sound support........ $enable_sound
|
||||||
screenshot support... $enable_screenshot
|
screenshot support... $enable_screenshot
|
||||||
netplay support...... $enable_netplay
|
netplay support...... $enable_netplay
|
||||||
|
|
|
@ -418,6 +418,22 @@ if test "x$enable_xvideo" = "xyes"; then
|
||||||
])
|
])
|
||||||
fi
|
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.
|
# Check if we have sound code for this platform.
|
||||||
|
|
||||||
AC_ARG_ENABLE([sound],
|
AC_ARG_ENABLE([sound],
|
||||||
|
@ -483,6 +499,7 @@ libs................. $S9XLIBS
|
||||||
|
|
||||||
features:
|
features:
|
||||||
Xvideo support....... $enable_xvideo
|
Xvideo support....... $enable_xvideo
|
||||||
|
Xinerama support..... $enable_xinerama
|
||||||
sound support........ $enable_sound
|
sound support........ $enable_sound
|
||||||
screenshot support... $enable_screenshot
|
screenshot support... $enable_screenshot
|
||||||
netplay support...... $enable_netplay
|
netplay support...... $enable_netplay
|
||||||
|
|
110
unix/x11.cpp
110
unix/x11.cpp
|
@ -212,6 +212,10 @@
|
||||||
#define FOURCC_YUY2 0x32595559
|
#define FOURCC_YUY2 0x32595559
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_XINERAMA
|
||||||
|
#include <X11/extensions/Xinerama.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef MITSHM
|
#ifdef MITSHM
|
||||||
#include <sys/ipc.h>
|
#include <sys/ipc.h>
|
||||||
#include <sys/shm.h>
|
#include <sys/shm.h>
|
||||||
|
@ -297,6 +301,9 @@ struct GUIData
|
||||||
unsigned char u_table[1 << 15];
|
unsigned char u_table[1 << 15];
|
||||||
unsigned char v_table[1 << 15];
|
unsigned char v_table[1 << 15];
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_XINERAMA
|
||||||
|
uint32 xinerama_head;
|
||||||
|
#endif
|
||||||
#ifdef MITSHM
|
#ifdef MITSHM
|
||||||
XShmSegmentInfo sm_info;
|
XShmSegmentInfo sm_info;
|
||||||
bool8 use_shared_memory;
|
bool8 use_shared_memory;
|
||||||
|
@ -361,6 +368,9 @@ void S9xExtraDisplayUsage (void)
|
||||||
#ifdef USE_XVIDEO
|
#ifdef USE_XVIDEO
|
||||||
S9xMessage(S9X_INFO, S9X_USAGE, "-xvideo Hardware accelerated scaling");
|
S9xMessage(S9X_INFO, S9X_USAGE, "-xvideo Hardware accelerated scaling");
|
||||||
S9xMessage(S9X_INFO, S9X_USAGE, "-maxaspect Try to fill the display, in fullscreen");
|
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
|
#endif
|
||||||
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
S9xMessage(S9X_INFO, S9X_USAGE, "");
|
||||||
S9xMessage(S9X_INFO, S9X_USAGE, "-v1 Video mode: Blocky (default)");
|
S9xMessage(S9X_INFO, S9X_USAGE, "-v1 Video mode: Blocky (default)");
|
||||||
|
@ -389,6 +399,16 @@ void S9xParseDisplayArg (char **argv, int &i, int argc)
|
||||||
if (!strcasecmp(argv[i], "-maxaspect"))
|
if (!strcasecmp(argv[i], "-maxaspect"))
|
||||||
GUI.maxaspect = TRUE;
|
GUI.maxaspect = TRUE;
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
|
#ifdef USE_XINERAMA
|
||||||
|
if (!strcasecmp(argv[i], "-xineramahead"))
|
||||||
|
{
|
||||||
|
if (i + 1 < argc)
|
||||||
|
GUI.xinerama_head = atoi(argv[++i]);
|
||||||
|
else
|
||||||
|
S9xUsage();
|
||||||
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
if (!strncasecmp(argv[i], "-v", 2))
|
if (!strncasecmp(argv[i], "-v", 2))
|
||||||
{
|
{
|
||||||
|
@ -553,6 +573,9 @@ const char * S9xParseDisplayConfig (ConfigFile &conf, int pass)
|
||||||
GUI.use_xvideo = conf.GetBool("Unix/X11::Xvideo", FALSE);
|
GUI.use_xvideo = conf.GetBool("Unix/X11::Xvideo", FALSE);
|
||||||
GUI.maxaspect = conf.GetBool("Unix/X11::MaxAspect", FALSE);
|
GUI.maxaspect = conf.GetBool("Unix/X11::MaxAspect", FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_XINERAMA
|
||||||
|
GUI.xinerama_head = conf.GetUInt("Unix/X11::XineramaHead", 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (conf.Exists("Unix/X11::VideoMode"))
|
if (conf.Exists("Unix/X11::VideoMode"))
|
||||||
{
|
{
|
||||||
|
@ -853,33 +876,80 @@ void S9xInitDisplay (int argc, char **argv)
|
||||||
attrib.background_pixel = BlackPixelOfScreen(GUI.screen);
|
attrib.background_pixel = BlackPixelOfScreen(GUI.screen);
|
||||||
attrib.colormap = XCreateColormap(GUI.display, RootWindowOfScreen(GUI.screen), GUI.visual, AllocNone);
|
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. */
|
/* Try to switch to Fullscreen. */
|
||||||
if (GUI.fullscreen == TRUE)
|
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. */
|
/* Create the window with maximum screen width,height positioned at 0,0. */
|
||||||
GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen),
|
GUI.window = XCreateWindow(GUI.display, RootWindowOfScreen(GUI.screen),
|
||||||
0, 0,
|
Hints.x, Hints.y,
|
||||||
WidthOfScreen(GUI.screen), HeightOfScreen(GUI.screen), 0,
|
screen_w, screen_h, 0,
|
||||||
GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib);
|
GUI.depth, InputOutput, GUI.visual, CWBackPixel | CWColormap, &attrib);
|
||||||
|
|
||||||
#ifdef USE_XVIDEO
|
#ifdef USE_XVIDEO
|
||||||
if (GUI.use_xvideo)
|
if (GUI.use_xvideo)
|
||||||
{
|
{
|
||||||
// Set some defaults
|
// Set some defaults
|
||||||
GUI.scale_w = WidthOfScreen(GUI.screen);
|
GUI.scale_w = screen_w;
|
||||||
GUI.scale_h = HeightOfScreen(GUI.screen);
|
GUI.scale_h = screen_h;
|
||||||
|
|
||||||
GUI.imageHeight = SNES_HEIGHT_EXTENDED * 2;
|
GUI.imageHeight = SNES_HEIGHT_EXTENDED * 2;
|
||||||
|
|
||||||
if (! GUI.maxaspect)
|
if (! GUI.maxaspect)
|
||||||
{
|
{
|
||||||
// Compute the maximum screen size for scaling xvideo window.
|
// 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 snesAspect = (double)SNES_WIDTH / SNES_HEIGHT_EXTENDED;
|
||||||
double ratio = screenAspect / snesAspect;
|
double ratio = screenAspect / snesAspect;
|
||||||
|
|
||||||
printf("\tScreen (%dx%d) aspect %f vs SNES (%dx%d) aspect %f (ratio: %f)\n",
|
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,
|
SNES_WIDTH,SNES_HEIGHT_EXTENDED,snesAspect,
|
||||||
ratio);
|
ratio);
|
||||||
|
|
||||||
|
@ -889,12 +959,12 @@ void S9xInitDisplay (int argc, char **argv)
|
||||||
// widescreen monitor, 4:3 snes
|
// widescreen monitor, 4:3 snes
|
||||||
// match height, scale width
|
// match height, scale width
|
||||||
GUI.scale_w /= ratio;
|
GUI.scale_w /= ratio;
|
||||||
GUI.x_offset = (WidthOfScreen(GUI.screen) - GUI.scale_w) / 2;
|
GUI.x_offset = (screen_w - GUI.scale_w) / 2;
|
||||||
} else {
|
} else {
|
||||||
// narrow monitor, 4:3 snes
|
// narrow monitor, 4:3 snes
|
||||||
// match width, scale height
|
// match width, scale height
|
||||||
GUI.scale_h *= ratio;
|
GUI.scale_h *= ratio;
|
||||||
GUI.y_offset = (HeightOfScreen(GUI.screen) - GUI.scale_h) / 2;
|
GUI.y_offset = (screen_h - GUI.scale_h) / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -904,23 +974,21 @@ void S9xInitDisplay (int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
/* Last: position the output window in the center of the screen. */
|
/* Last: position the output window in the center of the screen. */
|
||||||
GUI.x_offset = (WidthOfScreen(GUI.screen) - SNES_WIDTH * 2) / 2;
|
GUI.x_offset = (screen_w - SNES_WIDTH * 2) / 2;
|
||||||
GUI.y_offset = (HeightOfScreen(GUI.screen) - SNES_HEIGHT_EXTENDED * 2) / 2;
|
GUI.y_offset = (screen_h - SNES_HEIGHT_EXTENDED * 2) / 2;
|
||||||
}
|
}
|
||||||
} else {
|
} 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 */
|
/* Tell the Window Manager that we do not wish to be resizable */
|
||||||
XSizeHints Hints;
|
Hints.flags = PSize | PMinSize | PMaxSize | PPosition;
|
||||||
memset((void *) &Hints, 0, sizeof(XSizeHints));
|
Hints.x = screen_left + (screen_w - SNES_WIDTH * 2) / 2;
|
||||||
|
Hints.y = screen_top + (screen_h - SNES_HEIGHT_EXTENDED * 2) / 2;
|
||||||
Hints.flags = PSize | PMinSize | PMaxSize;
|
|
||||||
Hints.min_width = Hints.max_width = Hints.base_width = SNES_WIDTH * 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;
|
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. */
|
/* Last: Windowed SNES is not drawn with any offsets. */
|
||||||
GUI.x_offset = GUI.y_offset = 0;
|
GUI.x_offset = GUI.y_offset = 0;
|
||||||
|
@ -930,6 +998,8 @@ void S9xInitDisplay (int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XSetWMNormalHints(GUI.display, GUI.window, &Hints);
|
||||||
|
|
||||||
/* Load UI cursors */
|
/* Load UI cursors */
|
||||||
static XColor bg, fg;
|
static XColor bg, fg;
|
||||||
static char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
static char data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||||
|
|
Loading…
Reference in New Issue