Pong: small improvement in the c200 buttonmap; the left paddle is now controlled...
[Rockbox.git] / apps / plugins / dict.c
blob257a0c61478182cb78b8532d8d84ed2128dbb181
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Tomas Salfischberger
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 #include "plugin.h"
22 PLUGIN_HEADER
24 /* save the plugin api pointer. */
25 static struct plugin_api* rb;
26 /* screen info */
27 static int display_columns, display_lines;
29 /* Some lenghts */
30 #define WORDLEN 32 /* has to be the same in rdf2binary.c */
32 /* Struct packing */
33 #ifdef __GNUC__
34 #define STRUCT_PACKED __attribute__((packed))
35 #else
36 #define STRUCT_PACKED
37 #pragma pack (push, 2)
38 #endif
40 /* The word struct :) */
41 struct stWord
43 char word[WORDLEN];
44 long offset;
45 } STRUCT_PACKED;
47 /* A funtion to get width and height etc (from viewer.c) */
48 void init_screen(void)
50 #ifdef HAVE_LCD_BITMAP
51 int w,h;
53 rb->lcd_getstringsize("o", &w, &h);
54 display_lines = LCD_HEIGHT / h;
55 display_columns = LCD_WIDTH / w;
56 #else
58 display_lines = 2;
59 display_columns = 11;
60 #endif
63 /* global vars for pl_malloc() */
64 void *bufptr;
65 ssize_t bufleft;
67 /* simple function to "allocate" memory in pluginbuffer. */
68 void *pl_malloc(ssize_t size)
70 void *ptr;
71 ptr = bufptr;
73 if (bufleft < size)
75 return NULL;
77 else
79 bufptr += size;
80 return ptr;
84 /* init function for pl_malloc() */
85 void pl_malloc_init(void)
87 bufptr = rb->plugin_get_buffer((size_t *)&bufleft);
90 /* for endian problems */
91 #ifdef ROCKBOX_BIG_ENDIAN
92 #define reverse(x) x
93 #else
94 long reverse (long N) {
95 unsigned char B[4];
96 B[0] = (N & 0x000000FF) >> 0;
97 B[1] = (N & 0x0000FF00) >> 8;
98 B[2] = (N & 0x00FF0000) >> 16;
99 B[3] = (N & 0xFF000000) >> 24;
100 return ((B[0] << 24) | (B[1] << 16) | (B[2] << 8) | (B[3] << 0));
102 #endif
104 /* Button definitions */
105 #if CONFIG_KEYPAD == PLAYER_PAD
106 #define LP_QUIT BUTTON_STOP
107 #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
108 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
109 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
110 #define LP_QUIT BUTTON_MENU
111 #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
112 #define LP_QUIT BUTTON_PLAY
113 #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
114 #define LP_QUIT BUTTON_POWER
115 #elif CONFIG_KEYPAD == GIGABEAT_PAD
116 #define LP_QUIT BUTTON_POWER
117 #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
118 (CONFIG_KEYPAD == SANSA_C200_PAD)
119 #define LP_QUIT BUTTON_POWER
120 #elif CONFIG_KEYPAD == IRIVER_H10_PAD
121 #define LP_QUIT BUTTON_POWER
122 #else
123 #define LP_QUIT BUTTON_OFF
124 #endif
126 /* data files */
127 #define DICT_INDEX ROCKBOX_DIR "/rocks/apps/dict.index"
128 #define DICT_DESC ROCKBOX_DIR "/rocks/apps/dict.desc"
130 /* the main plugin function */
131 enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
133 char searchword[WORDLEN]; /* word to search for */
134 char *description; /* pointer to description buffer */
135 char *output; /* pointer to output buffer */
136 char *ptr, *space;
137 struct stWord word; /* the struct to read into */
138 int fIndex, fData; /* files */
139 int filesize, high, low, probe;
140 int lines, len, outputted, next;
142 /* plugin stuff */
143 (void)parameter;
144 rb = api;
146 /* get screen info */
147 init_screen();
149 /* get pl_malloc() buffer ready. */
150 pl_malloc_init();
152 /* init description buffer (size is because we don't have scrolling)*/
153 description = (char *)pl_malloc(display_columns * display_lines);
154 if (description == NULL)
156 DEBUGF("Err: failed to allocate description buffer.");
157 return PLUGIN_ERROR;
160 /* init output buffer */
161 output = (char *)pl_malloc(display_columns);
162 if (output == NULL)
164 DEBUGF("Err: failed to allocate output buffer.");
165 return PLUGIN_ERROR;
168 /* "clear" input buffer */
169 searchword[0] = '\0';
171 rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */
173 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
174 if (fIndex < 0)
176 DEBUGF("Err: Failed to open index file.\n");
177 rb->splash(HZ*2, "Failed to open index.");
178 return PLUGIN_ERROR;
181 filesize = rb->filesize(fIndex); /* get filesize */
183 DEBUGF("Filesize: %d bytes = %d words \n", filesize,
184 (filesize / (int)sizeof(struct stWord)));
186 /* for the searching algorithm */
187 high = filesize / sizeof( struct stWord );
188 low = -1;
190 while (high - low > 1)
192 probe = (high + low) / 2;
194 /* Jump to word pointed by probe, and read it. */
195 rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET);
196 rb->read(fIndex, &word, sizeof(struct stWord));
198 /* jump according to the found word. */
199 if (rb->strcasecmp(searchword, word.word) < 0)
201 high = probe;
203 else
205 low = probe;
209 /* read in the word */
210 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
211 rb->read(fIndex, &word, sizeof(struct stWord));
213 /* Check if we found something */
214 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
216 DEBUGF("Not found.\n");
217 rb->splash(HZ*2, "Not found.");
218 rb->close(fIndex);
219 return PLUGIN_OK;
222 DEBUGF("Found %s at offset %ld\n", word.word, reverse(word.offset));
224 /* now open the description file */
225 fData = rb->open(DICT_DESC, O_RDONLY);
226 if (fData < 0)
228 DEBUGF("Err: Failed to open description file.\n");
229 rb->splash(HZ*2, "Failed to open descriptions.");
230 rb->close(fIndex);
231 return PLUGIN_ERROR;
234 /* seek to the right offset */
235 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
237 /* Read in the description */
238 rb->read_line(fData, description, display_columns * display_lines);
240 /* And print it to debug. */
241 DEBUGF("Description: %s\n", description);
243 /* get pointer to first char */
244 ptr = description;
246 lines = 0;
247 outputted = 0;
248 len = rb->strlen(description);
250 /* clear screen */
251 rb->lcd_clear_display();
253 /* for large screens display the searched word. */
254 if(display_lines > 4)
256 rb->lcd_puts(0, lines, searchword);
257 lines++;
260 /* TODO: Scroll, or just stop when there are to much lines. */
261 while (1)
263 /* copy one lcd line */
264 rb->strncpy(output, ptr, display_columns);
265 output[display_columns] = '\0';
267 /* typecast to kill a warning... */
268 if((int)rb->strlen(ptr) < display_columns)
270 rb->lcd_puts(0, lines, output);
271 lines++;
272 break;
276 /* get the last spacechar */
277 space = rb->strrchr(output, ' ');
279 if (space != NULL)
281 *space = '\0';
282 next = (space - (char*)output) + 1;
284 else
286 next = display_columns;
289 /* put the line on screen */
290 rb->lcd_puts(0, lines, output);
292 /* get output count */
293 outputted += rb->strlen(output);
295 if (outputted < len)
297 /* set pointer to the next part */
298 ptr += next;
299 lines++;
301 else
303 break;
306 rb->lcd_update();
308 /* wait for keypress */
309 while(rb->button_get(true) != LP_QUIT)
311 /* do nothing */
312 /* maybe define some keys for navigation here someday. */
315 rb->close(fIndex);
316 rb->close(fData);
317 return PLUGIN_OK;