2 * This file is part of MPlayer.
4 * MPlayer is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * MPlayer is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include "libmpcodecs/img_format.h"
30 #include "libmpcodecs/mp_image.h"
31 #include "libmpcodecs/vf.h"
33 #include "libvo/fastmemcpy.h"
34 #include "libvo/video_out.h"
35 #include "libvo/font_load.h"
36 #include "libvo/sub.h"
37 #include "input/input.h"
40 #include "access_mpcontext.h"
43 static struct vf_priv_s
* st_priv
= NULL
;
45 static mp_image_t
* pause_mpi
= NULL
;
46 static int go2pause
= 0;
47 /// if nonzero display menu at startup
56 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
);
58 void vf_menu_pause_update(struct vf_instance
*vf
) {
59 const struct vo
*video_out
= mpctx_get_video_out(vf
->priv
->current
->ctx
);
61 put_image(vf
,pause_mpi
, MP_NOPTS_VALUE
);
62 // Don't draw the osd atm
63 //vf->control(vf,VFCTRL_DRAW_OSD,NULL);
64 vo_flip_page(video_out
, 0, -1);
68 static int cmd_filter(mp_cmd_t
* cmd
, void *ctx
)
70 struct vf_priv_s
*priv
= ctx
;
73 case MP_CMD_MENU
: { // Convert txt cmd from the users into libmenu stuff
74 char* arg
= cmd
->args
[0].v
.s
;
76 if (!priv
->current
->show
&& strcmp(arg
,"hide"))
77 priv
->current
->show
= 1;
78 else if(strcmp(arg
,"up") == 0)
79 menu_read_cmd(priv
->current
,MENU_CMD_UP
);
80 else if(strcmp(arg
,"down") == 0)
81 menu_read_cmd(priv
->current
,MENU_CMD_DOWN
);
82 else if(strcmp(arg
,"left") == 0)
83 menu_read_cmd(priv
->current
,MENU_CMD_LEFT
);
84 else if(strcmp(arg
,"right") == 0)
85 menu_read_cmd(priv
->current
,MENU_CMD_RIGHT
);
86 else if(strcmp(arg
,"ok") == 0)
87 menu_read_cmd(priv
->current
,MENU_CMD_OK
);
88 else if(strcmp(arg
,"cancel") == 0)
89 menu_read_cmd(priv
->current
,MENU_CMD_CANCEL
);
90 else if(strcmp(arg
,"home") == 0)
91 menu_read_cmd(priv
->current
,MENU_CMD_HOME
);
92 else if(strcmp(arg
,"end") == 0)
93 menu_read_cmd(priv
->current
,MENU_CMD_END
);
94 else if(strcmp(arg
,"pageup") == 0)
95 menu_read_cmd(priv
->current
,MENU_CMD_PAGE_UP
);
96 else if(strcmp(arg
,"pagedown") == 0)
97 menu_read_cmd(priv
->current
,MENU_CMD_PAGE_DOWN
);
98 else if(strcmp(arg
,"click") == 0)
99 menu_read_cmd(priv
->current
,MENU_CMD_CLICK
);
100 else if(strcmp(arg
,"hide") == 0 || strcmp(arg
,"toggle") == 0)
101 priv
->current
->show
= 0;
103 mp_tmsg(MSGT_GLOBAL
,MSGL_WARN
,"[MENU] Unknown command: '%s'.\n",arg
);
106 case MP_CMD_SET_MENU
: {
107 char* menu
= cmd
->args
[0].v
.s
;
108 menu_t
* l
= priv
->current
;
109 priv
->current
= menu_open(menu
);
111 mp_tmsg(MSGT_GLOBAL
,MSGL_WARN
,"[MENU] Failed to open menu: '%s'.\n",menu
);
113 priv
->current
->show
= 0;
115 priv
->current
->show
= 1;
116 priv
->current
->parent
= l
;
124 static void get_image(struct vf_instance
*vf
, mp_image_t
*mpi
){
127 if(mpi
->type
== MP_IMGTYPE_TEMP
&& (!(mpi
->flags
&MP_IMGFLAG_PRESERVE
)) ) {
128 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,mpi
->type
, mpi
->flags
, mpi
->w
, mpi
->h
);
129 memcpy(mpi
->planes
,dmpi
->planes
,MP_MAX_PLANES
*sizeof(unsigned char*));
130 memcpy(mpi
->stride
,dmpi
->stride
,MP_MAX_PLANES
*sizeof(unsigned int));
131 mpi
->flags
|=MP_IMGFLAG_DIRECT
;
132 mpi
->priv
=(void*)dmpi
;
137 static int key_cb(int code
) {
138 return menu_read_key(st_priv
->current
,code
);
141 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
142 mp_image_t
*dmpi
= NULL
;
144 if (vf
->priv
->passthrough
) {
145 dmpi
=vf_get_image(vf
->next
, IMGFMT_MPEGPES
, MP_IMGTYPE_EXPORT
,
147 dmpi
->planes
[0]=mpi
->planes
[0];
148 return vf_next_put_image(vf
,dmpi
, pts
);
151 // Close all menu who requested it
152 while(vf
->priv
->current
->cl
&& vf
->priv
->current
!= vf
->priv
->root
) {
153 menu_t
* m
= vf
->priv
->current
;
154 vf
->priv
->current
= m
->parent
? m
->parent
: vf
->priv
->root
;
158 // Try to capture the last frame before pause, or fallback to use
159 // last captured frame.
160 if(pause_mpi
&& (mpi
->w
!= pause_mpi
->w
|| mpi
->h
!= pause_mpi
->h
||
161 mpi
->imgfmt
!= pause_mpi
->imgfmt
)) {
162 free_mp_image(pause_mpi
);
166 pause_mpi
= alloc_mpi(mpi
->w
,mpi
->h
,mpi
->imgfmt
);
167 copy_mpi(pause_mpi
,mpi
);
169 else if (mpctx_get_osd_function(vf
->priv
->root
->ctx
) == OSD_PAUSE
)
170 copy_mpi(pause_mpi
,mpi
);
172 if (vf
->priv
->current
->show
) {
173 if (!mp_input_key_cb
)
174 mp_input_key_cb
= key_cb
;
176 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
179 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
180 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
184 menu_draw(vf
->priv
->current
,dmpi
);
188 mp_input_key_cb
= NULL
;
190 if(mpi
->flags
&MP_IMGFLAG_DIRECT
)
193 dmpi
= vf_get_image(vf
->next
,mpi
->imgfmt
,
194 MP_IMGTYPE_EXPORT
, MP_IMGFLAG_ACCEPT_STRIDE
,
197 dmpi
->stride
[0] = mpi
->stride
[0];
198 dmpi
->stride
[1] = mpi
->stride
[1];
199 dmpi
->stride
[2] = mpi
->stride
[2];
200 dmpi
->planes
[0] = mpi
->planes
[0];
201 dmpi
->planes
[1] = mpi
->planes
[1];
202 dmpi
->planes
[2] = mpi
->planes
[2];
203 dmpi
->priv
= mpi
->priv
;
206 return vf_next_put_image(vf
,dmpi
, pts
);
209 static void uninit(vf_instance_t
*vf
) {
212 free_mp_image(pause_mpi
);
217 static int config(struct vf_instance
*vf
, int width
, int height
, int d_width
, int d_height
,
218 unsigned int flags
, unsigned int outfmt
) {
219 #ifdef CONFIG_FREETYPE
220 // here is the right place to get screen dimensions
221 if (force_load_font
) {
223 load_font_ft(width
,height
,&vo_font
,font_name
,osd_font_scale_factor
);
226 if(outfmt
== IMGFMT_MPEGPES
)
227 vf
->priv
->passthrough
= 1;
228 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
231 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
232 return vf_next_query_format(vf
, fmt
);
235 static int open_vf(vf_instance_t
*vf
, char* args
){
237 st_priv
= calloc(1,sizeof(struct vf_priv_s
));
238 st_priv
->root
= st_priv
->current
= menu_open(args
);
239 if(!st_priv
->current
) {
244 st_priv
->root
->show
= menu_startup
;
245 mp_input_add_cmd_filter(cmd_filter
,st_priv
);
249 vf
->query_format
=query_format
;
250 vf
->put_image
= put_image
;
251 vf
->get_image
= get_image
;
260 vf_info_t vf_info_menu
= {
261 "Internal filter for libmenu",