1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
27 static int display_columns
, display_lines
;
30 #define WORDLEN 32 /* has to be the same in rdf2binary.c */
34 #define STRUCT_PACKED __attribute__((packed))
37 #pragma pack (push, 2)
40 /* The word struct :) */
47 /* A funtion to get width and height etc (from viewer.c) */
48 void init_screen(void)
50 #ifdef HAVE_LCD_BITMAP
53 rb
->lcd_getstringsize("o", &w
, &h
);
54 display_lines
= LCD_HEIGHT
/ h
;
55 display_columns
= LCD_WIDTH
/ w
;
63 /* global vars for pl_malloc() */
67 /* simple function to "allocate" memory in pluginbuffer. */
68 void *pl_malloc(ssize_t size
)
85 /* init function for pl_malloc() */
86 void pl_malloc_init(void)
88 bufptr
= rb
->plugin_get_buffer((size_t *)&bufleft
);
91 /* for endian problems */
92 #ifdef ROCKBOX_BIG_ENDIAN
95 long reverse (long N
) {
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));
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 == COWOND2_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 == ONDAVX747_PAD
144 #define LP_QUIT BUTTON_POWER
145 #elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
146 #define LP_QUIT BUTTON_LEFT
148 #define LP_QUIT BUTTON_OFF
152 #define DICT_INDEX PLUGIN_APPS_DIR "/dict.index"
153 #define DICT_DESC PLUGIN_APPS_DIR "/dict.desc"
155 /* the main plugin function */
156 enum plugin_status
plugin_start(UNUSED_ATTR
const void* parameter
)
158 char searchword
[WORDLEN
]; /* word to search for */
159 char *description
; /* pointer to description buffer */
160 char *output
; /* pointer to output buffer */
162 struct stWord word
; /* the struct to read into */
163 int fIndex
, fData
; /* files */
164 int filesize
, high
, low
, probe
;
165 int lines
, len
, outputted
, next
;
169 /* get screen info */
172 /* get pl_malloc() buffer ready. */
175 /* init description buffer (size is because we don't have scrolling)*/
176 description
= (char *)pl_malloc(display_columns
* display_lines
);
177 if (description
== NULL
)
179 DEBUGF("Err: failed to allocate description buffer.");
183 /* init output buffer */
184 output
= (char *)pl_malloc(display_columns
);
187 DEBUGF("Err: failed to allocate output buffer.");
191 /* "clear" input buffer */
192 searchword
[0] = '\0';
194 rb
->kbd_input(searchword
, sizeof(searchword
)); /* get the word to search */
196 fIndex
= rb
->open(DICT_INDEX
, O_RDONLY
); /* index file */
199 DEBUGF("Err: Failed to open index file.\n");
200 rb
->splash(HZ
*2, "Failed to open index.");
204 filesize
= rb
->filesize(fIndex
); /* get filesize */
206 DEBUGF("Filesize: %d bytes = %d words \n", filesize
,
207 (filesize
/ (int)sizeof(struct stWord
)));
209 /* for the searching algorithm */
210 high
= filesize
/ sizeof( struct stWord
);
213 while (high
- low
> 1)
215 probe
= (high
+ low
) / 2;
217 /* Jump to word pointed by probe, and read it. */
218 rb
->lseek(fIndex
, sizeof(struct stWord
) * probe
, SEEK_SET
);
219 rb
->read(fIndex
, &word
, sizeof(struct stWord
));
221 /* jump according to the found word. */
222 if (rb
->strcasecmp(searchword
, word
.word
) < 0)
232 /* read in the word */
233 rb
->lseek(fIndex
, sizeof(struct stWord
) * low
, SEEK_SET
);
234 rb
->read(fIndex
, &word
, sizeof(struct stWord
));
236 /* Check if we found something */
237 if (low
== -1 || rb
->strcasecmp(searchword
, word
.word
) != 0)
239 DEBUGF("Not found.\n");
240 rb
->splash(HZ
*2, "Not found.");
245 DEBUGF("Found %s at offset %ld\n", word
.word
, reverse(word
.offset
));
247 /* now open the description file */
248 fData
= rb
->open(DICT_DESC
, O_RDONLY
);
251 DEBUGF("Err: Failed to open description file.\n");
252 rb
->splash(HZ
*2, "Failed to open descriptions.");
257 /* seek to the right offset */
258 rb
->lseek(fData
, (off_t
)reverse(word
.offset
), SEEK_SET
);
260 /* Read in the description */
261 rb
->read_line(fData
, description
, display_columns
* display_lines
);
263 /* And print it to debug. */
264 DEBUGF("Description: %s\n", description
);
266 /* get pointer to first char */
271 len
= rb
->strlen(description
);
274 rb
->lcd_clear_display();
276 /* for large screens display the searched word. */
277 if(display_lines
> 4)
279 rb
->lcd_puts(0, lines
, searchword
);
283 /* TODO: Scroll, or just stop when there are to much lines. */
286 /* copy one lcd line */
287 rb
->strlcpy(output
, ptr
, display_columns
+ 1);
289 /* typecast to kill a warning... */
290 if((int)rb
->strlen(ptr
) < display_columns
)
292 rb
->lcd_puts(0, lines
, output
);
298 /* get the last spacechar */
299 space
= rb
->strrchr(output
, ' ');
304 next
= (space
- (char*)output
) + 1;
308 next
= display_columns
;
311 /* put the line on screen */
312 rb
->lcd_puts(0, lines
, output
);
314 /* get output count */
315 outputted
+= rb
->strlen(output
);
319 /* set pointer to the next part */
330 /* wait for keypress */
331 while(rb
->button_get(true) != LP_QUIT
)
334 /* maybe define some keys for navigation here someday. */