summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Salfischberger <tomas@rockbox.org>2005-05-02 15:03:46 +0000
committerTomas Salfischberger <tomas@rockbox.org>2005-05-02 15:03:46 +0000
commita810a67db7c923b01c4135761ef21ab866db256d (patch)
tree73ee3f328458d5067901be3674f970535d12d515
parent1ba26b8a60a5e557fe796dab6af28a482d6fbc0d (diff)
downloadrockbox-a810a67db7c923b01c4135761ef21ab866db256d.tar.gz
rockbox-a810a67db7c923b01c4135761ef21ab866db256d.zip
Dictionary plugin, first version... please bugtest.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6394 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/dict.c245
2 files changed, 246 insertions, 0 deletions
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES
index 8c5525a657..76be771fb3 100644
--- a/apps/plugins/SOURCES
+++ b/apps/plugins/SOURCES
@@ -15,6 +15,7 @@ sort.c
15stopwatch.c 15stopwatch.c
16vbrfix.c 16vbrfix.c
17viewer.c 17viewer.c
18dict.c
18 19
19#ifdef HAVE_LCD_BITMAP /* Recorder/Ondio models only */ 20#ifdef HAVE_LCD_BITMAP /* Recorder/Ondio models only */
20bounce.c 21bounce.c
diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c
new file mode 100644
index 0000000000..efaeab2ed3
--- /dev/null
+++ b/apps/plugins/dict.c
@@ -0,0 +1,245 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Tomas Salfischberger
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "plugin.h"
21
22/* as in hello world :) */
23static struct plugin_api* rb;
24/* screen info */
25static int display_columns, display_lines;
26
27/* Some lenghts */
28#define WORDLEN 32 /* has to be the same in rdf2binary.c */
29#define DESCLEN 2048
30
31/* The word struct :) */
32struct stWord
33{
34 char word[WORDLEN];
35 long offset;
36};
37
38/* A funtion to get width and height etc (from viewer.c) */
39void init_screen(void)
40{
41#ifdef HAVE_LCD_BITMAP
42 int w,h;
43
44 rb->lcd_getstringsize("o", &w, &h);
45 display_lines = LCD_HEIGHT / h;
46 display_columns = LCD_WIDTH / w;
47#else
48
49 display_lines = 2;
50 display_columns = 11;
51#endif
52}
53
54/* for endian problems */
55#ifdef LITTLE_ENDIAN
56#define readlong(x) x
57#else
58long readlong(void* value)
59{
60 unsigned char* bytes = (unsigned char*) value;
61 return (long)bytes[0] | ((long)bytes[1] << 8) |
62 ((long)bytes[2] << 16) | ((long)bytes[3] << 24);
63}
64#endif
65
66/* Button definitions */
67#if CONFIG_KEYPAD == PLAYER_PAD
68#define LP_QUIT BUTTON_STOP
69#else
70#define LP_QUIT BUTTON_OFF
71#endif
72
73/* the main plugin function */
74enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
75{
76 char searchword[WORDLEN]; /* word to search for */
77 char description[DESCLEN]; /* description buffer */
78 char output[DESCLEN]; /* output buffer */
79 char *ptr, *space;
80 struct stWord word; /* the struct to read into */
81 int fIndex, fData; /* files */
82 int filesize, high, low, probe;
83 int lines, len, outputted, next;
84
85 /* plugin stuff */
86 TEST_PLUGIN_API(api);
87 (void)parameter;
88 rb = api;
89
90 /* get screen info */
91 init_screen();
92
93 /* "clear" input buffer */
94 searchword[0] = '\0';
95
96 rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */
97
98 fIndex = rb->open("/.rockbox/dict.index", O_RDONLY); /* index file */
99 if (fIndex < 0)
100 {
101 DEBUGF("Err: Failed to open index file.\n");
102 rb->splash(HZ*2, true, "Failed to open index.");
103 return PLUGIN_ERROR;
104 }
105
106 filesize = rb->filesize(fIndex); /* get filesize */
107
108 DEBUGF("Filesize: %d bytes = %d words \n", filesize,
109 (filesize / sizeof(struct stWord)));
110
111 /* for the searching algorithm */
112 high = filesize / sizeof( struct stWord );
113 low = -1;
114
115 while (high - low > 1)
116 {
117 probe = (high + low) / 2;
118
119 /* Jump to word pointed by probe, and read it. */
120 rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET);
121 rb->read(fIndex, &word, sizeof(struct stWord));
122
123 /* jump according to the found word. */
124 if (rb->strcasecmp(searchword, word.word) < 0)
125 {
126 high = probe;
127 }
128 else
129 {
130 low = probe;
131 }
132 }
133
134 /* read in the word */
135 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
136 rb->read(fIndex, &word, sizeof(struct stWord));
137
138 /* Check if we found something */
139 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
140 {
141 DEBUGF("Not found.\n");
142 rb->splash(HZ*2, true, "Not found.");
143 rb->close(fIndex);
144 return PLUGIN_OK;
145 }
146
147 DEBUGF("Found %s at offset %d\n", word.word, readlong(&word.offset));
148
149 /* now open the description file */
150 fData = rb->open("/.rockbox/dict.desc", O_RDONLY);
151 if (fData < 0)
152 {
153 DEBUGF("Err: Failed to open description file.\n");
154 rb->splash(HZ*2, true, "Failed to open descriptions.");
155 rb->close(fIndex);
156 return PLUGIN_ERROR;
157 }
158
159 /* seek to the right offset */
160 rb->lseek(fData, readlong(&word.offset), SEEK_SET);
161
162 /* Read in the description */
163 rb->read_line(fData, description, DESCLEN);
164
165 /* And print it to debug. */
166 DEBUGF("Description: %s\n", description);
167
168 /* get pointer to first char */
169 ptr = description;
170
171 lines = 0;
172 outputted = 0;
173 len = rb->strlen(description);
174
175 /* clear screen */
176 rb->lcd_clear_display();
177
178 /* for large screens display the searched word. */
179 if(display_lines > 4)
180 {
181 rb->lcd_puts(0, lines, searchword);
182 lines++;
183 }
184
185 /* TODO: Scroll, or just stop when there are to much lines. */
186 while (1)
187 {
188 /* copy one lcd line */
189 rb->strncpy(output, ptr, display_columns);
190 output[display_columns] = '\0';
191
192 /* unsigned to kill a warning... */
193 if((int)rb->strlen(ptr) < display_columns) {
194 rb->lcd_puts(0, lines, output);
195 lines++;
196 break;
197 }
198
199
200 /* get the last spacechar */
201 space = rb->strrchr(output, ' ');
202
203 if (space != NULL)
204 {
205 *space = '\0';
206 next = (space - (char*)output) + 1;
207 }
208 else
209 {
210 next = display_columns;
211 }
212
213 /* put the line on screen */
214 rb->lcd_puts(0, lines, output);
215
216 /* get output count */
217 outputted += rb->strlen(output);
218
219 if (outputted < len)
220 {
221 /* set pointer to the next part */
222 ptr += next;
223 lines++;
224 }
225 else
226 {
227 break;
228 }
229 }
230
231#ifdef HAVE_LCD_BITMAP
232 rb->lcd_update();
233#endif
234
235 /* wait for keypress */
236 while(rb->button_get(true) != LP_QUIT)
237 {
238 /* do nothing */
239 /* maybe define some keys for navigation here someday. */
240 }
241
242 rb->close(fIndex);
243 rb->close(fData);
244 return PLUGIN_OK;
245}