summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/dict.c212
-rw-r--r--apps/plugins/lib/SOURCES1
-rw-r--r--apps/plugins/lib/simple_viewer.c260
-rw-r--r--apps/plugins/lib/simple_viewer.h28
4 files changed, 307 insertions, 194 deletions
diff --git a/apps/plugins/dict.c b/apps/plugins/dict.c
index 8c26292..13fe8e3 100644
--- a/apps/plugins/dict.c
+++ b/apps/plugins/dict.c
@@ -20,11 +20,11 @@
****************************************************************************/
#include "plugin.h"
+#include "lib/simple_viewer.h"
PLUGIN_HEADER
-/* screen info */
-static int display_columns, display_lines;
+#define MIN_DESC_BUF_SIZE 0x400 /* arbitrary minimum size for description */
/* Some lenghts */
#define WORDLEN 32 /* has to be the same in rdf2binary.c */
@@ -44,50 +44,6 @@ struct stWord
long offset;
} STRUCT_PACKED;
-/* 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
-}
-
-/* global vars for pl_malloc() */
-void *bufptr;
-size_t bufleft;
-
-/* simple function to "allocate" memory in pluginbuffer. */
-void *pl_malloc(size_t size)
-{
- void *ptr;
- ptr = bufptr;
-
- if (bufleft < size)
- {
- return NULL;
- }
- else
- {
- bufptr += size;
- bufleft -= size;
- return ptr;
- }
-}
-
-/* init function for pl_malloc() */
-void pl_malloc_init(void)
-{
- bufptr = rb->plugin_get_buffer(&bufleft);
-}
-
/* for endian problems */
#ifdef ROCKBOX_BIG_ENDIAN
#define reverse(x) x
@@ -102,59 +58,6 @@ long reverse (long N) {
}
#endif
-/* Button definitions */
-#if CONFIG_KEYPAD == PLAYER_PAD
-#define LP_QUIT BUTTON_STOP
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
- (CONFIG_KEYPAD == IPOD_3G_PAD) || \
- (CONFIG_KEYPAD == IPOD_1G2G_PAD)
-#define LP_QUIT BUTTON_MENU
-#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
-#define LP_QUIT BUTTON_PLAY
-#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == GIGABEAT_PAD
-#define LP_QUIT BUTTON_POWER
-#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
- (CONFIG_KEYPAD == SANSA_C200_PAD) || \
- (CONFIG_KEYPAD == SANSA_CLIP_PAD) || \
- (CONFIG_KEYPAD == SANSA_M200_PAD)
-#define LP_QUIT BUTTON_POWER
-#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
-#define LP_QUIT (BUTTON_HOME|BUTTON_REPEAT)
-#elif CONFIG_KEYPAD == IRIVER_H10_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == MROBE500_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == MROBE100_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
-#define LP_QUIT BUTTON_BACK
-#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
-#define LP_QUIT BUTTON_RC_REC
-#elif CONFIG_KEYPAD == COWON_D2_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == IAUDIO67_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
-#define LP_QUIT BUTTON_BACK
-#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == ONDAVX747_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == ONDAVX777_PAD
-#define LP_QUIT BUTTON_POWER
-#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD
-#define LP_QUIT BUTTON_LEFT
-#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
-#define LP_QUIT BUTTON_CANCEL
-#elif CONFIG_KEYPAD == MPIO_HD200_PAD
-#define LP_QUIT (BUTTON_REC|BUTTON_PLAY)
-#else
-#define LP_QUIT BUTTON_OFF
-#endif
/* data files */
#define DICT_INDEX PLUGIN_APPS_DIR "/dict.index"
@@ -165,42 +68,32 @@ enum plugin_status plugin_start(const void* parameter)
{
char searchword[WORDLEN]; /* word to search for */
char *description; /* pointer to description buffer */
- char *output; /* pointer to 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;
+ char *buffer;
+ size_t buffer_size;
/* plugin stuff */
(void)parameter;
- /* get screen info */
- init_screen();
-
- /* get pl_malloc() buffer ready. */
- pl_malloc_init();
-
- /* init description buffer (size is because we don't have scrolling)*/
- description = (char *)pl_malloc(display_columns * display_lines);
- if (description == NULL)
+ /* allocate buffer. */
+ buffer = rb->plugin_get_buffer(&buffer_size);
+ if (buffer == NULL || buffer_size < MIN_DESC_BUF_SIZE)
{
- DEBUGF("Err: failed to allocate description buffer.");
+ DEBUGF("Err: Failed to allocate buffer.\n");
+ rb->splash(HZ*2, "Failed to allocate buffer.");
return PLUGIN_ERROR;
}
- /* init output buffer */
- output = (char *)pl_malloc(display_columns);
- if (output == NULL)
- {
- DEBUGF("Err: failed to allocate output buffer.");
- return PLUGIN_ERROR;
- }
+ description = buffer;
/* "clear" input buffer */
searchword[0] = '\0';
- rb->kbd_input(searchword, sizeof(searchword)); /* get the word to search */
+ /* get the word to search */
+ if (rb->kbd_input(searchword, sizeof(searchword)) < 0)
+ return PLUGIN_OK; /* input cancelled */
fIndex = rb->open(DICT_INDEX, O_RDONLY); /* index file */
if (fIndex < 0)
@@ -241,13 +134,13 @@ enum plugin_status plugin_start(const void* parameter)
/* read in the word */
rb->lseek(fIndex, sizeof(struct stWord) * low, SEEK_SET);
rb->read(fIndex, &word, sizeof(struct stWord));
+ rb->close(fIndex);
/* Check if we found something */
if (low == -1 || rb->strcasecmp(searchword, word.word) != 0)
{
DEBUGF("Not found.\n");
rb->splash(HZ*2, "Not found.");
- rb->close(fIndex);
return PLUGIN_OK;
}
@@ -259,7 +152,6 @@ enum plugin_status plugin_start(const void* parameter)
{
DEBUGF("Err: Failed to open description file.\n");
rb->splash(HZ*2, "Failed to open descriptions.");
- rb->close(fIndex);
return PLUGIN_ERROR;
}
@@ -267,83 +159,15 @@ enum plugin_status plugin_start(const void* parameter)
rb->lseek(fData, (off_t)reverse(word.offset), SEEK_SET);
/* Read in the description */
- rb->read_line(fData, description, display_columns * display_lines);
+ rb->read_line(fData, description, buffer_size);
/* 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->strlcpy(output, ptr, display_columns + 1);
-
- /* typecast 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;
- }
- }
- rb->lcd_update();
+ rb->close(fData);
- /* wait for keypress */
- while(rb->button_get(true) != LP_QUIT)
- {
- /* do nothing */
- /* maybe define some keys for navigation here someday. */
- }
+ /* display description. */
+ view_text(searchword, description);
- rb->close(fIndex);
- rb->close(fData);
return PLUGIN_OK;
}
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index 8c160e1..5ed163f 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -9,6 +9,7 @@ fixedpoint.c
playback_control.c
rgb_hsv.c
buflib.c
+simple_viewer.c
display_text.c
strncpy.c
diff --git a/apps/plugins/lib/simple_viewer.c b/apps/plugins/lib/simple_viewer.c
new file mode 100644
index 0000000..c83f005
--- /dev/null
+++ b/apps/plugins/lib/simple_viewer.c
@@ -0,0 +1,260 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2010 Teruaki Kawashima
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "config.h"
+#include "plugin.h"
+#include "pluginlib_actions.h"
+#include "simple_viewer.h"
+#include <ctype.h>
+
+struct view_info {
+#ifdef HAVE_LCD_BITMAP
+ struct font* pf;
+#endif
+ const char *title;
+ const char *text; /* displayed text */
+ int display_lines; /* number of lines can be displayed */
+ int line_count; /* number of lines */
+ int line; /* current fisrt line */
+ int start; /* possition of first line in text */
+};
+
+static const char* get_next_line(const char *text, struct view_info *info)
+{
+ (void) info;
+ const char *ptr = text;
+ const char *space = NULL;
+ int total, n, w;
+ total = 0;
+ while(*ptr)
+ {
+#ifdef HAVE_LCD_CHARCELLS
+ n = rb->utf8seek(ptr, 1);
+ w = 1;
+#else
+ unsigned short ch;
+ n = ((long)rb->utf8decode(ptr, &ch) - (long)ptr);
+ w = rb->font_get_width(info->pf, ch);
+#endif
+ if (isspace(*ptr))
+ space = ptr+n;
+ if (*ptr == '\n')
+ {
+ ptr += n;
+ break;
+ }
+ if (total + w > LCD_WIDTH)
+ break;
+ ptr += n;
+ total += w;
+ }
+ return *ptr && space? space: ptr;
+}
+
+static void calc_line_count(struct view_info *info)
+{
+ const char *ptr = info->text;
+ int i = 0;
+
+ while (*ptr)
+ {
+ ptr = get_next_line(ptr, info);
+ i++;
+ }
+ info->line_count = i;
+}
+
+static void calc_first_line(struct view_info *info, int line)
+{
+ const char *ptr = info->text;
+ int i = 0;
+
+ if (line > info->line_count - info->display_lines)
+ line = info->line_count - info->display_lines;
+ if (line < 0)
+ line = 0;
+
+ DEBUGF("%d -> %d\n", info->line, line);
+ if (info->line <= line)
+ {
+ ptr += info->start;
+ i = info->line;
+ }
+ while (*ptr && i < line)
+ {
+ ptr = get_next_line(ptr, info);
+ i++;
+ }
+ info->start = ptr - info->text;
+ info->line = i;
+ DEBUGF("%d: %d\n", info->line, info->start);
+}
+
+static int init_view(struct view_info *info,
+ const char *title, const char *text)
+{
+#ifdef HAVE_LCD_BITMAP
+ info->pf = rb->font_get(FONT_UI);
+ info->display_lines = LCD_HEIGHT / info->pf->height;
+#else
+
+ info->display_lines = LCD_HEIGHT;
+#endif
+
+ info->title = title;
+ info->text = text;
+ info->line_count = 0;
+ info->line = 0;
+ info->start = 0;
+
+ /* no title for small screens. */
+ if (info->display_lines < 4)
+ {
+ info->title = NULL;
+ }
+ else
+ {
+ info->display_lines--;
+ }
+
+ calc_line_count(info);
+ return 0;
+}
+
+static void draw_text(struct view_info *info)
+{
+#ifdef HAVE_LCD_BITMAP
+#define OUTPUT_SIZE LCD_WIDTH+1
+#else
+#define OUTPUT_SIZE LCD_WIDTH*3+1
+#endif
+ static char output[OUTPUT_SIZE];
+ const char *text, *ptr;
+ int i, max_show, lines = 0;
+
+ /* clear screen */
+ rb->lcd_clear_display();
+
+ /* display title. */
+ if(info->title)
+ {
+ rb->lcd_puts(0, lines, info->title);
+ lines++;
+ }
+
+ max_show = MIN(info->line_count - info->line, info->display_lines);
+ DEBUGF("draw_text: %d-%d/%d\n",
+ info->line, info->line + max_show, info->line_count);
+ text = info->text + info->start;
+
+ for (i = 0; i < max_show; i++, lines++)
+ {
+ ptr = get_next_line(text, info);
+ DEBUGF("%d>%d-%d, ", i, text-info->text, ptr-text);
+ rb->strlcpy(output, text, ptr-text+1);
+ rb->lcd_puts(0, lines, output);
+ text = ptr;
+ }
+ DEBUGF("\n");
+
+ rb->lcd_update();
+}
+
+static void scroll_up(struct view_info *info)
+{
+ if (info->line <= 0)
+ return;
+ calc_first_line(info, info->line-1);
+ draw_text(info);
+ return;
+}
+
+static void scroll_down(struct view_info *info)
+{
+ if (info->line + info->display_lines >= info->line_count)
+ return;
+
+ calc_first_line(info, info->line+1);
+ draw_text(info);
+}
+
+static void scroll_to_top(struct view_info *info)
+{
+ if (info->line <= 0)
+ return;
+
+ calc_first_line(info, 0);
+ draw_text(info);
+}
+
+static void scroll_to_bottom(struct view_info *info)
+{
+ if (info->line + info->display_lines >= info->line_count)
+ return;
+
+ calc_first_line(info, info->line_count - info->display_lines);
+ draw_text(info);
+}
+
+int view_text(const char *title, const char *text)
+{
+ struct view_info info;
+ const struct button_mapping *view_contexts[] = {
+ pla_main_ctx,
+ };
+ int button;
+
+ init_view(&info, title, text);
+ draw_text(&info);
+
+ /* wait for keypress */
+ while(1)
+ {
+ button = pluginlib_getaction(TIMEOUT_BLOCK, view_contexts,
+ ARRAYLEN(view_contexts));
+ switch (button)
+ {
+ case PLA_UP:
+ case PLA_UP_REPEAT:
+ scroll_up(&info);
+ break;
+ case PLA_DOWN:
+ case PLA_DOWN_REPEAT:
+ scroll_down(&info);
+ break;
+ case PLA_LEFT_REPEAT:
+ scroll_to_top(&info);
+ break;
+ case PLA_RIGHT_REPEAT:
+ scroll_to_bottom(&info);
+ break;
+ case PLA_EXIT:
+ case PLA_CANCEL:
+ return PLUGIN_OK;
+ default:
+ if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
+ return PLUGIN_USB_CONNECTED;
+ break;
+ }
+ }
+
+ return PLUGIN_OK;
+}
diff --git a/apps/plugins/lib/simple_viewer.h b/apps/plugins/lib/simple_viewer.h
new file mode 100644
index 0000000..ff3ef23
--- /dev/null
+++ b/apps/plugins/lib/simple_viewer.h
@@ -0,0 +1,28 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id$
+*
+* Copyright (C) 2010 Teruaki Kawashima
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#ifndef __PLUGINLIB_VIEWER_H__
+#define __PLUGINLIB_VIEWER_H__
+
+#include "plugin.h"
+int view_text(const char *title, const char *text);
+
+#endif /* __PLUGINLIB_VIEWER_H__ */