summaryrefslogtreecommitdiffstats
path: root/video
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 /video
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.
Diffstat (limited to 'video')
-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
5 files changed, 77 insertions, 47 deletions
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;