Theme Editor: Factored out code to skip over enum/arg lists while scanning for childr...
[kugel-rb.git] / apps / plugins / dict.c
blob8c262923b756fab44b9c32130c67e5b3e7698f9b
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2005 Tomas Salfischberger
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.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
24 PLUGIN_HEADER
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 size_t bufleft;
67 /* simple function to "allocate" memory in pluginbuffer. */
68 void *pl_malloc(size_t size)
70 void *ptr;
71 ptr = bufptr;
73 if (bufleft < size)
75 return NULL;
77 else
79 bufptr += size;
80 bufleft -= size;
81 return ptr;
85 /* init function for pl_malloc() */
86 void pl_malloc_init(void)
88 bufptr = rb->plugin_get_buffer(&bufleft);
91 /* for endian problems */
92 #ifdef ROCKBOX_BIG_ENDIAN
93 #define reverse(x) x
94 #else
95 long reverse (long N) {
96 unsigned char B[4];
97 B[0] = (N & 0x000000FF) >> 0;
98 B[1] = (N & 0x0000FF00) >> 8;
99 B[2] = (N & 0x00FF0000) >> 16;
100 B[3] = (N & 0xFF000000) >> 24;
101 return ((B[0] << 24) | (B[1] << 16) | (B[2] << 8) | (B[3] << 0));
103 #endif
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
159 /* data files */
160 #define DICT_INDEX PLUGIN_APPS_DIR "/dict.index"
161 #define DICT_DESC PLUGIN_APPS_DIR "/dict.desc"
163 /* the main plugin function */
164 enum plugin_status plugin_start(const void* parameter)
166 char searchword[WORDLEN]; /* word to search for */
167 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 */
171 int fIndex, fData; /* files */
172 int filesize, high, low, probe;
173 int lines, len, outputted, next;
175 /* plugin stuff */
176 (void)parameter;
178 /* get screen info */
179 init_screen();
181 /* get pl_malloc() buffer ready. */
182 pl_malloc_init();
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)
188 DEBUGF("Err: failed to allocate description buffer.");
189 return PLUGIN_ERROR;
192 /* init output buffer */
193 output = (char *)pl_malloc(display_columns);
194 if (output == NULL)
196 DEBUGF("Err: failed to allocate output buffer.");
197 return PLUGIN_ERROR;
200 /* "clear" input buffer */
201 searchword[0] = '\0';
203 rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */
205 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
206 if (fIndex < 0)
208 DEBUGF("Err: Failed to open index file.\n");
209 rb->splash(HZ*2, "Failed to open index.");
210 return PLUGIN_ERROR;
213 filesize = rb->filesize(fIndex); /* get filesize */
215 DEBUGF("Filesize: %d bytes = %d words \n", filesize,
216 (filesize / (int)sizeof(struct stWord)));
218 /* for the searching algorithm */
219 high = filesize / sizeof( struct stWord );
220 low = -1;
222 while (high - low > 1)
224 probe = (high + low) / 2;
226 /* Jump to word pointed by probe, and read it. */
227 rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET);
228 rb->read(fIndex, &word, sizeof(struct stWord));
230 /* jump according to the found word. */
231 if (rb->strcasecmp(searchword, word.word) < 0)
233 high = probe;
235 else
237 low = probe;
241 /* read in the word */
242 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
243 rb->read(fIndex, &word, sizeof(struct stWord));
245 /* Check if we found something */
246 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
248 DEBUGF("Not found.\n");
249 rb->splash(HZ*2, "Not found.");
250 rb->close(fIndex);
251 return PLUGIN_OK;
254 DEBUGF("Found %s at offset %ld\n", word.word, reverse(word.offset));
256 /* now open the description file */
257 fData = rb->open(DICT_DESC, O_RDONLY);
258 if (fData < 0)
260 DEBUGF("Err: Failed to open description file.\n");
261 rb->splash(HZ*2, "Failed to open descriptions.");
262 rb->close(fIndex);
263 return PLUGIN_ERROR;
266 /* seek to the right offset */
267 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
269 /* Read in the description */
270 rb->read_line(fData, description, display_columns * display_lines);
272 /* And print it to debug. */
273 DEBUGF("Description: %s\n", description);
275 /* get pointer to first char */
276 ptr = description;
278 lines = 0;
279 outputted = 0;
280 len = rb->strlen(description);
282 /* clear screen */
283 rb->lcd_clear_display();
285 /* for large screens display the searched word. */
286 if(display_lines > 4)
288 rb->lcd_puts(0, lines, searchword);
289 lines++;
292 /* TODO: Scroll, or just stop when there are to much lines. */
293 while (1)
295 /* copy one lcd line */
296 rb->strlcpy(output, ptr, display_columns + 1);
298 /* typecast to kill a warning... */
299 if((int)rb->strlen(ptr) < display_columns)
301 rb->lcd_puts(0, lines, output);
302 lines++;
303 break;
307 /* get the last spacechar */
308 space = rb->strrchr(output, ' ');
310 if (space != NULL)
312 *space = '\0';
313 next = (space - (char*)output) + 1;
315 else
317 next = display_columns;
320 /* put the line on screen */
321 rb->lcd_puts(0, lines, output);
323 /* get output count */
324 outputted += rb->strlen(output);
326 if (outputted < len)
328 /* set pointer to the next part */
329 ptr += next;
330 lines++;
332 else
334 break;
337 rb->lcd_update();
339 /* wait for keypress */
340 while(rb->button_get(true) != LP_QUIT)
342 /* do nothing */
343 /* maybe define some keys for navigation here someday. */
346 rb->close(fIndex);
347 rb->close(fData);
348 return PLUGIN_OK;