Merge svn changes up to r28310
[mplayer.git] / libmenu / menu_txt.c
blob74648ff7c720c7183ccd3f2bdff9f6f679957fa3
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"
21 #include "help_mp.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
27 #include "libmpcodecs/img_format.h"
28 #include "libmpcodecs/mp_image.h"
30 #include "m_struct.h"
31 #include "m_option.h"
32 #include "menu.h"
34 #include "libvo/font_load.h"
35 #include "osdep/keycodes.h"
37 struct menu_priv_s {
38 char** lines;
39 int num_lines;
40 int cur_line;
41 int disp_lines;
42 int minb;
43 int hspace;
44 char* file;
47 static struct menu_priv_s cfg_dflt = {
48 NULL,
54 NULL
57 #define ST_OFF(m) M_ST_OFF(struct menu_priv_s,m)
59 static m_option_t cfg_fields[] = {
60 { "minbor", ST_OFF(minb), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
61 { "hspace", ST_OFF(hspace), CONF_TYPE_INT, M_OPT_MIN, 0, 0, NULL },
62 { "file", ST_OFF(file), CONF_TYPE_STRING, 0, 0, 0, NULL },
63 { NULL, NULL, NULL, 0,0,0,NULL }
66 #define mpriv (menu->priv)
68 static void read_cmd(menu_t* menu,int cmd) {
69 switch(cmd) {
70 case MENU_CMD_UP:
71 mpriv->cur_line -= mpriv->disp_lines / 2;
72 if(mpriv->cur_line < 0)
73 mpriv->cur_line = 0;
74 break;
75 case MENU_CMD_DOWN:
76 case MENU_CMD_OK:
77 mpriv->cur_line += mpriv->disp_lines / 2;
78 if(mpriv->cur_line >= mpriv->num_lines)
79 mpriv->cur_line = mpriv->num_lines - 1;
80 break;
81 case MENU_CMD_LEFT:
82 case MENU_CMD_CANCEL:
83 menu->show = 0;
84 menu->cl = 1;
85 break;
86 case MENU_CMD_HOME:
87 mpriv->cur_line = 0;
88 break;
89 case MENU_CMD_END:
90 mpriv->cur_line = mpriv->num_lines - 1;
91 break;
92 case MENU_CMD_PAGE_UP:
93 mpriv->cur_line = mpriv->cur_line > mpriv->disp_lines ?
94 mpriv->cur_line - mpriv->disp_lines : 0;
95 break;
96 case MENU_CMD_PAGE_DOWN:
97 mpriv->cur_line = mpriv->cur_line + mpriv->disp_lines > mpriv->num_lines - 1 ? mpriv->num_lines - 1 : mpriv->cur_line + mpriv->disp_lines;
98 break;
103 static void draw(menu_t* menu,mp_image_t* mpi) {
104 int x = mpriv->minb;
105 int y = mpriv->minb;
106 //int th = 2*mpriv->hspace + vo_font->height;
107 int i,end;
109 if(x < 0) x = 8;
110 if(y < 0) y = 8;
112 mpriv->disp_lines = (mpi->h + mpriv->hspace - 2*mpriv->minb) / ( vo_font->height + mpriv->hspace);
113 if(mpriv->num_lines - mpriv->cur_line < mpriv->disp_lines) {
114 i = mpriv->num_lines - 1 - mpriv->disp_lines;
115 if(i < 0) i = 0;
116 end = mpriv->num_lines - 1;
117 } else {
118 i = mpriv->cur_line;
119 end = i + mpriv->disp_lines;
120 if(end >= mpriv->num_lines) end = mpriv->num_lines - 1;
123 for( ; i < end ; i++) {
124 menu_draw_text(mpi,mpriv->lines[i],x,y);
125 y += vo_font->height + mpriv->hspace;
130 #define BUF_SIZE 1024
132 static int open_txt(menu_t* menu, char* args) {
133 FILE* fd;
134 char buf[BUF_SIZE];
135 char *l;
136 int s;
137 int pos = 0, r = 0;
138 args = NULL; // Warning kill
140 menu->draw = draw;
141 menu->read_cmd = read_cmd;
143 if(!mpriv->file) {
144 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuTxtNeedATxtFileName);
145 return 0;
148 fd = fopen(mpriv->file,"r");
149 if(!fd) {
150 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_MenuTxtCantOpen,mpriv->file);
151 return 0;
154 while(1) {
155 r = fread(buf+pos,1,BUF_SIZE-pos-1,fd);
156 if(r <= 0) {
157 if(pos > 0) {
158 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
159 mpriv->lines[mpriv->num_lines] = strdup(buf);
160 mpriv->num_lines++;
162 fclose(fd);
163 break;
165 pos += r;
166 buf[pos] = '\0';
168 while((l = strchr(buf,'\n')) != NULL) {
169 s = l-buf;
170 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
171 mpriv->lines[mpriv->num_lines] = malloc(s+1);
172 memcpy(mpriv->lines[mpriv->num_lines],buf,s);
173 mpriv->lines[mpriv->num_lines][s] = '\0';
174 pos -= s + 1;
175 if(pos > 0)
176 memmove(buf,l+1,pos);
177 buf[pos] = '\0';
178 mpriv->num_lines++;
180 if(pos >= BUF_SIZE-1) {
181 mp_msg(MSGT_GLOBAL,MSGL_WARN,MSGTR_LIBMENU_WarningTooLongLineSplitting);
182 mpriv->lines = realloc(mpriv->lines,(mpriv->num_lines + 1)*sizeof(char*));
183 mpriv->lines[mpriv->num_lines] = strdup(buf);
184 mpriv->num_lines++;
185 pos = 0;
189 mp_msg(MSGT_GLOBAL,MSGL_INFO,MSGTR_LIBMENU_ParsedLines,mpriv->num_lines);
191 return 1;
194 const menu_info_t menu_info_txt = {
195 "Text file viewer",
196 "txt",
197 "Albeu",
200 "txt_cfg",
201 sizeof(struct menu_priv_s),
202 &cfg_dflt,
203 cfg_fields
205 open_txt,