Fix vf_tcdump's compilation
[mplayer/kovensky.git] / libmenu / menu_txt.c
blob7064167b672c9ee5a78402fc8e91c215fbd56948
1 /*
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.
19 #include "config.h"
20 #include "mp_msg.h"
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
26 #include "libmpcodecs/img_format.h"
27 #include "libmpcodecs/mp_image.h"
29 #include "m_struct.h"
30 #include "m_option.h"
31 #include "menu.h"
33 #include "libvo/font_load.h"
34 #include "osdep/keycodes.h"
36 struct menu_priv_s {
37 char** lines;
38 int num_lines;
39 int cur_line;
40 int disp_lines;
41 int minb;
42 int hspace;
43 char* file;
46 static struct menu_priv_s cfg_dflt = {
47 NULL,
53 NULL
56 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
58 static m_option_t cfg_fields[] = {
59 { "minbor", ST_OFF(minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
60 { "hspace", ST_OFF(hspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
61 { "file", ST_OFF(file), CONF_TYPE_STRING, 0, 0, 0, NULL },
62 { NULL, NULL, NULL, 0,0,0,NULL }
65 #define mpriv (menu->priv)
67 static void read_cmd(menu_t* menu,int cmd) {
68 switch(cmd) {
69 case MENU_CMD_UP:
70 mpriv->cur_line -= mpriv->disp_lines / 2;
71 if(mpriv->cur_line < 0)
72 mpriv->cur_line = 0;
73 break;
74 case MENU_CMD_DOWN:
75 case MENU_CMD_OK:
76 mpriv->cur_line += mpriv->disp_lines / 2;
77 if(mpriv->cur_line >= mpriv->num_lines)
78 mpriv->cur_line = mpriv->num_lines - 1;
79 break;
80 case MENU_CMD_LEFT:
81 case MENU_CMD_CANCEL:
82 menu->show = 0;
83 menu->cl = 1;
84 break;
85 case MENU_CMD_HOME:
86 mpriv->cur_line = 0;
87 break;
88 case MENU_CMD_END:
89 mpriv->cur_line = mpriv->num_lines - 1;
90 break;
91 case MENU_CMD_PAGE_UP:
92 mpriv->cur_line = mpriv->cur_line > mpriv->disp_lines ?
93 mpriv->cur_line - mpriv->disp_lines : 0;
94 break;
95 case MENU_CMD_PAGE_DOWN:
96 mpriv->cur_line = mpriv->cur_line + mpriv->disp_lines > mpriv->num_lines - 1 ? mpriv->num_lines - 1 : mpriv->cur_line + mpriv->disp_lines;
97 break;
102 static void draw(menu_t* menu,mp_image_t* mpi) {
103 int x = mpriv->minb;
104 int y = mpriv->minb;
105 //int th = 2*mpriv->hspace + vo_font->height;
106 int i,end;
108 if(x < 0) x = 8;
109 if(y < 0) y = 8;
111 mpriv->disp_lines = (mpi->h + mpriv->hspace - 2*mpriv->minb) / ( vo_font->height + mpriv->hspace);
112 if(mpriv->num_lines - mpriv->cur_line < mpriv->disp_lines) {
113 i = mpriv->num_lines - 1 - mpriv->disp_lines;
114 if(i < 0) i = 0;
115 end = mpriv->num_lines - 1;
116 } else {
117 i = mpriv->cur_line;
118 end = i + mpriv->disp_lines;
119 if(end >= mpriv->num_lines) end = mpriv->num_lines - 1;
122 for( ; i < end ; i++) {
123 menu_draw_text(mpi,mpriv->lines[i],x,y);
124 y += vo_font->height + mpriv->hspace;
129 #define BUF_SIZE 1024
131 static int open_txt(menu_t* menu, char* args) {
132 FILE* fd;
133 char buf[BUF_SIZE];
134 char *l;
135 int s;
136 int pos = 0, r = 0;
137 args = NULL; // Warning kill
139 menu->draw = draw;
140 menu->read_cmd = read_cmd;
142 if(!mpriv->file) {
143 mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Text menu needs a textfile name (parameter file).\n");
144 return 0;
147 fd = fopen(mpriv->file,"r");
148 if(!fd) {
149 mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Can't open %s.\n",mpriv->file);
150 return 0;
153 while(1) {
154 r = fread(buf+pos,1,BUF_SIZE-pos-1,fd);
155 if(r <= 0) {
156 if(pos > 0) {
157 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
158 mpriv->lines[mpriv->num_lines] = strdup(buf);
159 mpriv->num_lines++;
161 fclose(fd);
162 break;
164 pos += r;
165 buf[pos] = '\0';
167 while((l = strchr(buf,'\n')) != NULL) {
168 s = l-buf;
169 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
170 mpriv->lines[mpriv->num_lines] = malloc(s+1);
171 memcpy(mpriv->lines[mpriv->num_lines],buf,s);
172 mpriv->lines[mpriv->num_lines][s] = '\0';
173 pos -= s + 1;
174 if(pos > 0)
175 memmove(buf,l+1,pos);
176 buf[pos] = '\0';
177 mpriv->num_lines++;
179 if(pos >= BUF_SIZE-1) {
180 mp_tmsg(MSGT_GLOBAL,MSGL_WARN,"[MENU] Warning, line too long. Splitting it.\n");
181 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
182 mpriv->lines[mpriv->num_lines] = strdup(buf);
183 mpriv->num_lines++;
184 pos = 0;
188 mp_tmsg(MSGT_GLOBAL,MSGL_INFO,"[MENU] Parsed %d lines.\n",mpriv->num_lines);
190 return 1;
193 const menu_info_t menu_info_txt = {
194 "Text file viewer",
195 "txt",
196 "Albeu",
199 "txt_cfg",
200 sizeof(struct menu_priv_s),
201 &cfg_dflt,
202 cfg_fields
204 open_txt,