summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/dict.c212
-rw-r--r--apps/plugins/lib/SOURCES1
-rw-r--r--apps/plugins/lib/simple_viewer.c260
-rw-r--r--apps/plugins/lib/simple_viewer.h28
4 files changed, 307 insertions, 194 deletions
diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c
index 8c262923b7..13fe8e3cc6 100644
--- a/apps/plugins/dict.c
+++ b/apps/plugins/dict.c
@@ -20,11 +20,11 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "plugin.h" 22#include "plugin.h"
23#include "lib/simple_viewer.h"
23 24
24PLUGIN_HEADER 25PLUGIN_HEADER
25 26
26/* screen info */ 27#define MIN_DESC_BUF_SIZE 0x400 /* arbitrary minimum size for description */
27static int display_columns, display_lines;
28 28
29/* Some lenghts */ 29/* Some lenghts */
30#define WORDLEN 32 /* has to be the same in rdf2binary.c */ 30#define WORDLEN 32 /* has to be the same in rdf2binary.c */
@@ -44,50 +44,6 @@ struct stWord
44 long offset; 44 long offset;
45} STRUCT_PACKED; 45} STRUCT_PACKED;
46 46
47/* A funtion to get width and height etc (from viewer.c) */
48void init_screen(void)
49{
50#ifdef HAVE_LCD_BITMAP
51 int w,h;
52
53 rb->lcd_getstringsize("o", &w, &h);
54 display_lines = LCD_HEIGHT / h;
55 display_columns = LCD_WIDTH / w;
56#else
57
58 display_lines = 2;
59 display_columns = 11;
60#endif
61}
62
63/* global vars for pl_malloc() */
64void *bufptr;
65size_t bufleft;
66
67/* simple function to "allocate" memory in pluginbuffer. */
68void *pl_malloc(size_t size)
69{
70 void *ptr;
71 ptr = bufptr;
72
73 if (bufleft < size)
74 {
75 return NULL;
76 }
77 else
78 {
79 bufptr += size;
80 bufleft -= size;
81 return ptr;
82 }
83}
84
85/* init function for pl_malloc() */
86void pl_malloc_init(void)
87{
88 bufptr = rb->plugin_get_buffer(&bufleft);
89}
90
91/* for endian problems */ 47/* for endian problems */
92#ifdef ROCKBOX_BIG_ENDIAN 48#ifdef ROCKBOX_BIG_ENDIAN
93#define reverse(x) x 49#define reverse(x) x
@@ -102,59 +58,6 @@ long reverse (long N) {
102} 58}
103#endif 59#endif
104 60
105/* Button definitions */
106#if CONFIG_KEYPAD == PLAYER_PAD
107#define LP_QUIT BUTTON_STOP
108#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
109 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
110 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
111#define LP_QUIT BUTTON_MENU
112#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
113#define LP_QUIT BUTTON_PLAY
114#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
115#define LP_QUIT BUTTON_POWER
116#elif CONFIG_KEYPAD == GIGABEAT_PAD
117#define LP_QUIT BUTTON_POWER
118#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
119 (CONFIG_KEYPAD == SANSA_C200_PAD) || \
120 (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
121 (CONFIG_KEYPAD == SANSA_M200_PAD)
122#define LP_QUIT BUTTON_POWER
123#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
124#define LP_QUIT (BUTTON_HOME|BUTTON_REPEAT)
125#elif CONFIG_KEYPAD == IRIVER_H10_PAD
126#define LP_QUIT BUTTON_POWER
127#elif CONFIG_KEYPAD == MROBE500_PAD
128#define LP_QUIT BUTTON_POWER
129#elif CONFIG_KEYPAD == MROBE100_PAD
130#define LP_QUIT BUTTON_POWER
131#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
132#define LP_QUIT BUTTON_BACK
133#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
134#define LP_QUIT BUTTON_RC_REC
135#elif CONFIG_KEYPAD == COWON_D2_PAD
136#define LP_QUIT BUTTON_POWER
137#elif CONFIG_KEYPAD == IAUDIO67_PAD
138#define LP_QUIT BUTTON_POWER
139#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
140#define LP_QUIT BUTTON_BACK
141#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
142#define LP_QUIT BUTTON_POWER
143#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
144#define LP_QUIT BUTTON_POWER
145#elif CONFIG_KEYPAD == ONDAVX747_PAD
146#define LP_QUIT BUTTON_POWER
147#elif CONFIG_KEYPAD == ONDAVX777_PAD
148#define LP_QUIT BUTTON_POWER
149#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
150#define LP_QUIT BUTTON_LEFT
151#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
152#define LP_QUIT BUTTON_CANCEL
153#elif CONFIG_KEYPAD == MPIO_HD200_PAD
154#define LP_QUIT (BUTTON_REC|BUTTON_PLAY)
155#else
156#define LP_QUIT BUTTON_OFF
157#endif
158 61
159/* data files */ 62/* data files */
160#define DICT_INDEX PLUGIN_APPS_DIR "/dict.index" 63#define DICT_INDEX PLUGIN_APPS_DIR "/dict.index"
@@ -165,42 +68,32 @@ enum plugin_status plugin_start(const void* parameter)
165{ 68{
166 char searchword[WORDLEN]; /* word to search for */ 69 char searchword[WORDLEN]; /* word to search for */
167 char *description; /* pointer to description buffer */ 70 char *description; /* pointer to description buffer */
168 char *output; /* pointer to output buffer */
169 char *ptr, *space;
170 struct stWord word; /* the struct to read into */ 71 struct stWord word; /* the struct to read into */
171 int fIndex, fData; /* files */ 72 int fIndex, fData; /* files */
172 int filesize, high, low, probe; 73 int filesize, high, low, probe;
173 int lines, len, outputted, next; 74 char *buffer;
75 size_t buffer_size;
174 76
175 /* plugin stuff */ 77 /* plugin stuff */
176 (void)parameter; 78 (void)parameter;
177 79
178 /* get screen info */ 80 /* allocate buffer. */
179 init_screen(); 81 buffer = rb->plugin_get_buffer(&buffer_size);
180 82 if (buffer == NULL || buffer_size < MIN_DESC_BUF_SIZE)
181 /* get pl_malloc() buffer ready. */
182 pl_malloc_init();
183
184 /* init description buffer (size is because we don't have scrolling)*/
185 description = (char *)pl_malloc(display_columns * display_lines);
186 if (description == NULL)
187 { 83 {
188 DEBUGF("Err: failed to allocate description buffer."); 84 DEBUGF("Err: Failed to allocate buffer.\n");
85 rb->splash(HZ*2, "Failed to allocate buffer.");
189 return PLUGIN_ERROR; 86 return PLUGIN_ERROR;
190 } 87 }
191 88
192 /* init output buffer */ 89 description = buffer;
193 output = (char *)pl_malloc(display_columns);
194 if (output == NULL)
195 {
196 DEBUGF("Err: failed to allocate output buffer.");
197 return PLUGIN_ERROR;
198 }
199 90
200 /* "clear" input buffer */ 91 /* "clear" input buffer */
201 searchword[0] = '\0'; 92 searchword[0] = '\0';
202 93
203 rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */ 94 /* get the word to search */
95 if (rb->kbd_input(searchword, sizeof(searchword)) < 0)
96 return PLUGIN_OK; /* input cancelled */
204 97
205 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */ 98 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
206 if (fIndex < 0) 99 if (fIndex < 0)
@@ -241,13 +134,13 @@ enum plugin_status plugin_start(const void* parameter)
241 /* read in the word */ 134 /* read in the word */
242 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET); 135 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
243 rb->read(fIndex, &word, sizeof(struct stWord)); 136 rb->read(fIndex, &word, sizeof(struct stWord));
137 rb->close(fIndex);
244 138
245 /* Check if we found something */ 139 /* Check if we found something */
246 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0) 140 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
247 { 141 {
248 DEBUGF("Not found.\n"); 142 DEBUGF("Not found.\n");
249 rb->splash(HZ*2, "Not found."); 143 rb->splash(HZ*2, "Not found.");
250 rb->close(fIndex);
251 return PLUGIN_OK; 144 return PLUGIN_OK;
252 } 145 }
253 146
@@ -259,7 +152,6 @@ enum plugin_status plugin_start(const void* parameter)
259 { 152 {
260 DEBUGF("Err: Failed to open description file.\n"); 153 DEBUGF("Err: Failed to open description file.\n");
261 rb->splash(HZ*2, "Failed to open descriptions."); 154 rb->splash(HZ*2, "Failed to open descriptions.");
262 rb->close(fIndex);
263 return PLUGIN_ERROR; 155 return PLUGIN_ERROR;
264 } 156 }
265 157
@@ -267,83 +159,15 @@ enum plugin_status plugin_start(const void* parameter)
267 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET); 159 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
268 160
269 /* Read in the description */ 161 /* Read in the description */
270 rb->read_line(fData, description, display_columns * display_lines); 162 rb->read_line(fData, description, buffer_size);
271 163
272 /* And print it to debug. */ 164 /* And print it to debug. */
273 DEBUGF("Description: %s\n", description); 165 DEBUGF("Description: %s\n", description);
274 166
275 /* get pointer to first char */ 167 rb->close(fData);
276 ptr = description;
277
278 lines = 0;
279 outputted = 0;
280 len = rb->strlen(description);
281
282 /* clear screen */
283 rb->lcd_clear_display();
284
285 /* for large screens display the searched word. */
286 if(display_lines > 4)
287 {
288 rb->lcd_puts(0, lines, searchword);
289 lines++;
290 }
291
292 /* TODO: Scroll, or just stop when there are to much lines. */
293 while (1)
294 {
295 /* copy one lcd line */
296 rb->strlcpy(output, ptr, display_columns + 1);
297
298 /* typecast to kill a warning... */
299 if((int)rb->strlen(ptr) < display_columns)
300 {
301 rb->lcd_puts(0, lines, output);
302 lines++;
303 break;
304 }
305
306
307 /* get the last spacechar */
308 space = rb->strrchr(output, ' ');
309
310 if (space != NULL)
311 {
312 *space = '\0';
313 next = (space - (char*)output) + 1;
314 }
315 else
316 {
317 next = display_columns;
318 }
319
320 /* put the line on screen */
321 rb->lcd_puts(0, lines, output);
322
323 /* get output count */
324 outputted += rb->strlen(output);
325
326 if (outputted < len)
327 {
328 /* set pointer to the next part */
329 ptr += next;
330 lines++;
331 }
332 else
333 {
334 break;
335 }
336 }
337 rb->lcd_update();
338 168
339 /* wait for keypress */ 169 /* display description. */
340 while(rb->button_get(true) != LP_QUIT) 170 view_text(searchword, description);
341 {
342 /* do nothing */
343 /* maybe define some keys for navigation here someday. */
344 }
345 171
346 rb->close(fIndex);
347 rb->close(fData);
348 return PLUGIN_OK; 172 return PLUGIN_OK;
349} 173}
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 8c160e1cc4..5ed163f951 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -9,6 +9,7 @@ fixedpoint.c
9playback_control.c 9playback_control.c
10rgb_hsv.c 10rgb_hsv.c
11buflib.c 11buflib.c
12simple_viewer.c
12display_text.c 13display_text.c
13strncpy.c 14strncpy.c
14 15
diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c
new file mode 100644
index 0000000000..c83f005ef4
--- /dev/null
+++ b/apps/plugins/lib/simple_viewer.c
@@ -0,0 +1,260 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2010 Teruaki Kawashima
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#include "config.h"
23#include "plugin.h"
24#include "pluginlib_actions.h"
25#include "simple_viewer.h"
26#include <ctype.h>
27
28struct view_info {
29#ifdef HAVE_LCD_BITMAP
30 struct font* pf;
31#endif
32 const char *title;
33 const char *text; /* displayed text */
34 int display_lines; /* number of lines can be displayed */
35 int line_count; /* number of lines */
36 int line; /* current fisrt line */
37 int start; /* possition of first line in text */
38};
39
40static const char* get_next_line(const char *text, struct view_info *info)
41{
42 (void) info;
43 const char *ptr = text;
44 const char *space = NULL;
45 int total, n, w;
46 total = 0;
47 while(*ptr)
48 {
49#ifdef HAVE_LCD_CHARCELLS
50 n = rb->utf8seek(ptr, 1);
51 w = 1;
52#else
53 unsigned short ch;
54 n = ((long)rb->utf8decode(ptr, &ch) - (long)ptr);
55 w = rb->font_get_width(info->pf, ch);
56#endif
57 if (isspace(*ptr))
58 space = ptr+n;
59 if (*ptr == '\n')
60 {
61 ptr += n;
62 break;
63 }
64 if (total + w > LCD_WIDTH)
65 break;
66 ptr += n;
67 total += w;
68 }
69 return *ptr && space? space: ptr;
70}
71
72static void calc_line_count(struct view_info *info)
73{
74 const char *ptr = info->text;
75 int i = 0;
76
77 while (*ptr)
78 {
79 ptr = get_next_line(ptr, info);
80 i++;
81 }
82 info->line_count = i;
83}
84
85static void calc_first_line(struct view_info *info, int line)
86{
87 const char *ptr = info->text;
88 int i = 0;
89
90 if (line > info->line_count - info->display_lines)
91 line = info->line_count - info->display_lines;
92 if (line < 0)
93 line = 0;
94
95 DEBUGF("%d -> %d\n", info->line, line);
96 if (info->line <= line)
97 {
98 ptr += info->start;
99 i = info->line;
100 }
101 while (*ptr && i < line)
102 {
103 ptr = get_next_line(ptr, info);
104 i++;
105 }
106 info->start = ptr - info->text;
107 info->line = i;
108 DEBUGF("%d: %d\n", info->line, info->start);
109}
110
111static int init_view(struct view_info *info,
112 const char *title, const char *text)
113{
114#ifdef HAVE_LCD_BITMAP
115 info->pf = rb->font_get(FONT_UI);
116 info->display_lines = LCD_HEIGHT / info->pf->height;
117#else
118
119 info->display_lines = LCD_HEIGHT;
120#endif
121
122 info->title = title;
123 info->text = text;
124 info->line_count = 0;
125 info->line = 0;
126 info->start = 0;
127
128 /* no title for small screens. */
129 if (info->display_lines < 4)
130 {
131 info->title = NULL;
132 }
133 else
134 {
135 info->display_lines--;
136 }
137
138 calc_line_count(info);
139 return 0;
140}
141
142static void draw_text(struct view_info *info)
143{
144#ifdef HAVE_LCD_BITMAP
145#define OUTPUT_SIZE LCD_WIDTH+1
146#else
147#define OUTPUT_SIZE LCD_WIDTH*3+1
148#endif
149 static char output[OUTPUT_SIZE];
150 const char *text, *ptr;
151 int i, max_show, lines = 0;
152
153 /* clear screen */
154 rb->lcd_clear_display();
155
156 /* display title. */
157 if(info->title)
158 {
159 rb->lcd_puts(0, lines, info->title);
160 lines++;
161 }
162
163 max_show = MIN(info->line_count - info->line, info->display_lines);
164 DEBUGF("draw_text: %d-%d/%d\n",
165 info->line, info->line + max_show, info->line_count);
166 text = info->text + info->start;
167
168 for (i = 0; i < max_show; i++, lines++)
169 {
170 ptr = get_next_line(text, info);
171 DEBUGF("%d>%d-%d, ", i, text-info->text, ptr-text);
172 rb->strlcpy(output, text, ptr-text+1);
173 rb->lcd_puts(0, lines, output);
174 text = ptr;
175 }
176 DEBUGF("\n");
177
178 rb->lcd_update();
179}
180
181static void scroll_up(struct view_info *info)
182{
183 if (info->line <= 0)
184 return;
185 calc_first_line(info, info->line-1);
186 draw_text(info);
187 return;
188}
189
190static void scroll_down(struct view_info *info)
191{
192 if (info->line + info->display_lines >= info->line_count)
193 return;
194
195 calc_first_line(info, info->line+1);
196 draw_text(info);
197}
198
199static void scroll_to_top(struct view_info *info)
200{
201 if (info->line <= 0)
202 return;
203
204 calc_first_line(info, 0);
205 draw_text(info);
206}
207
208static void scroll_to_bottom(struct view_info *info)
209{
210 if (info->line + info->display_lines >= info->line_count)
211 return;
212
213 calc_first_line(info, info->line_count - info->display_lines);
214 draw_text(info);
215}
216
217int view_text(const char *title, const char *text)
218{
219 struct view_info info;
220 const struct button_mapping *view_contexts[] = {
221 pla_main_ctx,
222 };
223 int button;
224
225 init_view(&info, title, text);
226 draw_text(&info);
227
228 /* wait for keypress */
229 while(1)
230 {
231 button = pluginlib_getaction(TIMEOUT_BLOCK, view_contexts,
232 ARRAYLEN(view_contexts));
233 switch (button)
234 {
235 case PLA_UP:
236 case PLA_UP_REPEAT:
237 scroll_up(&info);
238 break;
239 case PLA_DOWN:
240 case PLA_DOWN_REPEAT:
241 scroll_down(&info);
242 break;
243 case PLA_LEFT_REPEAT:
244 scroll_to_top(&info);
245 break;
246 case PLA_RIGHT_REPEAT:
247 scroll_to_bottom(&info);
248 break;
249 case PLA_EXIT:
250 case PLA_CANCEL:
251 return PLUGIN_OK;
252 default:
253 if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
254 return PLUGIN_USB_CONNECTED;
255 break;
256 }
257 }
258
259 return PLUGIN_OK;
260}
diff --git a/apps/plugins/lib/simple_viewer.h b/apps/plugins/lib/simple_viewer.h
new file mode 100644
index 0000000000..ff3ef23f14
--- /dev/null
+++ b/apps/plugins/lib/simple_viewer.h
@@ -0,0 +1,28 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id$
9*
10* Copyright (C) 2010 Teruaki Kawashima
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version 2
15* of the License, or (at your option) any later version.
16*
17* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18* KIND, either express or implied.
19*
20****************************************************************************/
21
22#ifndef __PLUGINLIB_VIEWER_H__
23#define __PLUGINLIB_VIEWER_H__
24
25#include "plugin.h"
26int view_text(const char *title, const char *text);
27
28#endif /* __PLUGINLIB_VIEWER_H__ */