2 * Support chapter list and selection.
4 * Copyright (C) 2006-2007 Benjamin Zores <ben A geexbox P org>
5 * Copyright (C) 2007 Ulion <ulion A gmail P com>
7 * This file is part of MPlayer.
9 * MPlayer is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * MPlayer is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License along
20 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
33 #include "input/input.h"
35 #include "stream/stream.h"
36 #include "libmpdemux/demuxer.h"
37 #include "access_mpcontext.h"
39 #include "libmpcodecs/mp_image.h"
42 #include "menu_list.h"
56 static struct menu_priv_s cfg_dflt
= {
60 "${chapter_name} [${start}]"
63 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
65 static const m_option_t cfg_fields
[] = {
66 MENU_LIST_PRIV_FIELDS
,
67 { "title", ST_OFF (title
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
68 { "auto-close", ST_OFF (auto_close
), CONF_TYPE_FLAG
, 0, 0, 1, NULL
},
69 { "fmt-with-time", ST_OFF (fmt_with_time
), CONF_TYPE_STRING
, 0, 0, 0, NULL
},
70 { NULL
, NULL
, NULL
, 0, 0, 0, NULL
}
73 static char *fmt_replace(const char *fmt
, const char *chapter_name
,
75 static const char ctag
[] = "${chapter_name}";
76 static const char stag
[] = "${start}";
78 int cl
= strlen(chapter_name
);
79 int sl
= strlen(start
);
80 char *str
= malloc(l
+ cl
+ sl
);
83 p
= strstr(str
, ctag
);
85 memmove(p
+cl
, p
+sizeof(ctag
)-1, str
+l
+1 - (p
+sizeof(ctag
)-1));
86 memcpy(p
, chapter_name
, cl
);
87 l
-= sizeof(ctag
) + 1;
90 p
= strstr(str
, stag
);
92 memmove(p
+sl
, p
+sizeof(stag
)-1, str
+l
+1 - (p
+sizeof(stag
)-1));
94 l
-= sizeof(stag
) + 1;
100 static int fill_menu (menu_t
* menu
)
103 int cid
, chapter_num
= 0;
105 demuxer_t
* demuxer
= mpctx_get_demuxer(menu
->ctx
);
108 chapter_num
= demuxer_chapter_count(demuxer
);
109 if (chapter_num
> 0) {
110 menu_list_init (menu
);
111 for (cid
= 0; cid
< chapter_num
; ++cid
)
112 if ((e
= calloc (1, sizeof (list_entry_t
))) != NULL
) {
115 char *str
= demuxer_chapter_display_name(demuxer
, cid
);
116 e
->p
.txt
= strdup(str
);
118 start_time
= demuxer_chapter_time(demuxer
, cid
, NULL
);
119 if (start_time
>= 0) {
122 int hour
= start_time
/ 3600;
123 int minute
= (start_time
/ 60) % 60;
124 int seconds
= start_time
% 60;
125 sprintf(timestr
,"%02d:%02d:%02d", hour
, minute
, seconds
);
127 tmp
= fmt_replace(menu
->priv
->fmt_with_time
, e
->p
.txt
, timestr
);
131 menu_list_add_entry(menu
, e
);
135 menu_list_read_cmd(menu
, MENU_CMD_CANCEL
);
140 static void read_cmd (menu_t
* menu
, int cmd
)
146 sprintf(cmdbuf
, "seek_chapter %d 1", menu
->priv
->p
.current
->cid
);
147 mp_input_queue_cmd(menu
->input_ctx
, mp_input_parse_cmd(cmdbuf
));
148 if (menu
->priv
->auto_close
)
149 mp_input_queue_cmd(menu
->input_ctx
, mp_input_parse_cmd("menu hide"));
153 menu_list_read_cmd (menu
, cmd
);
157 static void close_cs (menu_t
* menu
)
159 menu_list_uninit (menu
, NULL
);
162 static int open_cs (menu_t
* menu
, char* args
)
166 menu
->draw
= menu_list_draw
;
167 menu
->read_cmd
= read_cmd
;
168 menu
->close
= close_cs
;
169 menu
->priv
->p
.title
= menu
->priv
->title
;
171 return fill_menu (menu
);
174 const menu_info_t menu_info_chapsel
= {
175 "Chapter selector menu",
177 "Benjamin Zores & Ulion",
181 sizeof(struct menu_priv_s
),