summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorTomas Salfischberger <tomas@rockbox.org>2005-05-02 15:03:46 +0000
committerTomas Salfischberger <tomas@rockbox.org>2005-05-02 15:03:46 +0000
commita810a67db7c923b01c4135761ef21ab866db256d (patch)
tree73ee3f328458d5067901be3674f970535d12d515 /apps
parent1ba26b8a60a5e557fe796dab6af28a482d6fbc0d (diff)
Dictionary plugin, first version... please bugtest.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6394 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r--apps/plugins/SOURCES1
-rw-r--r--apps/plugins/dict.c245
2 files changed, 246 insertions, 0 deletions
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;
+}