mirror of
https://github.com/mpv-player/mpv
synced 2025-01-24 19:37:30 +01:00
options: move -geometry parsing to m_option.c
This also means the option is verified on program start, not when the VO is created. The actual code becomes a bit more complex, because the screen width/height is not available at program start. The actual parsing code is still the same, with its unusual sscanf() usage.
This commit is contained in:
parent
f2dcdca0c2
commit
4c56baba40
1
Makefile
1
Makefile
@ -266,7 +266,6 @@ SOURCES = talloc.c \
|
||||
video/out/bitmap_packer.c \
|
||||
video/out/aspect.c \
|
||||
video/out/filter_kernels.c \
|
||||
video/out/geometry.c \
|
||||
video/out/vo.c \
|
||||
video/out/vo_null.c \
|
||||
video/out/vo_image.c \
|
||||
|
@ -37,7 +37,6 @@
|
||||
extern char *lirc_configfile;
|
||||
|
||||
/* only used at startup (setting these values from configfile) */
|
||||
extern char *vo_geometry;
|
||||
extern int stop_xscreensaver;
|
||||
|
||||
extern int mp_msg_color;
|
||||
@ -586,8 +585,7 @@ const m_option_t mplayer_opts[]={
|
||||
// set screen dimensions (when not detectable or virtual!=visible)
|
||||
OPT_INTRANGE("screenw", vo_screenwidth, CONF_GLOBAL, 0, 4096),
|
||||
OPT_INTRANGE("screenh", vo_screenheight, CONF_GLOBAL, 0, 4096),
|
||||
// Geometry string
|
||||
{"geometry", &vo_geometry, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
OPT_GEOMETRY("geometry", vo_geometry, 0),
|
||||
OPT_MAKE_FLAGS("force-window-position", force_window_position, 0),
|
||||
// vo name (X classname) and window title strings
|
||||
OPT_STRING("name", vo_winname, 0),
|
||||
|
128
core/m_option.c
128
core/m_option.c
@ -1165,6 +1165,134 @@ const m_option_type_t m_option_type_color = {
|
||||
.parse = parse_color,
|
||||
};
|
||||
|
||||
|
||||
|
||||
static bool parse_geometry_str(struct m_geometry *gm, char *s)
|
||||
{
|
||||
if (s == NULL)
|
||||
return true;
|
||||
char xsign[2], ysign[2], dummy[2];
|
||||
int width, height, xoff, yoff, xper, yper;
|
||||
int ok = 0;
|
||||
for (int i = 0; !ok && i < 9; i++) {
|
||||
width = height = xoff = yoff = xper = yper = INT_MIN;
|
||||
strcpy(xsign, "+");
|
||||
strcpy(ysign, "+");
|
||||
switch (i) {
|
||||
case 0:
|
||||
ok = sscanf(s, "%ix%i%1[+-]%i%1[+-]%i%c",
|
||||
&width, &height, xsign, &xoff, ysign,
|
||||
&yoff, dummy) == 6;
|
||||
break;
|
||||
case 1:
|
||||
ok = sscanf(s, "%ix%i%c", &width, &height, dummy) == 2;
|
||||
break;
|
||||
case 2:
|
||||
ok = sscanf(s, "%1[+-]%i%1[+-]%i%c",
|
||||
xsign, &xoff, ysign, &yoff, dummy) == 4;
|
||||
break;
|
||||
case 3:
|
||||
ok = sscanf(s, "%i%%:%i%1[%]%c", &xper, &yper, dummy, dummy) == 3;
|
||||
break;
|
||||
case 4:
|
||||
ok = sscanf(s, "%i:%i%1[%]%c", &xoff, &yper, dummy, dummy) == 3;
|
||||
break;
|
||||
case 5:
|
||||
ok = sscanf(s, "%i%%:%i%c", &xper, &yoff, dummy) == 2;
|
||||
break;
|
||||
case 6:
|
||||
ok = sscanf(s, "%i:%i%c", &xoff, &yoff, dummy) == 2;
|
||||
break;
|
||||
case 7:
|
||||
ok = sscanf(s, "%i%1[%]%c", &xper, dummy, dummy) == 2;
|
||||
break;
|
||||
case 8:
|
||||
ok = sscanf(s, "%i%c", &xoff, dummy) == 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
gm->x_per = xper >= 0 && xper <= 100;
|
||||
gm->x = gm->x_per ? xper : xoff;
|
||||
gm->x_sign = xsign[0] == '-';
|
||||
gm->y_per = yper >= 0 && yper <= 100;
|
||||
gm->y = gm->y_per ? yper : yoff;
|
||||
gm->y_sign = ysign[0] == '-';
|
||||
gm->xy_valid = gm->x != INT_MIN || gm->y != INT_MIN;
|
||||
|
||||
gm->w = width;
|
||||
gm->h = height;
|
||||
gm->wh_valid = gm->w > 0 || gm->h > 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// xpos,ypos: position of the left upper corner
|
||||
// widw,widh: width and height of the window
|
||||
// scrw,scrh: width and height of the current screen
|
||||
// The input parameters should be set to a centered window (default fallbacks).
|
||||
void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh,
|
||||
int scrw, int scrh, struct m_geometry *gm)
|
||||
{
|
||||
if (gm->wh_valid) {
|
||||
if (gm->w > 0)
|
||||
*widw = gm->w;
|
||||
if (gm->h > 0)
|
||||
*widh = gm->h;
|
||||
}
|
||||
|
||||
if (gm->xy_valid) {
|
||||
if (gm->x != INT_MIN) {
|
||||
*xpos = gm->x;
|
||||
if (gm->x_per)
|
||||
*xpos = (scrw - *widw) * (*xpos / 100.0);
|
||||
if (gm->x_sign)
|
||||
*xpos = scrw - *widw - *xpos;
|
||||
}
|
||||
if (gm->y != INT_MIN) {
|
||||
*ypos = gm->y;
|
||||
if (gm->y_per)
|
||||
*ypos = (scrh - *widh) * (*ypos / 100.0);
|
||||
if (gm->x_sign)
|
||||
*ypos = scrh - *widh - *ypos;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_geometry(const m_option_t *opt, struct bstr name,
|
||||
struct bstr param, void *dst)
|
||||
{
|
||||
char *s = bstrdup0(NULL, param);
|
||||
struct m_geometry gm = {0};
|
||||
bool res = parse_geometry_str(&gm, s);
|
||||
talloc_free(s);
|
||||
if (!res)
|
||||
goto error;
|
||||
|
||||
if (dst)
|
||||
*((struct m_geometry *)dst) = gm;
|
||||
|
||||
return 1;
|
||||
|
||||
error:
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: invalid geometry: '%.*s'\n",
|
||||
BSTR_P(name), BSTR_P(param));
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Valid format: [WxH][[+-]X[+-]Y] | [X[%%]:[Y[%%]]]\n");
|
||||
return M_OPT_INVALID;
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_geometry = {
|
||||
.name = "Window geometry",
|
||||
.size = sizeof(struct m_geometry),
|
||||
.parse = parse_geometry,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#include "video/img_format.h"
|
||||
|
||||
static int parse_imgfmt(const m_option_t *opt, struct bstr name,
|
||||
|
@ -56,6 +56,7 @@ extern const m_option_type_t m_option_type_imgfmt;
|
||||
extern const m_option_type_t m_option_type_fourcc;
|
||||
extern const m_option_type_t m_option_type_afmt;
|
||||
extern const m_option_type_t m_option_type_color;
|
||||
extern const m_option_type_t m_option_type_geometry;
|
||||
|
||||
// Callback used by m_option_type_print_func options.
|
||||
typedef int (*m_opt_func_full_t)(const m_option_t *, const char *, const char *);
|
||||
@ -77,6 +78,15 @@ struct m_color {
|
||||
uint8_t r, g, b, a;
|
||||
};
|
||||
|
||||
struct m_geometry {
|
||||
int x, y, w, h;
|
||||
bool xy_valid : 1, wh_valid : 1;
|
||||
bool x_sign : 1, y_sign : 1, x_per : 1, y_per : 1;
|
||||
};
|
||||
|
||||
void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh,
|
||||
int scrw, int scrh, struct m_geometry *gm);
|
||||
|
||||
// Extra definition needed for \ref m_option_type_obj_settings_list options.
|
||||
typedef struct {
|
||||
// Pointer to an array of pointer to some object type description struct.
|
||||
@ -207,6 +217,7 @@ union m_option_value {
|
||||
double time;
|
||||
struct m_rel_time rel_time;
|
||||
struct m_color color;
|
||||
struct m_geometry geometry;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@ -521,6 +532,7 @@ static inline void m_option_free(const m_option_t *opt, void *dst)
|
||||
#define OPT_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_time)
|
||||
#define OPT_REL_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_rel_time)
|
||||
#define OPT_COLOR(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_color)
|
||||
#define OPT_GEOMETRY(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_geometry)
|
||||
|
||||
#define OPT_TRACKCHOICE(name, var) OPT_CHOICE_OR_INT(name, var, 0, 0, 8190, ({"no", -2}, {"auto", -1}))
|
||||
|
||||
|
@ -20,6 +20,7 @@ typedef struct MPOpts {
|
||||
int screen_size_y;
|
||||
int vo_screenwidth;
|
||||
int vo_screenheight;
|
||||
struct m_geometry vo_geometry;
|
||||
int force_window_position;
|
||||
char *vo_winname;
|
||||
char *vo_wintitle;
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
/* Stuff for correct aspect scaling. */
|
||||
#include "aspect.h"
|
||||
#include "geometry.h"
|
||||
#include "vo.h"
|
||||
#include "core/mp_msg.h"
|
||||
#include "core/options.h"
|
||||
@ -102,7 +101,7 @@ void aspect(struct vo *vo, int *srcw, int *srch, int zoom)
|
||||
int fitw;
|
||||
int fith;
|
||||
get_max_dims(vo, &fitw, &fith, zoom);
|
||||
if (!zoom && geometry_wh_changed) {
|
||||
if (!zoom && vo->opts->vo_geometry.wh_valid) {
|
||||
mp_msg(MSGT_VO, MSGL_DBG2, "aspect(0) no aspect forced!\n");
|
||||
return; // the user doesn't want to fix aspect
|
||||
}
|
||||
|
@ -1,112 +0,0 @@
|
||||
/*
|
||||
* copyright (C) 2002 Mark Zealey <mark@zealos.org>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include "geometry.h"
|
||||
#include "core/mp_msg.h"
|
||||
|
||||
/* A string of the form [WxH][+X+Y] or xpos[%]:ypos[%] */
|
||||
char *vo_geometry;
|
||||
// set when either width or height is changed
|
||||
int geometry_wh_changed;
|
||||
int geometry_xy_changed;
|
||||
|
||||
// xpos,ypos: position of the left upper corner
|
||||
// widw,widh: width and height of the window
|
||||
// scrw,scrh: width and height of the current screen
|
||||
int geometry(int *xpos, int *ypos, int *widw, int *widh, int scrw, int scrh)
|
||||
{
|
||||
if(vo_geometry != NULL) {
|
||||
char xsign[2], ysign[2], dummy[2];
|
||||
int width, height, xoff, yoff, xper, yper;
|
||||
int i;
|
||||
int ok = 0;
|
||||
for (i = 0; !ok && i < 9; i++) {
|
||||
width = height = xoff = yoff = xper = yper = INT_MIN;
|
||||
strcpy(xsign, "+");
|
||||
strcpy(ysign, "+");
|
||||
switch (i) {
|
||||
case 0:
|
||||
ok = sscanf(vo_geometry, "%ix%i%1[+-]%i%1[+-]%i%c",
|
||||
&width, &height, xsign, &xoff, ysign,
|
||||
&yoff, dummy) == 6;
|
||||
break;
|
||||
case 1:
|
||||
ok = sscanf(vo_geometry, "%ix%i%c", &width, &height, dummy) == 2;
|
||||
break;
|
||||
case 2:
|
||||
ok = sscanf(vo_geometry, "%1[+-]%i%1[+-]%i%c",
|
||||
xsign, &xoff, ysign, &yoff, dummy) == 4;
|
||||
break;
|
||||
case 3:
|
||||
ok = sscanf(vo_geometry, "%i%%:%i%1[%]%c", &xper, &yper, dummy, dummy) == 3;
|
||||
break;
|
||||
case 4:
|
||||
ok = sscanf(vo_geometry, "%i:%i%1[%]%c", &xoff, &yper, dummy, dummy) == 3;
|
||||
break;
|
||||
case 5:
|
||||
ok = sscanf(vo_geometry, "%i%%:%i%c", &xper, &yoff, dummy) == 2;
|
||||
break;
|
||||
case 6:
|
||||
ok = sscanf(vo_geometry, "%i:%i%c", &xoff, &yoff, dummy) == 2;
|
||||
break;
|
||||
case 7:
|
||||
ok = sscanf(vo_geometry, "%i%1[%]%c", &xper, dummy, dummy) == 2;
|
||||
break;
|
||||
case 8:
|
||||
ok = sscanf(vo_geometry, "%i%c", &xoff, dummy) == 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok) {
|
||||
mp_msg(MSGT_VO, MSGL_ERR,
|
||||
"-geometry must be in [WxH][[+-]X[+-]Y] | [X[%%]:[Y[%%]]] format, incorrect (%s)\n", vo_geometry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V,"geometry window parameter: widw: %i,"
|
||||
" widh: %i, scrw: %i, scrh: %i\n",*widw, *widh, scrw, scrh);
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V,"geometry set to width: %i,"
|
||||
"height: %i, xoff: %s%i, yoff: %s%i, xper: %i, yper: %i\n",
|
||||
width, height, xsign, xoff, ysign, yoff, xper, yper);
|
||||
|
||||
if (width > 0) *widw = width;
|
||||
if (height > 0) *widh = height;
|
||||
|
||||
if(xoff != INT_MIN && xsign[0] == '-') xoff = scrw - *widw - xoff;
|
||||
if(yoff != INT_MIN && ysign[0] == '-') yoff = scrh - *widh - yoff;
|
||||
if(xper >= 0 && xper <= 100) xoff = (scrw - *widw) * ((float)xper / 100.0);
|
||||
if(yper >= 0 && yper <= 100) yoff = (scrh - *widh) * ((float)yper / 100.0);
|
||||
|
||||
mp_msg(MSGT_VO, MSGL_V,"geometry set to width: %i,"
|
||||
"height: %i, xoff: %i, yoff: %i, xper: %i, yper: %i\n",
|
||||
width, height, xoff, yoff, xper, yper);
|
||||
|
||||
if (xoff != INT_MIN && xpos) *xpos = xoff;
|
||||
if (yoff != INT_MIN && ypos) *ypos = yoff;
|
||||
|
||||
geometry_wh_changed = width > 0 || height > 0;
|
||||
geometry_xy_changed = xoff != INT_MIN || yoff != INT_MIN;
|
||||
}
|
||||
return 1;
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* copyright (C) 2002 Mark Zealey <mark@zealos.org>
|
||||
*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* MPlayer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_GEOMETRY_H
|
||||
#define MPLAYER_GEOMETRY_H
|
||||
|
||||
extern char *vo_geometry;
|
||||
extern int geometry_wh_changed;
|
||||
extern int geometry_xy_changed;
|
||||
int geometry(int *xpos, int *ypos, int *widw, int *widh, int scrw, int scrh);
|
||||
|
||||
#endif /* MPLAYER_GEOMETRY_H */
|
@ -33,7 +33,6 @@
|
||||
#include "core/bstr.h"
|
||||
#include "vo.h"
|
||||
#include "aspect.h"
|
||||
#include "geometry.h"
|
||||
#include "core/input/input.h"
|
||||
#include "core/mp_fifo.h"
|
||||
#include "core/m_config.h"
|
||||
@ -403,9 +402,9 @@ static void determine_window_geometry(struct vo *vo, int d_w, int d_h)
|
||||
|
||||
vo->dx = (int)(opts->vo_screenwidth - d_w) / 2;
|
||||
vo->dy = (int)(opts->vo_screenheight - d_h) / 2;
|
||||
geometry(&vo->dx, &vo->dy, &d_w, &d_h,
|
||||
opts->vo_screenwidth, opts->vo_screenheight);
|
||||
geometry_xy_changed |= xinerama_screen >= 0;
|
||||
m_geometry_apply(&vo->dx, &vo->dy, &d_w, &d_h,
|
||||
opts->vo_screenwidth, opts->vo_screenheight,
|
||||
&opts->vo_geometry);
|
||||
|
||||
vo->dx += xinerama_x;
|
||||
vo->dy += xinerama_y;
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "vo.h"
|
||||
#include "video/vfcap.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "geometry.h"
|
||||
#include "sub/sub.h"
|
||||
#include "bitmap_packer.h"
|
||||
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "vo.h"
|
||||
#include "video/vfcap.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "geometry.h"
|
||||
#include "sub/sub.h"
|
||||
|
||||
#include "gl_common.h"
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include "aspect.h"
|
||||
#include "config.h"
|
||||
#include "vo.h"
|
||||
#include "geometry.h"
|
||||
|
||||
struct formatmap_entry {
|
||||
Uint32 sdl;
|
||||
@ -272,14 +271,12 @@ static bool try_create_renderer(struct vo *vo, int i, const char *driver,
|
||||
if (!is_good_renderer(&ri, driver, vc->allow_sw, NULL))
|
||||
return false;
|
||||
|
||||
bool xy_valid = vo->opts->vo_geometry.xy_valid;
|
||||
|
||||
// then actually try
|
||||
vc->window = SDL_CreateWindow("MPV",
|
||||
geometry_xy_changed
|
||||
? vo->dx
|
||||
: SDL_WINDOWPOS_UNDEFINED,
|
||||
geometry_xy_changed
|
||||
? vo->dy
|
||||
: SDL_WINDOWPOS_UNDEFINED,
|
||||
xy_valid ? vo->dx : SDL_WINDOWPOS_UNDEFINED,
|
||||
xy_valid ? vo->dy : SDL_WINDOWPOS_UNDEFINED,
|
||||
w, h,
|
||||
SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN);
|
||||
if (!vc->window) {
|
||||
|
@ -37,7 +37,6 @@
|
||||
|
||||
#include "vo.h"
|
||||
#include "aspect.h"
|
||||
#include "geometry.h"
|
||||
#include "osdep/timer.h"
|
||||
|
||||
#include <X11/Xmd.h>
|
||||
@ -1105,6 +1104,7 @@ void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
|
||||
struct MPOpts *opts = vo->opts;
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
Display *mDisplay = vo->x11->display;
|
||||
bool force_change_xy = opts->vo_geometry.xy_valid || xinerama_screen >= 0;
|
||||
if (WinID >= 0) {
|
||||
vo_fs = flags & VOFLAG_FULLSCREEN;
|
||||
x11->window = WinID ? (Window)WinID : x11->rootwin;
|
||||
@ -1148,7 +1148,7 @@ void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
|
||||
hint.x = x; hint.y = y;
|
||||
hint.width = width; hint.height = height;
|
||||
hint.flags = PSize;
|
||||
if (geometry_xy_changed)
|
||||
if (force_change_xy)
|
||||
hint.flags |= PPosition;
|
||||
XSetWMNormalHints(mDisplay, x11->window, &hint);
|
||||
if (!vo_border) vo_x11_decoration(vo, 0);
|
||||
@ -1167,7 +1167,7 @@ void vo_x11_create_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
|
||||
}
|
||||
vo_x11_update_window_title(vo);
|
||||
if (opts->vo_ontop) vo_x11_setlayer(vo, x11->window, opts->vo_ontop);
|
||||
vo_x11_update_geometry(vo, !geometry_xy_changed);
|
||||
vo_x11_update_geometry(vo, !force_change_xy);
|
||||
vo_x11_nofs_sizepos(vo, vo->dx, vo->dy, width, height);
|
||||
if (!!vo_fs != !!(flags & VOFLAG_FULLSCREEN))
|
||||
vo_x11_fullscreen(vo);
|
||||
|
Loading…
Reference in New Issue
Block a user