Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2005 Tomas Salfischberger |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 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. |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 16 | * |
| 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 Arnold | a36b1d4 | 2006-01-15 18:20:18 +0000 | [diff] [blame] | 24 | PLUGIN_HEADER |
| 25 | |
Tomas Salfischberger | 03f8c97 | 2006-02-11 14:58:52 +0000 | [diff] [blame] | 26 | /* save the plugin api pointer. */ |
Steve Bavin | 6526577 | 2008-05-13 09:57:56 +0000 | [diff] [blame] | 27 | static const struct plugin_api* rb; |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 28 | /* screen info */ |
| 29 | static int display_columns, display_lines; |
| 30 | |
| 31 | /* Some lenghts */ |
| 32 | #define WORDLEN 32 /* has to be the same in rdf2binary.c */ |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 33 | |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 34 | /* 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 Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 42 | /* The word struct :) */ |
| 43 | struct stWord |
| 44 | { |
| 45 | char word[WORDLEN]; |
| 46 | long offset; |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 47 | } STRUCT_PACKED; |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 48 | |
| 49 | /* A funtion to get width and height etc (from viewer.c) */ |
| 50 | void 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 Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 65 | /* global vars for pl_malloc() */ |
| 66 | void *bufptr; |
Michael Sevakis | 26d242a | 2007-04-21 18:38:25 +0000 | [diff] [blame] | 67 | ssize_t bufleft; |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 68 | |
| 69 | /* simple function to "allocate" memory in pluginbuffer. */ |
Michael Sevakis | 26d242a | 2007-04-21 18:38:25 +0000 | [diff] [blame] | 70 | void *pl_malloc(ssize_t size) |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 71 | { |
| 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() */ |
| 87 | void pl_malloc_init(void) |
| 88 | { |
Michael Sevakis | 8676dc2 | 2007-04-21 19:07:15 +0000 | [diff] [blame] | 89 | bufptr = rb->plugin_get_buffer((size_t *)&bufleft); |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 90 | } |
| 91 | |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 92 | /* for endian problems */ |
Tomas Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 93 | #ifdef ROCKBOX_BIG_ENDIAN |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 94 | #define reverse(x) x |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 95 | #else |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 96 | long 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 Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 103 | } |
| 104 | #endif |
| 105 | |
| 106 | /* Button definitions */ |
| 107 | #if CONFIG_KEYPAD == PLAYER_PAD |
| 108 | #define LP_QUIT BUTTON_STOP |
Dave Chapman | fb4e384 | 2006-02-24 20:54:09 +0000 | [diff] [blame] | 109 | #elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \ |
Jens Arnold | b701322 | 2007-07-27 09:57:27 +0000 | [diff] [blame] | 110 | (CONFIG_KEYPAD == IPOD_3G_PAD) || \ |
| 111 | (CONFIG_KEYPAD == IPOD_1G2G_PAD) |
Dave Chapman | 54d44c8 | 2005-12-14 01:31:37 +0000 | [diff] [blame] | 112 | #define LP_QUIT BUTTON_MENU |
Dave Chapman | d83e929 | 2006-01-12 00:35:50 +0000 | [diff] [blame] | 113 | #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD |
| 114 | #define LP_QUIT BUTTON_PLAY |
Jens Arnold | 85a226d | 2007-03-16 23:02:39 +0000 | [diff] [blame] | 115 | #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD |
Daniel Stenberg | cedba88 | 2006-01-18 11:09:06 +0000 | [diff] [blame] | 116 | #define LP_QUIT BUTTON_POWER |
Marcoen Hirschberg | 338e2bb | 2006-02-24 15:42:52 +0000 | [diff] [blame] | 117 | #elif CONFIG_KEYPAD == GIGABEAT_PAD |
Marcoen Hirschberg | a7168fe | 2007-05-19 23:38:09 +0000 | [diff] [blame] | 118 | #define LP_QUIT BUTTON_POWER |
Marianne Arnold | 12ddb8e | 2007-09-20 10:49:48 +0000 | [diff] [blame] | 119 | #elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \ |
| 120 | (CONFIG_KEYPAD == SANSA_C200_PAD) |
Barry Wardell | 24f4a2a | 2006-10-26 13:38:09 +0000 | [diff] [blame] | 121 | #define LP_QUIT BUTTON_POWER |
Daniel Stenberg | 1e88be5 | 2006-08-03 20:17:25 +0000 | [diff] [blame] | 122 | #elif CONFIG_KEYPAD == IRIVER_H10_PAD |
| 123 | #define LP_QUIT BUTTON_POWER |
Jonathan Gordon | 56ddddc | 2007-10-23 15:40:51 +0000 | [diff] [blame] | 124 | #elif CONFIG_KEYPAD == MROBE500_PAD |
| 125 | #define LP_QUIT BUTTON_POWER |
Robert Kukla | d6c8b57 | 2008-03-01 22:55:09 +0000 | [diff] [blame] | 126 | #elif CONFIG_KEYPAD == MROBE100_PAD |
| 127 | #define LP_QUIT BUTTON_POWER |
Will Robertson | 8215b34 | 2008-02-17 12:23:02 +0000 | [diff] [blame] | 128 | #elif CONFIG_KEYPAD == GIGABEAT_S_PAD |
| 129 | #define LP_QUIT BUTTON_BACK |
Jens Arnold | 29361ab | 2008-03-22 10:24:28 +0000 | [diff] [blame] | 130 | #elif CONFIG_KEYPAD == IAUDIO_M3_PAD |
| 131 | #define LP_QUIT BUTTON_RC_REC |
Rob Purchase | 554d7ed | 2008-03-22 22:03:34 +0000 | [diff] [blame] | 132 | #elif CONFIG_KEYPAD == COWOND2_PAD |
| 133 | #define LP_QUIT BUTTON_POWER |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 134 | #else |
| 135 | #define LP_QUIT BUTTON_OFF |
| 136 | #endif |
| 137 | |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 138 | /* data files */ |
Peter D'Hoye | 9674316 | 2007-08-08 23:32:35 +0000 | [diff] [blame] | 139 | #define DICT_INDEX ROCKBOX_DIR "/rocks/apps/dict.index" |
| 140 | #define DICT_DESC ROCKBOX_DIR "/rocks/apps/dict.desc" |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 141 | |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 142 | /* the main plugin function */ |
Steve Bavin | 6526577 | 2008-05-13 09:57:56 +0000 | [diff] [blame] | 143 | enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter) |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 144 | { |
| 145 | char searchword[WORDLEN]; /* word to search for */ |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 146 | char *description; /* pointer to description buffer */ |
| 147 | char *output; /* pointer to output buffer */ |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 148 | 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 Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 155 | (void)parameter; |
| 156 | rb = api; |
| 157 | |
| 158 | /* get screen info */ |
| 159 | init_screen(); |
| 160 | |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 161 | /* 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 Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 180 | /* "clear" input buffer */ |
| 181 | searchword[0] = '\0'; |
| 182 | |
| 183 | rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */ |
| 184 | |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 185 | fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */ |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 186 | if (fIndex < 0) |
| 187 | { |
| 188 | DEBUGF("Err: Failed to open index file.\n"); |
Jens Arnold | 4d6374c | 2007-03-16 21:56:08 +0000 | [diff] [blame] | 189 | rb->splash(HZ*2, "Failed to open index."); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 190 | return PLUGIN_ERROR; |
| 191 | } |
| 192 | |
| 193 | filesize = rb->filesize(fIndex); /* get filesize */ |
| 194 | |
| 195 | DEBUGF("Filesize: %d bytes = %d words \n", filesize, |
Jens Arnold | bd5c0ad | 2007-03-17 10:50:58 +0000 | [diff] [blame] | 196 | (filesize / (int)sizeof(struct stWord))); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 197 | |
| 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 Arnold | 4d6374c | 2007-03-16 21:56:08 +0000 | [diff] [blame] | 229 | rb->splash(HZ*2, "Not found."); |
Tomas Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 230 | rb->close(fIndex); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 231 | return PLUGIN_OK; |
| 232 | } |
| 233 | |
Jens Arnold | f68362a | 2007-03-17 09:54:28 +0000 | [diff] [blame] | 234 | DEBUGF("Found %s at offset %ld\n", word.word, reverse(word.offset)); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 235 | |
| 236 | /* now open the description file */ |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 237 | fData = rb->open(DICT_DESC, O_RDONLY); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 238 | if (fData < 0) |
| 239 | { |
| 240 | DEBUGF("Err: Failed to open description file.\n"); |
Jens Arnold | 4d6374c | 2007-03-16 21:56:08 +0000 | [diff] [blame] | 241 | rb->splash(HZ*2, "Failed to open descriptions."); |
Tomas Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 242 | rb->close(fIndex); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 243 | return PLUGIN_ERROR; |
| 244 | } |
| 245 | |
| 246 | /* seek to the right offset */ |
Tomas Salfischberger | b3c417b | 2005-06-05 14:21:51 +0000 | [diff] [blame] | 247 | rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 248 | |
| 249 | /* Read in the description */ |
Tomas Salfischberger | 84364bc | 2005-05-02 23:09:21 +0000 | [diff] [blame] | 250 | rb->read_line(fData, description, display_columns * display_lines); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 251 | |
| 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 Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 277 | output[display_columns] = '\0'; |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 278 | |
Tomas Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 279 | /* typecast to kill a warning... */ |
| 280 | if((int)rb->strlen(ptr) < display_columns) |
| 281 | { |
| 282 | rb->lcd_puts(0, lines, output); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 283 | lines++; |
Tomas Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 284 | break; |
| 285 | } |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 286 | |
| 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 Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 301 | /* put the line on screen */ |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 302 | 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 Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 318 | rb->lcd_update(); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 319 | |
| 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 Salfischberger | 23028f5 | 2005-05-02 16:06:05 +0000 | [diff] [blame] | 328 | rb->close(fData); |
Tomas Salfischberger | a810a67 | 2005-05-02 15:03:46 +0000 | [diff] [blame] | 329 | return PLUGIN_OK; |
| 330 | } |