blob: f893be3422f94b968f8e3d7c5797e8430bd8ddc3 [file] [log] [blame]
Tomas Salfischbergera810a672005-05-02 15:03:46 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 Tomas Salfischberger
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * 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.
Tomas Salfischbergera810a672005-05-02 15:03:46 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "plugin.h"
23
Jens Arnolda36b1d42006-01-15 18:20:18 +000024PLUGIN_HEADER
25
Tomas Salfischberger03f8c972006-02-11 14:58:52 +000026/* save the plugin api pointer. */
Steve Bavin65265772008-05-13 09:57:56 +000027static const struct plugin_api* rb;
Tomas Salfischbergera810a672005-05-02 15:03:46 +000028/* screen info */
29static int display_columns, display_lines;
30
31/* Some lenghts */
32#define WORDLEN 32 /* has to be the same in rdf2binary.c */
Tomas Salfischbergera810a672005-05-02 15:03:46 +000033
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +000034/* Struct packing */
35#ifdef __GNUC__
36#define STRUCT_PACKED __attribute__((packed))
37#else
38#define STRUCT_PACKED
39#pragma pack (push, 2)
40#endif
41
Tomas Salfischbergera810a672005-05-02 15:03:46 +000042/* The word struct :) */
43struct stWord
44{
45 char word[WORDLEN];
46 long offset;
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +000047} STRUCT_PACKED;
Tomas Salfischbergera810a672005-05-02 15:03:46 +000048
49/* A funtion to get width and height etc (from viewer.c) */
50void init_screen(void)
51{
52#ifdef HAVE_LCD_BITMAP
53 int w,h;
54
55 rb->lcd_getstringsize("o", &w, &h);
56 display_lines = LCD_HEIGHT / h;
57 display_columns = LCD_WIDTH / w;
58#else
59
60 display_lines = 2;
61 display_columns = 11;
62#endif
63}
64
Tomas Salfischberger84364bc2005-05-02 23:09:21 +000065/* global vars for pl_malloc() */
66void *bufptr;
Michael Sevakis26d242a2007-04-21 18:38:25 +000067ssize_t bufleft;
Tomas Salfischberger84364bc2005-05-02 23:09:21 +000068
69/* simple function to "allocate" memory in pluginbuffer. */
Michael Sevakis26d242a2007-04-21 18:38:25 +000070void *pl_malloc(ssize_t size)
Tomas Salfischberger84364bc2005-05-02 23:09:21 +000071{
72 void *ptr;
73 ptr = bufptr;
74
75 if (bufleft < size)
76 {
77 return NULL;
78 }
79 else
80 {
81 bufptr += size;
82 return ptr;
83 }
84}
85
86/* init function for pl_malloc() */
87void pl_malloc_init(void)
88{
Michael Sevakis8676dc22007-04-21 19:07:15 +000089 bufptr = rb->plugin_get_buffer((size_t *)&bufleft);
Tomas Salfischberger84364bc2005-05-02 23:09:21 +000090}
91
Tomas Salfischbergera810a672005-05-02 15:03:46 +000092/* for endian problems */
Tomas Salfischberger23028f52005-05-02 16:06:05 +000093#ifdef ROCKBOX_BIG_ENDIAN
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +000094#define reverse(x) x
Tomas Salfischbergera810a672005-05-02 15:03:46 +000095#else
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +000096long reverse (long N) {
97 unsigned char B[4];
98 B[0] = (N & 0x000000FF) >> 0;
99 B[1] = (N & 0x0000FF00) >> 8;
100 B[2] = (N & 0x00FF0000) >> 16;
101 B[3] = (N & 0xFF000000) >> 24;
102 return ((B[0] << 24) | (B[1] << 16) | (B[2] << 8) | (B[3] << 0));
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000103}
104#endif
105
106/* Button definitions */
107#if CONFIG_KEYPAD == PLAYER_PAD
108#define LP_QUIT BUTTON_STOP
Dave Chapmanfb4e3842006-02-24 20:54:09 +0000109#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
Jens Arnoldb7013222007-07-27 09:57:27 +0000110 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
111 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
Dave Chapman54d44c82005-12-14 01:31:37 +0000112#define LP_QUIT BUTTON_MENU
Dave Chapmand83e9292006-01-12 00:35:50 +0000113#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
114#define LP_QUIT BUTTON_PLAY
Jens Arnold85a226d2007-03-16 23:02:39 +0000115#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
Daniel Stenbergcedba882006-01-18 11:09:06 +0000116#define LP_QUIT BUTTON_POWER
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +0000117#elif CONFIG_KEYPAD == GIGABEAT_PAD
Marcoen Hirschberga7168fe2007-05-19 23:38:09 +0000118#define LP_QUIT BUTTON_POWER
Marianne Arnold12ddb8e2007-09-20 10:49:48 +0000119#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
120(CONFIG_KEYPAD == SANSA_C200_PAD)
Barry Wardell24f4a2a2006-10-26 13:38:09 +0000121#define LP_QUIT BUTTON_POWER
Daniel Stenberg1e88be52006-08-03 20:17:25 +0000122#elif CONFIG_KEYPAD == IRIVER_H10_PAD
123#define LP_QUIT BUTTON_POWER
Jonathan Gordon56ddddc2007-10-23 15:40:51 +0000124#elif CONFIG_KEYPAD == MROBE500_PAD
125#define LP_QUIT BUTTON_POWER
Robert Kuklad6c8b572008-03-01 22:55:09 +0000126#elif CONFIG_KEYPAD == MROBE100_PAD
127#define LP_QUIT BUTTON_POWER
Will Robertson8215b342008-02-17 12:23:02 +0000128#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
129#define LP_QUIT BUTTON_BACK
Jens Arnold29361ab2008-03-22 10:24:28 +0000130#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
131#define LP_QUIT BUTTON_RC_REC
Rob Purchase554d7ed2008-03-22 22:03:34 +0000132#elif CONFIG_KEYPAD == COWOND2_PAD
133#define LP_QUIT BUTTON_POWER
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000134#else
135#define LP_QUIT BUTTON_OFF
136#endif
137
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +0000138/* data files */
Peter D'Hoye96743162007-08-08 23:32:35 +0000139#define DICT_INDEX ROCKBOX_DIR "/rocks/apps/dict.index"
140#define DICT_DESC ROCKBOX_DIR "/rocks/apps/dict.desc"
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +0000141
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000142/* the main plugin function */
Steve Bavin65265772008-05-13 09:57:56 +0000143enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000144{
145 char searchword[WORDLEN]; /* word to search for */
Tomas Salfischberger84364bc2005-05-02 23:09:21 +0000146 char *description; /* pointer to description buffer */
147 char *output; /* pointer to output buffer */
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000148 char *ptr, *space;
149 struct stWord word; /* the struct to read into */
150 int fIndex, fData; /* files */
151 int filesize, high, low, probe;
152 int lines, len, outputted, next;
153
154 /* plugin stuff */
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000155 (void)parameter;
156 rb = api;
157
158 /* get screen info */
159 init_screen();
160
Tomas Salfischberger84364bc2005-05-02 23:09:21 +0000161 /* get pl_malloc() buffer ready. */
162 pl_malloc_init();
163
164 /* init description buffer (size is because we don't have scrolling)*/
165 description = (char *)pl_malloc(display_columns * display_lines);
166 if (description == NULL)
167 {
168 DEBUGF("Err: failed to allocate description buffer.");
169 return PLUGIN_ERROR;
170 }
171
172 /* init output buffer */
173 output = (char *)pl_malloc(display_columns);
174 if (output == NULL)
175 {
176 DEBUGF("Err: failed to allocate output buffer.");
177 return PLUGIN_ERROR;
178 }
179
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000180 /* "clear" input buffer */
181 searchword[0] = '\0';
182
183 rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */
184
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +0000185 fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000186 if (fIndex < 0)
187 {
188 DEBUGF("Err: Failed to open index file.\n");
Jens Arnold4d6374c2007-03-16 21:56:08 +0000189 rb->splash(HZ*2, "Failed to open index.");
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000190 return PLUGIN_ERROR;
191 }
192
193 filesize = rb->filesize(fIndex); /* get filesize */
194
195 DEBUGF("Filesize: %d bytes = %d words \n", filesize,
Jens Arnoldbd5c0ad2007-03-17 10:50:58 +0000196 (filesize / (int)sizeof(struct stWord)));
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000197
198 /* for the searching algorithm */
199 high = filesize / sizeof( struct stWord );
200 low = -1;
201
202 while (high - low > 1)
203 {
204 probe = (high + low) / 2;
205
206 /* Jump to word pointed by probe, and read it. */
207 rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET);
208 rb->read(fIndex, &word, sizeof(struct stWord));
209
210 /* jump according to the found word. */
211 if (rb->strcasecmp(searchword, word.word) < 0)
212 {
213 high = probe;
214 }
215 else
216 {
217 low = probe;
218 }
219 }
220
221 /* read in the word */
222 rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
223 rb->read(fIndex, &word, sizeof(struct stWord));
224
225 /* Check if we found something */
226 if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
227 {
228 DEBUGF("Not found.\n");
Jens Arnold4d6374c2007-03-16 21:56:08 +0000229 rb->splash(HZ*2, "Not found.");
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000230 rb->close(fIndex);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000231 return PLUGIN_OK;
232 }
233
Jens Arnoldf68362a2007-03-17 09:54:28 +0000234 DEBUGF("Found %s at offset %ld\n", word.word, reverse(word.offset));
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000235
236 /* now open the description file */
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +0000237 fData = rb->open(DICT_DESC, O_RDONLY);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000238 if (fData < 0)
239 {
240 DEBUGF("Err: Failed to open description file.\n");
Jens Arnold4d6374c2007-03-16 21:56:08 +0000241 rb->splash(HZ*2, "Failed to open descriptions.");
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000242 rb->close(fIndex);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000243 return PLUGIN_ERROR;
244 }
245
246 /* seek to the right offset */
Tomas Salfischbergerb3c417b2005-06-05 14:21:51 +0000247 rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000248
249 /* Read in the description */
Tomas Salfischberger84364bc2005-05-02 23:09:21 +0000250 rb->read_line(fData, description, display_columns * display_lines);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000251
252 /* And print it to debug. */
253 DEBUGF("Description: %s\n", description);
254
255 /* get pointer to first char */
256 ptr = description;
257
258 lines = 0;
259 outputted = 0;
260 len = rb->strlen(description);
261
262 /* clear screen */
263 rb->lcd_clear_display();
264
265 /* for large screens display the searched word. */
266 if(display_lines > 4)
267 {
268 rb->lcd_puts(0, lines, searchword);
269 lines++;
270 }
271
272 /* TODO: Scroll, or just stop when there are to much lines. */
273 while (1)
274 {
275 /* copy one lcd line */
276 rb->strncpy(output, ptr, display_columns);
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000277 output[display_columns] = '\0';
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000278
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000279 /* typecast to kill a warning... */
280 if((int)rb->strlen(ptr) < display_columns)
281 {
282 rb->lcd_puts(0, lines, output);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000283 lines++;
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000284 break;
285 }
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000286
287
288 /* get the last spacechar */
289 space = rb->strrchr(output, ' ');
290
291 if (space != NULL)
292 {
293 *space = '\0';
294 next = (space - (char*)output) + 1;
295 }
296 else
297 {
298 next = display_columns;
299 }
300
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000301 /* put the line on screen */
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000302 rb->lcd_puts(0, lines, output);
303
304 /* get output count */
305 outputted += rb->strlen(output);
306
307 if (outputted < len)
308 {
309 /* set pointer to the next part */
310 ptr += next;
311 lines++;
312 }
313 else
314 {
315 break;
316 }
317 }
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000318 rb->lcd_update();
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000319
320 /* wait for keypress */
321 while(rb->button_get(true) != LP_QUIT)
322 {
323 /* do nothing */
324 /* maybe define some keys for navigation here someday. */
325 }
326
327 rb->close(fIndex);
Tomas Salfischberger23028f52005-05-02 16:06:05 +0000328 rb->close(fData);
Tomas Salfischbergera810a672005-05-02 15:03:46 +0000329 return PLUGIN_OK;
330}