diff options
author | Tomas Salfischberger <tomas@rockbox.org> | 2005-05-02 15:03:46 +0000 |
---|---|---|
committer | Tomas Salfischberger <tomas@rockbox.org> | 2005-05-02 15:03:46 +0000 |
commit | a810a67db7c923b01c4135761ef21ab866db256d (patch) | |
tree | 73ee3f328458d5067901be3674f970535d12d515 /apps | |
parent | 1ba26b8a60a5e557fe796dab6af28a482d6fbc0d (diff) | |
download | rockbox-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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/dict.c | 245 |
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 | |||
15 | stopwatch.c | 15 | stopwatch.c |
16 | vbrfix.c | 16 | vbrfix.c |
17 | viewer.c | 17 | viewer.c |
18 | dict.c | ||
18 | 19 | ||
19 | #ifdef HAVE_LCD_BITMAP /* Recorder/Ondio models only */ | 20 | #ifdef HAVE_LCD_BITMAP /* Recorder/Ondio models only */ |
20 | bounce.c | 21 | bounce.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 :) */ | ||
23 | static struct plugin_api* rb; | ||
24 | /* screen info */ | ||
25 | static 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 :) */ | ||
32 | struct stWord | ||
33 | { | ||
34 | char word[WORDLEN]; | ||
35 | long offset; | ||
36 | }; | ||
37 | |||
38 | /* A funtion to get width and height etc (from viewer.c) */ | ||
39 | void 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 | ||
58 | long 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 */ | ||
74 | enum 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 | } | ||