mirror of https://github.com/mpv-player/mpv
libmenu: remove OSD menu functionality (--menu)
Something like the OSD menu functionality could be useful. However the current implementation has several problems and would require a relatively large amount of work to get into good shape. As far as I know there are few users of the existing functionality. Nobody is working on the existing code and keeping it compiling at all while changing other code would require extra work. So delete the menu code and some related code elsewhere that's used by nothing else.
This commit is contained in:
parent
b200583403
commit
8b5efd6455
|
@ -199,17 +199,6 @@ loop <value> [abs]
|
|||
Adjust/set how many times the movie should be looped. -1 means no loop,
|
||||
and 0 forever.
|
||||
|
||||
menu <command>
|
||||
Execute an OSD menu command.
|
||||
up Move cursor up.
|
||||
down Move cursor down.
|
||||
ok Accept selection.
|
||||
cancel Cancel selection.
|
||||
hide Hide the OSD menu.
|
||||
|
||||
set_menu <menu_name>
|
||||
Display the menu named <menu_name>.
|
||||
|
||||
mute [value]
|
||||
Toggle sound output muting or set it to [value] when [value] >= 0
|
||||
(1 == on, 0 == off).
|
||||
|
@ -269,6 +258,9 @@ radio_step_channel <-1|1>
|
|||
radio_step_freq <value>
|
||||
Tune frequency by the <value> (positive - up, negative - down).
|
||||
|
||||
run <value>
|
||||
Run <value> as shell command.
|
||||
|
||||
seek <value> [type] [hr-seek]
|
||||
Seek to some place in the movie.
|
||||
type = 0 is a relative seek of +/- <value> seconds (default).
|
||||
|
@ -495,23 +487,6 @@ volume <value> [abs]
|
|||
Increase/decrease volume or set it to <value> if [abs] is nonzero.
|
||||
|
||||
|
||||
The following commands are really only useful for OSD menu console mode:
|
||||
|
||||
help
|
||||
Displays help text, currently empty.
|
||||
|
||||
exit
|
||||
Exits from OSD menu console. Unlike 'quit', does not quit MPlayer.
|
||||
|
||||
hide
|
||||
Hides the OSD menu console. Clicking a menu command unhides it. Other
|
||||
keybindings act as usual.
|
||||
|
||||
run <value>
|
||||
Run <value> as shell command. In OSD menu console mode stdout and stdin
|
||||
are through the video output driver.
|
||||
|
||||
|
||||
Available properties:
|
||||
|
||||
name type min max get set step comment
|
||||
|
|
13
Makefile
13
Makefile
|
@ -466,18 +466,6 @@ SRCS_MPLAYER-$(JOYSTICK) += input/joystick.c
|
|||
SRCS_MPLAYER-$(JPEG) += libvo/vo_jpeg.c
|
||||
SRCS_MPLAYER-$(KAI) += libao2/ao_kai.c
|
||||
SRCS_MPLAYER-$(KVA) += libvo/vo_kva.c
|
||||
SRCS_MPLAYER-$(LIBMENU) += libmenu/menu.c \
|
||||
libmenu/menu_chapsel.c \
|
||||
libmenu/menu_cmdlist.c \
|
||||
libmenu/menu_console.c \
|
||||
libmenu/menu_filesel.c \
|
||||
libmenu/menu_list.c \
|
||||
libmenu/menu_param.c \
|
||||
libmenu/menu_pt.c \
|
||||
libmenu/menu_txt.c \
|
||||
libmenu/vf_menu.c \
|
||||
|
||||
SRCS_MPLAYER-$(LIBMENU_DVBIN) += libmenu/menu_dvbin.c
|
||||
SRCS_MPLAYER-$(LIRC) += input/lirc.c
|
||||
SRCS_MPLAYER-$(MD5SUM) += libvo/vo_md5sum.c
|
||||
SRCS_MPLAYER-$(MGA) += libvo/vo_mga.c
|
||||
|
@ -555,7 +543,6 @@ DIRS = . \
|
|||
libdvdnav \
|
||||
libdvdnav/vm \
|
||||
libdvdread4 \
|
||||
libmenu \
|
||||
libmpcodecs \
|
||||
libmpcodecs/native \
|
||||
libmpdemux \
|
||||
|
|
|
@ -44,13 +44,6 @@ extern char *lirc_configfile;
|
|||
extern char *vo_geometry;
|
||||
extern int stop_xscreensaver;
|
||||
|
||||
extern int menu_startup;
|
||||
extern int menu_keepdir;
|
||||
extern char *menu_chroot;
|
||||
extern char *menu_fribidi_charset;
|
||||
extern int menu_flip_hebrew;
|
||||
extern int menu_fribidi_flip_commas;
|
||||
|
||||
extern char *unrar_executable;
|
||||
|
||||
extern char *mp_msg_charset;
|
||||
|
@ -321,7 +314,6 @@ const m_option_t msgl_config[]={
|
|||
{ "afilter", &mp_msg_levels[MSGT_AFILTER], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "netst", &mp_msg_levels[MSGT_NETST], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "muxer", &mp_msg_levels[MSGT_MUXER], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "osd-menu", &mp_msg_levels[MSGT_OSD_MENU], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "identify", &mp_msg_levels[MSGT_IDENTIFY], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "ass", &mp_msg_levels[MSGT_ASS], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
{ "statusline", &mp_msg_levels[MSGT_STATUSLINE], CONF_TYPE_INT, CONF_RANGE, -1, 9, NULL },
|
||||
|
@ -362,7 +354,6 @@ const m_option_t msgl_config[]={
|
|||
" sws\n"
|
||||
" vobsub\n"
|
||||
" subreader\n"
|
||||
" osd-menu - OSD menu messages\n"
|
||||
" afilter - Audio filter messages\n"
|
||||
" netst - Netstream\n"
|
||||
" muxer - muxer layer\n"
|
||||
|
@ -854,24 +845,6 @@ const m_option_t mplayer_opts[]={
|
|||
OPT_INTRANGE("osdlevel", osd_level, 0, 0, 3),
|
||||
OPT_INTRANGE("osd-duration", osd_duration, 0, 0, 3600000),
|
||||
OPT_INTRANGE("osd-fractions", osd_fractions, 0, 0, 2),
|
||||
#ifdef CONFIG_MENU
|
||||
{"menu", &use_menu, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL},
|
||||
{"nomenu", &use_menu, CONF_TYPE_FLAG, CONF_GLOBAL, 1, 0, NULL},
|
||||
{"menu-root", &menu_root, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
|
||||
{"menu-cfg", &menu_cfg, CONF_TYPE_STRING, CONF_GLOBAL, 0, 0, NULL},
|
||||
{"menu-startup", &menu_startup, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL},
|
||||
{"menu-keepdir", &menu_keepdir, CONF_TYPE_FLAG, CONF_GLOBAL, 0, 1, NULL},
|
||||
{"menu-chroot", &menu_chroot, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
#ifdef CONFIG_FRIBIDI
|
||||
{"menu-fribidi-charset", &menu_fribidi_charset, CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{"menu-flip-hebrew", &menu_flip_hebrew, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"menu-noflip-hebrew", &menu_flip_hebrew, CONF_TYPE_FLAG, 0, 1, 0, NULL},
|
||||
{"menu-flip-hebrew-commas", &menu_fribidi_flip_commas, CONF_TYPE_FLAG, 0, 1, 0, NULL},
|
||||
{"menu-noflip-hebrew-commas", &menu_fribidi_flip_commas, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
#endif /* CONFIG_FRIBIDI */
|
||||
#else
|
||||
{"menu", "OSD menu support was not compiled in.\n", CONF_TYPE_PRINT,0, 0, 0, NULL},
|
||||
#endif /* CONFIG_MENU */
|
||||
|
||||
OPT_STRING("vobsub", vobsub_name, 0),
|
||||
{"vobsubid", &vobsub_id, CONF_TYPE_INT, CONF_RANGE, 0, 31, NULL},
|
||||
|
|
11
command.c
11
command.c
|
@ -66,14 +66,11 @@
|
|||
#endif
|
||||
#include "stream/stream_dvdnav.h"
|
||||
#include "m_struct.h"
|
||||
#include "libmenu/menu.h"
|
||||
|
||||
#include "mp_core.h"
|
||||
#include "mp_fifo.h"
|
||||
#include "libavutil/avstring.h"
|
||||
|
||||
extern int use_menu;
|
||||
|
||||
static void rescale_input_coordinates(struct MPContext *mpctx, int ix, int iy,
|
||||
double *dx, double *dy)
|
||||
{
|
||||
|
@ -2979,10 +2976,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||
add_step_frame(mpctx);
|
||||
break;
|
||||
|
||||
case MP_CMD_FILE_FILTER:
|
||||
file_filter = cmd->args[0].v.i;
|
||||
break;
|
||||
|
||||
case MP_CMD_QUIT:
|
||||
exit_player_with_rc(mpctx, EXIT_QUIT,
|
||||
(cmd->nargs > 0) ? cmd->args[0].v.i : 0);
|
||||
|
@ -3556,10 +3549,6 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
|||
set_osd_msg(OSD_MSG_TEXT, 1, osd_duration,
|
||||
"Selected button number %d", button);
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_MENU
|
||||
if (use_menu && dx >= 0.0 && dy >= 0.0)
|
||||
menu_update_mouse_pos(dx, dy);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -334,7 +334,6 @@ Optional features:
|
|||
--disable-freetype disable FreeType 2 font rendering [autodetect]
|
||||
--disable-fontconfig disable fontconfig font lookup [autodetect]
|
||||
--disable-unrarexec disable using of UnRAR executable [enabled]
|
||||
--enable-menu enable OSD menu (not DVD menu) [disabled]
|
||||
--disable-sortsub disable subtitle sorting [enabled]
|
||||
--enable-fribidi enable the FriBiDi libs [autodetect]
|
||||
--disable-enca disable ENCA charset oracle library [autodetect]
|
||||
|
@ -678,7 +677,6 @@ _big_endian=auto
|
|||
_bitmap_font=yes
|
||||
_freetype=auto
|
||||
_fontconfig=auto
|
||||
_menu=no
|
||||
_qtx=auto
|
||||
_coreaudio=auto
|
||||
_corevideo=auto
|
||||
|
@ -1110,9 +1108,6 @@ for ac_option do
|
|||
--enable-dga2) _dga2=yes ;;
|
||||
--disable-dga2) _dga2=no ;;
|
||||
|
||||
--enable-menu) _menu=yes ;;
|
||||
--disable-menu) _menu=no ;;
|
||||
|
||||
--enable-qtx) _qtx=yes ;;
|
||||
--disable-qtx) _qtx=no ;;
|
||||
|
||||
|
@ -6388,17 +6383,6 @@ fi
|
|||
echores "$_vstream"
|
||||
|
||||
|
||||
echocheck "OSD menu"
|
||||
if test "$_menu" = yes ; then
|
||||
def_menu='#define CONFIG_MENU 1'
|
||||
test $_dvbin = "yes" && _menu_dvbin=yes
|
||||
else
|
||||
def_menu='#undef CONFIG_MENU'
|
||||
_menu_dvbin=no
|
||||
fi
|
||||
echores "$_menu"
|
||||
|
||||
|
||||
echocheck "Subtitles sorting"
|
||||
if test "$_sortsub" = yes ; then
|
||||
def_sortsub='#define CONFIG_SORTSUB 1'
|
||||
|
@ -6716,8 +6700,6 @@ LIBDCA = $_libdca
|
|||
LIBDV = $_libdv
|
||||
LIBDVDCSS_INTERNAL = $_libdvdcss_internal
|
||||
LIBMAD = $_mad
|
||||
LIBMENU = $_menu
|
||||
LIBMENU_DVBIN = $_menu_dvbin
|
||||
LIBNEMESI = $_nemesi
|
||||
LIBNUT = $_libnut
|
||||
LIBSMBCLIENT = $_smb
|
||||
|
@ -6938,7 +6920,6 @@ $def_charset
|
|||
$def_crash_debug
|
||||
$def_debug
|
||||
$def_fastmemcpy
|
||||
$def_menu
|
||||
$def_runtime_cpudetection
|
||||
$def_sighandler
|
||||
$def_sortsub
|
||||
|
@ -7245,9 +7226,10 @@ skipping autodetection. This behavior is unlike what you may be used to from
|
|||
autoconf-based configure scripts that can decide to override you. This greater
|
||||
level of control comes at a price. You may have to provide the correct compiler
|
||||
and linker flags yourself.
|
||||
If you used one of these options (except --enable-menu and similar ones that
|
||||
turn on internal features) and experience a compilation or linking failure,
|
||||
make sure you have passed the necessary compiler/linker flags to configure.
|
||||
If you used one of these options (except --enable-runtime-cpudetection and
|
||||
similar ones that turn on internal features) and experience a compilation or
|
||||
linking failure, make sure you have passed the necessary compiler/linker flags
|
||||
to configure.
|
||||
|
||||
If you suspect a bug, please read DOCS/HTML/$language_doc/bugreports.html.
|
||||
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
|
||||
<txt name="man" file="manpage.txt"/>
|
||||
|
||||
<filesel name="open_file"/>
|
||||
<filesel name="open_list" file-action="loadlist '%p'" auto-close="yes"
|
||||
title="Open a playlist: %p" />
|
||||
|
||||
<dvbsel title="Channel List" name="dvbsel" />
|
||||
|
||||
|
||||
<pt name="jump_to"/>
|
||||
|
||||
<console name="console0" height="80" vspace="0">Welcome to MPlayer</console>
|
||||
|
||||
<txt name="man" file="manpage.txt"/>
|
||||
|
||||
<pref name="general_pref" title="General">
|
||||
<e name="autoq"/>
|
||||
<e name="autosync" />
|
||||
<e name="framedrop"/>
|
||||
<e name="quiet"/>
|
||||
<e name="softsleep" />
|
||||
</pref>
|
||||
|
||||
<pref name="demuxer_pref" title="Demuxer">
|
||||
<e name="aid"/>
|
||||
<e name="alang" />
|
||||
<e name="cache"/>
|
||||
<e name="channels"/>
|
||||
<e name="dvdangle" />
|
||||
<e name="forceidx"/>
|
||||
<e name="fps"/>
|
||||
<e name="hr-mp3-seek"/>
|
||||
<e name="idx"/>
|
||||
<e name="mc"/>
|
||||
<e name="ni"/>
|
||||
<e name="nobps"/>
|
||||
<e name="srate"/>
|
||||
<e name="vid"/>
|
||||
</pref>
|
||||
|
||||
|
||||
<pref name="osd_sub_pref" title="OSD & Subs">
|
||||
<e name="ffactor"/>
|
||||
<e name="noautosub"/>
|
||||
<e name="osdlevel"/>
|
||||
<e name="sid"/>
|
||||
<e name="slang"/>
|
||||
<e name="subdelay"/>
|
||||
<e name="subfps"/>
|
||||
<e name="subpos"/>
|
||||
<e name="unicode"/>
|
||||
<e name="utf8"/>
|
||||
<e name="vobsubid"/>
|
||||
</pref>
|
||||
|
||||
<pref name="audio_pref" title="Audio">
|
||||
<e name="abs"/>
|
||||
<e name="af"/>
|
||||
<e name="ao"/>
|
||||
<e name="delay"/>
|
||||
<e name="mixer"/>
|
||||
</pref>
|
||||
|
||||
<pref name="video_pref" title="Video">
|
||||
<e name="bpp"/>
|
||||
<e name="brightness"/>
|
||||
<e name="contrast"/>
|
||||
<e name="display"/>
|
||||
<e name="double"/>
|
||||
<e name="dr"/>
|
||||
<e name="fs"/>
|
||||
<e name="geometry"/>
|
||||
<e name="hue"/>
|
||||
<e name="icelayer"/>
|
||||
<e name="noslices"/>
|
||||
<e name="panscan"/>
|
||||
<e name="rootwin"/>
|
||||
<e name="saturation"/>
|
||||
<e name="vm"/>
|
||||
<e name="vo"/>
|
||||
<e name="vf"/>
|
||||
<e name="xineramascreen"/>
|
||||
</pref>
|
||||
|
||||
|
||||
<cmdlist name="pref_main" title="Preferences" ptr="<>" >
|
||||
<e name="General ..." ok="set_menu general_pref"/>
|
||||
<e name="Demuxer ..." ok="set_menu demuxer_pref"/>
|
||||
<e name="Osd/Subtitles ..." ok="set_menu osd_sub_pref"/>
|
||||
<e name="Audio ..." ok="set_menu audio_pref"/>
|
||||
<e name="Video ..." ok="set_menu video_pref"/>
|
||||
</cmdlist>
|
||||
|
||||
<cmdlist name="main" title="MPlayer OSD menu" ptr="<>" >
|
||||
<e name="Pause" ok="pause"/>
|
||||
<e name="Prev/Next" ok="pt_step 1" cancel="pt_step -1"/>
|
||||
<e name="Jump to ..." ok="set_menu jump_to"/>
|
||||
<e name="Open ..." ok="set_menu open_file"/>
|
||||
<e name="Open playlist ..." ok="set_menu open_list"/>
|
||||
<e name="DVB" ok="set_menu dvbsel"/>
|
||||
<e name="Help" ok="set_menu man"/>
|
||||
<e name="Pref" ok="set_menu pref_main"/>
|
||||
<e name="Console" ok="set_menu console0"/>
|
||||
<e name="Quit" ok="quit"/>
|
||||
</cmdlist>
|
|
@ -109,14 +109,10 @@ JOY_BTN0 pause
|
|||
JOY_BTN1 osd
|
||||
JOY_BTN2 volume 1
|
||||
JOY_BTN3 volume -1
|
||||
JOY_BTN4 set_menu main
|
||||
|
||||
##
|
||||
## Apple Remote section
|
||||
##
|
||||
## To use OSD menu with Apple Remote, set key AR_MENU to any OSD menu command,
|
||||
## or just comment out the 'AR_MENU osd' line and uncomment the line after it.
|
||||
##
|
||||
|
||||
AR_PLAY pause
|
||||
AR_PLAY_HOLD quit
|
||||
|
@ -124,33 +120,10 @@ AR_NEXT seek 30
|
|||
AR_NEXT_HOLD seek 120
|
||||
AR_PREV seek -10
|
||||
AR_PREV_HOLD seek -120
|
||||
AR_MENU menu up
|
||||
#AR_MENU menu cancel
|
||||
AR_MENU_HOLD mute
|
||||
AR_VUP volume 1
|
||||
AR_VDOWN volume -1
|
||||
|
||||
##
|
||||
## OSD Menu movement keys
|
||||
##
|
||||
## If you are using only the keyboard it is enough to define one command (like
|
||||
## "menu up"), because then that single key will display the menu, which can
|
||||
## then be navigated with the cursor keys and ENTER (defined in menu.conf).
|
||||
##
|
||||
## LIRC users should bind each "menu" command to a button on their remote.
|
||||
##
|
||||
## The set_menu command directly displays the (sub)menu specified as
|
||||
## its argument. Usage should be self-explanatory (although not likely
|
||||
## to be needed), after reading input.conf.
|
||||
##
|
||||
|
||||
#MOUSE_BTN0 menu up
|
||||
#y menu down
|
||||
#y menu ok
|
||||
#y menu cancel
|
||||
#y menu hide
|
||||
#y set_menu general_pref
|
||||
|
||||
##
|
||||
## DVDNAV
|
||||
## Requires dvdnav://
|
||||
|
|
151
etc/menu.conf
151
etc/menu.conf
|
@ -1,151 +0,0 @@
|
|||
<keybindings name="default">
|
||||
<binding key="UP" cmd="menu up" />
|
||||
<binding key="DOWN" cmd="menu down" />
|
||||
<binding key="LEFT" cmd="menu left" />
|
||||
<binding key="RIGHT" cmd="menu right" />
|
||||
<binding key="ENTER" cmd="menu ok" />
|
||||
<binding key="ESC" cmd="menu cancel" />
|
||||
<binding key="HOME" cmd="menu home" />
|
||||
<binding key="END" cmd="menu end" />
|
||||
<binding key="PGUP" cmd="menu pageup" />
|
||||
<binding key="PGDWN" cmd="menu pagedown" />
|
||||
<binding key="JOY_UP" cmd="menu up" />
|
||||
<binding key="JOY_DOWN" cmd="menu down" />
|
||||
<binding key="JOY_LEFT" cmd="menu left" />
|
||||
<binding key="JOY_RIGHT" cmd="menu right" />
|
||||
<binding key="JOY_BTN0" cmd="menu ok" />
|
||||
<binding key="JOY_BTN1" cmd="menu cancel" />
|
||||
<binding key="AR_VUP" cmd="menu up" />
|
||||
<binding key="AR_VDOWN" cmd="menu down" />
|
||||
<binding key="AR_PREV" cmd="menu left" />
|
||||
<binding key="AR_NEXT" cmd="menu right" />
|
||||
<binding key="AR_PLAY" cmd="menu ok" />
|
||||
<binding key="AR_MENU" cmd="menu cancel" />
|
||||
<binding key="AR_PREV_HOLD" cmd="menu home" />
|
||||
<binding key="AR_NEXT_HOLD" cmd="menu end" />
|
||||
<binding key="MOUSE_BTN0" cmd="menu click" />
|
||||
<binding key="MOUSE_BTN2" cmd="menu cancel" />
|
||||
</keybindings>
|
||||
<keybindings name="list" parent="default">
|
||||
<binding key="AR_PREV" cmd="menu pageup" />
|
||||
<binding key="AR_NEXT" cmd="menu pagedown" />
|
||||
</keybindings>
|
||||
<keybindings name="filesel" parent="list">
|
||||
<binding key="BS" cmd="menu left" />
|
||||
</keybindings>
|
||||
<keybindings name="chapsel" parent="list" />
|
||||
<keybindings name="cmdlist" parent="list">
|
||||
<binding key="AR_PREV" cmd="menu left" />
|
||||
<binding key="AR_NEXT" cmd="menu right" />
|
||||
</keybindings>
|
||||
<keybindings name="txt" parent="list" />
|
||||
<keybindings name="pt" parent="list" />
|
||||
<keybindings name="pref" parent="list">
|
||||
<binding key="AR_PREV" cmd="menu left" />
|
||||
<binding key="AR_NEXT" cmd="menu right" />
|
||||
<binding key="AR_PREV_HOLD" cmd="menu left" />
|
||||
<binding key="AR_NEXT_HOLD" cmd="menu right" />
|
||||
</keybindings>
|
||||
|
||||
<txt name="man" file="manpage.txt"/>
|
||||
|
||||
<filesel name="open_file"/>
|
||||
<filesel name="open_list" file-action="loadlist '%p'"
|
||||
title="Open a playlist: %p"
|
||||
filter="/etc/mplayer/extensions_filter"
|
||||
actions="d:run 'mp_loader \'%p\' d',c:run 'mp_loader \'%p\' c'" />
|
||||
|
||||
<chapsel name="select_chapter" />
|
||||
|
||||
<pt name="jump_to"/>
|
||||
|
||||
<console name="console0" height="80" vspace="0">Welcome to MPlayer</console>
|
||||
|
||||
<txt name="man" file="manpage.txt"/>
|
||||
|
||||
<pref name="general_pref" title="General">
|
||||
<e property="osdlevel" name="OSD level"/>
|
||||
<e property="speed" name="Speed"/>
|
||||
<e property="loop" name="Loop"/>
|
||||
</pref>
|
||||
|
||||
<pref name="demuxer_pref" title="Demuxer">
|
||||
</pref>
|
||||
|
||||
|
||||
<pref name="osd_sub_pref" title="Subtitles">
|
||||
<e property="sub" name="Subtitles"/>
|
||||
<e property="sub_visibility" name="Visibility"/>
|
||||
<e property="sub_forced_only" name="Forced sub only"/>
|
||||
<e property="sub_alignment" name="Alignment"/>
|
||||
<e property="sub_pos" name="Position"/>
|
||||
<e property="sub_delay" name="Delay"/>
|
||||
<e property="sub_scale" name="Scale"/>
|
||||
</pref>
|
||||
|
||||
<pref name="audio_pref" title="Audio">
|
||||
<e property="volume" name="Volume"/>
|
||||
<e property="balance" name="Balance"/>
|
||||
<e property="mute" name="Mute"/>
|
||||
<e property="audio_delay" name="Delay"/>
|
||||
</pref>
|
||||
|
||||
<pref name="colors_pref" title="Colors">
|
||||
<e property="gamma" name="Gamma"/>
|
||||
<e property="brightness" name="Brightness"/>
|
||||
<e property="contrast" name="Contrast"/>
|
||||
<e property="saturation" name="Saturation"/>
|
||||
<e property="hue" name="Hue"/>
|
||||
</pref>
|
||||
|
||||
<pref name="video_pref" title="Video">
|
||||
<e property="fullscreen" name="Fullscreen"/>
|
||||
<e property="panscan" name="Panscan"/>
|
||||
<menu menu="colors_pref" name="Colors ..."/>
|
||||
<e property="ontop" name="Always on top"/>
|
||||
<e property="rootwin" name="Root window"/>
|
||||
<e property="framedropping" name="Frame dropping"/>
|
||||
<e property="vsync" name="VSync"/>
|
||||
</pref>
|
||||
|
||||
|
||||
<cmdlist name="pref_main" title="Preferences" ptr="<>" >
|
||||
<e name="General ..." ok="set_menu general_pref"/>
|
||||
<e name="Audio ..." ok="set_menu audio_pref"/>
|
||||
<e name="Video ..." ok="set_menu video_pref"/>
|
||||
<e name="Subtitles ..." ok="set_menu osd_sub_pref"/>
|
||||
<e name="Back" ok="menu cancel"/>
|
||||
</cmdlist>
|
||||
|
||||
<pref name="properties" title="Stream Properties">
|
||||
<e txt="${filename}" name="Name"/>
|
||||
<e txt="${video_format}" name="Video Codec"/>
|
||||
<e txt="${video_bitrate}" name="Video Bitrate"/>
|
||||
<e txt="${width} x ${height}" name="Resolution"/>
|
||||
<e txt="${audio_codec}" name="Audio Codec"/>
|
||||
<e txt="${audio_bitrate}" name="Audio Bitrate"/>
|
||||
<e txt="${samplerate}, ${channels}" name="Audio Samples"/>
|
||||
<e txt="${metadata/Title}" name="Title"/>
|
||||
<e txt="${metadata/Artist}" name="Artist"/>
|
||||
<e txt="${metadata/Album}" name="Album"/>
|
||||
<e txt="${metadata/Year}" name="Year"/>
|
||||
<e txt="${metadata/Comment}" name="Comment"/>
|
||||
<e txt="${metadata/Track}" name="Track"/>
|
||||
<e txt="${metadata/Genre}" name="Genre"/>
|
||||
<e txt="${metadata/Software}" name="Software"/>
|
||||
</pref>
|
||||
|
||||
<cmdlist name="main" title="MPlayer OSD menu" ptr="<>" >
|
||||
<e name="Pause" ok="pause"/>
|
||||
<e name="Chapter ..." ok="set_menu select_chapter"
|
||||
left="seek_chapter -1" right="seek_chapter +1"/>
|
||||
<e name="Prev/Next ..." ok="set_menu jump_to"
|
||||
left="pt_step -1" right="pt_step 1"/>
|
||||
<e name="Open ..." ok="set_menu open_file"/>
|
||||
<e name="Open playlist ..." ok="set_menu open_list"/>
|
||||
<e name="Help" ok="set_menu man"/>
|
||||
<e name="Pref" ok="set_menu pref_main"/>
|
||||
<e name="Properties" ok="set_menu properties"/>
|
||||
<e name="Console" ok="set_menu console0"/>
|
||||
<e name="Quit" ok="quit"/>
|
||||
</cmdlist>
|
|
@ -174,7 +174,6 @@ static const mp_cmd_t mp_cmds[] = {
|
|||
{ MP_CMD_SWITCH_RATIO, "switch_ratio", 0, { {MP_CMD_ARG_FLOAT,{0}}, {-1,{0}} } },
|
||||
{ MP_CMD_VO_FULLSCREEN, "vo_fullscreen", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_VO_ONTOP, "vo_ontop", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_FILE_FILTER, "file_filter", 1, { { MP_CMD_ARG_INT, {0}}, {-1,{0}}}},
|
||||
{ MP_CMD_VO_ROOTWIN, "vo_rootwin", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_VO_BORDER, "vo_border", 0, { {MP_CMD_ARG_INT,{-1}}, {-1,{0}} } },
|
||||
{ MP_CMD_SCREENSHOT, "screenshot", 0, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
|
@ -192,14 +191,6 @@ static const mp_cmd_t mp_cmds[] = {
|
|||
{ MP_CMD_DVDNAV, "dvdnav", 1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MENU
|
||||
{ MP_CMD_MENU, "menu",1, { {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
{ MP_CMD_SET_MENU, "set_menu",1, { {MP_CMD_ARG_STRING, {0}}, {MP_CMD_ARG_STRING, {0}}, {-1,{0}} } },
|
||||
{ MP_CMD_CHELP, "help", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_CEXIT, "exit", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_CHIDE, "hide", 0, { {MP_CMD_ARG_INT,{3000}}, {-1,{0}} } },
|
||||
#endif
|
||||
|
||||
{ MP_CMD_GET_VO_FULLSCREEN, "get_vo_fullscreen", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_GET_SUB_VISIBILITY, "get_sub_visibility", 0, { {-1,{0}} } },
|
||||
{ MP_CMD_KEYDOWN_EVENTS, "key_down_event", 1, { {MP_CMD_ARG_INT,{0}}, {-1,{0}} } },
|
||||
|
@ -570,12 +561,6 @@ struct input_fd {
|
|||
int pos, size;
|
||||
};
|
||||
|
||||
struct cmd_filter {
|
||||
mp_input_cmd_filter filter;
|
||||
void *ctx;
|
||||
struct cmd_filter *next;
|
||||
};
|
||||
|
||||
struct cmd_bind_section {
|
||||
struct cmd_bind *cmd_binds;
|
||||
char *section;
|
||||
|
@ -630,11 +615,6 @@ struct input_ctx {
|
|||
};
|
||||
|
||||
|
||||
static struct cmd_filter *cmd_filters = NULL;
|
||||
|
||||
// Callback to allow the menu filter to grab the incoming keys
|
||||
int (*mp_input_key_cb)(int code) = NULL;
|
||||
|
||||
int async_quit_request;
|
||||
|
||||
static int print_key_list(m_option_t *cfg);
|
||||
|
@ -1099,17 +1079,6 @@ static int default_cmd_func(int fd, char *buf, int l)
|
|||
}
|
||||
|
||||
|
||||
void mp_input_add_cmd_filter(mp_input_cmd_filter func, void *ctx)
|
||||
{
|
||||
struct cmd_filter *filter = talloc_ptrtype(NULL, filter);
|
||||
|
||||
filter->filter = func;
|
||||
filter->ctx = ctx;
|
||||
filter->next = cmd_filters;
|
||||
cmd_filters = filter;
|
||||
}
|
||||
|
||||
|
||||
static char *find_bind_for_key(const struct cmd_bind *binds, int n, int *keys)
|
||||
{
|
||||
int j;
|
||||
|
@ -1203,14 +1172,6 @@ static mp_cmd_t *interpret_key(struct input_ctx *ictx, int code)
|
|||
if (unmod < 256 && unmod != KEY_ENTER && unmod != KEY_TAB)
|
||||
code &= ~KEY_MODIFIER_SHIFT;
|
||||
|
||||
if (mp_input_key_cb) {
|
||||
if (code & MP_KEY_DOWN)
|
||||
return NULL;
|
||||
code &= ~(MP_KEY_DOWN | MP_NO_REPEAT_KEY);
|
||||
if (mp_input_key_cb(code))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (code & MP_KEY_DOWN) {
|
||||
if (ictx->num_key_down > MP_MAX_KEY_DOWN) {
|
||||
mp_tmsg(MSGT_INPUT, MSGL_ERR, "Too many key down events "
|
||||
|
@ -1483,16 +1444,6 @@ mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int peek_only)
|
|||
} else
|
||||
ret = queue->first;
|
||||
|
||||
for (struct cmd_filter *cf = cmd_filters; cf; cf = cf->next) {
|
||||
if (cf->filter(ret, cf->ctx)) {
|
||||
// The filter ate the cmd, so remove it from the queue
|
||||
queue_pop(queue);
|
||||
mp_cmd_free(ret);
|
||||
// Retry with next command
|
||||
return mp_input_get_cmd(ictx, 0, peek_only);
|
||||
}
|
||||
}
|
||||
|
||||
if (!peek_only)
|
||||
queue_pop(queue);
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@ enum mp_command_type {
|
|||
MP_CMD_GAMMA,
|
||||
MP_CMD_SUB_VISIBILITY,
|
||||
MP_CMD_VOBSUB_LANG, // deprecated: combined with SUB_SELECT
|
||||
MP_CMD_MENU,
|
||||
MP_CMD_SET_MENU,
|
||||
MP_CMD_GET_TIME_LENGTH,
|
||||
MP_CMD_GET_PERCENT_POS,
|
||||
MP_CMD_SUB_STEP,
|
||||
|
@ -96,7 +94,6 @@ enum mp_command_type {
|
|||
MP_CMD_OSD_SHOW_PROPERTY_TEXT,
|
||||
MP_CMD_OSD_SHOW_PROGRESSION,
|
||||
MP_CMD_SEEK_CHAPTER,
|
||||
MP_CMD_FILE_FILTER,
|
||||
MP_CMD_GET_FILENAME,
|
||||
MP_CMD_GET_VIDEO_CODEC,
|
||||
MP_CMD_GET_VIDEO_BITRATE,
|
||||
|
@ -147,11 +144,6 @@ enum mp_command_type {
|
|||
/// DVB commands
|
||||
MP_CMD_DVB_SET_CHANNEL = 5101,
|
||||
|
||||
/// Console commands
|
||||
MP_CMD_CHELP = 7000,
|
||||
MP_CMD_CEXIT,
|
||||
MP_CMD_CHIDE,
|
||||
|
||||
/// Audio Filter commands
|
||||
MP_CMD_AF_SWITCH,
|
||||
MP_CMD_AF_ADD,
|
||||
|
@ -207,11 +199,6 @@ typedef struct mp_cmd {
|
|||
} mp_cmd_t;
|
||||
|
||||
|
||||
// Set this to grab all incoming key codes
|
||||
extern int (*mp_input_key_cb)(int code);
|
||||
// Should return 1 if the command was processed
|
||||
typedef int (*mp_input_cmd_filter)(struct mp_cmd *cmd, void *ctx);
|
||||
|
||||
/* Add a new command input source.
|
||||
* "fd" is a file descriptor (use a negative value if you don't use any fd)
|
||||
* "select" tells whether to use select() on the fd to determine when to
|
||||
|
@ -264,10 +251,6 @@ struct mp_cmd *mp_input_parse_cmd(char *str);
|
|||
*/
|
||||
int mp_input_parse_and_queue_cmds(struct input_ctx *ictx, const char *str);
|
||||
|
||||
// These filters allow you to process the command before MPlayer.
|
||||
// If a filter returns a true value mp_input_get_cmd will return NULL.
|
||||
void mp_input_add_cmd_filter(mp_input_cmd_filter, void *ctx);
|
||||
|
||||
// After getting a command from mp_input_get_cmd you need to free it using this
|
||||
// function
|
||||
void mp_cmd_free(struct mp_cmd *cmd);
|
||||
|
|
776
libmenu/menu.c
776
libmenu/menu.c
|
@ -1,776 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libvo/osd.h"
|
||||
#include "sub/font_load.h"
|
||||
#include "sub/sub.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "asxparser.h"
|
||||
#include "stream/stream.h"
|
||||
#include "input/input.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
#include "m_option.h"
|
||||
#include "m_struct.h"
|
||||
#include "menu.h"
|
||||
|
||||
extern menu_info_t menu_info_cmdlist;
|
||||
extern menu_info_t menu_info_chapsel;
|
||||
extern menu_info_t menu_info_pt;
|
||||
extern menu_info_t menu_info_filesel;
|
||||
extern menu_info_t menu_info_txt;
|
||||
extern menu_info_t menu_info_console;
|
||||
extern menu_info_t menu_info_pref;
|
||||
extern menu_info_t menu_info_dvbsel;
|
||||
|
||||
|
||||
menu_info_t* menu_info_list[] = {
|
||||
&menu_info_pt,
|
||||
&menu_info_cmdlist,
|
||||
&menu_info_chapsel,
|
||||
&menu_info_filesel,
|
||||
&menu_info_txt,
|
||||
&menu_info_console,
|
||||
#ifdef CONFIG_DVBIN
|
||||
&menu_info_dvbsel,
|
||||
#endif
|
||||
&menu_info_pref,
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef struct key_cmd_s {
|
||||
int key;
|
||||
char *cmd;
|
||||
} key_cmd_t;
|
||||
|
||||
typedef struct menu_cmd_bindings_s {
|
||||
char *name;
|
||||
key_cmd_t *bindings;
|
||||
int binding_num;
|
||||
struct menu_cmd_bindings_s *parent;
|
||||
} menu_cmd_bindings_t;
|
||||
|
||||
struct menu_def_st {
|
||||
char* name;
|
||||
menu_info_t* type;
|
||||
void* cfg;
|
||||
char* args;
|
||||
};
|
||||
|
||||
double menu_mouse_x = -1.0;
|
||||
double menu_mouse_y = -1.0;
|
||||
int menu_mouse_pos_updated = 0;
|
||||
|
||||
static struct MPContext *menu_ctx = NULL;
|
||||
static struct m_config *menu_mconfig = NULL;
|
||||
static struct input_ctx *menu_input = NULL;
|
||||
static menu_def_t* menu_list = NULL;
|
||||
static int menu_count = 0;
|
||||
static menu_cmd_bindings_t *cmd_bindings = NULL;
|
||||
static int cmd_bindings_num = 0;
|
||||
|
||||
|
||||
static menu_cmd_bindings_t *get_cmd_bindings(const char *name)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cmd_bindings_num; ++i)
|
||||
if (!strcasecmp(cmd_bindings[i].name, name))
|
||||
return &cmd_bindings[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int menu_parse_config(char* buffer, struct m_config *mconfig)
|
||||
{
|
||||
char *element,*body, **attribs, *name;
|
||||
menu_info_t* minfo = NULL;
|
||||
int r,i;
|
||||
ASX_Parser_t* parser = asx_parser_new(mconfig);
|
||||
|
||||
while(1) {
|
||||
r = asx_get_element(parser,&buffer,&element,&body,&attribs);
|
||||
if(r < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] syntax error at line: %d\n",parser->line);
|
||||
asx_parser_free(parser);
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
asx_parser_free(parser);
|
||||
return 1;
|
||||
}
|
||||
// Has it a name ?
|
||||
name = asx_get_attrib("name",attribs);
|
||||
if(!name) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Menu definitions need a name attribute (line %d).\n",parser->line);
|
||||
free(element);
|
||||
free(body);
|
||||
asx_free_attribs(attribs);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strcasecmp(element, "keybindings")) {
|
||||
menu_cmd_bindings_t *bindings = cmd_bindings;
|
||||
char *parent_bindings;
|
||||
cmd_bindings = realloc(cmd_bindings,
|
||||
(cmd_bindings_num+1)*sizeof(menu_cmd_bindings_t));
|
||||
for (i = 0; i < cmd_bindings_num; ++i)
|
||||
if (cmd_bindings[i].parent)
|
||||
cmd_bindings[i].parent = cmd_bindings[i].parent-bindings+cmd_bindings;
|
||||
bindings = &cmd_bindings[cmd_bindings_num];
|
||||
memset(bindings, 0, sizeof(menu_cmd_bindings_t));
|
||||
bindings->name = name;
|
||||
parent_bindings = asx_get_attrib("parent",attribs);
|
||||
if (parent_bindings) {
|
||||
bindings->parent = get_cmd_bindings(parent_bindings);
|
||||
free(parent_bindings);
|
||||
}
|
||||
free(element);
|
||||
asx_free_attribs(attribs);
|
||||
if (body) {
|
||||
char *bd = body;
|
||||
char *b, *key, *cmd;
|
||||
int keycode;
|
||||
for(;;) {
|
||||
r = asx_get_element(parser,&bd,&element,&b,&attribs);
|
||||
if(r < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] syntax error at line: %d\n",
|
||||
parser->line);
|
||||
free(body);
|
||||
asx_parser_free(parser);
|
||||
return 0;
|
||||
}
|
||||
if(r == 0)
|
||||
break;
|
||||
if (!strcasecmp(element, "binding")) {
|
||||
key = asx_get_attrib("key",attribs);
|
||||
cmd = asx_get_attrib("cmd",attribs);
|
||||
if (key && (keycode = mp_input_get_key_from_name(key)) >= 0) {
|
||||
keycode &= ~MP_NO_REPEAT_KEY;
|
||||
mp_msg(MSGT_GLOBAL,MSGL_V,
|
||||
"[libmenu] got keybinding element %d %s=>[%s].\n",
|
||||
keycode, key, cmd ? cmd : "");
|
||||
bindings->bindings = realloc(bindings->bindings,
|
||||
(bindings->binding_num+1)*sizeof(key_cmd_t));
|
||||
bindings->bindings[bindings->binding_num].key = keycode;
|
||||
bindings->bindings[bindings->binding_num].cmd = cmd;
|
||||
++bindings->binding_num;
|
||||
}
|
||||
else
|
||||
free(cmd);
|
||||
free(key);
|
||||
}
|
||||
free(element);
|
||||
asx_free_attribs(attribs);
|
||||
free(b);
|
||||
}
|
||||
free(body);
|
||||
}
|
||||
++cmd_bindings_num;
|
||||
continue;
|
||||
}
|
||||
// Try to find this menu type in our list
|
||||
for(i = 0, minfo = NULL ; menu_info_list[i] ; i++) {
|
||||
if(strcasecmp(element,menu_info_list[i]->name) == 0) {
|
||||
minfo = menu_info_list[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Got it : add this to our list
|
||||
if(minfo) {
|
||||
menu_list = realloc(menu_list,(menu_count+2)*sizeof(menu_def_t));
|
||||
menu_list[menu_count].name = name;
|
||||
menu_list[menu_count].type = minfo;
|
||||
menu_list[menu_count].cfg = m_struct_alloc(&minfo->priv_st);
|
||||
menu_list[menu_count].args = body;
|
||||
// Setup the attribs
|
||||
for(i = 0 ; attribs[2*i] ; i++) {
|
||||
if(strcasecmp(attribs[2*i],"name") == 0) continue;
|
||||
if (!m_struct_set(&minfo->priv_st, menu_list[menu_count].cfg,
|
||||
attribs[2*i], bstr(attribs[2*i+1])))
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] bad attribute %s=%s in menu '%s' at line %d\n",attribs[2*i],attribs[2*i+1],
|
||||
name,parser->line);
|
||||
}
|
||||
menu_count++;
|
||||
memset(&menu_list[menu_count],0,sizeof(menu_def_t));
|
||||
} else {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] unknown menu type '%s' at line %d\n",element,parser->line);
|
||||
free(name);
|
||||
free(body);
|
||||
}
|
||||
|
||||
free(element);
|
||||
asx_free_attribs(attribs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// This will build the menu_defs list from the cfg file
|
||||
#define BUF_STEP 1024
|
||||
#define BUF_MIN 128
|
||||
#define BUF_MAX BUF_STEP*1024
|
||||
int menu_init(struct MPContext *mpctx, struct m_config *mconfig,
|
||||
struct input_ctx *input_ctx, char* cfg_file)
|
||||
{
|
||||
char* buffer = NULL;
|
||||
int bl = BUF_STEP, br = 0;
|
||||
int f, fd;
|
||||
#ifndef CONFIG_FREETYPE
|
||||
if(vo_font == NULL)
|
||||
return 0;
|
||||
#endif
|
||||
fd = open(cfg_file, O_RDONLY);
|
||||
if(fd < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Can't open menu config file: %s\n",cfg_file);
|
||||
return 0;
|
||||
}
|
||||
buffer = malloc(bl);
|
||||
while(1) {
|
||||
int r;
|
||||
if(bl - br < BUF_MIN) {
|
||||
if(bl >= BUF_MAX) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Config file is too big (> %d KB)\n",BUF_MAX/1024);
|
||||
close(fd);
|
||||
free(buffer);
|
||||
return 0;
|
||||
}
|
||||
bl += BUF_STEP;
|
||||
buffer = realloc(buffer,bl);
|
||||
}
|
||||
r = read(fd,buffer+br,bl-br);
|
||||
if(r == 0) break;
|
||||
br += r;
|
||||
}
|
||||
if(!br) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Config file is empty.\n");
|
||||
return 0;
|
||||
}
|
||||
buffer[br-1] = '\0';
|
||||
|
||||
close(fd);
|
||||
|
||||
menu_ctx = mpctx;
|
||||
menu_mconfig = mconfig;
|
||||
menu_input = input_ctx;
|
||||
f = menu_parse_config(buffer, mconfig);
|
||||
free(buffer);
|
||||
return f;
|
||||
}
|
||||
|
||||
// Destroy all this stuff
|
||||
void menu_uninit(void) {
|
||||
int i;
|
||||
for(i = 0 ; menu_list && menu_list[i].name ; i++) {
|
||||
free(menu_list[i].name);
|
||||
m_struct_free(&menu_list[i].type->priv_st,menu_list[i].cfg);
|
||||
free(menu_list[i].args);
|
||||
}
|
||||
free(menu_list);
|
||||
menu_count = 0;
|
||||
for (i = 0; i < cmd_bindings_num; ++i) {
|
||||
free(cmd_bindings[i].name);
|
||||
while(cmd_bindings[i].binding_num > 0)
|
||||
free(cmd_bindings[i].bindings[--cmd_bindings[i].binding_num].cmd);
|
||||
free(cmd_bindings[i].bindings);
|
||||
}
|
||||
free(cmd_bindings);
|
||||
}
|
||||
|
||||
/// Default read_key function
|
||||
int menu_dflt_read_key(menu_t* menu,int cmd) {
|
||||
int i;
|
||||
menu_cmd_bindings_t *bindings = get_cmd_bindings(menu->type->name);
|
||||
if (!bindings)
|
||||
bindings = get_cmd_bindings(menu->type->type->name);
|
||||
if (!bindings)
|
||||
bindings = get_cmd_bindings("default");
|
||||
while (bindings) {
|
||||
for (i = 0; i < bindings->binding_num; ++i) {
|
||||
if (bindings->bindings[i].key == cmd) {
|
||||
if (bindings->bindings[i].cmd)
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx,
|
||||
bindings->bindings[i].cmd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
bindings = bindings->parent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
menu_t* menu_open(char *name) {
|
||||
menu_t* m;
|
||||
int i;
|
||||
|
||||
for(i = 0 ; menu_list[i].name != NULL ; i++) {
|
||||
if(strcmp(name,menu_list[i].name) == 0)
|
||||
break;
|
||||
}
|
||||
if(menu_list[i].name == NULL) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Menu %s not found.\n",name);
|
||||
return NULL;
|
||||
}
|
||||
m = calloc(1,sizeof(menu_t));
|
||||
m->priv_st = &(menu_list[i].type->priv_st);
|
||||
m->priv = m_struct_copy(m->priv_st,menu_list[i].cfg);
|
||||
m->ctx = menu_ctx;
|
||||
m->mconfig = menu_mconfig;
|
||||
m->input_ctx = menu_input;
|
||||
m->type = &menu_list[i];
|
||||
if(menu_list[i].type->open(m,menu_list[i].args))
|
||||
return m;
|
||||
if(m->priv)
|
||||
m_struct_free(m->priv_st,m->priv);
|
||||
free(m);
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Menu '%s': Init failed.\n",name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void menu_draw(menu_t* menu,mp_image_t* mpi) {
|
||||
if(menu->show && menu->draw)
|
||||
menu->draw(menu,mpi);
|
||||
}
|
||||
|
||||
void menu_update_mouse_pos(double x, double y) {
|
||||
menu_mouse_x = x;
|
||||
menu_mouse_y = y;
|
||||
menu_mouse_pos_updated = 1;
|
||||
}
|
||||
|
||||
void menu_read_cmd(menu_t* menu,int cmd) {
|
||||
if(menu->read_cmd)
|
||||
menu->read_cmd(menu,cmd);
|
||||
}
|
||||
|
||||
void menu_close(menu_t* menu) {
|
||||
if(menu->close)
|
||||
menu->close(menu);
|
||||
if(menu->priv)
|
||||
m_struct_free(menu->priv_st,menu->priv);
|
||||
free(menu);
|
||||
}
|
||||
|
||||
int menu_read_key(menu_t* menu,int cmd) {
|
||||
if(menu->read_key)
|
||||
return menu->read_key(menu,cmd);
|
||||
else
|
||||
return menu_dflt_read_key(menu,cmd);
|
||||
}
|
||||
|
||||
///////////////////////////// Helpers ////////////////////////////////////
|
||||
|
||||
typedef void (*draw_alpha_f)(int w,int h, unsigned char* src, unsigned char *srca, int srcstride, unsigned char* dstbase,int dststride);
|
||||
|
||||
inline static draw_alpha_f get_draw_alpha(uint32_t fmt) {
|
||||
switch(fmt) {
|
||||
case IMGFMT_BGR12:
|
||||
case IMGFMT_RGB12:
|
||||
return vo_draw_alpha_rgb12;
|
||||
case IMGFMT_BGR15:
|
||||
case IMGFMT_RGB15:
|
||||
return vo_draw_alpha_rgb15;
|
||||
case IMGFMT_BGR16:
|
||||
case IMGFMT_RGB16:
|
||||
return vo_draw_alpha_rgb16;
|
||||
case IMGFMT_BGR24:
|
||||
case IMGFMT_RGB24:
|
||||
return vo_draw_alpha_rgb24;
|
||||
case IMGFMT_BGR32:
|
||||
case IMGFMT_RGB32:
|
||||
return vo_draw_alpha_rgb32;
|
||||
case IMGFMT_YV12:
|
||||
case IMGFMT_I420:
|
||||
case IMGFMT_IYUV:
|
||||
case IMGFMT_YVU9:
|
||||
case IMGFMT_IF09:
|
||||
case IMGFMT_Y800:
|
||||
case IMGFMT_Y8:
|
||||
return vo_draw_alpha_yv12;
|
||||
case IMGFMT_YUY2:
|
||||
return vo_draw_alpha_yuy2;
|
||||
case IMGFMT_UYVY:
|
||||
return vo_draw_alpha_uyvy;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// return the real height of a char:
|
||||
static inline int get_height(int c,int h){
|
||||
int font;
|
||||
if ((font=vo_font->font[c])>=0)
|
||||
if(h<vo_font->pic_a[font]->h) h=vo_font->pic_a[font]->h;
|
||||
return h;
|
||||
}
|
||||
|
||||
static void render_txt(char *txt)
|
||||
{
|
||||
while (*txt) {
|
||||
int c = utf8_get_char((const char**)&txt);
|
||||
render_one_glyph(vo_font, c);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRIBIDI
|
||||
#include <fribidi/fribidi.h>
|
||||
#include "libavutil/common.h"
|
||||
char *menu_fribidi_charset = NULL;
|
||||
int menu_flip_hebrew = 0;
|
||||
int menu_fribidi_flip_commas = 0;
|
||||
|
||||
static char *menu_fribidi(char *txt)
|
||||
{
|
||||
static int char_set_num = -1;
|
||||
static FriBidiChar *logical, *visual;
|
||||
static size_t buffer_size = 1024;
|
||||
static char *outputstr;
|
||||
|
||||
#if FRIBIDI_INTERFACE_VERSION < 3
|
||||
FriBidiCharType base;
|
||||
#else
|
||||
FriBidiParType base;
|
||||
#endif
|
||||
fribidi_boolean log2vis;
|
||||
size_t len;
|
||||
|
||||
if (menu_flip_hebrew) {
|
||||
len = strlen(txt);
|
||||
if (char_set_num == -1) {
|
||||
fribidi_set_mirroring (1);
|
||||
fribidi_set_reorder_nsm (0);
|
||||
char_set_num = fribidi_parse_charset("UTF-8");
|
||||
buffer_size = FFMAX(1024,len+1);
|
||||
logical = malloc(buffer_size);
|
||||
visual = malloc(buffer_size);
|
||||
outputstr = malloc(buffer_size);
|
||||
} else if (len+1 > buffer_size) {
|
||||
buffer_size = len+1;
|
||||
logical = realloc(logical, buffer_size);
|
||||
visual = realloc(visual, buffer_size);
|
||||
outputstr = realloc(outputstr, buffer_size);
|
||||
}
|
||||
len = fribidi_charset_to_unicode (char_set_num, txt, len, logical);
|
||||
base = menu_fribidi_flip_commas?FRIBIDI_TYPE_ON:FRIBIDI_TYPE_L;
|
||||
log2vis = fribidi_log2vis (logical, len, &base, visual, NULL, NULL, NULL);
|
||||
if (log2vis) {
|
||||
len = fribidi_remove_bidi_marks (visual, len, NULL, NULL, NULL);
|
||||
fribidi_unicode_to_charset (char_set_num, visual, len, outputstr);
|
||||
return outputstr;
|
||||
}
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
#endif
|
||||
|
||||
void menu_draw_text(mp_image_t* mpi,char* txt, int x, int y) {
|
||||
draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt);
|
||||
int font;
|
||||
|
||||
if(!draw_alpha) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Unsupported output format!!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRIBIDI
|
||||
txt = menu_fribidi(txt);
|
||||
#endif
|
||||
render_txt(txt);
|
||||
|
||||
while (*txt) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
if ((font=vo_font->font[c])>=0 && (x + vo_font->width[c] <= mpi->w) && (y + vo_font->pic_a[font]->h <= mpi->h))
|
||||
draw_alpha(vo_font->width[c], vo_font->pic_a[font]->h,
|
||||
vo_font->pic_b[font]->bmp+vo_font->start[c],
|
||||
vo_font->pic_a[font]->bmp+vo_font->start[c],
|
||||
vo_font->pic_a[font]->w,
|
||||
mpi->planes[0] + y * mpi->stride[0] + x * (mpi->bpp>>3),
|
||||
mpi->stride[0]);
|
||||
x+=vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void menu_draw_text_full(mp_image_t* mpi,char* txt,
|
||||
int x, int y,int w, int h,
|
||||
int vspace, int warp, int align, int anchor) {
|
||||
int need_w,need_h;
|
||||
int sy, ymin, ymax;
|
||||
int sx, xmin, xmax, xmid, xrmin;
|
||||
int ll = 0;
|
||||
int font;
|
||||
draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt);
|
||||
|
||||
if(!draw_alpha) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Unsupported output format!!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_FRIBIDI
|
||||
txt = menu_fribidi(txt);
|
||||
#endif
|
||||
render_txt(txt);
|
||||
|
||||
if(x > mpi->w || y > mpi->h)
|
||||
return;
|
||||
|
||||
if(anchor & MENU_TEXT_VCENTER) {
|
||||
if(h <= 0) h = mpi->h;
|
||||
ymin = y - h/2;
|
||||
ymax = y + h/2;
|
||||
} else if(anchor & MENU_TEXT_BOT) {
|
||||
if(h <= 0) h = mpi->h - y;
|
||||
ymin = y - h;
|
||||
ymax = y;
|
||||
} else {
|
||||
if(h <= 0) h = mpi->h - y;
|
||||
ymin = y;
|
||||
ymax = y + h;
|
||||
}
|
||||
|
||||
if(anchor & MENU_TEXT_HCENTER) {
|
||||
if(w <= 0) w = mpi->w;
|
||||
xmin = x - w/2;
|
||||
xmax = x + w/2;
|
||||
} else if(anchor & MENU_TEXT_RIGHT) {
|
||||
if(w <= 0) w = mpi->w -x;
|
||||
xmin = x - w;
|
||||
xmax = x;
|
||||
} else {
|
||||
if(w <= 0) w = mpi->w -x;
|
||||
xmin = x;
|
||||
xmax = x + w;
|
||||
}
|
||||
|
||||
// How many space do we need to draw this ?
|
||||
menu_text_size(txt,w,vspace,warp,&need_w,&need_h);
|
||||
|
||||
// Find the first line
|
||||
if(align & MENU_TEXT_VCENTER)
|
||||
sy = ymin + ((h - need_h)/2);
|
||||
else if(align & MENU_TEXT_BOT)
|
||||
sy = ymax - need_h - 1;
|
||||
else
|
||||
sy = y;
|
||||
|
||||
#if 0
|
||||
// Find the first col
|
||||
if(align & MENU_TEXT_HCENTER)
|
||||
sx = xmin + ((w - need_w)/2);
|
||||
else if(align & MENU_TEXT_RIGHT)
|
||||
sx = xmax - need_w;
|
||||
#endif
|
||||
|
||||
xmid = xmin + (xmax - xmin) / 2;
|
||||
xrmin = xmin;
|
||||
// Clamp the bb to the mpi size
|
||||
if(ymin < 0) ymin = 0;
|
||||
if(xmin < 0) xmin = 0;
|
||||
if(ymax > mpi->h) ymax = mpi->h;
|
||||
if(xmax > mpi->w) xmax = mpi->w;
|
||||
|
||||
// Jump some the beginnig text if needed
|
||||
while(sy < ymin && *txt) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
if(c == '\n' || (warp && ll + vo_font->width[c] > w)) {
|
||||
ll = 0;
|
||||
sy += vo_font->height + vspace;
|
||||
if(c == '\n') continue;
|
||||
}
|
||||
ll += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
if(*txt == '\0') // Nothing left to draw
|
||||
return;
|
||||
|
||||
while(sy < ymax && *txt) {
|
||||
char* line_end = NULL;
|
||||
int n;
|
||||
|
||||
if(txt[0] == '\n') { // New line
|
||||
sy += vo_font->height + vspace;
|
||||
txt++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the length and end of this line
|
||||
for(n = 0, ll = 0 ; txt[n] != '\0' && txt[n] != '\n' ; n++) {
|
||||
unsigned char c = txt[n];
|
||||
if(warp && ll + vo_font->width[c] > w) break;
|
||||
ll += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
line_end = &txt[n];
|
||||
ll -= vo_font->charspace;
|
||||
|
||||
|
||||
if(align & (MENU_TEXT_HCENTER|MENU_TEXT_RIGHT)) {
|
||||
// Too long line
|
||||
if(ll > xmax-xmin) {
|
||||
if(align & MENU_TEXT_HCENTER) {
|
||||
int mid = ll/2;
|
||||
// Find the middle point
|
||||
for(n--, ll = 0 ; n <= 0 ; n--) {
|
||||
ll += vo_font->width[(int)txt[n]]+vo_font->charspace;
|
||||
if(ll - vo_font->charspace > mid) break;
|
||||
}
|
||||
ll -= vo_font->charspace;
|
||||
sx = xmid + mid - ll;
|
||||
} else// MENU_TEXT_RIGHT)
|
||||
sx = xmax + vo_font->charspace;
|
||||
|
||||
// We are after the start point -> go back
|
||||
if(sx > xmin) {
|
||||
for(n-- ; n <= 0 ; n--) {
|
||||
unsigned char c = txt[n];
|
||||
if(sx - vo_font->width[c] - vo_font->charspace < xmin) break;
|
||||
sx -= vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
} else { // We are before the start point -> go forward
|
||||
for( ; sx < xmin && (&txt[n]) != line_end ; n++) {
|
||||
unsigned char c = txt[n];
|
||||
sx += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
}
|
||||
txt = &txt[n]; // Jump to the new start char
|
||||
} else {
|
||||
if(align & MENU_TEXT_HCENTER)
|
||||
sx = xmid - ll/2;
|
||||
else
|
||||
sx = xmax - 1 - ll;
|
||||
}
|
||||
} else {
|
||||
for(sx = xrmin ; sx < xmin && txt != line_end ; txt++) {
|
||||
unsigned char c = txt[n];
|
||||
sx += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
}
|
||||
|
||||
while(sx < xmax && txt != line_end) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
font = vo_font->font[c];
|
||||
if(font >= 0) {
|
||||
int cs = (vo_font->pic_a[font]->h - vo_font->height) / 2;
|
||||
if ((sx + vo_font->width[c] <= xmax) && (sy + vo_font->height <= ymax) )
|
||||
draw_alpha(vo_font->width[c], vo_font->height,
|
||||
vo_font->pic_b[font]->bmp+vo_font->start[c] +
|
||||
cs * vo_font->pic_a[font]->w,
|
||||
vo_font->pic_a[font]->bmp+vo_font->start[c] +
|
||||
cs * vo_font->pic_a[font]->w,
|
||||
vo_font->pic_a[font]->w,
|
||||
mpi->planes[0] + sy * mpi->stride[0] + sx * (mpi->bpp>>3),
|
||||
mpi->stride[0]);
|
||||
// else
|
||||
//printf("Can't draw '%c'\n",c);
|
||||
}
|
||||
sx+=vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
txt = line_end;
|
||||
if(txt[0] == '\0') break;
|
||||
sy += vo_font->height + vspace;
|
||||
}
|
||||
}
|
||||
|
||||
int menu_text_length(char* txt) {
|
||||
int l = 0;
|
||||
render_txt(txt);
|
||||
while (*txt) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
l += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
return l - vo_font->charspace;
|
||||
}
|
||||
|
||||
void menu_text_size(char* txt,int max_width, int vspace, int warp, int* _w, int* _h) {
|
||||
int l = 1, i = 0;
|
||||
int w = 0;
|
||||
|
||||
render_txt(txt);
|
||||
while (*txt) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
if(c == '\n' || (warp && i + vo_font->width[c] >= max_width)) {
|
||||
i -= vo_font->charspace;
|
||||
if (i > w) w = i;
|
||||
if(*txt)
|
||||
l++;
|
||||
i = 0;
|
||||
if(c == '\n') continue;
|
||||
}
|
||||
i += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
if (i > 0) {
|
||||
i -= vo_font->charspace;
|
||||
if (i > w) w = i;
|
||||
}
|
||||
|
||||
*_w = w;
|
||||
*_h = (l-1) * (vo_font->height + vspace) + vo_font->height;
|
||||
}
|
||||
|
||||
|
||||
int menu_text_num_lines(char* txt, int max_width) {
|
||||
int l = 1, i = 0;
|
||||
render_txt(txt);
|
||||
while (*txt) {
|
||||
int c=utf8_get_char((const char**)&txt);
|
||||
if(c == '\n' || i + vo_font->width[c] > max_width) {
|
||||
l++;
|
||||
i = 0;
|
||||
if(c == '\n') continue;
|
||||
}
|
||||
i += vo_font->width[c]+vo_font->charspace;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
void menu_draw_box(mp_image_t* mpi,unsigned char grey,unsigned char alpha, int x, int y, int w, int h) {
|
||||
draw_alpha_f draw_alpha = get_draw_alpha(mpi->imgfmt);
|
||||
int g;
|
||||
|
||||
if(!draw_alpha) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Unsupported output format!!!!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if(x > mpi->w || y > mpi->h) return;
|
||||
|
||||
if(x < 0) w += x, x = 0;
|
||||
if(x+w > mpi->w) w = mpi->w-x;
|
||||
if(y < 0) h += y, y = 0;
|
||||
if(y+h > mpi->h) h = mpi->h-y;
|
||||
|
||||
g = ((256-alpha)*grey)>>8;
|
||||
if(g < 1) g = 1;
|
||||
|
||||
{
|
||||
int stride = (w+7)&(~7); // round to 8
|
||||
char pic[stride*h],pic_alpha[stride*h];
|
||||
memset(pic,g,stride*h);
|
||||
memset(pic_alpha,alpha,stride*h);
|
||||
draw_alpha(w,h,pic,pic_alpha,stride,
|
||||
mpi->planes[0] + y * mpi->stride[0] + x * (mpi->bpp>>3),
|
||||
mpi->stride[0]);
|
||||
}
|
||||
|
||||
}
|
127
libmenu/menu.h
127
libmenu/menu.h
|
@ -1,127 +0,0 @@
|
|||
/*
|
||||
* 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_MENU_H
|
||||
#define MPLAYER_MENU_H
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
extern double menu_mouse_x;
|
||||
extern double menu_mouse_y;
|
||||
extern int menu_mouse_pos_updated;
|
||||
extern const struct vf_info vf_info_menu;
|
||||
|
||||
struct menu_priv_s;
|
||||
typedef struct menu_s menu_t;
|
||||
|
||||
typedef struct menu_def_st menu_def_t;
|
||||
|
||||
struct m_struct_st;
|
||||
|
||||
struct menu_s {
|
||||
struct MPContext *ctx;
|
||||
struct m_config *mconfig;
|
||||
struct input_ctx *input_ctx;
|
||||
void (*draw)(menu_t* menu,mp_image_t* mpi);
|
||||
void (*read_cmd)(menu_t* menu,int cmd);
|
||||
int (*read_key)(menu_t* menu,int cmd);
|
||||
void (*close)(menu_t* menu);
|
||||
struct m_struct_st* priv_st;
|
||||
struct menu_priv_s* priv;
|
||||
int show; // Draw it ?
|
||||
int cl; // Close request (user sent a close cmd or
|
||||
menu_t* parent;
|
||||
menu_def_t *type;
|
||||
};
|
||||
|
||||
typedef struct menu_info_s {
|
||||
const char *info;
|
||||
const char *name;
|
||||
const char *author;
|
||||
const char *comment;
|
||||
struct m_struct_st priv_st; // Config struct definition
|
||||
// cfg is a config struct as defined in cfg_st, it may be used as a priv struct
|
||||
// cfg is filled from the attributs found in the cfg file
|
||||
// the args param hold the content of the balise in the cfg file (if any)
|
||||
int (*open)(menu_t* menu, char* args);
|
||||
} menu_info_t;
|
||||
|
||||
|
||||
#define MENU_CMD_UP 0
|
||||
#define MENU_CMD_DOWN 1
|
||||
#define MENU_CMD_OK 2
|
||||
#define MENU_CMD_CANCEL 3
|
||||
#define MENU_CMD_LEFT 4
|
||||
#define MENU_CMD_RIGHT 5
|
||||
#define MENU_CMD_ACTION 6
|
||||
#define MENU_CMD_HOME 7
|
||||
#define MENU_CMD_END 8
|
||||
#define MENU_CMD_PAGE_UP 9
|
||||
#define MENU_CMD_PAGE_DOWN 10
|
||||
#define MENU_CMD_CLICK 11
|
||||
|
||||
/// Global init/uninit
|
||||
int menu_init(struct MPContext *mpctx, struct m_config *mconfig,
|
||||
struct input_ctx *input_ctx, char* cfg_file);
|
||||
void menu_uninit(void);
|
||||
|
||||
/// Open a menu defined in the config file
|
||||
menu_t* menu_open(char *name);
|
||||
|
||||
void menu_draw(menu_t* menu,mp_image_t* mpi);
|
||||
void menu_read_cmd(menu_t* menu,int cmd);
|
||||
void menu_close(menu_t* menu);
|
||||
int menu_read_key(menu_t* menu,int cmd);
|
||||
|
||||
//// Default implementation
|
||||
int menu_dflt_read_key(menu_t* menu,int cmd);
|
||||
|
||||
/// Receive mouse position events.
|
||||
void menu_update_mouse_pos(double x, double y);
|
||||
|
||||
/////////// Helpers
|
||||
|
||||
#define MENU_TEXT_TOP (1<<0)
|
||||
#define MENU_TEXT_VCENTER (1<<1)
|
||||
#define MENU_TEXT_BOT (1<<2)
|
||||
#define MENU_TEXT_VMASK (MENU_TEXT_TOP|MENU_TEXT_VCENTER|MENU_TEXT_BOT)
|
||||
#define MENU_TEXT_LEFT (1<<3)
|
||||
#define MENU_TEXT_HCENTER (1<<4)
|
||||
#define MENU_TEXT_RIGHT (1<<5)
|
||||
#define MENU_TEXT_HMASK (MENU_TEXT_LEFT|MENU_TEXT_HCENTER|MENU_TEXT_RIGHT)
|
||||
#define MENU_TEXT_CENTER (MENU_TEXT_VCENTER|MENU_TEXT_HCENTER)
|
||||
|
||||
void menu_draw_text(mp_image_t* mpi, char* txt, int x, int y);
|
||||
int menu_text_length(char* txt);
|
||||
int menu_text_num_lines(char* txt, int max_width);
|
||||
|
||||
void menu_text_size(char* txt,int max_width,
|
||||
int vspace, int warp,
|
||||
int* _w, int* _h);
|
||||
|
||||
void menu_draw_text_full(mp_image_t* mpi,char* txt,
|
||||
int x, int y,int w, int h,
|
||||
int vspace, int warp, int align, int anchor);
|
||||
|
||||
void menu_draw_box(mp_image_t* mpi, unsigned char grey, unsigned char alpha, int x, int y, int w, int h);
|
||||
|
||||
struct vf_instance;
|
||||
void vf_menu_pause_update(struct vf_instance *vf);
|
||||
|
||||
#endif /* MPLAYER_MENU_H */
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
* Support chapter list and selection.
|
||||
*
|
||||
* Copyright (C) 2006-2007 Benjamin Zores <ben A geexbox P org>
|
||||
* Copyright (C) 2007 Ulion <ulion A gmail P com>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "talloc.h"
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
#include "input/input.h"
|
||||
|
||||
#include "stream/stream.h"
|
||||
#include "libmpdemux/demuxer.h"
|
||||
#include "access_mpcontext.h"
|
||||
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
int cid;
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
char* title;
|
||||
int auto_close;
|
||||
char* fmt_with_time;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
"Select chapter",
|
||||
0,
|
||||
"${chapter_name} [${start}]"
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "title", ST_OFF (title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "auto-close", ST_OFF (auto_close), CONF_TYPE_FLAG, 0, 0, 1, NULL },
|
||||
{ "fmt-with-time", ST_OFF (fmt_with_time), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ NULL, NULL, NULL, 0, 0, 0, NULL }
|
||||
};
|
||||
|
||||
static char *fmt_replace(const char *fmt, const char *chapter_name,
|
||||
const char *start) {
|
||||
static const char ctag[] = "${chapter_name}";
|
||||
static const char stag[] = "${start}";
|
||||
int l = strlen(fmt);
|
||||
int cl = strlen(chapter_name);
|
||||
int sl = strlen(start);
|
||||
char *str = malloc(l + cl + sl);
|
||||
char *p;
|
||||
strcpy(str, fmt);
|
||||
p = strstr(str, ctag);
|
||||
if (p) {
|
||||
memmove(p+cl, p+sizeof(ctag)-1, str+l+1 - (p+sizeof(ctag)-1));
|
||||
memcpy(p, chapter_name, cl);
|
||||
l -= sizeof(ctag) + 1;
|
||||
l += cl;
|
||||
}
|
||||
p = strstr(str, stag);
|
||||
if (p) {
|
||||
memmove(p+sl, p+sizeof(stag)-1, str+l+1 - (p+sizeof(stag)-1));
|
||||
memcpy(p, start, sl);
|
||||
l -= sizeof(stag) + 1;
|
||||
l += sl;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static int fill_menu (menu_t* menu)
|
||||
{
|
||||
list_entry_t* e;
|
||||
int cid, chapter_num = 0;
|
||||
int start_time;
|
||||
demuxer_t* demuxer = mpctx_get_demuxer(menu->ctx);
|
||||
|
||||
if (demuxer)
|
||||
chapter_num = demuxer_chapter_count(demuxer);
|
||||
if (chapter_num > 0) {
|
||||
menu_list_init (menu);
|
||||
for (cid = 0; cid < chapter_num; ++cid)
|
||||
if ((e = calloc (1, sizeof (list_entry_t))) != NULL) {
|
||||
e->cid = cid + 1;
|
||||
e->p.next = NULL;
|
||||
char *str = demuxer_chapter_display_name(demuxer, cid);
|
||||
e->p.txt = strdup(str);
|
||||
talloc_free(str);
|
||||
start_time = demuxer_chapter_time(demuxer, cid, NULL);
|
||||
if (start_time >= 0) {
|
||||
char timestr[13];
|
||||
char *tmp;
|
||||
int hour = start_time / 3600;
|
||||
int minute = (start_time / 60) % 60;
|
||||
int seconds = start_time % 60;
|
||||
sprintf(timestr,"%02d:%02d:%02d", hour, minute, seconds);
|
||||
|
||||
tmp = fmt_replace(menu->priv->fmt_with_time, e->p.txt, timestr);
|
||||
free(e->p.txt);
|
||||
e->p.txt = tmp;
|
||||
}
|
||||
menu_list_add_entry(menu, e);
|
||||
}
|
||||
}
|
||||
else
|
||||
menu_list_read_cmd(menu, MENU_CMD_CANCEL);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void read_cmd (menu_t* menu, int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK: {
|
||||
char cmdbuf[26];
|
||||
sprintf(cmdbuf, "seek_chapter %d 1", menu->priv->p.current->cid);
|
||||
mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd(cmdbuf));
|
||||
if (menu->priv->auto_close)
|
||||
mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd("menu hide"));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
menu_list_read_cmd (menu, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void close_cs (menu_t* menu)
|
||||
{
|
||||
menu_list_uninit (menu, NULL);
|
||||
}
|
||||
|
||||
static int open_cs (menu_t* menu, char* args)
|
||||
{
|
||||
args = NULL;
|
||||
|
||||
menu->draw = menu_list_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->close = close_cs;
|
||||
menu->priv->p.title = menu->priv->title;
|
||||
|
||||
return fill_menu (menu);
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_chapsel = {
|
||||
"Chapter selector menu",
|
||||
"chapsel",
|
||||
"Benjamin Zores & Ulion",
|
||||
"",
|
||||
{
|
||||
"chapsel_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
open_cs
|
||||
};
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "m_option.h"
|
||||
#include "m_struct.h"
|
||||
#include "asxparser.h"
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
|
||||
#include "sub/font_load.h"
|
||||
|
||||
#include "input/input.h"
|
||||
|
||||
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
|
||||
char* ok;
|
||||
char* cancel;
|
||||
char* left;
|
||||
char* right;
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s, m)
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
};
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "title",M_ST_OFF(struct menu_priv_s,p.title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_RIGHT:
|
||||
if(mpriv->p.current->right) {
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->right);
|
||||
break;
|
||||
} // fallback on ok if right is not defined
|
||||
case MENU_CMD_OK:
|
||||
if (mpriv->p.current->ok)
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->ok);
|
||||
break;
|
||||
case MENU_CMD_LEFT:
|
||||
if(mpriv->p.current->left) {
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->left);
|
||||
break;
|
||||
} // fallback on cancel if left is not defined
|
||||
case MENU_CMD_CANCEL:
|
||||
if(mpriv->p.current->cancel) {
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, mpriv->p.current->cancel);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
menu_list_read_cmd(menu,cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static void free_entry(list_entry_t* entry) {
|
||||
free(entry->ok);
|
||||
free(entry->cancel);
|
||||
free(entry->left);
|
||||
free(entry->right);
|
||||
free(entry->p.txt);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static void close_menu(menu_t* menu) {
|
||||
menu_list_uninit(menu,free_entry);
|
||||
}
|
||||
|
||||
static int parse_args(menu_t* menu,char* args) {
|
||||
char *element,*body, **attribs, *name;
|
||||
list_entry_t* m = NULL;
|
||||
int r;
|
||||
ASX_Parser_t* parser = asx_parser_new(menu->mconfig);
|
||||
|
||||
while(1) {
|
||||
r = asx_get_element(parser,&args,&element,&body,&attribs);
|
||||
if(r < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] syntax error at line: %d\n",parser->line);
|
||||
asx_parser_free(parser);
|
||||
return -1;
|
||||
} else if(r == 0) {
|
||||
asx_parser_free(parser);
|
||||
if(!m)
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] No entry found in the menu definition.\n");
|
||||
return m ? 1 : 0;
|
||||
}
|
||||
// Has it a name ?
|
||||
name = asx_get_attrib("name",attribs);
|
||||
if(!name) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] List menu entry definitions need a name (line %d).\n",parser->line);
|
||||
free(element);
|
||||
free(body);
|
||||
asx_free_attribs(attribs);
|
||||
continue;
|
||||
}
|
||||
m = calloc(1,sizeof(struct list_entry_s));
|
||||
m->p.txt = name;
|
||||
m->ok = asx_get_attrib("ok",attribs);
|
||||
m->cancel = asx_get_attrib("cancel",attribs);
|
||||
m->left = asx_get_attrib("left",attribs);
|
||||
m->right = asx_get_attrib("right",attribs);
|
||||
menu_list_add_entry(menu,m);
|
||||
|
||||
free(element);
|
||||
free(body);
|
||||
asx_free_attribs(attribs);
|
||||
}
|
||||
}
|
||||
|
||||
static int open_cmdlist(menu_t* menu, char* args) {
|
||||
menu->draw = menu_list_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->close = close_menu;
|
||||
|
||||
if(!args) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] List menu needs an argument.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
menu_list_init(menu);
|
||||
if(!parse_args(menu,args))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_cmdlist = {
|
||||
"Command list menu",
|
||||
"cmdlist",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"cmdlist_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
open_cmdlist
|
||||
};
|
|
@ -1,498 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef __MINGW32__
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
#include "menu.h"
|
||||
|
||||
#include "sub/font_load.h"
|
||||
#include "input/keycodes.h"
|
||||
#include "input/input.h"
|
||||
#include "osdep/timer.h"
|
||||
|
||||
typedef struct history_st history_t;
|
||||
|
||||
struct history_st {
|
||||
char* buffer;
|
||||
int size;
|
||||
history_t* next;
|
||||
history_t* prev;
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
char** lines; // Our buffer
|
||||
int last_line;
|
||||
int num_lines;
|
||||
int add_line;
|
||||
unsigned int hide_ts;
|
||||
unsigned int show_ts;
|
||||
pid_t child; // Child process if we are running a shell cmd
|
||||
int child_fd[3]; // The 3 default fd
|
||||
char* prompt;
|
||||
//int max_lines; // Max number of lines with the last mpi
|
||||
history_t* history;
|
||||
history_t* cur_history;
|
||||
int history_size;
|
||||
|
||||
char* mp_prompt;
|
||||
char* child_prompt;
|
||||
int buf_lines; // Buffer size (in line)
|
||||
int height; // Display size in %
|
||||
int minb;
|
||||
int vspace;
|
||||
int bg,bg_alpha;
|
||||
unsigned int hide_time;
|
||||
unsigned int show_time;
|
||||
int history_max;
|
||||
int raw_child;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
{ 0 , 0, 0 },
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
|
||||
"# ",
|
||||
"$ ",
|
||||
50, // lines
|
||||
33, // %
|
||||
3,
|
||||
3,
|
||||
0x80,0x40,
|
||||
500,
|
||||
500,
|
||||
10,
|
||||
0
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
{ "prompt", ST_OFF(mp_prompt), CONF_TYPE_STRING, M_OPT_MIN, 1, 0, NULL },
|
||||
{ "child-prompt", ST_OFF(child_prompt), CONF_TYPE_STRING, M_OPT_MIN, 1, 0, NULL },
|
||||
{ "buffer-lines", ST_OFF(buf_lines), CONF_TYPE_INT, M_OPT_MIN, 5, 0, NULL },
|
||||
{ "height", ST_OFF(height), CONF_TYPE_INT, M_OPT_RANGE, 1, 100, NULL },
|
||||
{ "minbor", ST_OFF(minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "vspace", ST_OFF(vspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "bg", ST_OFF(bg), CONF_TYPE_INT, M_OPT_RANGE, -1, 255, NULL },
|
||||
{ "bg-alpha", ST_OFF(bg_alpha), CONF_TYPE_INT, M_OPT_RANGE, 0, 255, NULL },
|
||||
{ "show-time",ST_OFF(show_time), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "hide-time",ST_OFF(hide_time), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "history-size",ST_OFF(history_max), CONF_TYPE_INT, M_OPT_MIN, 1, 0, NULL },
|
||||
{ "raw-child", ST_OFF(raw_child), CONF_TYPE_FLAG, 0, 0, 1, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void check_child(menu_t* menu);
|
||||
|
||||
static void add_line(struct menu_priv_s* priv, char* l) {
|
||||
char* eol = strchr(l,'\n');
|
||||
|
||||
if(eol) {
|
||||
if(eol != l) {
|
||||
eol[0] = '\0';
|
||||
add_line(priv,l);
|
||||
}
|
||||
if(eol[1]) add_line(priv,eol+1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(priv->num_lines >= priv->buf_lines)
|
||||
free(priv->lines[priv->last_line]);
|
||||
else
|
||||
priv->num_lines++;
|
||||
|
||||
priv->lines[priv->last_line] = strdup(l);
|
||||
priv->last_line = (priv->last_line + 1) % priv->buf_lines;
|
||||
priv->add_line = 1;
|
||||
}
|
||||
|
||||
static void add_string(struct menu_priv_s* priv, char* l) {
|
||||
char* eol = strchr(l,'\n');
|
||||
int ll = priv->last_line > 0 ? priv->last_line - 1 : priv->buf_lines-1;
|
||||
|
||||
if(priv->num_lines <= 0 || priv->add_line || eol == l) {
|
||||
add_line(priv,l);
|
||||
priv->add_line = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(eol) {
|
||||
eol[0] = '\0';
|
||||
add_string(priv,l);
|
||||
if(eol[1]) {
|
||||
add_line(priv,eol+1);
|
||||
priv->add_line = 0;
|
||||
} else
|
||||
priv->add_line = 1;
|
||||
return;
|
||||
}
|
||||
priv->lines[ll] = realloc(priv->lines[ll],strlen(priv->lines[ll]) + strlen(l) + 1);
|
||||
if ( priv->lines[ll] != NULL )
|
||||
{
|
||||
strcat(priv->lines[ll],l);
|
||||
}
|
||||
}
|
||||
|
||||
static void draw(menu_t* menu, mp_image_t* mpi) {
|
||||
int h = mpi->h*mpriv->height/100;
|
||||
int w = mpi->w - 2* mpriv->minb;
|
||||
int x = mpriv->minb, y;
|
||||
int lw,lh,i, ll;
|
||||
|
||||
if(mpriv->child) check_child(menu);
|
||||
|
||||
ll = mpriv->last_line - 1;
|
||||
|
||||
if(mpriv->hide_ts) {
|
||||
unsigned int t = GetTimerMS() - mpriv->hide_ts;
|
||||
if(t >= mpriv->hide_time) {
|
||||
mpriv->hide_ts = 0;
|
||||
menu->show = 0;
|
||||
return;
|
||||
}
|
||||
h = mpi->h*(mpriv->height - (mpriv->height * t /mpriv->hide_time))/100;
|
||||
} else if(mpriv->show_time && mpriv->show_ts == 0) {
|
||||
mpriv->show_ts = GetTimerMS();
|
||||
return;
|
||||
} else if(mpriv->show_ts > 0) {
|
||||
unsigned int t = GetTimerMS() - mpriv->show_ts;
|
||||
if(t > mpriv->show_time)
|
||||
mpriv->show_ts = -1;
|
||||
else
|
||||
h = mpi->h*(mpriv->height * t /mpriv->hide_time)/100;
|
||||
}
|
||||
|
||||
y = h - mpriv->vspace;
|
||||
|
||||
if(x < 0 || y < 0 || w <= 0 || h <= 0 )
|
||||
return;
|
||||
|
||||
if(mpriv->bg >= 0)
|
||||
menu_draw_box(mpi,mpriv->bg,mpriv->bg_alpha,0,0,mpi->w,h);
|
||||
|
||||
if(!mpriv->child || !mpriv->raw_child){
|
||||
char input[strlen(mpriv->cur_history->buffer) + strlen(mpriv->prompt) + 1];
|
||||
sprintf(input,"%s%s",mpriv->prompt,mpriv->cur_history->buffer);
|
||||
menu_text_size(input,w,mpriv->vspace,1,&lw,&lh);
|
||||
menu_draw_text_full(mpi,input,x,y,w,h,mpriv->vspace,1,
|
||||
MENU_TEXT_BOT|MENU_TEXT_LEFT,
|
||||
MENU_TEXT_BOT|MENU_TEXT_LEFT);
|
||||
y -= lh + mpriv->vspace;
|
||||
}
|
||||
|
||||
|
||||
for( i = 0 ; y > mpriv->minb && i < mpriv->num_lines ; i++){
|
||||
int c = (ll - i) >= 0 ? ll - i : mpriv->buf_lines + ll - i;
|
||||
menu_text_size(mpriv->lines[c],w,mpriv->vspace,1,&lw,&lh);
|
||||
menu_draw_text_full(mpi,mpriv->lines[c],x,y,w,h,mpriv->vspace,1,
|
||||
MENU_TEXT_BOT|MENU_TEXT_LEFT,
|
||||
MENU_TEXT_BOT|MENU_TEXT_LEFT);
|
||||
y -= lh + mpriv->vspace;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void check_child(menu_t* menu) {
|
||||
#ifndef __MINGW32__
|
||||
fd_set rfd;
|
||||
struct timeval tv;
|
||||
int max_fd = mpriv->child_fd[2] > mpriv->child_fd[1] ? mpriv->child_fd[2] :
|
||||
mpriv->child_fd[1];
|
||||
int i,r,child_status,w;
|
||||
char buffer[256];
|
||||
|
||||
if(!mpriv->child) return;
|
||||
|
||||
memset(&tv,0,sizeof(struct timeval));
|
||||
FD_ZERO(&rfd);
|
||||
FD_SET(mpriv->child_fd[1],&rfd);
|
||||
FD_SET(mpriv->child_fd[2],&rfd);
|
||||
|
||||
r = select(max_fd+1,&rfd, NULL, NULL, &tv);
|
||||
if(r == 0) {
|
||||
r = waitpid(mpriv->child,&child_status,WNOHANG);
|
||||
if(r < 0){
|
||||
if(errno==ECHILD){ ///exiting children get handled in mplayer.c
|
||||
for(i = 0 ; i < 3 ; i++)
|
||||
close(mpriv->child_fd[i]);
|
||||
mpriv->child = 0;
|
||||
mpriv->prompt = mpriv->mp_prompt;
|
||||
//add_line(mpriv,"Child process exited");
|
||||
}
|
||||
else mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Waitpid error: %s.\n",strerror(errno));
|
||||
}
|
||||
} else if(r < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Select error.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
w = 0;
|
||||
for(i = 1 ; i < 3 ; i++) {
|
||||
if(FD_ISSET(mpriv->child_fd[i],&rfd)){
|
||||
if(w) mpriv->add_line = 1;
|
||||
r = read(mpriv->child_fd[i],buffer,255);
|
||||
if(r < 0)
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Read error on child's file descriptor: %s.\n", i == 1 ? "stdout":"stderr");
|
||||
else if(r>0) {
|
||||
buffer[r] = '\0';
|
||||
add_string(mpriv,buffer);
|
||||
}
|
||||
w = 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#define close_pipe(pipe) close(pipe[0]); close(pipe[1])
|
||||
|
||||
static int run_shell_cmd(menu_t* menu, char* cmd) {
|
||||
#ifndef __MINGW32__
|
||||
int in[2],out[2],err[2];
|
||||
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_INFO,"[MENU] Console run: %s ...\n",cmd);
|
||||
if(mpriv->child) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] A child is already running.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pipe(in);
|
||||
pipe(out);
|
||||
pipe(err);
|
||||
|
||||
mpriv->child = fork();
|
||||
if(mpriv->child < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Fork failed !!!\n");
|
||||
close_pipe(in);
|
||||
close_pipe(out);
|
||||
close_pipe(err);
|
||||
return 0;
|
||||
}
|
||||
if(!mpriv->child) { // Chlid process
|
||||
int err_fd = dup(2);
|
||||
FILE* errf = fdopen(err_fd,"w");
|
||||
// Bind the std fd to our pipes
|
||||
dup2(in[0],0);
|
||||
dup2(out[1],1);
|
||||
dup2(err[1],2);
|
||||
execl("/bin/sh","sh","-c",cmd,(void*)NULL);
|
||||
fprintf(errf,"exec failed : %s\n",strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
// MPlayer
|
||||
mpriv->child_fd[0] = in[1];
|
||||
mpriv->child_fd[1] = out[0];
|
||||
mpriv->child_fd[2] = err[0];
|
||||
mpriv->prompt = mpriv->child_prompt;
|
||||
//add_line(mpriv,"Child process started");
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void enter_cmd(menu_t* menu) {
|
||||
history_t* h;
|
||||
char input[strlen(mpriv->cur_history->buffer) + strlen(mpriv->prompt) + 1];
|
||||
|
||||
sprintf(input,"%s%s",mpriv->prompt,mpriv->cur_history->buffer);
|
||||
add_line(mpriv,input);
|
||||
|
||||
if(mpriv->history == mpriv->cur_history) {
|
||||
if(mpriv->history_size >= mpriv->history_max) {
|
||||
history_t* i;
|
||||
for(i = mpriv->history ; i->prev ; i = i->prev)
|
||||
/**/;
|
||||
i->next->prev = NULL;
|
||||
free(i->buffer);
|
||||
free(i);
|
||||
} else
|
||||
mpriv->history_size++;
|
||||
h = calloc(1,sizeof(history_t));
|
||||
h->size = 255;
|
||||
h->buffer = calloc(h->size,1);
|
||||
h->prev = mpriv->history;
|
||||
mpriv->history->next = h;
|
||||
mpriv->history = h;
|
||||
} else
|
||||
mpriv->history->buffer[0] = '\0';
|
||||
|
||||
mpriv->cur_history = mpriv->history;
|
||||
//mpriv->input = mpriv->cur_history->buffer;
|
||||
}
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_CANCEL:
|
||||
if(mpriv->hide_time)
|
||||
mpriv->hide_ts = GetTimerMS();
|
||||
else
|
||||
menu->show = 0;
|
||||
mpriv->show_ts = 0;
|
||||
return;
|
||||
case MENU_CMD_OK: {
|
||||
mp_cmd_t* c;
|
||||
if(mpriv->child) {
|
||||
char *str = mpriv->cur_history->buffer;
|
||||
int l = strlen(str);
|
||||
while(l > 0) {
|
||||
int w = write(mpriv->child_fd[0],str,l);
|
||||
if(w < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] write error\n");
|
||||
break;
|
||||
}
|
||||
l -= w;
|
||||
str += w;
|
||||
}
|
||||
if(write(mpriv->child_fd[0],"\n",1) < 0)
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] write error\n");
|
||||
enter_cmd(menu);
|
||||
return;
|
||||
}
|
||||
c = mp_input_parse_cmd(mpriv->cur_history->buffer);
|
||||
enter_cmd(menu);
|
||||
if(!c)
|
||||
add_line(mpriv,"Invalid command try help");
|
||||
else {
|
||||
switch(c->id) {
|
||||
case MP_CMD_CHELP:
|
||||
add_line(mpriv,"MPlayer console 0.01");
|
||||
add_line(mpriv,"TODO: meaningful help message ;)");
|
||||
add_line(mpriv,"Enter any slave command");
|
||||
add_line(mpriv,"exit close this console");
|
||||
break;
|
||||
case MP_CMD_CEXIT:
|
||||
menu->show = 0;
|
||||
menu->cl = 1;
|
||||
break;
|
||||
case MP_CMD_CHIDE:
|
||||
if(mpriv->hide_time)
|
||||
mpriv->hide_ts = GetTimerMS();
|
||||
else
|
||||
menu->show = 0;
|
||||
mpriv->show_ts = 0;
|
||||
break;
|
||||
case MP_CMD_RUN:
|
||||
run_shell_cmd(menu,c->args[0].v.s);
|
||||
break;
|
||||
default: // Send the other commands to mplayer
|
||||
mp_input_queue_cmd(menu->input_ctx, c);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MENU_CMD_UP:
|
||||
if(mpriv->cur_history->prev)
|
||||
mpriv->cur_history = mpriv->cur_history->prev;
|
||||
break;
|
||||
case MENU_CMD_DOWN:
|
||||
if(mpriv->cur_history->next)
|
||||
mpriv->cur_history = mpriv->cur_history->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int read_key(menu_t* menu,int c) {
|
||||
if(mpriv->child && mpriv->raw_child) {
|
||||
write(mpriv->child_fd[0],&c,sizeof(int));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (c == KEY_DELETE || c == KEY_BS) {
|
||||
unsigned int i = strlen(mpriv->cur_history->buffer);
|
||||
if(i > 0)
|
||||
mpriv->cur_history->buffer[i-1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
if (menu_dflt_read_key(menu, c))
|
||||
return 1;
|
||||
|
||||
if(isascii(c)) {
|
||||
int l = strlen(mpriv->cur_history->buffer);
|
||||
if(l >= mpriv->cur_history->size) {
|
||||
mpriv->cur_history->size += 255;
|
||||
mpriv->cur_history->buffer = realloc(mpriv->cur_history,mpriv->cur_history->size);
|
||||
}
|
||||
mpriv->cur_history->buffer[l] = (char)c;
|
||||
mpriv->cur_history->buffer[l+1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int openMenu(menu_t* menu, char* args) {
|
||||
|
||||
|
||||
menu->draw = draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->read_key = read_key;
|
||||
|
||||
mpriv->lines = calloc(mpriv->buf_lines,sizeof(char*));
|
||||
mpriv->prompt = mpriv->mp_prompt;
|
||||
mpriv->cur_history = mpriv->history = calloc(1,sizeof(history_t));
|
||||
mpriv->cur_history->buffer = calloc(255,1);
|
||||
mpriv->cur_history->size = 255;
|
||||
|
||||
if(args)
|
||||
add_line(mpriv,args);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_console = {
|
||||
"MPlayer console",
|
||||
"console",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"console_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
openMenu,
|
||||
};
|
|
@ -1,301 +0,0 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
#include "input/input.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
#include "stream/dvbin.h"
|
||||
|
||||
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
int num; //the position of the chosen channel in the list
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
char* title;
|
||||
char* file;
|
||||
int card;
|
||||
int level;
|
||||
int auto_close;
|
||||
dvb_config_t *config;
|
||||
};
|
||||
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s, m)
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "title", ST_OFF(title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "auto-close", ST_OFF(auto_close), CONF_TYPE_FLAG, 0, 0, 1, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL },
|
||||
};
|
||||
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
"Select a channel: ",
|
||||
"channels.conf",
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static void free_entry(list_entry_t* entry)
|
||||
{
|
||||
free(entry->p.txt);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
||||
static int fill_channels_menu(menu_t *menu, dvb_channels_list *dvb_list_ptr)
|
||||
{
|
||||
int n;
|
||||
dvb_channel_t *channel;
|
||||
list_entry_t* elem;
|
||||
|
||||
mpriv->level = 2;
|
||||
if(dvb_list_ptr == NULL)
|
||||
{
|
||||
mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_set_channel: LIST NULL PTR, quit\n");
|
||||
n = 1;
|
||||
if((elem = calloc(1, sizeof(list_entry_t))) != NULL)
|
||||
{
|
||||
elem->p.next = NULL;
|
||||
elem->p.txt = strdup("There are no channels for this DVB card!");
|
||||
|
||||
menu_list_add_entry(menu, elem);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
for(n = 0; n < dvb_list_ptr->NUM_CHANNELS; n++)
|
||||
{
|
||||
channel = &(dvb_list_ptr->channels[n]);
|
||||
if((elem = calloc(1, sizeof(list_entry_t))) != NULL)
|
||||
{
|
||||
elem->p.next = NULL;
|
||||
elem->p.txt = strdup(channel->name);
|
||||
elem->num = n;
|
||||
|
||||
menu_list_add_entry(menu, elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
mp_msg(MSGT_DEMUX, MSGL_ERR, "dvb_menu: fill_menu: couldn't malloc %zd bytes for menu item: %s, exit\n",
|
||||
sizeof(list_entry_t), strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int fill_cards_menu(menu_t *menu, dvb_config_t *conf)
|
||||
{
|
||||
int n;
|
||||
list_entry_t* elem;
|
||||
|
||||
for(n = 0; n < conf->count; n++)
|
||||
{
|
||||
if((elem = calloc(1, sizeof(list_entry_t))) != NULL)
|
||||
{
|
||||
elem->p.next = NULL;
|
||||
elem->p.txt = strdup(conf->cards[n].name);
|
||||
elem->num = n;
|
||||
|
||||
if(n == 0)
|
||||
elem->p.prev = NULL;
|
||||
|
||||
menu_list_add_entry(menu, elem);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "dvb_menu: fill_menu: couldn't malloc %zd bytes for menu item: %s, exit\n",
|
||||
sizeof(list_entry_t), strerror(errno));
|
||||
if(n)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static int fill_menu(menu_t* menu)
|
||||
{
|
||||
list_entry_t* elem;
|
||||
dvb_channels_list *dvb_list_ptr;
|
||||
|
||||
menu_list_init(menu);
|
||||
|
||||
if(mpriv->config == NULL)
|
||||
{
|
||||
if((elem = calloc(1, sizeof(list_entry_t))) != NULL)
|
||||
{
|
||||
elem->p.prev = elem->p.next = NULL;
|
||||
elem->p.txt = strdup("NO DVB configuration present!");
|
||||
|
||||
menu_list_add_entry(menu, elem);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
mpriv->p.title = mpriv->title;
|
||||
if(mpriv->level == 1 && mpriv->config->count > 1)
|
||||
return fill_cards_menu(menu, mpriv->config);
|
||||
else
|
||||
{
|
||||
dvb_list_ptr = mpriv->config->cards[mpriv->card].list;
|
||||
return fill_channels_menu(menu, dvb_list_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void read_cmd(menu_t* menu, int cmd)
|
||||
{
|
||||
list_entry_t *elem;
|
||||
mp_cmd_t* c;
|
||||
char *cmd_name;
|
||||
switch(cmd)
|
||||
{
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK:
|
||||
{
|
||||
elem = mpriv->p.current;
|
||||
|
||||
if(mpriv->level == 1)
|
||||
{
|
||||
mpriv->card = mpriv->p.current->num;
|
||||
mpriv->level = 2;
|
||||
menu_list_uninit(menu, free_entry);
|
||||
fill_menu(menu);
|
||||
}
|
||||
else
|
||||
{
|
||||
dvb_priv_t *dvbp = (dvb_priv_t*) mpriv->config->priv;
|
||||
cmd_name = malloc(25 + strlen(elem->p.txt));
|
||||
if(dvbp != NULL)
|
||||
sprintf(cmd_name, "dvb_set_channel %d %d", elem->num, mpriv->card);
|
||||
else
|
||||
sprintf(cmd_name, "loadfile 'dvb://%d@%s'", mpriv->card+1, elem->p.txt);
|
||||
|
||||
c = mp_input_parse_cmd(cmd_name);
|
||||
free(cmd_name);
|
||||
if(c)
|
||||
{
|
||||
if(mpriv->auto_close)
|
||||
mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd ("menu hide"));
|
||||
mp_input_queue_cmd(menu->input_ctx, c);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MENU_CMD_LEFT:
|
||||
case MENU_CMD_CANCEL:
|
||||
{
|
||||
elem = mpriv->p.current;
|
||||
|
||||
menu_list_uninit(menu, free_entry);
|
||||
if(mpriv->config->count > 1)
|
||||
mpriv->level--;
|
||||
else
|
||||
mpriv->level = 0;
|
||||
|
||||
if(mpriv->level > 0)
|
||||
{
|
||||
fill_menu(menu);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
menu_list_read_cmd(menu, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void close_menu(menu_t* menu)
|
||||
{
|
||||
dvb_free_config(mpriv->config);
|
||||
menu_list_uninit(menu, free_entry);
|
||||
}
|
||||
|
||||
|
||||
static int open_dvb_sel(menu_t* menu, char* args)
|
||||
{
|
||||
mpriv->config = dvb_get_config();
|
||||
if(mpriv->config == NULL)
|
||||
return 0;
|
||||
|
||||
menu->draw = menu_list_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->close = close_menu;
|
||||
|
||||
mpriv->card = 0;
|
||||
mpriv->level = 1;
|
||||
return fill_menu(menu);
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_dvbsel =
|
||||
{
|
||||
"DVB channels menu", //descr
|
||||
"dvbsel", //name
|
||||
"Nico", //author
|
||||
"dvb_sel",
|
||||
{ //m_struct_t priv_st=
|
||||
"dvb_cfg", //name
|
||||
sizeof(struct menu_priv_s), //size
|
||||
&cfg_dflt, //defaults
|
||||
cfg_fields //settable fields
|
||||
},
|
||||
open_dvb_sel //open function
|
||||
};
|
|
@ -1,506 +0,0 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
#include "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
#include "input/input.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
#define MENU_KEEP_PATH "/tmp/mp_current_path"
|
||||
|
||||
int menu_keepdir = 0;
|
||||
char *menu_chroot = NULL;
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
int d;
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
char* dir; // current dir
|
||||
/// Cfg fields
|
||||
char* path;
|
||||
char* title;
|
||||
char* file_action;
|
||||
char* dir_action;
|
||||
char** actions;
|
||||
char* filter;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
NULL,
|
||||
|
||||
NULL,
|
||||
"Select a file: %p",
|
||||
"loadfile '%p'",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "path", ST_OFF(path), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "title", ST_OFF(title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "file-action", ST_OFF(file_action), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "dir-action", ST_OFF(dir_action), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "actions", ST_OFF(actions), CONF_TYPE_STRING_LIST, 0, 0, 0, NULL},
|
||||
{ "filter", ST_OFF(filter), CONF_TYPE_STRING, 0, 0, 0, NULL},
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void free_entry(list_entry_t* entry) {
|
||||
free(entry->p.txt);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static char* replace_path(char* title , char* dir , int escape) {
|
||||
char *p = strstr(title,"%p");
|
||||
if(p) {
|
||||
int tl = strlen(title);
|
||||
int dl = strlen(dir);
|
||||
int t1l = p-title;
|
||||
int l = tl - 2 + dl;
|
||||
char *r, *n, *d = dir;
|
||||
|
||||
if (escape) {
|
||||
do {
|
||||
if (*d == '\\')
|
||||
l++;
|
||||
else if (*d == '\'') /* ' -> \'\\\'\' */
|
||||
l+=7;
|
||||
} while (*d++);
|
||||
}
|
||||
r = malloc(l + 1);
|
||||
n = r + t1l;
|
||||
memcpy(r,title,t1l);
|
||||
do {
|
||||
if (escape) {
|
||||
if (*dir == '\\')
|
||||
*n++ = '\\';
|
||||
else if (*dir == '\'') { /* ' -> \'\\\'\' */
|
||||
*n++ = '\\'; *n++ = '\'';
|
||||
*n++ = '\\'; *n++ = '\\';
|
||||
*n++ = '\\'; *n++ = '\'';
|
||||
*n++ = '\\';
|
||||
}
|
||||
}
|
||||
} while ((*n++ = *dir++));
|
||||
if(tl - t1l - 2 > 0)
|
||||
strcpy(n-1,p+2);
|
||||
return r;
|
||||
} else
|
||||
return title;
|
||||
}
|
||||
|
||||
typedef int (*kill_warn)(const void*, const void*);
|
||||
|
||||
static int mylstat(char *dir, char *file,struct stat* st) {
|
||||
int l = strlen(dir) + strlen(file);
|
||||
char s[l+2];
|
||||
if (!strcmp("..", file)) {
|
||||
char *slash;
|
||||
l -= 3;
|
||||
strcpy(s, dir);
|
||||
#if HAVE_DOS_PATHS
|
||||
if (s[l] == '/' || s[l] == '\\')
|
||||
#else
|
||||
if (s[l] == '/')
|
||||
#endif
|
||||
s[l] = '\0';
|
||||
slash = strrchr(s, '/');
|
||||
#if HAVE_DOS_PATHS
|
||||
if (!slash)
|
||||
slash = strrchr(s,'\\');
|
||||
#endif
|
||||
if (!slash)
|
||||
return stat(dir,st);
|
||||
slash[1] = '\0';
|
||||
return stat(s,st);
|
||||
}
|
||||
sprintf(s,"%s/%s",dir,file);
|
||||
return stat(s,st);
|
||||
}
|
||||
|
||||
static int compare(char **a, char **b){
|
||||
if((*a)[strlen(*a) - 1] == '/') {
|
||||
if((*b)[strlen(*b) - 1] == '/')
|
||||
return strcmp(*b, *a) ;
|
||||
else
|
||||
return 1;
|
||||
} else {
|
||||
if((*b)[strlen(*b) - 1] == '/')
|
||||
return -1;
|
||||
else
|
||||
return strcmp(*b, *a);
|
||||
}
|
||||
}
|
||||
|
||||
static char **get_extensions(menu_t *menu){
|
||||
char **extensions, ext[32];
|
||||
FILE *fp;
|
||||
int n = 1;
|
||||
|
||||
if (!mpriv->filter)
|
||||
return NULL;
|
||||
|
||||
fp = fopen(mpriv->filter, "r");
|
||||
if(!fp)
|
||||
return NULL;
|
||||
|
||||
extensions = malloc(sizeof(*extensions));
|
||||
*extensions = NULL;
|
||||
|
||||
while(fgets(ext,sizeof(ext),fp)) {
|
||||
char **l, *e;
|
||||
int s = strlen (ext);
|
||||
|
||||
if(ext[s-1] == '\n') {
|
||||
ext[s-1] = '\0';
|
||||
s--;
|
||||
}
|
||||
e = malloc(s+1);
|
||||
extensions = realloc(extensions, ++n * sizeof(*extensions));
|
||||
extensions = realloc(extensions, ++n * sizeof(*extensions));
|
||||
strcpy (e, ext);
|
||||
for (l=extensions; *l; l++);
|
||||
*l++ = e;
|
||||
*l = NULL;
|
||||
}
|
||||
|
||||
fclose (fp);
|
||||
return extensions;
|
||||
}
|
||||
|
||||
static void free_extensions(char **extensions){
|
||||
if (extensions) {
|
||||
char **l = extensions;
|
||||
while (*l)
|
||||
free (*l++);
|
||||
free (extensions);
|
||||
}
|
||||
}
|
||||
|
||||
static int open_dir(menu_t* menu,char* args) {
|
||||
char **namelist, **tp;
|
||||
struct dirent *dp;
|
||||
struct stat st;
|
||||
int n;
|
||||
int path_fp;
|
||||
list_entry_t* e;
|
||||
DIR* dirp;
|
||||
extern int file_filter;
|
||||
char **extensions, **elem, *ext;
|
||||
|
||||
menu_list_init(menu);
|
||||
|
||||
free(mpriv->dir);
|
||||
mpriv->dir = strdup(args);
|
||||
if(mpriv->p.title && mpriv->p.title != mpriv->title && mpriv->p.title != cfg_dflt.p.title)
|
||||
free(mpriv->p.title);
|
||||
|
||||
mpriv->p.title = replace_path(mpriv->title,mpriv->dir,0);
|
||||
|
||||
if ((dirp = opendir (mpriv->dir)) == NULL){
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] opendir error: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (menu_keepdir) {
|
||||
path_fp = open (MENU_KEEP_PATH, O_CREAT | O_WRONLY | O_TRUNC, 0666);
|
||||
if (path_fp >= 0) {
|
||||
write (path_fp, mpriv->dir, strlen (mpriv->dir));
|
||||
close (path_fp);
|
||||
}
|
||||
}
|
||||
|
||||
namelist = malloc(sizeof(char *));
|
||||
extensions = get_extensions(menu);
|
||||
|
||||
n=0;
|
||||
while ((dp = readdir(dirp)) != NULL) {
|
||||
if(dp->d_name[0] == '.' && strcmp(dp->d_name,"..") != 0)
|
||||
continue;
|
||||
if (menu_chroot && !strcmp (dp->d_name,"..")) {
|
||||
size_t len = strlen (menu_chroot);
|
||||
if ((strlen (mpriv->dir) == len || strlen (mpriv->dir) == len + 1)
|
||||
&& !strncmp (mpriv->dir, menu_chroot, len))
|
||||
continue;
|
||||
}
|
||||
if (mylstat(args,dp->d_name,&st))
|
||||
continue;
|
||||
if (file_filter && extensions && !S_ISDIR(st.st_mode)) {
|
||||
if((ext = strrchr(dp->d_name,'.')) == NULL)
|
||||
continue;
|
||||
ext++;
|
||||
elem = extensions;
|
||||
do {
|
||||
if (!strcasecmp(ext, *elem))
|
||||
break;
|
||||
} while (*++elem);
|
||||
if (*elem == NULL)
|
||||
continue;
|
||||
}
|
||||
if(n%20 == 0){ // Get some more mem
|
||||
if((tp = realloc(namelist, (n+20) * sizeof (char *)))
|
||||
== NULL) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] realloc error: %s\n", strerror(errno));
|
||||
n--;
|
||||
goto bailout;
|
||||
}
|
||||
namelist=tp;
|
||||
}
|
||||
|
||||
namelist[n] = malloc(strlen(dp->d_name) + 2);
|
||||
if(namelist[n] == NULL){
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] memory allocation error: %s\n", strerror(errno));
|
||||
n--;
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
strcpy(namelist[n], dp->d_name);
|
||||
if(S_ISDIR(st.st_mode))
|
||||
strcat(namelist[n], "/");
|
||||
n++;
|
||||
}
|
||||
|
||||
bailout:
|
||||
free_extensions (extensions);
|
||||
closedir(dirp);
|
||||
|
||||
qsort(namelist, n, sizeof(char *), (kill_warn)compare);
|
||||
|
||||
if (n < 0) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] readdir error: %s\n",strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
while(n--) {
|
||||
if((e = calloc(1,sizeof(list_entry_t))) != NULL){
|
||||
e->p.next = NULL;
|
||||
e->p.txt = strdup(namelist[n]);
|
||||
if(strchr(namelist[n], '/') != NULL)
|
||||
e->d = 1;
|
||||
menu_list_add_entry(menu,e);
|
||||
}else{
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] memory allocation error: %s\n", strerror(errno));
|
||||
}
|
||||
free(namelist[n]);
|
||||
}
|
||||
free(namelist);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static char *action;
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_LEFT:
|
||||
mpriv->p.current = mpriv->p.menu; // Hack : we consider that the first entry is ../
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK: {
|
||||
// Directory
|
||||
if(mpriv->p.current->d && !mpriv->dir_action) {
|
||||
// Default action : open this dirctory ourself
|
||||
int l = strlen(mpriv->dir);
|
||||
char *slash = NULL, *p = NULL;
|
||||
if(strcmp(mpriv->p.current->p.txt,"../") == 0) {
|
||||
if(l <= 1) break;
|
||||
mpriv->dir[l-1] = '\0';
|
||||
slash = strrchr(mpriv->dir,'/');
|
||||
#if HAVE_DOS_PATHS
|
||||
if (!slash)
|
||||
slash = strrchr(mpriv->dir,'\\');
|
||||
#endif
|
||||
if(!slash) break;
|
||||
slash[1] = '\0';
|
||||
p = strdup(mpriv->dir);
|
||||
} else {
|
||||
p = malloc(l + strlen(mpriv->p.current->p.txt) + 1);
|
||||
sprintf(p,"%s%s",mpriv->dir,mpriv->p.current->p.txt);
|
||||
}
|
||||
menu_list_uninit(menu,free_entry);
|
||||
if(!open_dir(menu,p)) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_ERR,"[MENU] Can't open directory %s.\n",p);
|
||||
menu->cl = 1;
|
||||
}
|
||||
free(p);
|
||||
} else { // File and directory dealt with action string.
|
||||
int fname_len = strlen(mpriv->dir) + strlen(mpriv->p.current->p.txt) + 1;
|
||||
char filename[fname_len];
|
||||
char *str;
|
||||
char *action = mpriv->p.current->d ? mpriv->dir_action:mpriv->file_action;
|
||||
sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt);
|
||||
str = replace_path(action, filename,1);
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, str);
|
||||
if (str != action)
|
||||
free(str);
|
||||
}
|
||||
} break;
|
||||
case MENU_CMD_ACTION: {
|
||||
int fname_len = strlen(mpriv->dir) + strlen(mpriv->p.current->p.txt) + 1;
|
||||
char filename[fname_len];
|
||||
char *str;
|
||||
sprintf(filename,"%s%s",mpriv->dir,mpriv->p.current->p.txt);
|
||||
str = replace_path(action, filename,1);
|
||||
mp_input_parse_and_queue_cmds(menu->input_ctx, str);
|
||||
if(str != action)
|
||||
free(str);
|
||||
} break;
|
||||
default:
|
||||
menu_list_read_cmd(menu,cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_key(menu_t* menu,int c){
|
||||
char **str;
|
||||
for (str=mpriv->actions; str && *str; str++)
|
||||
if (c == (*str)[0]) {
|
||||
action = &(*str)[2];
|
||||
read_cmd(menu,MENU_CMD_ACTION);
|
||||
return 1;
|
||||
}
|
||||
if (menu_dflt_read_key(menu, c))
|
||||
return 1;
|
||||
return menu_list_jump_to_key(menu, c);
|
||||
}
|
||||
|
||||
static void clos(menu_t* menu) {
|
||||
menu_list_uninit(menu,free_entry);
|
||||
free(mpriv->dir);
|
||||
}
|
||||
|
||||
static int open_fs(menu_t* menu, char* args) {
|
||||
char *path = mpriv->path;
|
||||
int r = 0;
|
||||
char wd[PATH_MAX+1], b[PATH_MAX+1];
|
||||
args = NULL; // Warning kill
|
||||
|
||||
menu->draw = menu_list_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->read_key = read_key;
|
||||
menu->close = clos;
|
||||
|
||||
if (menu_keepdir) {
|
||||
if (!path || path[0] == '\0') {
|
||||
struct stat st;
|
||||
int path_fp;
|
||||
|
||||
path_fp = open (MENU_KEEP_PATH, O_RDONLY);
|
||||
if (path_fp >= 0) {
|
||||
if (!fstat (path_fp, &st) && (st.st_size > 0)) {
|
||||
path = malloc(st.st_size+1);
|
||||
path[st.st_size] = '\0';
|
||||
if (!((read(path_fp, path, st.st_size) == st.st_size) && path[0] == '/'
|
||||
&& !stat(path, &st) && S_ISDIR(st.st_mode))) {
|
||||
free(path);
|
||||
path = NULL;
|
||||
}
|
||||
}
|
||||
close (path_fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getcwd(wd,PATH_MAX);
|
||||
if (!path || path[0] == '\0') {
|
||||
#if 0
|
||||
char *slash = NULL;
|
||||
if (filename && !strstr(filename, "://") && (path=realpath(filename, b))) {
|
||||
slash = strrchr(path, '/');
|
||||
#if HAVE_DOS_PATHS
|
||||
// FIXME: Do we need and can convert all '\\' in path to '/' on win32?
|
||||
if (!slash)
|
||||
slash = strrchr(path, '\\');
|
||||
#endif
|
||||
}
|
||||
if (slash)
|
||||
slash[1] = '\0';
|
||||
else
|
||||
#endif
|
||||
path = wd;
|
||||
}
|
||||
if (path[0] != '/') {
|
||||
if(path[strlen(path)-1] != '/')
|
||||
snprintf(b,sizeof(b),"%s/%s/",wd,path);
|
||||
else
|
||||
snprintf(b,sizeof(b),"%s/%s",wd,path);
|
||||
path = b;
|
||||
} else if (path[strlen(path)-1]!='/') {
|
||||
sprintf(b,"%s/",path);
|
||||
path = b;
|
||||
}
|
||||
if (menu_chroot && menu_chroot[0] == '/') {
|
||||
int l = strlen(menu_chroot);
|
||||
if (l > 0 && menu_chroot[l-1] == '/')
|
||||
--l;
|
||||
if (strncmp(menu_chroot, path, l) || (path[l] != '\0' && path[l] != '/')) {
|
||||
if (menu_chroot[l] == '/')
|
||||
path = menu_chroot;
|
||||
else {
|
||||
sprintf(b,"%s/",menu_chroot);
|
||||
path = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
r = open_dir(menu,path);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_filesel = {
|
||||
"File seletor menu",
|
||||
"filesel",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"fs_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
open_fs
|
||||
};
|
|
@ -1,331 +0,0 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "menu.h"
|
||||
|
||||
#include "sub/font_load.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
#define IMPL 1
|
||||
#include "menu_list.h"
|
||||
|
||||
static int mouse_x;
|
||||
static int mouse_y;
|
||||
static int selection_x;
|
||||
static int selection_y;
|
||||
static int selection_w;
|
||||
static int selection_h;
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
void menu_list_draw(menu_t* menu,mp_image_t* mpi) {
|
||||
int x = mpriv->x;
|
||||
int y = mpriv->y;
|
||||
int i;
|
||||
int h = mpriv->h;
|
||||
int w = mpriv->w;
|
||||
int dh = 0,dw = 0;
|
||||
int bx, dx, dy = 0;
|
||||
int need_h = 0,need_w = 0,ptr_l,sidx = 0;
|
||||
int th,count = 0;
|
||||
int bg_w;
|
||||
int line_h;
|
||||
list_entry_t* m;
|
||||
|
||||
if(mpriv->count < 1)
|
||||
return;
|
||||
|
||||
if(h <= 0) h = mpi->height;
|
||||
if(w <= 0) w = mpi->width;
|
||||
dh = h - 2*mpriv->minb;
|
||||
dw = w - 2*mpriv->minb;
|
||||
ptr_l = mpriv->ptr ? menu_text_length(mpriv->ptr) : 0;
|
||||
// mpi is too small
|
||||
if(h - vo_font->height <= 0 || w - ptr_l <= 0 || dw <= 0 || dh <= 0)
|
||||
return;
|
||||
|
||||
line_h = mpriv->vspace + vo_font->height;
|
||||
th = menu_text_num_lines(mpriv->title,dw) * line_h + mpriv->vspace;
|
||||
|
||||
// the selected item is hidden, find a visible one
|
||||
if(mpriv->current->hide) {
|
||||
// try the next
|
||||
for(m = mpriv->current->next ; m ; m = m->next)
|
||||
if(!m->hide) break;
|
||||
if(!m) // or the previous
|
||||
for(m = mpriv->current->prev ; m ; m = m->prev)
|
||||
if(!m->hide) break;
|
||||
if(m) mpriv->current = m;
|
||||
else ptr_l = 0;
|
||||
}
|
||||
|
||||
for(i = 0, m = mpriv->menu ; m ; m = m->next, i++) {
|
||||
int ll;
|
||||
if(m->hide) continue;
|
||||
ll = menu_text_length(m->txt);
|
||||
if(ptr_l + ll > need_w) need_w = ptr_l + ll;
|
||||
if(m == mpriv->current) sidx = i;
|
||||
count++;
|
||||
}
|
||||
if(need_w > dw) need_w = dw;
|
||||
if(x >= 0)
|
||||
x += mpriv->minb;
|
||||
if(y > 0)
|
||||
y += mpriv->minb;
|
||||
else
|
||||
y = mpriv->minb;
|
||||
|
||||
need_h = count * line_h - mpriv->vspace;
|
||||
if( need_h + th > dh) {
|
||||
int start,end;
|
||||
mpriv->disp_lines = (dh + mpriv->vspace - th) / line_h;
|
||||
if(mpriv->disp_lines < 4) {
|
||||
th = 0;
|
||||
mpriv->disp_lines = (dh + mpriv->vspace) / line_h;
|
||||
}
|
||||
// Too smoll
|
||||
if(mpriv->disp_lines < 1) return;
|
||||
need_h = mpriv->disp_lines * line_h - mpriv->vspace;
|
||||
|
||||
start = sidx - (mpriv->disp_lines/2);
|
||||
if(start < 0) start = 0;
|
||||
end = start + mpriv->disp_lines;
|
||||
if(end > count) {
|
||||
end = count;
|
||||
if(end - start < mpriv->disp_lines)
|
||||
start = end - mpriv->disp_lines < 0 ? 0 : end - mpriv->disp_lines;
|
||||
}
|
||||
m = mpriv->menu;
|
||||
for(i = 0 ; m->next && i < start ; ) {
|
||||
if(!m->hide) i++;
|
||||
m = m->next;
|
||||
}
|
||||
} else {
|
||||
m = mpriv->menu;
|
||||
mpriv->disp_lines = count;
|
||||
}
|
||||
|
||||
bg_w = need_w+2*mpriv->minb;
|
||||
if(th > 0) {
|
||||
int tw,th2;
|
||||
menu_text_size(mpriv->title,dw,mpriv->vspace,1,&tw,&th2);
|
||||
if(mpriv->title_bg >= 0) {
|
||||
if(tw+2*mpriv->minb > bg_w) bg_w = tw+2*mpriv->minb;
|
||||
menu_draw_box(mpi,mpriv->title_bg,mpriv->title_bg_alpha,
|
||||
x < 0 ? (mpi->w-bg_w)/2 : x-mpriv->minb,dy+y-mpriv->vspace/2,bg_w,th);
|
||||
}
|
||||
menu_draw_text_full(mpi,mpriv->title,
|
||||
x < 0 ? mpi->w / 2 : x,
|
||||
dy+y, x < 0 ? dw : (tw > need_w ? tw : need_w), 0,
|
||||
mpriv->vspace,1,
|
||||
MENU_TEXT_TOP|MENU_TEXT_HCENTER,
|
||||
MENU_TEXT_TOP|(x < 0 ? MENU_TEXT_HCENTER :MENU_TEXT_LEFT));
|
||||
dy += th;
|
||||
}
|
||||
|
||||
dx = x < 0 ? (mpi->w - need_w) / 2 : x;
|
||||
bx = x < 0 ? (mpi->w - bg_w) / 2 : x - mpriv->minb;
|
||||
|
||||
// If mouse moved, try to update selected menu item by the mouse position.
|
||||
if (menu_mouse_pos_updated) {
|
||||
mouse_x = menu_mouse_x * mpi->width;
|
||||
mouse_y = menu_mouse_y * mpi->height;
|
||||
if (mouse_x >= bx && mouse_x < bx + bg_w) {
|
||||
int by = dy + y - mpriv->vspace / 2;
|
||||
int max_by = dh + y + mpriv->vspace / 2;
|
||||
if (mouse_y >= by && mouse_y < max_by) {
|
||||
int cur_no = (mouse_y - by) / line_h;
|
||||
list_entry_t* e = m;
|
||||
for (i = 0; e != NULL; e = e->next) {
|
||||
if (e->hide) continue;
|
||||
if (i == cur_no) {
|
||||
mpriv->current = e;
|
||||
break;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
menu_mouse_pos_updated = 0;
|
||||
}
|
||||
|
||||
for( ; m != NULL && dy + vo_font->height < dh ; m = m->next ) {
|
||||
if(m->hide) continue;
|
||||
if(m == mpriv->current) {
|
||||
// Record rectangle of current selection box.
|
||||
selection_x = bx;
|
||||
selection_y = dy + y - mpriv->vspace / 2;
|
||||
selection_w = bg_w;
|
||||
selection_h = line_h;
|
||||
|
||||
if(mpriv->ptr_bg >= 0)
|
||||
menu_draw_box(mpi,mpriv->ptr_bg,mpriv->ptr_bg_alpha,
|
||||
bx, dy + y - mpriv->vspace / 2,
|
||||
bg_w, line_h);
|
||||
if(ptr_l > 0)
|
||||
menu_draw_text_full(mpi,mpriv->ptr,
|
||||
dx,
|
||||
dy+y,dw,dh - dy,
|
||||
mpriv->vspace,0,
|
||||
MENU_TEXT_TOP|MENU_TEXT_LEFT,
|
||||
MENU_TEXT_TOP|MENU_TEXT_LEFT);
|
||||
} else if(mpriv->item_bg >= 0)
|
||||
menu_draw_box(mpi,mpriv->item_bg,mpriv->item_bg_alpha,
|
||||
bx, dy + y - mpriv->vspace / 2,
|
||||
bg_w, line_h);
|
||||
menu_draw_text_full(mpi,m->txt,
|
||||
dx + ptr_l,
|
||||
dy+y,dw-ptr_l,dh - dy,
|
||||
mpriv->vspace,0,
|
||||
MENU_TEXT_TOP|MENU_TEXT_LEFT,
|
||||
MENU_TEXT_TOP|MENU_TEXT_LEFT);
|
||||
dy += line_h;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void menu_list_read_cmd(menu_t* menu,int cmd) {
|
||||
list_entry_t* m;
|
||||
int i;
|
||||
switch(cmd) {
|
||||
case MENU_CMD_UP:
|
||||
while(mpriv->current->prev) {
|
||||
mpriv->current = mpriv->current->prev;
|
||||
if(!mpriv->current->hide) return;
|
||||
}
|
||||
for( ; mpriv->current->next != NULL ; mpriv->current = mpriv->current->next)
|
||||
/* NOTHING */;
|
||||
if(!mpriv->current->hide) return;
|
||||
while(mpriv->current->prev) {
|
||||
mpriv->current = mpriv->current->prev;
|
||||
if(!mpriv->current->hide) return;
|
||||
}
|
||||
break;
|
||||
case MENU_CMD_DOWN:
|
||||
while(mpriv->current->next) {
|
||||
mpriv->current = mpriv->current->next;
|
||||
if(!mpriv->current->hide) return;
|
||||
}
|
||||
mpriv->current = mpriv->menu;
|
||||
if(!mpriv->current->hide) return;
|
||||
while(mpriv->current->next) {
|
||||
mpriv->current = mpriv->current->next;
|
||||
if(!mpriv->current->hide) return;
|
||||
}
|
||||
break;
|
||||
case MENU_CMD_HOME:
|
||||
mpriv->current = mpriv->menu;
|
||||
break;
|
||||
case MENU_CMD_END:
|
||||
for(m = mpriv->current ; m && m->next ; m = m->next)
|
||||
/**/;
|
||||
if(m)
|
||||
mpriv->current = m;
|
||||
break;
|
||||
case MENU_CMD_PAGE_UP:
|
||||
for(i = 0, m = mpriv->current ; m && m->prev && i < mpriv->disp_lines ; m = m->prev, i++)
|
||||
/**/;
|
||||
if(m)
|
||||
mpriv->current = m;
|
||||
break;
|
||||
case MENU_CMD_PAGE_DOWN:
|
||||
for(i = 0, m = mpriv->current ; m && m->next && i < mpriv->disp_lines ; m = m->next, i++)
|
||||
/**/;
|
||||
if(m)
|
||||
mpriv->current = m;
|
||||
break;
|
||||
case MENU_CMD_LEFT:
|
||||
case MENU_CMD_CANCEL:
|
||||
menu->show = 0;
|
||||
menu->cl = 1;
|
||||
break;
|
||||
case MENU_CMD_CLICK:
|
||||
if (mouse_x >= selection_x && mouse_x < selection_x + selection_w &&
|
||||
mouse_y >= selection_y && mouse_y < selection_y + selection_h)
|
||||
menu_read_cmd(menu, MENU_CMD_OK);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int menu_list_jump_to_key(menu_t* menu,int c) {
|
||||
if(c < 256 && isalnum(c)) {
|
||||
list_entry_t* e = mpriv->current;
|
||||
if(e->txt[0] == c) e = e->next;
|
||||
for( ; e ; e = e->next) {
|
||||
if(e->txt[0] == c) {
|
||||
mpriv->current = e;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
for(e = mpriv->menu ; e ; e = e->next) {
|
||||
if(e->txt[0] == c) {
|
||||
mpriv->current = e;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void menu_list_add_entry(menu_t* menu,list_entry_t* entry) {
|
||||
list_entry_t* l;
|
||||
mpriv->count++;
|
||||
|
||||
if(mpriv->menu == NULL) {
|
||||
mpriv->menu = mpriv->current = entry;
|
||||
return;
|
||||
}
|
||||
|
||||
for(l = mpriv->menu ; l->next != NULL ; l = l->next)
|
||||
/* NOP */;
|
||||
l->next = entry;
|
||||
entry->prev = l;
|
||||
}
|
||||
|
||||
void menu_list_init(menu_t* menu) {
|
||||
if(!mpriv)
|
||||
mpriv = calloc(1,sizeof(struct menu_priv_s));
|
||||
|
||||
}
|
||||
|
||||
void menu_list_uninit(menu_t* menu,free_entry_t free_func) {
|
||||
list_entry_t *i,*j;
|
||||
|
||||
if(!free_func) free_func = (free_entry_t)free;
|
||||
|
||||
for(i = mpriv->menu ; i != NULL ; ) {
|
||||
j = i->next;
|
||||
free_func(i);
|
||||
i = j;
|
||||
}
|
||||
|
||||
mpriv->menu = mpriv->current = NULL;
|
||||
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/*
|
||||
* 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_MENU_LIST_H
|
||||
#define MPLAYER_MENU_LIST_H
|
||||
|
||||
#include "menu.h"
|
||||
|
||||
typedef struct list_entry_s list_entry_t;
|
||||
|
||||
|
||||
#ifdef IMPL
|
||||
struct list_entry_s {
|
||||
#else
|
||||
struct list_entry {
|
||||
#endif
|
||||
list_entry_t* prev;
|
||||
list_entry_t* next;
|
||||
|
||||
char* txt;
|
||||
char hide;
|
||||
};
|
||||
|
||||
|
||||
#ifndef IMPL
|
||||
typedef struct menu_list_priv_s {
|
||||
#else
|
||||
typedef struct menu_priv_s {
|
||||
#endif
|
||||
list_entry_t* menu;
|
||||
list_entry_t* current;
|
||||
int count;
|
||||
|
||||
char* title;
|
||||
int x,y;
|
||||
int w,h;
|
||||
int vspace, minb;
|
||||
int disp_lines;
|
||||
char* ptr;
|
||||
int title_bg,title_bg_alpha;
|
||||
int item_bg,item_bg_alpha;
|
||||
int ptr_bg,ptr_bg_alpha;
|
||||
} menu_list_priv_t;
|
||||
|
||||
typedef void (*free_entry_t)(list_entry_t* entry);
|
||||
|
||||
void menu_list_read_cmd(menu_t* menu,int cmd);
|
||||
void menu_list_draw(menu_t* menu,mp_image_t* mpi);
|
||||
void menu_list_add_entry(menu_t* menu,list_entry_t* entry);
|
||||
void menu_list_init(menu_t* menu);
|
||||
void menu_list_uninit(menu_t* menu,free_entry_t free_func);
|
||||
int menu_list_jump_to_key(menu_t* menu,int c);
|
||||
|
||||
extern const menu_list_priv_t menu_list_priv_dflt;
|
||||
|
||||
#define MENU_LIST_PRIV_DFLT { \
|
||||
NULL, \
|
||||
NULL, \
|
||||
0, \
|
||||
\
|
||||
"MPlayer", \
|
||||
-1,-1, \
|
||||
0,0, \
|
||||
5, 3, \
|
||||
0, \
|
||||
NULL, \
|
||||
0xFF, 0xFF, \
|
||||
0xFF, 0xFF, \
|
||||
0xA4, 0x50 \
|
||||
}
|
||||
|
||||
|
||||
#define MENU_LIST_PRIV_FIELDS \
|
||||
{ "minbor", M_ST_OFF(menu_list_priv_t,minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "vspace", M_ST_OFF(menu_list_priv_t,vspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "x", M_ST_OFF(menu_list_priv_t,x), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "y", M_ST_OFF(menu_list_priv_t,y), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "w", M_ST_OFF(menu_list_priv_t,w), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "h", M_ST_OFF(menu_list_priv_t,h), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL }, \
|
||||
{ "ptr", M_ST_OFF(menu_list_priv_t,ptr), CONF_TYPE_STRING, 0, 0, 0, NULL }, \
|
||||
{ "title-bg", M_ST_OFF(menu_list_priv_t,title_bg), CONF_TYPE_INT, M_OPT_RANGE, -1, 255, NULL }, \
|
||||
{ "title-bg-alpha", M_ST_OFF(menu_list_priv_t,title_bg_alpha), \
|
||||
CONF_TYPE_INT, M_OPT_RANGE, 0, 255, NULL }, \
|
||||
{ "item-bg", M_ST_OFF(menu_list_priv_t,item_bg), CONF_TYPE_INT, M_OPT_RANGE, -1, 255, NULL }, \
|
||||
{ "item-bg-alpha", M_ST_OFF(menu_list_priv_t,item_bg_alpha), \
|
||||
CONF_TYPE_INT, M_OPT_RANGE, 0, 255, NULL }, \
|
||||
{ "ptr-bg", M_ST_OFF(menu_list_priv_t,ptr_bg), CONF_TYPE_INT, M_OPT_RANGE, -1, 255, NULL }, \
|
||||
{ "ptr-bg-alpha", M_ST_OFF(menu_list_priv_t,ptr_bg_alpha), \
|
||||
CONF_TYPE_INT, M_OPT_RANGE, 0, 255, NULL } \
|
||||
|
||||
#endif /* MPLAYER_MENU_LIST_H */
|
|
@ -1,301 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
#include "m_property.h"
|
||||
#include "asxparser.h"
|
||||
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
#include "input/input.h"
|
||||
#include "command.h"
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
char* name;
|
||||
char* txt;
|
||||
char* prop;
|
||||
m_option_t* opt;
|
||||
char* menu;
|
||||
int auto_update;
|
||||
};
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
char* ptr;
|
||||
int edit;
|
||||
/// Cfg fields
|
||||
char* na;
|
||||
int hide_na;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
NULL,
|
||||
0,
|
||||
"N/A",
|
||||
1
|
||||
};
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "title", M_ST_OFF(menu_list_priv_t,title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "na", M_ST_OFF(struct menu_priv_s,na), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "hide-na", M_ST_OFF(struct menu_priv_s,hide_na), CONF_TYPE_FLAG, CONF_RANGE, 0, 1, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void entry_set_text(menu_t* menu, list_entry_t* e) {
|
||||
char* val = e->txt ? property_expand_string(menu->ctx, e->txt) :
|
||||
mp_property_print(e->prop, menu->ctx);
|
||||
int l,edit = (mpriv->edit && e == mpriv->p.current);
|
||||
if(!val || !val[0]) {
|
||||
free(val);
|
||||
if(mpriv->hide_na) {
|
||||
e->p.hide = 1;
|
||||
return;
|
||||
}
|
||||
val = strdup(mpriv->na);
|
||||
} else if(mpriv->hide_na)
|
||||
e->p.hide = 0;
|
||||
l = strlen(e->name) + 2 + strlen(val) + (edit ? 4 : 0) + 1;
|
||||
free(e->p.txt);
|
||||
e->p.txt = malloc(l);
|
||||
sprintf(e->p.txt,"%s: %s%s%s",e->name,edit ? "> " : "",val,edit ? " <" : "");
|
||||
free(val);
|
||||
}
|
||||
|
||||
static void update_entries(menu_t* menu, int auto_update) {
|
||||
list_entry_t* e;
|
||||
for(e = mpriv->p.menu ; e ; e = e->p.next)
|
||||
if ((e->txt || e->prop) && (!auto_update || e->auto_update))
|
||||
entry_set_text(menu, e);
|
||||
}
|
||||
|
||||
static int parse_args(menu_t* menu,char* args) {
|
||||
char *element,*body, **attribs, *name, *txt, *auto_update;
|
||||
list_entry_t* m = NULL;
|
||||
int r;
|
||||
m_option_t* opt;
|
||||
ASX_Parser_t* parser = asx_parser_new(menu->mconfig);
|
||||
|
||||
|
||||
while(1) {
|
||||
r = asx_get_element(parser,&args,&element,&body,&attribs);
|
||||
if(r < 0) {
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_ERR,"[MENU] syntax error at line: %d\n",parser->line);
|
||||
asx_parser_free(parser);
|
||||
return -1;
|
||||
} else if(r == 0) {
|
||||
asx_parser_free(parser);
|
||||
if(!m)
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_WARN,"[MENU] No entry found in the menu definition.\n");
|
||||
m = calloc(1,sizeof(struct list_entry_s));
|
||||
m->p.txt = strdup("Back");
|
||||
menu_list_add_entry(menu,m);
|
||||
return 1;
|
||||
}
|
||||
if(!strcmp(element,"menu")) {
|
||||
name = asx_get_attrib("menu",attribs);
|
||||
if(!name) {
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_WARN,"[MENU] Submenu definition needs a 'menu' attribute.\n");
|
||||
goto next_element;
|
||||
}
|
||||
m = calloc(1,sizeof(struct list_entry_s));
|
||||
m->menu = name;
|
||||
name = NULL; // we want to keep it
|
||||
m->p.txt = asx_get_attrib("name",attribs);
|
||||
if(!m->p.txt) m->p.txt = strdup(m->menu);
|
||||
menu_list_add_entry(menu,m);
|
||||
goto next_element;
|
||||
}
|
||||
|
||||
name = asx_get_attrib("property",attribs);
|
||||
opt = NULL;
|
||||
if(name && mp_property_do(name,M_PROPERTY_GET_TYPE,&opt,menu->ctx) <= 0) {
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_WARN,"[MENU] Invalid property '%s' in pref menu entry. (line %d).\n",
|
||||
name,parser->line);
|
||||
goto next_element;
|
||||
}
|
||||
txt = asx_get_attrib("txt",attribs);
|
||||
if(!(name || txt)) {
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_WARN,"[MENU] Pref menu entry definitions need a valid 'property' or 'txt' attribute (line %d).\n",parser->line);
|
||||
free(txt);
|
||||
txt = NULL;
|
||||
goto next_element;
|
||||
}
|
||||
m = calloc(1,sizeof(struct list_entry_s));
|
||||
m->opt = opt;
|
||||
m->txt = txt; txt = NULL;
|
||||
m->prop = name; name = NULL;
|
||||
m->name = asx_get_attrib("name",attribs);
|
||||
if(!m->name) m->name = strdup(opt ? opt->name : "-");
|
||||
auto_update = asx_get_attrib("auto-update", attribs);
|
||||
if (auto_update) {
|
||||
if (!strcmp(auto_update, "1") ||
|
||||
!strcasecmp(auto_update, "on") ||
|
||||
!strcasecmp(auto_update, "yes") ||
|
||||
!strcasecmp(auto_update, "true"))
|
||||
m->auto_update = 1;
|
||||
free(auto_update);
|
||||
}
|
||||
entry_set_text(menu,m);
|
||||
menu_list_add_entry(menu,m);
|
||||
|
||||
next_element:
|
||||
free(element);
|
||||
free(body);
|
||||
free(name);
|
||||
asx_free_attribs(attribs);
|
||||
}
|
||||
}
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
list_entry_t* e = mpriv->p.current;
|
||||
|
||||
if(e->opt) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_UP:
|
||||
if(!mpriv->edit) break;
|
||||
case MENU_CMD_RIGHT:
|
||||
if(mp_property_do(e->prop,M_PROPERTY_STEP_UP,NULL,menu->ctx) > 0)
|
||||
update_entries(menu, 0);
|
||||
return;
|
||||
case MENU_CMD_DOWN:
|
||||
if(!mpriv->edit) break;
|
||||
case MENU_CMD_LEFT:
|
||||
if(mp_property_do(e->prop,M_PROPERTY_STEP_DOWN,NULL,menu->ctx) > 0)
|
||||
update_entries(menu, 0);
|
||||
return;
|
||||
|
||||
case MENU_CMD_OK:
|
||||
// check that the property is writable
|
||||
if(mp_property_do(e->prop,M_PROPERTY_SET,NULL,menu->ctx) < 0) return;
|
||||
// shortcut for flags
|
||||
if(e->opt->type == CONF_TYPE_FLAG) {
|
||||
if(mp_property_do(e->prop,M_PROPERTY_STEP_UP,NULL,menu->ctx) > 0)
|
||||
update_entries(menu, 0);
|
||||
return;
|
||||
}
|
||||
// switch
|
||||
mpriv->edit = !mpriv->edit;
|
||||
// update the menu
|
||||
update_entries(menu, 0);
|
||||
// switch the pointer
|
||||
if(mpriv->edit) {
|
||||
mpriv->ptr = mpriv->p.ptr;
|
||||
mpriv->p.ptr = NULL;
|
||||
} else
|
||||
mpriv->p.ptr = mpriv->ptr;
|
||||
return;
|
||||
case MENU_CMD_CANCEL:
|
||||
if(!mpriv->edit) break;
|
||||
mpriv->edit = 0;
|
||||
update_entries(menu, 0);
|
||||
mpriv->p.ptr = mpriv->ptr;
|
||||
return;
|
||||
}
|
||||
} else if(e->menu) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK: {
|
||||
mp_cmd_t* c;
|
||||
char* txt = malloc(10 + strlen(e->menu) + 1);
|
||||
sprintf(txt,"set_menu %s",e->menu);
|
||||
c = mp_input_parse_cmd(txt);
|
||||
if(c) mp_input_queue_cmd(menu->input_ctx, c);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK:
|
||||
menu->show = 0;
|
||||
menu->cl = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
menu_list_read_cmd(menu,cmd);
|
||||
}
|
||||
|
||||
static void free_entry(list_entry_t* entry) {
|
||||
free(entry->p.txt);
|
||||
free(entry->name);
|
||||
free(entry->txt);
|
||||
free(entry->prop);
|
||||
free(entry->menu);
|
||||
free(entry);
|
||||
}
|
||||
|
||||
static void closeMenu(menu_t* menu) {
|
||||
menu_list_uninit(menu,free_entry);
|
||||
}
|
||||
|
||||
static void menu_pref_draw(menu_t* menu, mp_image_t* mpi) {
|
||||
update_entries(menu, 1);
|
||||
menu_list_draw(menu, mpi);
|
||||
}
|
||||
|
||||
static int openMenu(menu_t* menu, char* args) {
|
||||
|
||||
menu->draw = menu_pref_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->close = closeMenu;
|
||||
|
||||
|
||||
if(!args) {
|
||||
mp_tmsg(MSGT_OSD_MENU,MSGL_ERR,"[MENU] Pref menu needs an argument.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
menu_list_init(menu);
|
||||
return parse_args(menu,args);
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_pref = {
|
||||
"Preferences menu",
|
||||
"pref",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"pref_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
openMenu
|
||||
};
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
* 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 <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
//#include <libgen.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "mp_msg.h"
|
||||
#include "path.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
#include "menu.h"
|
||||
#include "menu_list.h"
|
||||
|
||||
|
||||
#include "playtree.h"
|
||||
#include "input/input.h"
|
||||
#include "access_mpcontext.h"
|
||||
|
||||
struct list_entry_s {
|
||||
struct list_entry p;
|
||||
play_tree_t* pt;
|
||||
};
|
||||
|
||||
|
||||
struct menu_priv_s {
|
||||
menu_list_priv_t p;
|
||||
char* title;
|
||||
int auto_close;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
MENU_LIST_PRIV_DFLT,
|
||||
"Jump to",
|
||||
0
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
MENU_LIST_PRIV_FIELDS,
|
||||
{ "title", ST_OFF(title), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ "auto-close", ST_OFF(auto_close), CONF_TYPE_FLAG, 0, 0, 1, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_RIGHT:
|
||||
case MENU_CMD_OK: {
|
||||
int d = 1;
|
||||
char str[15];
|
||||
play_tree_t* i;
|
||||
mp_cmd_t* c;
|
||||
play_tree_iter_t* playtree_iter = mpctx_get_playtree_iter(menu->ctx);
|
||||
|
||||
if(playtree_iter->tree == mpriv->p.current->pt)
|
||||
break;
|
||||
|
||||
if(playtree_iter->tree->parent && mpriv->p.current->pt == playtree_iter->tree->parent)
|
||||
snprintf(str,15,"pt_up_step 1");
|
||||
else {
|
||||
for(i = playtree_iter->tree->next; i != NULL ; i = i->next) {
|
||||
if(i == mpriv->p.current->pt)
|
||||
break;
|
||||
d++;
|
||||
}
|
||||
if(i == NULL) {
|
||||
d = -1;
|
||||
for(i = playtree_iter->tree->prev; i != NULL ; i = i->prev) {
|
||||
if(i == mpriv->p.current->pt)
|
||||
break;
|
||||
d--;
|
||||
}
|
||||
if(i == NULL) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Can't find the target item ????\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
snprintf(str,15,"pt_step %d",d);
|
||||
}
|
||||
c = mp_input_parse_cmd(str);
|
||||
if(c) {
|
||||
if(mpriv->auto_close)
|
||||
mp_input_queue_cmd(menu->input_ctx, mp_input_parse_cmd("menu hide"));
|
||||
mp_input_queue_cmd(menu->input_ctx, c);
|
||||
}
|
||||
else
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Failed to build command: %s.\n",str);
|
||||
} break;
|
||||
default:
|
||||
menu_list_read_cmd(menu,cmd);
|
||||
}
|
||||
}
|
||||
|
||||
static int read_key(menu_t* menu,int c){
|
||||
if (menu_dflt_read_key(menu, c))
|
||||
return 1;
|
||||
return menu_list_jump_to_key(menu, c);
|
||||
}
|
||||
|
||||
static void close_menu(menu_t* menu) {
|
||||
menu_list_uninit(menu,NULL);
|
||||
}
|
||||
|
||||
static int op(menu_t* menu, char* args) {
|
||||
play_tree_t* i;
|
||||
list_entry_t* e;
|
||||
play_tree_iter_t* playtree_iter = mpctx_get_playtree_iter(menu->ctx);
|
||||
|
||||
args = NULL; // Warning kill
|
||||
|
||||
menu->draw = menu_list_draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
menu->read_key = read_key;
|
||||
menu->close = close_menu;
|
||||
|
||||
menu_list_init(menu);
|
||||
|
||||
mpriv->p.title = mpriv->title;
|
||||
|
||||
if(playtree_iter->tree->parent != playtree_iter->root) {
|
||||
e = calloc(1,sizeof(list_entry_t));
|
||||
e->p.txt = "..";
|
||||
e->pt = playtree_iter->tree->parent;
|
||||
menu_list_add_entry(menu,e);
|
||||
}
|
||||
|
||||
for(i = playtree_iter->tree ; i->prev != NULL ; i = i->prev)
|
||||
/* NOP */;
|
||||
for( ; i != NULL ; i = i->next ) {
|
||||
e = calloc(1,sizeof(list_entry_t));
|
||||
if(i->files)
|
||||
e->p.txt = (char *)mp_basename(i->files[0]);
|
||||
else
|
||||
e->p.txt = "Group ...";
|
||||
e->pt = i;
|
||||
menu_list_add_entry(menu,e);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_pt = {
|
||||
"Playtree menu",
|
||||
"pt",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"pt_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
op
|
||||
};
|
|
@ -1,205 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
|
||||
#include "m_struct.h"
|
||||
#include "m_option.h"
|
||||
#include "menu.h"
|
||||
|
||||
#include "sub/font_load.h"
|
||||
#include "input/keycodes.h"
|
||||
|
||||
struct menu_priv_s {
|
||||
char** lines;
|
||||
int num_lines;
|
||||
int cur_line;
|
||||
int disp_lines;
|
||||
int minb;
|
||||
int hspace;
|
||||
char* file;
|
||||
};
|
||||
|
||||
static struct menu_priv_s cfg_dflt = {
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
3,
|
||||
NULL
|
||||
};
|
||||
|
||||
#define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
|
||||
|
||||
static const m_option_t cfg_fields[] = {
|
||||
{ "minbor", ST_OFF(minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "hspace", ST_OFF(hspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
|
||||
{ "file", ST_OFF(file), CONF_TYPE_STRING, 0, 0, 0, NULL },
|
||||
{ NULL, NULL, NULL, 0,0,0,NULL }
|
||||
};
|
||||
|
||||
#define mpriv (menu->priv)
|
||||
|
||||
static void read_cmd(menu_t* menu,int cmd) {
|
||||
switch(cmd) {
|
||||
case MENU_CMD_UP:
|
||||
mpriv->cur_line -= mpriv->disp_lines / 2;
|
||||
if(mpriv->cur_line < 0)
|
||||
mpriv->cur_line = 0;
|
||||
break;
|
||||
case MENU_CMD_DOWN:
|
||||
case MENU_CMD_OK:
|
||||
mpriv->cur_line += mpriv->disp_lines / 2;
|
||||
if(mpriv->cur_line >= mpriv->num_lines)
|
||||
mpriv->cur_line = mpriv->num_lines - 1;
|
||||
break;
|
||||
case MENU_CMD_LEFT:
|
||||
case MENU_CMD_CANCEL:
|
||||
menu->show = 0;
|
||||
menu->cl = 1;
|
||||
break;
|
||||
case MENU_CMD_HOME:
|
||||
mpriv->cur_line = 0;
|
||||
break;
|
||||
case MENU_CMD_END:
|
||||
mpriv->cur_line = mpriv->num_lines - 1;
|
||||
break;
|
||||
case MENU_CMD_PAGE_UP:
|
||||
mpriv->cur_line = mpriv->cur_line > mpriv->disp_lines ?
|
||||
mpriv->cur_line - mpriv->disp_lines : 0;
|
||||
break;
|
||||
case MENU_CMD_PAGE_DOWN:
|
||||
mpriv->cur_line = mpriv->cur_line + mpriv->disp_lines > mpriv->num_lines - 1 ? mpriv->num_lines - 1 : mpriv->cur_line + mpriv->disp_lines;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void draw(menu_t* menu,mp_image_t* mpi) {
|
||||
int x = mpriv->minb;
|
||||
int y = mpriv->minb;
|
||||
//int th = 2*mpriv->hspace + vo_font->height;
|
||||
int i,end;
|
||||
|
||||
if(x < 0) x = 8;
|
||||
if(y < 0) y = 8;
|
||||
|
||||
mpriv->disp_lines = (mpi->h + mpriv->hspace - 2*mpriv->minb) / ( vo_font->height + mpriv->hspace);
|
||||
if(mpriv->num_lines - mpriv->cur_line < mpriv->disp_lines) {
|
||||
i = mpriv->num_lines - 1 - mpriv->disp_lines;
|
||||
if(i < 0) i = 0;
|
||||
end = mpriv->num_lines - 1;
|
||||
} else {
|
||||
i = mpriv->cur_line;
|
||||
end = i + mpriv->disp_lines;
|
||||
if(end >= mpriv->num_lines) end = mpriv->num_lines - 1;
|
||||
}
|
||||
|
||||
for( ; i < end ; i++) {
|
||||
menu_draw_text(mpi,mpriv->lines[i],x,y);
|
||||
y += vo_font->height + mpriv->hspace;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
static int open_txt(menu_t* menu, char* args) {
|
||||
FILE* fd;
|
||||
char buf[BUF_SIZE];
|
||||
char *l;
|
||||
int s;
|
||||
int pos = 0, r = 0;
|
||||
args = NULL; // Warning kill
|
||||
|
||||
menu->draw = draw;
|
||||
menu->read_cmd = read_cmd;
|
||||
|
||||
if(!mpriv->file) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Text menu needs a textfile name (parameter file).\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fd = fopen(mpriv->file,"r");
|
||||
if(!fd) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Can't open %s.\n",mpriv->file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while(1) {
|
||||
r = fread(buf+pos,1,BUF_SIZE-pos-1,fd);
|
||||
if(r <= 0) {
|
||||
if(pos > 0) {
|
||||
mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
|
||||
mpriv->lines[mpriv->num_lines] = strdup(buf);
|
||||
mpriv->num_lines++;
|
||||
}
|
||||
fclose(fd);
|
||||
break;
|
||||
}
|
||||
pos += r;
|
||||
buf[pos] = '\0';
|
||||
|
||||
while((l = strchr(buf,'\n')) != NULL) {
|
||||
s = l-buf;
|
||||
mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
|
||||
mpriv->lines[mpriv->num_lines] = malloc(s+1);
|
||||
memcpy(mpriv->lines[mpriv->num_lines],buf,s);
|
||||
mpriv->lines[mpriv->num_lines][s] = '\0';
|
||||
pos -= s + 1;
|
||||
if(pos > 0)
|
||||
memmove(buf,l+1,pos);
|
||||
buf[pos] = '\0';
|
||||
mpriv->num_lines++;
|
||||
}
|
||||
if(pos >= BUF_SIZE-1) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Warning, line too long. Splitting it.\n");
|
||||
mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
|
||||
mpriv->lines[mpriv->num_lines] = strdup(buf);
|
||||
mpriv->num_lines++;
|
||||
pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_INFO,"[MENU] Parsed %d lines.\n",mpriv->num_lines);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
const menu_info_t menu_info_txt = {
|
||||
"Text file viewer",
|
||||
"txt",
|
||||
"Albeu",
|
||||
"",
|
||||
{
|
||||
"txt_cfg",
|
||||
sizeof(struct menu_priv_s),
|
||||
&cfg_dflt,
|
||||
cfg_fields
|
||||
},
|
||||
open_txt,
|
||||
};
|
|
@ -1,267 +0,0 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mplayer.h"
|
||||
#include "mp_msg.h"
|
||||
|
||||
#include "libmpcodecs/img_format.h"
|
||||
#include "libmpcodecs/mp_image.h"
|
||||
#include "libmpcodecs/vf.h"
|
||||
|
||||
#include "libvo/fastmemcpy.h"
|
||||
#include "libvo/video_out.h"
|
||||
#include "sub/font_load.h"
|
||||
#include "sub/sub.h"
|
||||
#include "input/input.h"
|
||||
#include "m_struct.h"
|
||||
#include "menu.h"
|
||||
#include "access_mpcontext.h"
|
||||
|
||||
|
||||
static struct vf_priv_s* st_priv = NULL;
|
||||
|
||||
static mp_image_t* pause_mpi = NULL;
|
||||
static int go2pause = 0;
|
||||
/// if nonzero display menu at startup
|
||||
int menu_startup = 0;
|
||||
|
||||
struct vf_priv_s {
|
||||
menu_t* root;
|
||||
menu_t* current;
|
||||
int passthrough;
|
||||
};
|
||||
|
||||
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts);
|
||||
|
||||
void vf_menu_pause_update(struct vf_instance *vf) {
|
||||
struct vo *video_out = mpctx_get_video_out(vf->priv->current->ctx);
|
||||
if(pause_mpi) {
|
||||
put_image(vf,pause_mpi, MP_NOPTS_VALUE);
|
||||
// Don't draw the osd atm
|
||||
//vf->control(vf,VFCTRL_DRAW_OSD,NULL);
|
||||
vo_flip_page(video_out, 0, -1);
|
||||
}
|
||||
}
|
||||
|
||||
static int cmd_filter(mp_cmd_t* cmd, void *ctx)
|
||||
{
|
||||
struct vf_priv_s *priv = ctx;
|
||||
|
||||
switch(cmd->id) {
|
||||
case MP_CMD_MENU : { // Convert txt cmd from the users into libmenu stuff
|
||||
char* arg = cmd->args[0].v.s;
|
||||
|
||||
if (!priv->current->show && strcmp(arg,"hide"))
|
||||
priv->current->show = 1;
|
||||
else if(strcmp(arg,"up") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_UP);
|
||||
else if(strcmp(arg,"down") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_DOWN);
|
||||
else if(strcmp(arg,"left") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_LEFT);
|
||||
else if(strcmp(arg,"right") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_RIGHT);
|
||||
else if(strcmp(arg,"ok") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_OK);
|
||||
else if(strcmp(arg,"cancel") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_CANCEL);
|
||||
else if(strcmp(arg,"home") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_HOME);
|
||||
else if(strcmp(arg,"end") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_END);
|
||||
else if(strcmp(arg,"pageup") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_PAGE_UP);
|
||||
else if(strcmp(arg,"pagedown") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_PAGE_DOWN);
|
||||
else if(strcmp(arg,"click") == 0)
|
||||
menu_read_cmd(priv->current,MENU_CMD_CLICK);
|
||||
else if(strcmp(arg,"hide") == 0 || strcmp(arg,"toggle") == 0)
|
||||
priv->current->show = 0;
|
||||
else
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Unknown command: '%s'.\n",arg);
|
||||
return 1;
|
||||
}
|
||||
case MP_CMD_SET_MENU : {
|
||||
char* menu = cmd->args[0].v.s;
|
||||
menu_t* l = priv->current;
|
||||
priv->current = menu_open(menu);
|
||||
if(!priv->current) {
|
||||
mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Failed to open menu: '%s'.\n",menu);
|
||||
priv->current = l;
|
||||
priv->current->show = 0;
|
||||
} else {
|
||||
priv->current->show = 1;
|
||||
priv->current->parent = l;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_image(struct vf_instance *vf, mp_image_t *mpi){
|
||||
mp_image_t *dmpi;
|
||||
|
||||
if(mpi->type == MP_IMGTYPE_TEMP && (!(mpi->flags&MP_IMGFLAG_PRESERVE)) ) {
|
||||
dmpi = vf_get_image(vf->next,mpi->imgfmt,mpi->type, mpi->flags, mpi->w, mpi->h);
|
||||
memcpy(mpi->planes,dmpi->planes,MP_MAX_PLANES*sizeof(unsigned char*));
|
||||
memcpy(mpi->stride,dmpi->stride,MP_MAX_PLANES*sizeof(unsigned int));
|
||||
mpi->flags|=MP_IMGFLAG_DIRECT;
|
||||
mpi->priv=(void*)dmpi;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static int key_cb(int code) {
|
||||
return menu_read_key(st_priv->current,code);
|
||||
}
|
||||
|
||||
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){
|
||||
mp_image_t *dmpi = NULL;
|
||||
|
||||
if (vf->priv->passthrough) {
|
||||
dmpi=vf_get_image(vf->next, IMGFMT_MPEGPES, MP_IMGTYPE_EXPORT,
|
||||
0, mpi->w, mpi->h);
|
||||
dmpi->planes[0]=mpi->planes[0];
|
||||
return vf_next_put_image(vf,dmpi, pts);
|
||||
}
|
||||
|
||||
// Close all menu who requested it
|
||||
while(vf->priv->current->cl && vf->priv->current != vf->priv->root) {
|
||||
menu_t* m = vf->priv->current;
|
||||
vf->priv->current = m->parent ? m->parent : vf->priv->root;
|
||||
menu_close(m);
|
||||
}
|
||||
|
||||
// Try to capture the last frame before pause, or fallback to use
|
||||
// last captured frame.
|
||||
if(pause_mpi && (mpi->w != pause_mpi->w || mpi->h != pause_mpi->h ||
|
||||
mpi->imgfmt != pause_mpi->imgfmt)) {
|
||||
free_mp_image(pause_mpi);
|
||||
pause_mpi = NULL;
|
||||
}
|
||||
if (!pause_mpi) {
|
||||
pause_mpi = alloc_mpi(mpi->w,mpi->h,mpi->imgfmt);
|
||||
copy_mpi(pause_mpi,mpi);
|
||||
}
|
||||
else if (mpctx_get_osd_function(vf->priv->root->ctx) == OSD_PAUSE)
|
||||
copy_mpi(pause_mpi,mpi);
|
||||
|
||||
if (vf->priv->current->show) {
|
||||
if (!mp_input_key_cb)
|
||||
mp_input_key_cb = key_cb;
|
||||
|
||||
if(mpi->flags&MP_IMGFLAG_DIRECT)
|
||||
dmpi = mpi->priv;
|
||||
else {
|
||||
dmpi = vf_get_image(vf->next,mpi->imgfmt,
|
||||
MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE,
|
||||
mpi->w,mpi->h);
|
||||
copy_mpi(dmpi,mpi);
|
||||
}
|
||||
menu_draw(vf->priv->current,dmpi);
|
||||
|
||||
} else {
|
||||
if(mp_input_key_cb)
|
||||
mp_input_key_cb = NULL;
|
||||
|
||||
if(mpi->flags&MP_IMGFLAG_DIRECT)
|
||||
dmpi = mpi->priv;
|
||||
else {
|
||||
dmpi = vf_get_image(vf->next,mpi->imgfmt,
|
||||
MP_IMGTYPE_EXPORT, MP_IMGFLAG_ACCEPT_STRIDE,
|
||||
mpi->w,mpi->h);
|
||||
|
||||
dmpi->stride[0] = mpi->stride[0];
|
||||
dmpi->stride[1] = mpi->stride[1];
|
||||
dmpi->stride[2] = mpi->stride[2];
|
||||
dmpi->planes[0] = mpi->planes[0];
|
||||
dmpi->planes[1] = mpi->planes[1];
|
||||
dmpi->planes[2] = mpi->planes[2];
|
||||
dmpi->priv = mpi->priv;
|
||||
}
|
||||
}
|
||||
return vf_next_put_image(vf,dmpi, pts);
|
||||
}
|
||||
|
||||
static void uninit(vf_instance_t *vf) {
|
||||
vf->priv=NULL;
|
||||
if(pause_mpi) {
|
||||
free_mp_image(pause_mpi);
|
||||
pause_mpi = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int config(struct vf_instance *vf, int width, int height, int d_width, int d_height,
|
||||
unsigned int flags, unsigned int outfmt) {
|
||||
#ifdef CONFIG_FREETYPE
|
||||
// here is the right place to get screen dimensions
|
||||
if (force_load_font) {
|
||||
force_load_font = 0;
|
||||
load_font_ft(width,height,&vo_font,font_name,osd_font_scale_factor);
|
||||
}
|
||||
#endif
|
||||
if(outfmt == IMGFMT_MPEGPES)
|
||||
vf->priv->passthrough = 1;
|
||||
return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt);
|
||||
}
|
||||
|
||||
static int query_format(struct vf_instance *vf, unsigned int fmt){
|
||||
return vf_next_query_format(vf, fmt);
|
||||
}
|
||||
|
||||
static int open_vf(vf_instance_t *vf, char* args){
|
||||
if(!st_priv) {
|
||||
st_priv = calloc(1,sizeof(struct vf_priv_s));
|
||||
st_priv->root = st_priv->current = menu_open(args);
|
||||
if(!st_priv->current) {
|
||||
free(st_priv);
|
||||
st_priv = NULL;
|
||||
return 0;
|
||||
}
|
||||
st_priv->root->show = menu_startup;
|
||||
mp_input_add_cmd_filter(cmd_filter,st_priv);
|
||||
}
|
||||
|
||||
vf->config = config;
|
||||
vf->query_format=query_format;
|
||||
vf->put_image = put_image;
|
||||
vf->get_image = get_image;
|
||||
vf->uninit=uninit;
|
||||
vf->priv=st_priv;
|
||||
go2pause=0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
const vf_info_t vf_info_menu = {
|
||||
"Internal filter for libmenu",
|
||||
"menu",
|
||||
"Albeu",
|
||||
"",
|
||||
open_vf,
|
||||
NULL
|
||||
};
|
|
@ -225,9 +225,8 @@ typedef struct MPContext {
|
|||
} MPContext;
|
||||
|
||||
|
||||
// Most of these should not be globals
|
||||
// should not be global
|
||||
extern FILE *edl_fd;
|
||||
extern int file_filter;
|
||||
// These appear in options list
|
||||
extern int forced_subs_only;
|
||||
|
||||
|
|
2
mp_msg.h
2
mp_msg.h
|
@ -112,8 +112,6 @@ extern int verbose;
|
|||
|
||||
#define MSGT_MUXER 39 // muxer layer
|
||||
|
||||
#define MSGT_OSD_MENU 40
|
||||
|
||||
#define MSGT_IDENTIFY 41 // -identify output
|
||||
|
||||
#define MSGT_RADIO 42
|
||||
|
|
63
mplayer.c
63
mplayer.c
|
@ -301,7 +301,6 @@ int dvdsub_lang_id;
|
|||
int vobsub_id = -1;
|
||||
static char *spudec_ifo = NULL;
|
||||
int forced_subs_only = 0;
|
||||
int file_filter = 1;
|
||||
|
||||
// cache2:
|
||||
int stream_cache_size = -1;
|
||||
|
@ -337,20 +336,6 @@ char *current_module; // for debugging
|
|||
|
||||
// ---
|
||||
|
||||
#ifdef CONFIG_MENU
|
||||
#include "m_struct.h"
|
||||
#include "libmenu/menu.h"
|
||||
static const vf_info_t * const libmenu_vfs[] = {
|
||||
&vf_info_menu,
|
||||
NULL
|
||||
};
|
||||
static vf_instance_t *vf_menu;
|
||||
int use_menu;
|
||||
static char *menu_cfg;
|
||||
static char *menu_root = "main";
|
||||
#endif
|
||||
|
||||
|
||||
edl_record_ptr edl_records = NULL; ///< EDL entries memory area
|
||||
edl_record_ptr next_edl_record = NULL; ///< only for traversing edl_records
|
||||
FILE *edl_fd; // file to write to when in -edlout mode.
|
||||
|
@ -643,9 +628,6 @@ void uninit_player(struct MPContext *mpctx, unsigned int mask)
|
|||
if (mpctx->sh_video)
|
||||
uninit_video(mpctx->sh_video);
|
||||
mpctx->sh_video = NULL;
|
||||
#ifdef CONFIG_MENU
|
||||
vf_menu = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mask & INITIALIZED_DEMUXER) {
|
||||
|
@ -747,10 +729,6 @@ void exit_player_with_rc(struct MPContext *mpctx, enum exit_reason how, int rc)
|
|||
|
||||
current_module = "uninit_input";
|
||||
mp_input_uninit(mpctx->input);
|
||||
#ifdef CONFIG_MENU
|
||||
if (use_menu)
|
||||
menu_uninit();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FREETYPE
|
||||
current_module = "uninit_font";
|
||||
|
@ -2731,22 +2709,6 @@ int reinit_video_chain(struct MPContext *mpctx)
|
|||
};
|
||||
sh_video->vfilter = vf_open_filter(opts, NULL, "vo", vf_arg);
|
||||
}
|
||||
#ifdef CONFIG_MENU
|
||||
if (use_menu) {
|
||||
char *vf_arg[] = {
|
||||
"_oldargs_", menu_root, NULL
|
||||
};
|
||||
vf_menu = vf_open_plugin(opts, libmenu_vfs, sh_video->vfilter, "menu",
|
||||
vf_arg);
|
||||
if (!vf_menu) {
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Can't open libmenu video filter "
|
||||
"with root menu %s.\n", menu_root);
|
||||
use_menu = 0;
|
||||
}
|
||||
}
|
||||
if (vf_menu)
|
||||
sh_video->vfilter = vf_menu;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ASS
|
||||
if (opts->ass_enabled) {
|
||||
|
@ -3084,10 +3046,6 @@ static void pause_loop(struct MPContext *mpctx)
|
|||
}
|
||||
if (mpctx->sh_video && mpctx->video_out)
|
||||
vo_check_events(mpctx->video_out);
|
||||
#ifdef CONFIG_MENU
|
||||
if (vf_menu)
|
||||
vf_menu_pause_update(vf_menu);
|
||||
#endif
|
||||
usec_sleep(20000);
|
||||
update_osd_msg(mpctx);
|
||||
int hack = vo_osd_changed(0);
|
||||
|
@ -4221,27 +4179,6 @@ int main(int argc, char *argv[])
|
|||
// Set the libstream interrupt callback
|
||||
stream_set_interrupt_callback(mp_input_check_interrupt, mpctx->input);
|
||||
|
||||
#ifdef CONFIG_MENU
|
||||
if (use_menu) {
|
||||
if (menu_cfg && menu_init(mpctx, mpctx->mconfig, mpctx->input, menu_cfg))
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_V, "Menu initialized: %s\n", menu_cfg);
|
||||
else {
|
||||
menu_cfg = get_path("menu.conf");
|
||||
if (menu_init(mpctx, mpctx->mconfig, mpctx->input, menu_cfg))
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_V, "Menu initialized: %s\n", menu_cfg);
|
||||
else {
|
||||
if (menu_init(mpctx, mpctx->mconfig, mpctx->input,
|
||||
MPLAYER_CONFDIR "/menu.conf"))
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_V, "Menu initialized: %s\n", MPLAYER_CONFDIR "/menu.conf");
|
||||
else {
|
||||
mp_tmsg(MSGT_CPLAYER, MSGL_ERR, "Menu init failed.\n");
|
||||
use_menu = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
current_module = NULL;
|
||||
|
||||
/// Catch signals
|
||||
|
|
|
@ -130,7 +130,6 @@ mv DOCS/man/zh DOCS/man/zh_CN
|
|||
%{!?_with_samba:--disable-smb} \
|
||||
--disable-dvdread-internal \
|
||||
--disable-libdvdcss-internal \
|
||||
--enable-menu \
|
||||
\
|
||||
%{!?_with_amr:--disable-libamr_nb --disable-libamr_wb} \
|
||||
%{!?_with_libmad:--disable-mad} \
|
||||
|
@ -171,7 +170,6 @@ mv -f mplayer gmplayer
|
|||
%{!?_with_samba:--disable-smb} \
|
||||
--disable-dvdread-internal \
|
||||
--disable-libdvdcss-internal \
|
||||
--enable-menu \
|
||||
\
|
||||
%{!?_with_amr:--disable-libamr_nb --disable-libamr_wb} \
|
||||
%{!?_with_libmad:--disable-mad} \
|
||||
|
@ -218,8 +216,6 @@ install -Dpm 644 etc/example.conf \
|
|||
echo "fontconfig=yes" >>$RPM_BUILD_ROOT%{_sysconfdir}/mplayer/mplayer.conf
|
||||
echo "font=\"Sans\"" >>$RPM_BUILD_ROOT%{_sysconfdir}/mplayer/mplayer.conf
|
||||
|
||||
install -pm 644 etc/{input,menu}.conf $RPM_BUILD_ROOT%{_sysconfdir}/mplayer/
|
||||
|
||||
# GUI mplayer
|
||||
install -pm 755 g%{name} $RPM_BUILD_ROOT%{_bindir}/
|
||||
|
||||
|
@ -262,7 +258,6 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%dir %{_sysconfdir}/mplayer
|
||||
%config(noreplace) %{_sysconfdir}/mplayer/mplayer.conf
|
||||
%config(noreplace) %{_sysconfdir}/mplayer/input.conf
|
||||
%config(noreplace) %{_sysconfdir}/mplayer/menu.conf
|
||||
%{_bindir}/midentify.sh
|
||||
%{_bindir}/mplayer
|
||||
%dir %{codecsdir}/
|
||||
|
|
Loading…
Reference in New Issue