summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-02-17 16:35:44 +0100
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2013-02-21 22:23:08 +0100
commite540e5d4da607420cc10f4c2b412aa0ff3d1fb5c (patch)
tree1355bc1cfbce42f775d12ac95f664acb7eb37f86
parent41c1749f46e0e36af39be2487ee992cbf18e6679 (diff)
downloadmpv-e540e5d4da607420cc10f4c2b412aa0ff3d1fb5c.tar.bz2
mpv-e540e5d4da607420cc10f4c2b412aa0ff3d1fb5c.tar.xz
core: add fs-screen option for fullscreen display selection
`--fs-screen` allows to decide what display to go fullscreen into. The semantics of `--screen` changed and now it is only used to select the windowed display when starting the application. This is useful for people using mpv with an external TV. They will start windowed on their laptop's screen and switch to fullscreen on the TV. @wm4 worked on the x11 and w32 parts of the code. All is squashed in one commit for history clarity.
-rw-r--r--DOCS/man/en/options.rst41
-rw-r--r--core/cfg-mplayer.h3
-rw-r--r--core/defaultopts.c1
-rw-r--r--core/options.h1
-rw-r--r--video/out/cocoa_common.m45
-rw-r--r--video/out/w32_common.c11
-rw-r--r--video/out/w32_common.h1
-rw-r--r--video/out/x11_common.c65
-rw-r--r--video/out/x11_common.h2
9 files changed, 111 insertions, 59 deletions
diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst
index 14548f807c..fcab7ae8e0 100644
--- a/DOCS/man/en/options.rst
+++ b/DOCS/man/en/options.rst
@@ -649,6 +649,21 @@
--fullscreen, --fs
Fullscreen playback (centers movie, and paints black bands around it).
+
+--fs-screen=<all|current|0-32>
+ In multi-monitor configurations (i.e. a single desktop that spans across
+ multiple displays) this option tells mpv which screen to go fullscreen to.
+ If ``default`` is provided mpv will fallback to using the behaviour
+ depending on what the user provided with the ``screen`` option.
+
+ *NOTE (X11)*: this option does not work properly with all window managers.
+ ``all`` in particular will usually only work with ``--fstype=-fullscreen``
+ or ``--fstype=none``, and even then only with some window managers.
+
+ *NOTE (OSX)*: ``all`` doesn't work on OSX and will behave like ``current``.
+
+ See also ``--screen``.
+
--fsmode-dontuse=<0-31>
OBSOLETE, use the ``--fs`` option.
Try this option if you still experience fullscreen problems.
@@ -734,6 +749,8 @@
located on the the bottom-left corner. For instance, ``0:0`` will place the
window at the bottom-left of the screen.
+ *NOTE (X11)*: this option does not work properly with all window managers.
+
*EXAMPLE*:
``50:40``
@@ -1710,6 +1727,18 @@
Seek to byte position. Useful for playback from CD-ROM images or VOB files
with junk at the beginning. See also ``--start``.
+--screen=<default|0-32>
+ In multi-monitor configurations (i.e. a single desktop that spans across
+ multiple displays) this option tells mpv which screen to display the
+ movie on.
+
+ This option doesn't always work. In these cases, try to use ``--geometry``
+ to position the window explicitly.
+
+ *NOTE (X11)*: this option does not work properly with all window managers.
+
+ See also ``--fs-screen``.
+
--screenshot-format=<type>
Set the image file type used for saving screenshots.
@@ -2327,15 +2356,3 @@
--wid=<ID>
(X11 and win32 only)
This tells mpv to attach to an existing window.See ``--slave-broken``.
-
---screen=<all|current|0-32>
- In multi-monitor configurations (i.e. a single desktop that spans across
- multiple displays) this option tells mpv which screen to display the
- movie on. A value of ``all`` means fullscreen across the whole virtual display
- (in this case system provided information is completely ignored), ``current`` means
- fullscreen on the display the window currently is on. The initial position
- set via the ``--geometry`` option is relative to the specified screen.
- Will usually only work with ``--fstype=-fullscreen`` or ``--fstype=none``.
- This option is not suitable to only set the startup screen (because it
- will always display on the given screen in fullscreen mode),
- ``--geometry`` is the best that is available for that purpose currently.
diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h
index 23c4bedee8..3a79702959 100644
--- a/core/cfg-mplayer.h
+++ b/core/cfg-mplayer.h
@@ -613,6 +613,9 @@ const m_option_t mplayer_opts[]={
{"mouseinput", &vo_nomouse_input, CONF_TYPE_FLAG, 0, 1, 0, NULL},
OPT_CHOICE_OR_INT("screen", vo_screen_id, 0, 0, 32,
+ ({"default", -1})),
+
+ OPT_CHOICE_OR_INT("fs-screen", vo_fsscreen_id, 0, 0, 32,
({"all", -2}, {"current", -1})),
OPT_INTRANGE("brightness", vo_gamma_brightness, 0, -100, 100),
diff --git a/core/defaultopts.c b/core/defaultopts.c
index b6e7f28524..a3c315b186 100644
--- a/core/defaultopts.c
+++ b/core/defaultopts.c
@@ -23,6 +23,7 @@ void set_default_mplayer_options(struct MPOpts *opts)
.vo_panscanrange = 1.0,
.cursor_autohide_delay = 1000,
.vo_screen_id = -1,
+ .vo_fsscreen_id = -1,
.vo_gamma_gamma = 1000,
.vo_gamma_brightness = 1000,
.vo_gamma_contrast = 1000,
diff --git a/core/options.h b/core/options.h
index 8e64c07723..254af2e241 100644
--- a/core/options.h
+++ b/core/options.h
@@ -19,6 +19,7 @@ typedef struct MPOpts {
int vo_screenwidth;
int vo_screenheight;
int vo_screen_id;
+ int vo_fsscreen_id;
struct m_geometry vo_geometry;
struct m_geometry vo_autofit;
struct m_geometry vo_autofit_larger;
diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m
index 77b9d0c96f..4f61ffe29e 100644
--- a/video/out/cocoa_common.m
+++ b/video/out/cocoa_common.m
@@ -108,8 +108,8 @@ struct vo_cocoa_state {
NSSize previous_video_size;
NSRect screen_frame;
+ NSRect fsscreen_frame;
NSScreen *screen_handle;
- NSArray *screen_array;
NSInteger windowed_mask;
NSInteger fullscreen_mask;
@@ -253,26 +253,39 @@ static int current_screen_has_dock_or_menubar(struct vo *vo)
return f.size.height > vf.size.height || f.size.width > vf.size.width;
}
+static int get_screen_handle(int identifier, NSWindow *window, NSScreen **screen) {
+ NSArray *screens = [NSScreen screens];
+ int n_of_displays = [screens count];
+
+ if (identifier >= n_of_displays) { // check if the identifier is out of bounds
+ mp_msg(MSGT_VO, MSGL_INFO, "[cocoa] Screen ID %d does not exist, "
+ "falling back to main device\n", identifier);
+ identifier = -1;
+ }
+
+ if (identifier < 0) {
+ // default behaviour gets either the window screen or the main screen
+ // if window is not available
+ if (! (*screen = [window screen]) )
+ *screen = [screens objectAtIndex:0];
+ return 0;
+ } else {
+ *screen = [screens objectAtIndex:(identifier)];
+ return 1;
+ }
+}
+
static void update_screen_info(struct vo *vo)
{
struct vo_cocoa_state *s = vo->cocoa;
struct MPOpts *opts = vo->opts;
- int screen_id = opts->vo_screen_id;
- s->screen_array = [NSScreen screens];
- if (screen_id >= (int)[s->screen_array count]) {
- mp_msg(MSGT_VO, MSGL_INFO, "[cocoa] Device ID %d does not exist, "
- "falling back to main device\n", screen_id);
- screen_id = -1;
- }
+ NSScreen *ws, *fss;
- if (screen_id < 0) { // default behaviour
- if (! (s->screen_handle = [s->window screen]) )
- s->screen_handle = [s->screen_array objectAtIndex:0];
- } else {
- s->screen_handle = [s->screen_array objectAtIndex:(screen_id)];
- }
+ get_screen_handle(opts->vo_screen_id, s->window, &ws);
+ s->screen_frame = [ws frame];
- s->screen_frame = [s->screen_handle frame];
+ get_screen_handle(opts->vo_fsscreen_id, s->window, &fss);
+ s->fsscreen_frame = [fss frame];
}
void vo_cocoa_update_xinerama_info(struct vo *vo)
@@ -642,7 +655,7 @@ void create_menu()
s->windowed_frame = [self frame];
[self setHasShadow:NO];
[self setStyleMask:s->fullscreen_mask];
- [self setFrame:s->screen_frame display:YES animate:NO];
+ [self setFrame:s->fsscreen_frame display:YES animate:NO];
vo_fs = VO_TRUE;
vo_cocoa_display_cursor(_vo, 0);
[self setMovableByWindowBackground: NO];
diff --git a/video/out/w32_common.c b/video/out/w32_common.c
index 6b92066860..54620bdec6 100644
--- a/video/out/w32_common.c
+++ b/video/out/w32_common.c
@@ -312,13 +312,12 @@ static BOOL CALLBACK mon_enum(HMONITOR hmon, HDC hdc, LPRECT r, LPARAM p)
{
struct vo *vo = (void*)p;
struct vo_w32_state *w32 = vo->w32;
- struct MPOpts *opts = vo->opts;
// this defaults to the last screen if specified number does not exist
xinerama_x = r->left;
xinerama_y = r->top;
vo->opts->vo_screenwidth = r->right - r->left;
vo->opts->vo_screenheight = r->bottom - r->top;
- if (w32->mon_cnt == opts->vo_screen_id)
+ if (w32->mon_cnt == w32->mon_id)
return FALSE;
w32->mon_cnt++;
return TRUE;
@@ -342,8 +341,9 @@ void w32_update_xinerama_info(struct vo *vo)
{
struct vo_w32_state *w32 = vo->w32;
struct MPOpts *opts = vo->opts;
+ int screen = vo_fs ? opts->vo_fsscreen_id : opts->vo_screen_id;
xinerama_x = xinerama_y = 0;
- if (opts->vo_screen_id < -1) {
+ if (vo_fs && screen == -2) {
int tmp;
xinerama_x = GetSystemMetrics(SM_XVIRTUALSCREEN);
xinerama_y = GetSystemMetrics(SM_YVIRTUALSCREEN);
@@ -351,7 +351,7 @@ void w32_update_xinerama_info(struct vo *vo)
if (tmp) vo->opts->vo_screenwidth = tmp;
tmp = GetSystemMetrics(SM_CYVIRTUALSCREEN);
if (tmp) vo->opts->vo_screenheight = tmp;
- } else if (opts->vo_screen_id == -1) {
+ } else if (screen == -1) {
MONITORINFO mi;
HMONITOR m = MonitorFromWindow(w32->window, MONITOR_DEFAULTTOPRIMARY);
mi.cbSize = sizeof(mi);
@@ -360,8 +360,9 @@ void w32_update_xinerama_info(struct vo *vo)
xinerama_y = mi.rcMonitor.top;
vo->opts->vo_screenwidth = mi.rcMonitor.right - mi.rcMonitor.left;
vo->opts->vo_screenheight = mi.rcMonitor.bottom - mi.rcMonitor.top;
- } else if (opts->vo_screen_id > 0) {
+ } else if (screen >= 0) {
w32->mon_cnt = 0;
+ w32->mon_id = screen;
EnumDisplayMonitors(NULL, NULL, mon_enum, (LONG_PTR)vo);
}
aspect_save_screenres(vo, vo->opts->vo_screenwidth,
diff --git a/video/out/w32_common.h b/video/out/w32_common.h
index cd74ae17ac..57997dd67b 100644
--- a/video/out/w32_common.h
+++ b/video/out/w32_common.h
@@ -50,6 +50,7 @@ struct vo_w32_state {
int event_flags;
int mon_cnt;
+ int mon_id;
};
int vo_w32_init(struct vo *vo);
diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index a3bf5c10cf..a78ca11402 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -374,10 +374,17 @@ static void init_atoms(struct vo_x11_state *x11)
void vo_x11_update_screeninfo(struct vo *vo)
{
struct MPOpts *opts = vo->opts;
+ bool all_screens = vo_fs && opts->vo_fsscreen_id == -2;
xinerama_x = xinerama_y = 0;
+ if (all_screens) {
+ opts->vo_screenwidth = vo->x11->ws_width;
+ opts->vo_screenheight = vo->x11->ws_height;
+ }
#ifdef CONFIG_XINERAMA
- if (opts->vo_screen_id >= -1 && XineramaIsActive(vo->x11->display)) {
- int screen = opts->vo_screen_id;
+ if (opts->vo_screen_id >= -1 && XineramaIsActive(vo->x11->display) &&
+ !all_screens)
+ {
+ int screen = vo_fs ? opts->vo_fsscreen_id : opts->vo_screen_id;
XineramaScreenInfo *screens;
int num_screens;
@@ -450,23 +457,16 @@ int vo_x11_init(struct vo *vo)
init_atoms(vo->x11);
-#ifdef CONFIG_XF86VM
- {
- int clock;
- XF86VidModeModeLine modeline;
-
- XF86VidModeGetModeLine(x11->display, x11->screen, &clock, &modeline);
- if (!opts->vo_screenwidth)
- opts->vo_screenwidth = modeline.hdisplay;
- if (!opts->vo_screenheight)
- opts->vo_screenheight = modeline.vdisplay;
- }
-#endif
+ x11->ws_width = opts->vo_screenwidth;
+ x11->ws_height = opts->vo_screenheight;
+
+ if (!x11->ws_width)
+ x11->ws_width = DisplayWidth(x11->display, x11->screen);
+ if (!x11->ws_height)
+ x11->ws_height = DisplayHeight(x11->display, x11->screen);
- if (!opts->vo_screenwidth)
- opts->vo_screenwidth = DisplayWidth(x11->display, x11->screen);
- if (!opts->vo_screenheight)
- opts->vo_screenheight = DisplayHeight(x11->display, x11->screen);
+ opts->vo_screenwidth = x11->ws_width;
+ opts->vo_screenheight = x11->ws_height;
if (strncmp(dispName, "unix:", 5) == 0)
dispName += 4;
@@ -1297,6 +1297,10 @@ void vo_x11_fullscreen(struct vo *vo)
if (vo_fs) {
vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_REMOVE); // removes fullscreen state if wm supports EWMH
+ if ((x11->fs_type & vo_wm_FULLSCREEN) && opts->vo_fsscreen_id != -1) {
+ XMoveResizeWindow(x11->display, x11->window, x, y, w, h);
+ vo_x11_sizehint(vo, x, y, w, h, 0);
+ }
vo_fs = VO_FALSE;
if (x11->size_changed_during_fs && (x11->fs_type & vo_wm_FULLSCREEN)) {
vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, x11->last_video_width,
@@ -1305,20 +1309,29 @@ void vo_x11_fullscreen(struct vo *vo)
x11->size_changed_during_fs = false;
} else {
// win->fs
- vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH
-
vo_fs = VO_TRUE;
- if (!(x11->fs_type & vo_wm_FULLSCREEN)) { // not needed with EWMH fs
- x11->vo_old_x = vo->dx;
- x11->vo_old_y = vo->dy;
- x11->vo_old_width = vo->dwidth;
- x11->vo_old_height = vo->dheight;
- }
+
+ x11->vo_old_x = vo->dx;
+ x11->vo_old_y = vo->dy;
+ x11->vo_old_width = vo->dwidth;
+ x11->vo_old_height = vo->dheight;
+
vo_x11_update_screeninfo(vo);
+
x = xinerama_x;
y = xinerama_y;
w = opts->vo_screenwidth;
h = opts->vo_screenheight;
+
+ if ((x11->fs_type & vo_wm_FULLSCREEN) && opts->vo_fsscreen_id != -1) {
+ // The EWMH fullscreen hint always works on the current screen, so
+ // change the current screen forcibly.
+ // This was observed to work under IceWM, but not Unity/Compiz and
+ // awesome (but --screen etc. doesn't really work on these either).
+ XMoveResizeWindow(x11->display, x11->window, x, y, w, h);
+ }
+
+ vo_x11_ewmh_fullscreen(x11, _NET_WM_STATE_ADD); // sends fullscreen state to be added if wm supports EWMH
}
{
long dummy;
diff --git a/video/out/x11_common.h b/video/out/x11_common.h
index d638d6b15f..5553c070f5 100644
--- a/video/out/x11_common.h
+++ b/video/out/x11_common.h
@@ -34,6 +34,8 @@ struct vo_x11_state {
Window rootwin;
int screen;
int display_is_local;
+ int ws_width;
+ int ws_height;
int screensaver_off;
int dpms_disabled;