summaryrefslogtreecommitdiffstats
path: root/video/out/vo.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-06 20:22:32 +0200
committerwm4 <wm4@nowhere>2014-05-06 20:22:32 +0200
commitfeb1f8f18fc2bf1de81ea43d7b57e318c1bf4e69 (patch)
tree65498de7e44716f35d79bedec935e5eb79fd69c5 /video/out/vo.c
parent587f42b56c7cba07fadbb3b73032cdd186f76f5f (diff)
downloadmpv-feb1f8f18fc2bf1de81ea43d7b57e318c1bf4e69.tar.bz2
mpv-feb1f8f18fc2bf1de81ea43d7b57e318c1bf4e69.tar.xz
video/out: separate out code to compute window size
Currently, vo_reconfig() calculates the requested window size and sets the vo->dwidth/dheight fields _if_ VOCTRL_UPDATE_SCREENINFO is implemented by the VO or the windowing backend. The window size can be different from the display size if e.g. the --geometry option is used. It will also set the vo->dx/dy fields and read vo->xinerama_x/y. It turned out that this is very backwards and actually requires the windowing backends to workaround these things. There's also MPOpts.screenwidth/screenheight, which used to map to actual options, but is now used only to communicate the screen size to the vo.c code calculating the window size and position. Change this by making the window geometry calculations available as separate functions. This commit doesn't change any VO code yet, and just emulates the old way using the new functions. VO code will remove its usage of VOCTRL_UPDATE_SCREENINFO and use the new functions directly.
Diffstat (limited to 'video/out/vo.c')
-rw-r--r--video/out/vo.c103
1 files changed, 18 insertions, 85 deletions
diff --git a/video/out/vo.c b/video/out/vo.c
index 43e5d08fa2..dd65552ec0 100644
--- a/video/out/vo.c
+++ b/video/out/vo.c
@@ -36,6 +36,7 @@
#include "bstr/bstr.h"
#include "vo.h"
#include "aspect.h"
+#include "win_state.h"
#include "input/input.h"
#include "options/m_config.h"
#include "common/msg.h"
@@ -234,78 +235,6 @@ void vo_destroy(struct vo *vo)
talloc_free(vo);
}
-static void calc_monitor_aspect(struct mp_vo_opts *opts, int scr_w, int scr_h,
- float *pixelaspect, int *w, int *h)
-{
- *pixelaspect = 1.0 / opts->monitor_pixel_aspect;
-
- if (scr_w > 0 && scr_h > 0 && opts->force_monitor_aspect)
- *pixelaspect = opts->force_monitor_aspect * scr_h / scr_w;
-
- if (*pixelaspect < 1) {
- *h /= *pixelaspect;
- } else {
- *w *= *pixelaspect;
- }
-}
-
-// Fit *w/*h into the size specified by geo.
-static void apply_autofit(int *w, int *h, int scr_w, int scr_h,
- struct m_geometry *geo, bool allow_upscale)
-{
- if (!geo->wh_valid)
- return;
-
- int dummy;
- int n_w = *w, n_h = *h;
- m_geometry_apply(&dummy, &dummy, &n_w, &n_h, scr_w, scr_h, geo);
-
- if (!allow_upscale && *w <= n_w && *h <= n_h)
- return;
-
- // If aspect mismatches, always make the window smaller than the fit box
- double asp = (double)*w / *h;
- double n_asp = (double)n_w / n_h;
- if (n_asp <= asp) {
- *w = n_w;
- *h = n_w / asp;
- } else {
- *w = n_h * asp;
- *h = n_h;
- }
-}
-
-// Set window size (vo->dwidth/dheight) and position (vo->dx/dy) according to
-// the video display size d_w/d_h.
-// NOTE: currently, all GUI backends do their own handling of window geometry
-// additional to this code. This is to deal with initial window placement,
-// fullscreen handling, avoiding resize on config() with no size change,
-// multi-monitor stuff, and possibly more.
-static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
-{
- struct mp_vo_opts *opts = vo->opts;
-
- int scr_w = opts->screenwidth;
- int scr_h = opts->screenheight;
-
- MP_DBG(vo, "screen size: %dx%d\n", scr_w, scr_h);
-
- calc_monitor_aspect(opts, scr_w, scr_h, &vo->monitor_par, &d_w, &d_h);
-
- apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit, true);
- apply_autofit(&d_w, &d_h, scr_w, scr_h, &opts->autofit_larger, false);
-
- vo->dx = (int)(opts->screenwidth - d_w) / 2;
- vo->dy = (int)(opts->screenheight - d_h) / 2;
- m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h, scr_w, scr_h,
- &opts->geometry);
-
- vo->dx += vo->xinerama_x;
- vo->dy += vo->xinerama_y;
- vo->dwidth = d_w;
- vo->dheight = d_h;
-}
-
static void check_vo_caps(struct vo *vo)
{
int rot = vo->params->rotate;
@@ -320,23 +249,27 @@ static void check_vo_caps(struct vo *vo)
int vo_reconfig(struct vo *vo, struct mp_image_params *params, int flags)
{
- int d_width = params->d_w;
- int d_height = params->d_h;
-
- if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
- int w = params->d_w, h = params->d_h;
- if ((vo->driver->caps & VO_CAP_ROTATE90) && params->rotate % 180 == 90)
- MPSWAP(int, w, h);
- determine_window_geometry(vo, w, h);
- d_width = vo->dwidth;
- d_height = vo->dheight;
- }
- vo->dwidth = d_width;
- vo->dheight = d_height;
+ vo->dwidth = params->d_w;
+ vo->dheight = params->d_h;
talloc_free(vo->params);
vo->params = talloc_memdup(vo, params, sizeof(*params));
+ // Emulate the old way of calculating the window geometry settings.
+ if (vo_control(vo, VOCTRL_UPDATE_SCREENINFO, NULL) == VO_TRUE) {
+ struct mp_rect rc = {
+ vo->xinerama_x,
+ vo->xinerama_y,
+ vo->xinerama_x + vo->opts->screenwidth,
+ vo->xinerama_y + vo->opts->screenheight,
+ };
+ struct vo_win_geometry geo;
+ vo_calc_window_geometry(vo, &rc, &geo);
+ vo_apply_window_geometry(vo, &geo);
+ vo->dx = geo.win.x0;
+ vo->dy = geo.win.y0;
+ }
+
int ret = vo->driver->reconfig(vo, vo->params, flags);
vo->config_ok = ret >= 0;
if (vo->config_ok) {