From a810a67db7c923b01c4135761ef21ab866db256d Mon Sep 17 00:00:00 2001 From: Tomas Salfischberger Date: Mon, 2 May 2005 15:03:46 +0000 Subject: Dictionary plugin, first version... please bugtest. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6394 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/SOURCES | 1 + apps/plugins/dict.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 246 insertions(+) create mode 100644 apps/plugins/dict.c (limited to 'apps') diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index 8c5525a657..76be771fb3 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES @@ -15,6 +15,7 @@ sort.c stopwatch.c vbrfix.c viewer.c +dict.c #ifdef HAVE_LCD_BITMAP /* Recorder/Ondio models only */ bounce.c diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c new file mode 100644 index 0000000000..efaeab2ed3 --- /dev/null +++ b/apps/plugins/dict.c @@ -0,0 +1,245 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2005 Tomas Salfischberger + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#include "plugin.h" + +/* as in hello world :) */ +static struct plugin_api* rb; +/* screen info */ +static int display_columns, display_lines; + +/* Some lenghts */ +#define WORDLEN 32 /* has to be the same in rdf2binary.c */ +#define DESCLEN 2048 + +/* The word struct :) */ +struct stWord +{ + char word[WORDLEN]; + long offset; +}; + +/* A funtion to get width and height etc (from viewer.c) */ +void init_screen(void) +{ +#ifdef HAVE_LCD_BITMAP + int w,h; + + rb->lcd_getstringsize("o", &w, &h); + display_lines = LCD_HEIGHT / h; + display_columns = LCD_WIDTH / w; +#else + + display_lines = 2; + display_columns = 11; +#endif +} + +/* for endian problems */ +#ifdef LITTLE_ENDIAN +#define readlong(x) x +#else +long readlong(void* value) +{ + unsigned char* bytes = (unsigned char*) value; + return (long)bytes[0] | ((long)bytes[1] << 8) | + ((long)bytes[2] << 16) | ((long)bytes[3] << 24); +} +#endif + +/* Button definitions */ +#if CONFIG_KEYPAD == PLAYER_PAD +#define LP_QUIT BUTTON_STOP +#else +#define LP_QUIT BUTTON_OFF +#endif + +/* the main plugin function */ +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) +{ + char searchword[WORDLEN]; /* word to search for */ + char description[DESCLEN]; /* description buffer */ + char output[DESCLEN]; /* output buffer */ + char *ptr, *space; + struct stWord word; /* the struct to read into */ + int fIndex, fData; /* files */ + int filesize, high, low, probe; + int lines, len, outputted, next; + + /* plugin stuff */ + TEST_PLUGIN_API(api); + (void)parameter; + rb = api; + + /* get screen info */ + init_screen(); + + /* "clear" input buffer */ + searchword[0] = '\0'; + + rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */ + + fIndex = rb->open("/.rockbox/dict.index", O_RDONLY); /* index file */ + if (fIndex < 0) + { + DEBUGF("Err: Failed to open index file.\n"); + rb->splash(HZ*2, true, "Failed to open index."); + return PLUGIN_ERROR; + } + + filesize = rb->filesize(fIndex); /* get filesize */ + + DEBUGF("Filesize: %d bytes = %d words \n", filesize, + (filesize / sizeof(struct stWord))); + + /* for the searching algorithm */ + high = filesize / sizeof( struct stWord ); + low = -1; + + while (high - low > 1) + { + probe = (high + low) / 2; + + /* Jump to word pointed by probe, and read it. */ + rb->lseek(fIndex, sizeof(struct stWord) * probe, SEEK_SET); + rb->read(fIndex, &word, sizeof(struct stWord)); + + /* jump according to the found word. */ + if (rb->strcasecmp(searchword, word.word) < 0) + { + high = probe; + } + else + { + low = probe; + } + } + + /* read in the word */ + rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET); + rb->read(fIndex, &word, sizeof(struct stWord)); + + /* Check if we found something */ + if (low == -1 || rb->strcasecmp(searchword, word.word) != 0) + { + DEBUGF("Not found.\n"); + rb->splash(HZ*2, true, "Not found."); + rb->close(fIndex); + return PLUGIN_OK; + } + + DEBUGF("Found %s at offset %d\n", word.word, readlong(&word.offset)); + + /* now open the description file */ + fData = rb->open("/.rockbox/dict.desc", O_RDONLY); + if (fData < 0) + { + DEBUGF("Err: Failed to open description file.\n"); + rb->splash(HZ*2, true, "Failed to open descriptions."); + rb->close(fIndex); + return PLUGIN_ERROR; + } + + /* seek to the right offset */ + rb->lseek(fData, readlong(&word.offset), SEEK_SET); + + /* Read in the description */ + rb->read_line(fData, description, DESCLEN); + + /* And print it to debug. */ + DEBUGF("Description: %s\n", description); + + /* get pointer to first char */ + ptr = description; + + lines = 0; + outputted = 0; + len = rb->strlen(description); + + /* clear screen */ + rb->lcd_clear_display(); + + /* for large screens display the searched word. */ + if(display_lines > 4) + { + rb->lcd_puts(0, lines, searchword); + lines++; + } + + /* TODO: Scroll, or just stop when there are to much lines. */ + while (1) + { + /* copy one lcd line */ + rb->strncpy(output, ptr, display_columns); + output[display_columns] = '\0'; + + /* unsigned to kill a warning... */ + if((int)rb->strlen(ptr) < display_columns) { + rb->lcd_puts(0, lines, output); + lines++; + break; + } + + + /* get the last spacechar */ + space = rb->strrchr(output, ' '); + + if (space != NULL) + { + *space = '\0'; + next = (space - (char*)output) + 1; + } + else + { + next = display_columns; + } + + /* put the line on screen */ + rb->lcd_puts(0, lines, output); + + /* get output count */ + outputted += rb->strlen(output); + + if (outputted < len) + { + /* set pointer to the next part */ + ptr += next; + lines++; + } + else + { + break; + } + } + +#ifdef HAVE_LCD_BITMAP + rb->lcd_update(); +#endif + + /* wait for keypress */ + while(rb->button_get(true) != LP_QUIT) + { + /* do nothing */ + /* maybe define some keys for navigation here someday. */ + } + + rb->close(fIndex); + rb->close(fData); + return PLUGIN_OK; +} -- cgit v1.2.3