blob: 7005745e01c172807c4d3ea48b29dfec44abaf08 [file] [log] [blame]
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001/***************************************************************************
2 *
3 * __________ __ ___.
4 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
5 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
6 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
7 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
8 * \/ \/ \/ \/ \/
Daniel Stenberg773e7a72002-09-30 19:05:03 +00009 *
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000010 *
11 * Copyright (C) 2002 Gilles Roux, 2003 Garrett Derner
Daniel Stenberg773e7a72002-09-30 19:05:03 +000012 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000013 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
Daniel Stenberg773e7a72002-09-30 19:05:03 +000017 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
Björn Stenbergba371fb2003-06-29 16:33:04 +000022#include "plugin.h"
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000023#include <ctype.h>
Hristo Kovacheve16339e2006-04-04 12:04:15 +000024#include "playback_control.h"
Jonathan Gordon77a458a2007-05-08 11:55:43 +000025#include "oldmenuapi.h"
Robert Hakfe18ca52003-07-24 12:22:10 +000026
Jens Arnolda36b1d42006-01-15 18:20:18 +000027PLUGIN_HEADER
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000028
Daniel Stenbergc9ee0522007-08-21 21:15:32 +000029#define SETTINGS_FILE VIEWERS_DIR "/viewer.dat" /* binary file, so dont use .cfg */
30#define BOOKMARKS_FILE VIEWERS_DIR "/viewer_bookmarks.dat"
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +000031
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000032#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
33#define MAX_COLUMNS 64 /* Max displayable string len (over-estimate) */
34#define MAX_WIDTH 910 /* Max line length in WIDE mode */
35#define READ_PREV_ZONE 910 /* Arbitrary number less than SMALL_BLOCK_SIZE */
36#define SMALL_BLOCK_SIZE 0x1000 /* 4k: Smallest file chunk we will read */
37#define LARGE_BLOCK_SIZE 0x2000 /* 8k: Preferable size of file chunk to read */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000038#define TOP_SECTOR buffer
39#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE)
40#define BOTTOM_SECTOR (buffer + 2*(SMALL_BLOCK_SIZE))
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +000041#define SCROLLBAR_WIDTH 6
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000042
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +000043#define MAX_BOOKMARKED_FILES ((buffer_size/(signed)sizeof(struct bookmarked_file_info))-1)
Jonathan Gordonc4c05832006-09-17 10:32:49 +000044
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000045/* Out-Of-Bounds test for any pointer to data in the buffer */
46#define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end)
47
48/* Does the buffer contain the beginning of the file? */
49#define BUFFER_BOF() (file_pos==0)
50
51/* Does the buffer contain the end of the file? */
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +000052#define BUFFER_EOF() (file_size-file_pos <= buffer_size)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000053
54/* Formula for the endpoint address outside of buffer data */
55#define BUFFER_END() \
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +000056 ((BUFFER_EOF()) ? (file_size-file_pos+buffer) : (buffer+buffer_size))
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000057
58/* Is the entire file being shown in one screen? */
59#define ONE_SCREEN_FITS_ALL() \
60 (next_screen_ptr==NULL && screen_top_ptr==buffer && BUFFER_BOF())
61
62/* Is a scrollbar called for on the current screen? */
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +000063#define NEED_SCROLLBAR() \
Zakk Roberts07fcf772006-05-01 05:45:18 +000064 ((!(ONE_SCREEN_FITS_ALL())) && (prefs.scrollbar_mode==SB_ON))
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +000065
Jens Arnoldcc8cff22004-10-16 00:07:43 +000066/* variable button definitions */
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +000067
68/* Recorder keys */
Jens Arnoldcc8cff22004-10-16 00:07:43 +000069#if CONFIG_KEYPAD == RECORDER_PAD
Zakk Roberts07fcf772006-05-01 05:45:18 +000070#define VIEWER_QUIT BUTTON_OFF
Jens Arnoldcc8cff22004-10-16 00:07:43 +000071#define VIEWER_PAGE_UP BUTTON_UP
72#define VIEWER_PAGE_DOWN BUTTON_DOWN
73#define VIEWER_SCREEN_LEFT BUTTON_LEFT
74#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Zakk Roberts07fcf772006-05-01 05:45:18 +000075#define VIEWER_MENU BUTTON_F1
76#define VIEWER_AUTOSCROLL BUTTON_PLAY
Jens Arnoldcc8cff22004-10-16 00:07:43 +000077#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
78#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
79#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
80#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
81
Dave Chapmand64e6262007-01-14 13:48:09 +000082#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
83#define VIEWER_QUIT BUTTON_OFF
84#define VIEWER_PAGE_UP BUTTON_UP
85#define VIEWER_PAGE_DOWN BUTTON_DOWN
86#define VIEWER_SCREEN_LEFT BUTTON_LEFT
87#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
88#define VIEWER_MENU BUTTON_F1
89#define VIEWER_AUTOSCROLL BUTTON_SELECT
90#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
91#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
92#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
93#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
94
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +000095/* Ondio keys */
Jens Arnoldcc8cff22004-10-16 00:07:43 +000096#elif CONFIG_KEYPAD == ONDIO_PAD
Jens Arnold2343a192006-05-03 23:16:53 +000097#define VIEWER_QUIT BUTTON_OFF
Jens Arnoldcc8cff22004-10-16 00:07:43 +000098#define VIEWER_PAGE_UP BUTTON_UP
99#define VIEWER_PAGE_DOWN BUTTON_DOWN
100#define VIEWER_SCREEN_LEFT BUTTON_LEFT
101#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Jens Arnold2343a192006-05-03 23:16:53 +0000102#define VIEWER_MENU (BUTTON_MENU|BUTTON_REPEAT)
103#define VIEWER_AUTOSCROLL_PRE BUTTON_MENU
104#define VIEWER_AUTOSCROLL (BUTTON_MENU|BUTTON_REL)
Jens Arnoldcc8cff22004-10-16 00:07:43 +0000105
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +0000106/* Player keys */
Jens Arnoldcc8cff22004-10-16 00:07:43 +0000107#elif CONFIG_KEYPAD == PLAYER_PAD
Zakk Roberts07fcf772006-05-01 05:45:18 +0000108#define VIEWER_QUIT BUTTON_STOP
Jens Arnoldcc8cff22004-10-16 00:07:43 +0000109#define VIEWER_PAGE_UP BUTTON_LEFT
110#define VIEWER_PAGE_DOWN BUTTON_RIGHT
Jens Arnold2343a192006-05-03 23:16:53 +0000111#define VIEWER_SCREEN_LEFT (BUTTON_ON|BUTTON_LEFT)
112#define VIEWER_SCREEN_RIGHT (BUTTON_ON|BUTTON_RIGHT)
Zakk Roberts07fcf772006-05-01 05:45:18 +0000113#define VIEWER_MENU BUTTON_MENU
Jens Arnold2343a192006-05-03 23:16:53 +0000114#define VIEWER_AUTOSCROLL BUTTON_PLAY
Jens Arnoldcc8cff22004-10-16 00:07:43 +0000115
Daniel Stenberg01377e22005-06-29 12:47:24 +0000116/* iRiver H1x0 && H3x0 keys */
117#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
118 (CONFIG_KEYPAD == IRIVER_H300_PAD)
Zakk Roberts07fcf772006-05-01 05:45:18 +0000119#define VIEWER_QUIT BUTTON_OFF
Daniel Stenberg6700ad82005-02-04 12:41:09 +0000120#define VIEWER_PAGE_UP BUTTON_UP
121#define VIEWER_PAGE_DOWN BUTTON_DOWN
122#define VIEWER_SCREEN_LEFT BUTTON_LEFT
123#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Zakk Roberts07fcf772006-05-01 05:45:18 +0000124#define VIEWER_MENU BUTTON_MODE
125#define VIEWER_AUTOSCROLL BUTTON_SELECT
Jens Arnolddbe19112005-02-12 02:02:20 +0000126#define VIEWER_LINE_UP (BUTTON_ON | BUTTON_UP)
127#define VIEWER_LINE_DOWN (BUTTON_ON | BUTTON_DOWN)
Jens Arnold2343a192006-05-03 23:16:53 +0000128#define VIEWER_COLUMN_LEFT (BUTTON_ON | BUTTON_LEFT)
129#define VIEWER_COLUMN_RIGHT (BUTTON_ON | BUTTON_RIGHT)
Daniel Stenberg6700ad82005-02-04 12:41:09 +0000130
Kevin Ferrare0e027bd2006-06-30 16:43:47 +0000131#define VIEWER_RC_QUIT BUTTON_RC_STOP
132
Jens Arnoldb7013222007-07-27 09:57:27 +0000133/* iPods */
Dave Chapmanfb4e3842006-02-24 20:54:09 +0000134#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
Jens Arnoldb7013222007-07-27 09:57:27 +0000135 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
136 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
Zakk Roberts07fcf772006-05-01 05:45:18 +0000137#define VIEWER_QUIT_PRE BUTTON_SELECT
138#define VIEWER_QUIT (BUTTON_SELECT | BUTTON_MENU)
Zakk Robertsde236792006-02-16 01:18:21 +0000139#define VIEWER_PAGE_UP BUTTON_SCROLL_BACK
140#define VIEWER_PAGE_DOWN BUTTON_SCROLL_FWD
Dave Chapman54d44c82005-12-14 01:31:37 +0000141#define VIEWER_SCREEN_LEFT BUTTON_LEFT
142#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Jens Arnold2343a192006-05-03 23:16:53 +0000143#define VIEWER_MENU BUTTON_MENU
144#define VIEWER_AUTOSCROLL BUTTON_PLAY
Dave Chapman54d44c82005-12-14 01:31:37 +0000145
Dave Chapmand83e9292006-01-12 00:35:50 +0000146/* iFP7xx keys */
147#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
Zakk Roberts07fcf772006-05-01 05:45:18 +0000148#define VIEWER_QUIT BUTTON_PLAY
Dave Chapmand83e9292006-01-12 00:35:50 +0000149#define VIEWER_PAGE_UP BUTTON_UP
150#define VIEWER_PAGE_DOWN BUTTON_DOWN
151#define VIEWER_SCREEN_LEFT BUTTON_LEFT
152#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Zakk Roberts07fcf772006-05-01 05:45:18 +0000153#define VIEWER_MENU BUTTON_MODE
154#define VIEWER_AUTOSCROLL BUTTON_SELECT
Dave Chapmand83e9292006-01-12 00:35:50 +0000155
Daniel Stenbergcedba882006-01-18 11:09:06 +0000156/* iAudio X5 keys */
Jens Arnold85a226d2007-03-16 23:02:39 +0000157#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
Zakk Roberts07fcf772006-05-01 05:45:18 +0000158#define VIEWER_QUIT BUTTON_POWER
Daniel Stenbergcedba882006-01-18 11:09:06 +0000159#define VIEWER_PAGE_UP BUTTON_UP
160#define VIEWER_PAGE_DOWN BUTTON_DOWN
161#define VIEWER_SCREEN_LEFT BUTTON_LEFT
162#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Zakk Roberts07fcf772006-05-01 05:45:18 +0000163#define VIEWER_MENU BUTTON_SELECT
164#define VIEWER_AUTOSCROLL BUTTON_PLAY
Daniel Stenbergcedba882006-01-18 11:09:06 +0000165
Zakk Roberts07fcf772006-05-01 05:45:18 +0000166/* GIGABEAT keys */
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +0000167#elif CONFIG_KEYPAD == GIGABEAT_PAD
Zakk Roberts07fcf772006-05-01 05:45:18 +0000168#define VIEWER_QUIT BUTTON_POWER
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +0000169#define VIEWER_PAGE_UP BUTTON_UP
170#define VIEWER_PAGE_DOWN BUTTON_DOWN
171#define VIEWER_SCREEN_LEFT BUTTON_LEFT
172#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
Zakk Roberts07fcf772006-05-01 05:45:18 +0000173#define VIEWER_MENU BUTTON_MENU
174#define VIEWER_AUTOSCROLL BUTTON_A
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +0000175
Barry Wardell24f4a2a2006-10-26 13:38:09 +0000176/* Sansa E200 keys */
177#elif CONFIG_KEYPAD == SANSA_E200_PAD
178#define VIEWER_QUIT BUTTON_POWER
179#define VIEWER_PAGE_UP BUTTON_UP
180#define VIEWER_PAGE_DOWN BUTTON_DOWN
181#define VIEWER_SCREEN_LEFT BUTTON_LEFT
182#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
183#define VIEWER_MENU BUTTON_SELECT
Jonathan Gordon0e8a9e42007-05-06 15:41:10 +0000184#define VIEWER_AUTOSCROLL BUTTON_REC
Dave Chapmand7d073a2008-01-17 11:29:14 +0000185#define VIEWER_LINE_UP BUTTON_SCROLL_BACK
186#define VIEWER_LINE_DOWN BUTTON_SCROLL_FWD
Barry Wardell24f4a2a2006-10-26 13:38:09 +0000187
Marianne Arnold12ddb8e2007-09-20 10:49:48 +0000188/* Sansa C200 keys */
189#elif CONFIG_KEYPAD == SANSA_C200_PAD
190#define VIEWER_QUIT BUTTON_POWER
191#define VIEWER_PAGE_UP BUTTON_VOL_UP
192#define VIEWER_PAGE_DOWN BUTTON_VOL_DOWN
193#define VIEWER_SCREEN_LEFT BUTTON_LEFT
194#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
195#define VIEWER_MENU BUTTON_SELECT
196#define VIEWER_AUTOSCROLL BUTTON_REC
197#define VIEWER_LINE_UP BUTTON_UP
198#define VIEWER_LINE_DOWN BUTTON_DOWN
199
Daniel Stenberg1e88be52006-08-03 20:17:25 +0000200/* iriver H10 keys */
201#elif CONFIG_KEYPAD == IRIVER_H10_PAD
202#define VIEWER_QUIT BUTTON_POWER
203#define VIEWER_PAGE_UP BUTTON_SCROLL_UP
204#define VIEWER_PAGE_DOWN BUTTON_SCROLL_DOWN
205#define VIEWER_SCREEN_LEFT BUTTON_LEFT
206#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
207#define VIEWER_MENU BUTTON_REW
208#define VIEWER_AUTOSCROLL BUTTON_PLAY
209
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000210/*M-Robe 500 keys */
Jonathan Gordon56ddddc2007-10-23 15:40:51 +0000211#elif CONFIG_KEYPAD == MROBE500_PAD
212#define VIEWER_QUIT BUTTON_POWER
213#define VIEWER_PAGE_UP BUTTON_RC_PLAY
214#define VIEWER_PAGE_DOWN BUTTON_RC_DOWN
215#define VIEWER_SCREEN_LEFT BUTTON_LEFT
216#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
217#define VIEWER_MENU BUTTON_RC_HEART
218#define VIEWER_AUTOSCROLL BUTTON_RC_MODE
219
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000220/*Gigabeat S keys */
Will Robertson8215b342008-02-17 12:23:02 +0000221#elif CONFIG_KEYPAD == GIGABEAT_S_PAD
222#define VIEWER_QUIT BUTTON_BACK
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000223#define VIEWER_PAGE_UP BUTTON_PREV
224#define VIEWER_PAGE_DOWN BUTTON_NEXT
225#define VIEWER_SCREEN_LEFT (BUTTON_PLAY | BUTTON_LEFT)
226#define VIEWER_SCREEN_RIGHT (BUTTON_PLAY | BUTTON_RIGHT)
Will Robertson8215b342008-02-17 12:23:02 +0000227#define VIEWER_MENU BUTTON_MENU
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000228#define VIEWER_AUTOSCROLL_PRE BUTTON_PLAY
229#define VIEWER_AUTOSCROLL (BUTTON_PLAY|BUTTON_REL)
230#define VIEWER_LINE_UP BUTTON_UP
231#define VIEWER_LINE_DOWN BUTTON_DOWN
232#define VIEWER_COLUMN_LEFT BUTTON_LEFT
233#define VIEWER_COLUMN_RIGHT BUTTON_RIGHT
Will Robertson8215b342008-02-17 12:23:02 +0000234
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000235/*M-Robe 100 keys */
Robert Kuklad6c8b572008-03-01 22:55:09 +0000236#elif CONFIG_KEYPAD == MROBE100_PAD
237#define VIEWER_QUIT BUTTON_POWER
238#define VIEWER_PAGE_UP BUTTON_UP
239#define VIEWER_PAGE_DOWN BUTTON_DOWN
240#define VIEWER_SCREEN_LEFT BUTTON_LEFT
241#define VIEWER_SCREEN_RIGHT BUTTON_RIGHT
242#define VIEWER_MENU BUTTON_MENU
243#define VIEWER_AUTOSCROLL BUTTON_DISPLAY
244
Jens Arnold29361ab2008-03-22 10:24:28 +0000245/* iAUdio M3 keys */
246#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
247#define VIEWER_QUIT BUTTON_RC_REC
248#define VIEWER_PAGE_UP BUTTON_RC_VOL_UP
249#define VIEWER_PAGE_DOWN BUTTON_RC_VOL_DOWN
250#define VIEWER_SCREEN_LEFT BUTTON_RC_REW
251#define VIEWER_SCREEN_RIGHT BUTTON_RC_FF
252#define VIEWER_MENU BUTTON_RC_MENU
253#define VIEWER_AUTOSCROLL BUTTON_RC_MODE
Jens Arnold29361ab2008-03-22 10:24:28 +0000254#define VIEWER_RC_QUIT BUTTON_REC
255
Mustapha Senhaji79ba6692008-05-18 14:09:33 +0000256/* Cowon D2 keys */
Rob Purchase554d7ed2008-03-22 22:03:34 +0000257#elif CONFIG_KEYPAD == COWOND2_PAD
258#define VIEWER_QUIT BUTTON_POWER
Rob Purchase554d7ed2008-03-22 22:03:34 +0000259#define VIEWER_MENU BUTTON_MENU
Rob Purchase554d7ed2008-03-22 22:03:34 +0000260
Robert Kuklad6c8b572008-03-01 22:55:09 +0000261#else
262#error No keymap defined!
Jens Arnoldcc8cff22004-10-16 00:07:43 +0000263#endif
264
Rob Purchase297e0502008-04-27 15:30:19 +0000265#ifdef HAVE_TOUCHPAD
266#ifndef VIEWER_QUIT
267#define VIEWER_QUIT BUTTON_TOPLEFT
268#endif
269#ifndef VIEWER_PAGE_UP
270#define VIEWER_PAGE_UP BUTTON_TOPMIDDLE
271#endif
272#ifndef VIEWER_PAGE_DOWN
273#define VIEWER_PAGE_DOWN BUTTON_BOTTOMMIDDLE
274#endif
275#ifndef VIEWER_SCREEN_LEFT
276#define VIEWER_SCREEN_LEFT BUTTON_MIDLEFT
277#endif
278#ifndef VIEWER_SCREEN_RIGHT
279#define VIEWER_SCREEN_RIGHT BUTTON_MIDRIGHT
280#endif
281#ifndef VIEWER_MENU
282#define VIEWER_MENU BUTTON_TOPRIGHT
283#endif
284#ifndef VIEWER_AUTOSCROLL
285#define VIEWER_AUTOSCROLL BUTTON_CENTER
286#endif
287#endif
288
Jonathan Gordon09a990c2006-09-18 15:31:51 +0000289/* stuff for the bookmarking */
Jonathan Gordonc4c05832006-09-17 10:32:49 +0000290struct bookmarked_file_info {
291 long file_position;
292 int top_ptr_pos;
293 char filename[MAX_PATH];
294};
Jonathan Gordon09a990c2006-09-18 15:31:51 +0000295
296struct bookmark_file_data {
297 signed int bookmarked_files_count;
298 struct bookmarked_file_info bookmarks[];
299};
300
Zakk Roberts07fcf772006-05-01 05:45:18 +0000301struct preferences {
302 enum {
303 WRAP=0,
304 CHOP,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000305 } word_mode;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000306
Zakk Roberts07fcf772006-05-01 05:45:18 +0000307 enum {
308 NORMAL=0,
309 JOIN,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000310 EXPAND,
Jens Arnold2343a192006-05-03 23:16:53 +0000311 REFLOW, /* won't be set on charcell LCD, must be last */
Zakk Roberts07fcf772006-05-01 05:45:18 +0000312 } line_mode;
Jens Arnold5bb70722005-05-14 16:46:31 +0000313
Zakk Roberts07fcf772006-05-01 05:45:18 +0000314 enum {
315 NARROW=0,
316 WIDE,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000317 } view_mode;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000318
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000319 enum {
320 ISO_8859_1=0,
321 ISO_8859_7,
322 ISO_8859_8,
323 CP1251,
324 ISO_8859_11,
325 ISO_8859_6,
326 ISO_8859_9,
327 ISO_8859_2,
Marcoen Hirschbergded94e62007-10-01 17:16:31 +0000328 CP1250,
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000329 SJIS,
330 GB2312,
331 KSX1001,
332 BIG5,
333 UTF8,
334 ENCODINGS
335 } encoding; /* FIXME: What should default encoding be? */
336
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000337#ifdef HAVE_LCD_BITMAP
Zakk Roberts07fcf772006-05-01 05:45:18 +0000338 enum {
339 SB_OFF=0,
340 SB_ON,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000341 } scrollbar_mode;
342 bool need_scrollbar;
Daniel Stenberg1ca465a2006-01-27 13:30:57 +0000343
Zakk Roberts07fcf772006-05-01 05:45:18 +0000344 enum {
345 NO_OVERLAP=0,
346 OVERLAP,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000347 } page_mode;
Zakk Roberts07fcf772006-05-01 05:45:18 +0000348#endif /* HAVE_LCD_BITMAP */
Daniel Stenberg1ca465a2006-01-27 13:30:57 +0000349
Zakk Roberts07fcf772006-05-01 05:45:18 +0000350 enum {
351 PAGE=0,
352 LINE,
Zakk Roberts07fcf772006-05-01 05:45:18 +0000353 } scroll_mode;
Daniel Stenberg1ca465a2006-01-27 13:30:57 +0000354
Zakk Roberts07fcf772006-05-01 05:45:18 +0000355 int autoscroll_speed;
Jonathan Gordon09a990c2006-09-18 15:31:51 +0000356
Marcoen Hirschberg2b30bf92007-11-19 20:51:42 +0000357};
358
359struct preferences prefs;
360struct preferences old_prefs;
Daniel Stenberg1ca465a2006-01-27 13:30:57 +0000361
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +0000362static unsigned char *buffer;
363static long buffer_size;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000364static unsigned char line_break[] = {0,0x20,9,0xB,0xC,'-'};
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000365static int display_columns; /* number of (pixel) columns on the display */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000366static int display_lines; /* number of lines on the display */
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000367static int draw_columns; /* number of (pixel) columns available for text */
368static int par_indent_spaces; /* number of spaces to indent first paragraph */
Daniel Stenberg773e7a72002-09-30 19:05:03 +0000369static int fd;
Steve Bavin65265772008-05-13 09:57:56 +0000370static const char *file_name;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000371static long file_size;
Marcoen Hirschberg4c62c002007-11-19 16:02:45 +0000372static long start_position; /* position in the file after the viewer is started */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000373static bool mac_text;
374static long file_pos; /* Position of the top of the buffer in the file */
375static unsigned char *buffer_end; /*Set to BUFFER_END() when file_pos changes*/
376static int max_line_len;
377static unsigned char *screen_top_ptr;
378static unsigned char *next_screen_ptr;
379static unsigned char *next_screen_to_draw_ptr;
380static unsigned char *next_line_ptr;
Steve Bavin65265772008-05-13 09:57:56 +0000381static const struct plugin_api* rb;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000382#ifdef HAVE_LCD_BITMAP
383static struct font *pf;
384#endif
Daniel Stenberg773e7a72002-09-30 19:05:03 +0000385
Jonathan Gordonc4c05832006-09-17 10:32:49 +0000386
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000387int glyph_width(int ch)
388{
389 if (ch == 0)
390 ch = ' ';
391
392#ifdef HAVE_LCD_BITMAP
393 return rb->font_get_width(pf, ch);
394#else
395 return 1;
396#endif
397}
398
399unsigned char* get_ucs(const unsigned char* str, unsigned short* ch)
400{
401 unsigned char utf8_tmp[6];
402 int count;
403
404 if (prefs.encoding == UTF8)
405 return (unsigned char*)rb->utf8decode(str, ch);
406
407 count = BUFFER_OOB(str+2)? 1:2;
408 rb->iso_decode(str, utf8_tmp, prefs.encoding, count);
409 rb->utf8decode(utf8_tmp, ch);
410
411 if ((prefs.encoding == SJIS && *str > 0xA0 && *str < 0xE0) || prefs.encoding < SJIS)
412 return (unsigned char*)str+1;
413 else
414 return (unsigned char*)str+2;
415}
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000416
Zakk Roberts07fcf772006-05-01 05:45:18 +0000417bool done = false;
418int col = 0;
419
Karl Kurbjunca8fa652006-06-03 07:04:02 +0000420#define ADVANCE_COUNTERS(c) { width += glyph_width(c); k++; }
Linus Nielsen Feltzing73c283e2006-08-01 17:48:38 +0000421#define LINE_IS_FULL ((k>=MAX_COLUMNS-1) ||( width >= draw_columns))
Karl Kurbjunca8fa652006-06-03 07:04:02 +0000422#define LINE_IS_NOT_FULL ((k<MAX_COLUMNS-1) &&( width < draw_columns))
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000423static unsigned char* crop_at_width(const unsigned char* p)
424{
425 int k,width;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000426 unsigned short ch;
427 const unsigned char *oldp = p;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000428
429 k=width=0;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000430
Karl Kurbjunca8fa652006-06-03 07:04:02 +0000431 while (LINE_IS_NOT_FULL) {
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000432 oldp = p;
433 p = get_ucs(p, &ch);
434 ADVANCE_COUNTERS(ch);
435 }
436
437 return (unsigned char*)oldp;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000438}
439
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000440static unsigned char* find_first_feed(const unsigned char* p, int size)
441{
442 int i;
Daniel Stenberg773e7a72002-09-30 19:05:03 +0000443
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000444 for (i=0; i < size; i++)
445 if (p[i] == 0)
446 return (unsigned char*) p+i;
447
448 return NULL;
449}
450
451static unsigned char* find_last_feed(const unsigned char* p, int size)
452{
453 int i;
454
455 for (i=size-1; i>=0; i--)
456 if (p[i] == 0)
457 return (unsigned char*) p+i;
458
459 return NULL;
460}
461
462static unsigned char* find_last_space(const unsigned char* p, int size)
463{
464 int i, j, k;
465
Zakk Roberts07fcf772006-05-01 05:45:18 +0000466 k = (prefs.line_mode==JOIN) || (prefs.line_mode==REFLOW) ? 0:1;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000467
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000468 if (!BUFFER_OOB(&p[size]))
469 for (j=k; j < ((int) sizeof(line_break)) - 1; j++)
470 if (p[size] == line_break[j])
471 return (unsigned char*) p+size;
472
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000473 for (i=size-1; i>=0; i--)
474 for (j=k; j < (int) sizeof(line_break); j++)
Jonathan Gordon739f0ec2007-08-05 04:16:21 +0000475 {
Robert Kukla2ae0d632007-08-13 13:53:33 +0000476 if (!((p[i] == '-') && (prefs.word_mode == WRAP)))
Jonathan Gordon739f0ec2007-08-05 04:16:21 +0000477 if (p[i] == line_break[j])
478 return (unsigned char*) p+i;
479 }
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000480
481 return NULL;
482}
483
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000484static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_short)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000485{
486 const unsigned char *next_line = NULL;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000487 int size, i, j, k, width, search_len, spaces, newlines;
488 bool first_chars;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000489 unsigned char c;
490
Zakk Robertsde236792006-02-16 01:18:21 +0000491 if (is_short != NULL)
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000492 *is_short = true;
Zakk Robertsde236792006-02-16 01:18:21 +0000493
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000494 if BUFFER_OOB(cur_line)
495 return NULL;
496
Zakk Roberts07fcf772006-05-01 05:45:18 +0000497 if (prefs.view_mode == WIDE) {
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000498 search_len = MAX_WIDTH;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000499 }
Zakk Roberts07fcf772006-05-01 05:45:18 +0000500 else { /* prefs.view_mode == NARROW */
Zakk Robertsde236792006-02-16 01:18:21 +0000501 search_len = crop_at_width(cur_line) - cur_line;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000502 }
503
504 size = BUFFER_OOB(cur_line+search_len) ? buffer_end-cur_line : search_len;
505
Zakk Roberts07fcf772006-05-01 05:45:18 +0000506 if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW)) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000507 /* Need to scan ahead and possibly increase search_len and size,
508 or possibly set next_line at second hard return in a row. */
509 next_line = NULL;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000510 first_chars=true;
511 for (j=k=width=spaces=newlines=0; ; j++) {
Jens Arnold5bb70722005-05-14 16:46:31 +0000512 if (BUFFER_OOB(cur_line+j))
513 return NULL;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000514 if (LINE_IS_FULL) {
515 size = search_len = j;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000516 break;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000517 }
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000518
519 c = cur_line[j];
520 switch (c) {
521 case ' ':
Zakk Roberts07fcf772006-05-01 05:45:18 +0000522 if (prefs.line_mode == REFLOW) {
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000523 if (newlines > 0) {
524 size = j;
525 next_line = cur_line + size;
526 return (unsigned char*) next_line;
527 }
528 if (j==0) /* i=1 is intentional */
529 for (i=0; i<par_indent_spaces; i++)
Zakk Robertsde236792006-02-16 01:18:21 +0000530 ADVANCE_COUNTERS(' ');
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000531 }
532 if (!first_chars) spaces++;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000533 break;
534
535 case 0:
536 if (newlines > 0) {
537 size = j;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000538 next_line = cur_line + size - spaces;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000539 if (next_line != cur_line)
540 return (unsigned char*) next_line;
541 break;
542 }
Zakk Robertsde236792006-02-16 01:18:21 +0000543
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000544 newlines++;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000545 size += spaces -1;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000546 if (BUFFER_OOB(cur_line+size) || size > 2*search_len)
547 return NULL;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000548 search_len = size;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000549 spaces = first_chars? 0:1;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000550 break;
551
552 default:
Zakk Roberts07fcf772006-05-01 05:45:18 +0000553 if (prefs.line_mode==JOIN || newlines>0) {
Jens Arnold5bb70722005-05-14 16:46:31 +0000554 while (spaces) {
555 spaces--;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000556 ADVANCE_COUNTERS(' ');
557 if (LINE_IS_FULL) {
558 size = search_len = j;
Jens Arnold5bb70722005-05-14 16:46:31 +0000559 break;
560 }
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000561 }
562 newlines=0;
Jens Arnold5bb70722005-05-14 16:46:31 +0000563 } else if (spaces) {
Zakk Robertsde236792006-02-16 01:18:21 +0000564 /* REFLOW, multiple spaces between words: count only
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000565 * one. If more are needed, they will be added
Zakk Robertsde236792006-02-16 01:18:21 +0000566 * while drawing. */
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000567 search_len = size;
568 spaces=0;
569 ADVANCE_COUNTERS(' ');
570 if (LINE_IS_FULL) {
571 size = search_len = j;
572 break;
573 }
Zakk Robertsde236792006-02-16 01:18:21 +0000574 }
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000575 first_chars = false;
576 ADVANCE_COUNTERS(c);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000577 break;
578 }
579 }
580 }
581 else {
582 /* find first hard return */
583 next_line = find_first_feed(cur_line, size);
584 }
585
586 if (next_line == NULL)
587 if (size == search_len) {
Zakk Roberts07fcf772006-05-01 05:45:18 +0000588 if (prefs.word_mode == WRAP) /* Find last space */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000589 next_line = find_last_space(cur_line, size);
590
591 if (next_line == NULL)
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000592 next_line = crop_at_width(cur_line);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000593 else
Zakk Roberts07fcf772006-05-01 05:45:18 +0000594 if (prefs.word_mode == WRAP)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000595 for (i=0;
596 i<WRAP_TRIM && isspace(next_line[0]) && !BUFFER_OOB(next_line);
597 i++)
598 next_line++;
599 }
600
Zakk Roberts07fcf772006-05-01 05:45:18 +0000601 if (prefs.line_mode == EXPAND)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000602 if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
603 if (next_line[0] == 0)
604 if (next_line != cur_line)
605 return (unsigned char*) next_line;
606
607 /* If next_line is pointing to a zero, increment it; i.e.,
608 leave the terminator at the end of cur_line. If pointing
609 to a hyphen, increment only if there is room to display
610 the hyphen on current line (won't apply in WIDE mode,
611 since it's guarenteed there won't be room). */
612 if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000613 if (next_line[0] == 0)/* ||
614 (next_line[0] == '-' && next_line-cur_line < draw_columns)) */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000615 next_line++;
616
617 if (BUFFER_OOB(next_line))
618 return NULL;
619
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000620 if (is_short)
621 *is_short = false;
Zakk Robertsde236792006-02-16 01:18:21 +0000622
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000623 return (unsigned char*) next_line;
624}
625
626static unsigned char* find_prev_line(const unsigned char* cur_line)
627{
628 const unsigned char *prev_line = NULL;
629 const unsigned char *p;
630
631 if BUFFER_OOB(cur_line)
632 return NULL;
633
634 /* To wrap consistently at the same places, we must
635 start with a known hard return, then work downwards.
636 We can either search backwards for a hard return,
637 or simply start wrapping downwards from top of buffer.
638 If current line is not near top of buffer, this is
639 a file with long lines (paragraphs). We would need to
640 read earlier sectors before we could decide how to
641 properly wrap the lines above the current line, but
642 it probably is not worth the disk access. Instead,
643 start with top of buffer and wrap down from there.
644 This may result in some lines wrapping at different
645 points from where they wrap when scrolling down.
646 If buffer is at top of file, start at top of buffer. */
647
Zakk Roberts07fcf772006-05-01 05:45:18 +0000648 if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW))
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000649 prev_line = p = NULL;
650 else
651 prev_line = p = find_last_feed(buffer, cur_line-buffer-1);
652 /* Null means no line feeds in buffer above current line. */
653
654 if (prev_line == NULL)
655 if (BUFFER_BOF() || cur_line - buffer > READ_PREV_ZONE)
656 prev_line = p = buffer;
657 /* (else return NULL and read previous block) */
658
659 /* Wrap downwards until too far, then use the one before. */
660 while (p < cur_line && p != NULL) {
661 prev_line = p;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000662 p = find_next_line(prev_line, NULL);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000663 }
664
665 if (BUFFER_OOB(prev_line))
666 return NULL;
667
668 return (unsigned char*) prev_line;
669}
670
671static void fill_buffer(long pos, unsigned char* buf, unsigned size)
672{
673 /* Read from file and preprocess the data */
674 /* To minimize disk access, always read on sector boundaries */
675 unsigned numread, i;
676 bool found_CR = false;
677
678 rb->lseek(fd, pos, SEEK_SET);
679 numread = rb->read(fd, buf, size);
Jens Arnold3c348df2005-01-26 22:48:25 +0000680 rb->button_clear_queue(); /* clear button queue */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000681
682 for(i = 0; i < numread; i++) {
683 switch(buf[i]) {
684 case '\r':
685 if (mac_text) {
686 buf[i] = 0;
687 }
688 else {
689 buf[i] = ' ';
690 found_CR = true;
691 }
692 break;
693
694 case '\n':
695 buf[i] = 0;
696 found_CR = false;
697 break;
698
699 case 0: /* No break between case 0 and default, intentionally */
700 buf[i] = ' ';
701 default:
702 if (found_CR) {
703 buf[i - 1] = 0;
704 found_CR = false;
705 mac_text = true;
706 }
707 break;
708 }
709 }
710}
711
712static int read_and_synch(int direction)
713{
714/* Read next (or prev) block, and reposition global pointers. */
715/* direction: 1 for down (i.e., further into file), -1 for up */
716 int move_size, move_vector, offset;
717 unsigned char *fill_buf;
Zakk Robertsde236792006-02-16 01:18:21 +0000718
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000719 if (direction == -1) /* up */ {
720 move_size = SMALL_BLOCK_SIZE;
721 offset = 0;
722 fill_buf = TOP_SECTOR;
723 rb->memcpy(BOTTOM_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
724 rb->memcpy(MID_SECTOR, TOP_SECTOR, SMALL_BLOCK_SIZE);
725 }
726 else /* down */ {
Zakk Roberts07fcf772006-05-01 05:45:18 +0000727 if (prefs.view_mode == WIDE) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000728 /* WIDE mode needs more buffer so we have to read smaller blocks */
729 move_size = SMALL_BLOCK_SIZE;
730 offset = LARGE_BLOCK_SIZE;
731 fill_buf = BOTTOM_SECTOR;
732 rb->memcpy(TOP_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
733 rb->memcpy(MID_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
734 }
735 else {
736 move_size = LARGE_BLOCK_SIZE;
737 offset = SMALL_BLOCK_SIZE;
738 fill_buf = MID_SECTOR;
739 rb->memcpy(TOP_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
740 }
741 }
742 move_vector = direction * move_size;
743 screen_top_ptr -= move_vector;
744 file_pos += move_vector;
745 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
746 fill_buffer(file_pos + offset, fill_buf, move_size);
747 return move_vector;
748}
749
750static void viewer_scroll_up(void)
751{
752 unsigned char *p;
753
754 p = find_prev_line(screen_top_ptr);
755 if (p == NULL && !BUFFER_BOF()) {
756 read_and_synch(-1);
757 p = find_prev_line(screen_top_ptr);
758 }
759 if (p != NULL)
760 screen_top_ptr = p;
761}
762
Zakk Roberts07fcf772006-05-01 05:45:18 +0000763static void viewer_scroll_down(void)
764{
765 if (next_screen_ptr != NULL)
766 screen_top_ptr = next_line_ptr;
767}
768
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000769#ifdef HAVE_LCD_BITMAP
770static void viewer_scrollbar(void) {
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000771 int items, min_shown, max_shown;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000772
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000773 items = (int) file_size; /* (SH1 int is same as long) */
774 min_shown = (int) file_pos + (screen_top_ptr - buffer);
775
776 if (next_screen_ptr == NULL)
777 max_shown = items;
778 else
779 max_shown = min_shown + (next_screen_ptr - screen_top_ptr);
780
Jonathan Gordon62885232006-11-19 14:11:42 +0000781 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, 0, SCROLLBAR_WIDTH-1,
782 LCD_HEIGHT, items, min_shown, max_shown, VERTICAL);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000783}
784#endif
785
786static void viewer_draw(int col)
787{
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000788 int i, j, k, line_len, line_width, resynch_move, spaces, left_col=0;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000789 int width, extra_spaces, indent_spaces, spaces_per_word;
790 bool multiple_spacing, line_is_short;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000791 unsigned short ch;
792 unsigned char *str, *oldstr;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000793 unsigned char *line_begin;
794 unsigned char *line_end;
795 unsigned char c;
796 unsigned char scratch_buffer[MAX_COLUMNS + 1];
Linus Nielsen Feltzingf954a532006-03-01 13:31:36 +0000797 unsigned char utf8_buffer[MAX_COLUMNS*4 + 1];
Linus Nielsen Feltzingf954a532006-03-01 13:31:36 +0000798 unsigned char *endptr;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000799
800 /* If col==-1 do all calculations but don't display */
801 if (col != -1) {
802#ifdef HAVE_LCD_BITMAP
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000803 left_col = prefs.need_scrollbar? SCROLLBAR_WIDTH:0;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000804#else
805 left_col = 0;
806#endif
807 rb->lcd_clear_display();
808 }
809 max_line_len = 0;
810 line_begin = line_end = screen_top_ptr;
811
812 for (i = 0; i < display_lines; i++) {
813 if (BUFFER_OOB(line_end))
814 break; /* Happens after display last line at BUFFER_EOF() */
815
816 line_begin = line_end;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000817 line_end = find_next_line(line_begin, &line_is_short);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000818
819 if (line_end == NULL) {
820 if (BUFFER_EOF()) {
821 if (i < display_lines - 1 && !BUFFER_BOF()) {
822 if (col != -1)
823 rb->lcd_clear_display();
824
825 for (; i < display_lines - 1; i++)
826 viewer_scroll_up();
827
828 line_begin = line_end = screen_top_ptr;
829 i = -1;
830 continue;
831 }
832 else {
833 line_end = buffer_end;
834 }
835 }
836 else {
837 resynch_move = read_and_synch(1); /* Read block & move ptrs */
838 line_begin -= resynch_move;
839 if (i > 0)
840 next_line_ptr -= resynch_move;
841
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000842 line_end = find_next_line(line_begin, NULL);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000843 if (line_end == NULL) /* Should not really happen */
844 break;
845 }
846 }
847 line_len = line_end - line_begin;
848
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000849 /* calculate line_len */
850 str = oldstr = line_begin;
851 j = -1;
852 while (str < line_end) {
853 oldstr = str;
854 str = crop_at_width(str);
855 j++;
856 }
857 line_width = j*draw_columns;
858 while (oldstr < line_end) {
859 oldstr = get_ucs(oldstr, &ch);
860 line_width += glyph_width(ch);
861 }
862
Zakk Roberts07fcf772006-05-01 05:45:18 +0000863 if (prefs.line_mode == JOIN) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000864 if (line_begin[0] == 0) {
865 line_begin++;
Zakk Roberts07fcf772006-05-01 05:45:18 +0000866 if (prefs.word_mode == CHOP)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000867 line_end++;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000868 else
869 line_len--;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000870 }
871 for (j=k=spaces=0; j < line_len; j++) {
872 if (k == MAX_COLUMNS)
873 break;
874
875 c = line_begin[j];
876 switch (c) {
877 case ' ':
878 spaces++;
879 break;
880 case 0:
881 spaces = 0;
882 scratch_buffer[k++] = ' ';
883 break;
884 default:
885 while (spaces) {
886 spaces--;
887 scratch_buffer[k++] = ' ';
888 if (k == MAX_COLUMNS - 1)
889 break;
890 }
891 scratch_buffer[k++] = c;
892 break;
893 }
894 }
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000895 if (col != -1) {
896 scratch_buffer[k] = 0;
897 endptr = rb->iso_decode(scratch_buffer + col, utf8_buffer,
Linus Nielsen Feltzing73c283e2006-08-01 17:48:38 +0000898 prefs.encoding, draw_columns/glyph_width('i'));
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000899 *endptr = 0;
900 }
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000901 }
Zakk Roberts07fcf772006-05-01 05:45:18 +0000902 else if (prefs.line_mode == REFLOW) {
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000903 if (line_begin[0] == 0) {
904 line_begin++;
Zakk Roberts07fcf772006-05-01 05:45:18 +0000905 if (prefs.word_mode == CHOP)
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000906 line_end++;
907 else
908 line_len--;
909 }
910
911 indent_spaces = 0;
912 if (!line_is_short) {
913 multiple_spacing = false;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000914 width=spaces=0;
915 for (str = line_begin; str < line_end; ) {
916 str = get_ucs(str, &ch);
917 switch (ch) {
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000918 case ' ':
919 case 0:
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000920 if ((str == line_begin) && (prefs.word_mode==WRAP))
Zakk Robertsde236792006-02-16 01:18:21 +0000921 /* special case: indent the paragraph,
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000922 * don't count spaces */
923 indent_spaces = par_indent_spaces;
Zakk Robertsde236792006-02-16 01:18:21 +0000924 else if (!multiple_spacing)
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000925 spaces++;
926 multiple_spacing = true;
927 break;
928 default:
929 multiple_spacing = false;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000930 width += glyph_width(ch);
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000931 break;
932 }
933 }
934 if (multiple_spacing) spaces--;
Zakk Robertsde236792006-02-16 01:18:21 +0000935
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000936 if (spaces) {
937 /* total number of spaces to insert between words */
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000938 extra_spaces = (draw_columns-width)/glyph_width(' ')
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000939 - indent_spaces;
940 /* number of spaces between each word*/
941 spaces_per_word = extra_spaces / spaces;
942 /* number of words with n+1 spaces (to fill up) */
943 extra_spaces = extra_spaces % spaces;
944 if (spaces_per_word > 2) { /* too much spacing is awful */
945 spaces_per_word = 3;
946 extra_spaces = 0;
Zakk Robertsde236792006-02-16 01:18:21 +0000947 }
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000948 } else { /* this doesn't matter much... no spaces anyway */
949 spaces_per_word = extra_spaces = 0;
950 }
951 } else { /* end of a paragraph: don't fill line */
952 spaces_per_word = 1;
953 extra_spaces = 0;
954 }
Zakk Robertsde236792006-02-16 01:18:21 +0000955
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000956 multiple_spacing = false;
957 for (j=k=spaces=0; j < line_len; j++) {
958 if (k == MAX_COLUMNS)
959 break;
960
961 c = line_begin[j];
962 switch (c) {
963 case ' ':
964 case 0:
Zakk Roberts07fcf772006-05-01 05:45:18 +0000965 if (j==0 && prefs.word_mode==WRAP) { /* indent paragraph */
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000966 for (j=0; j<par_indent_spaces; j++)
967 scratch_buffer[k++] = ' ';
968 j=0;
Zakk Robertsde236792006-02-16 01:18:21 +0000969 }
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +0000970 else if (!multiple_spacing) {
971 for (width = spaces<extra_spaces ? -1:0; width < spaces_per_word; width++)
972 scratch_buffer[k++] = ' ';
973 spaces++;
974 }
975 multiple_spacing = true;
976 break;
977 default:
978 scratch_buffer[k++] = c;
979 multiple_spacing = false;
980 break;
981 }
982 }
Zakk Robertsde236792006-02-16 01:18:21 +0000983
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000984 if (col != -1) {
985 scratch_buffer[k] = 0;
986 endptr = rb->iso_decode(scratch_buffer + col, utf8_buffer,
987 prefs.encoding, k-col);
988 *endptr = 0;
989 }
Zakk Robertsde236792006-02-16 01:18:21 +0000990 }
Zakk Roberts07fcf772006-05-01 05:45:18 +0000991 else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +0000992 if (col != -1)
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000993 if (line_width > col) {
994 str = oldstr = line_begin;
995 k = col;
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +0000996 width = 0;
Karl Kurbjunca8fa652006-06-03 07:04:02 +0000997 while( (width<draw_columns) && (oldstr<line_end) )
998 {
999 oldstr = get_ucs(oldstr, &ch);
Mark Arigo073d73b2006-07-25 20:49:53 +00001000 if (k > 0) {
1001 k -= glyph_width(ch);
1002 line_begin = oldstr;
1003 } else {
1004 width += glyph_width(ch);
1005 }
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001006 }
Karl Kurbjunca8fa652006-06-03 07:04:02 +00001007
1008 if(prefs.view_mode==WIDE)
1009 endptr = rb->iso_decode(line_begin, utf8_buffer,
1010 prefs.encoding, oldstr-line_begin);
1011 else
1012 endptr = rb->iso_decode(line_begin, utf8_buffer,
1013 prefs.encoding, line_end-line_begin);
Linus Nielsen Feltzingf954a532006-03-01 13:31:36 +00001014 *endptr = 0;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001015 }
1016 }
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001017 if (col != -1 && line_width > col)
1018#ifdef HAVE_LCD_BITMAP
1019 rb->lcd_putsxy(left_col, i*pf->height, utf8_buffer);
1020#else
1021 rb->lcd_puts(left_col, i, utf8_buffer);
1022#endif
1023 if (line_width > max_line_len)
1024 max_line_len = line_width;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001025
1026 if (i == 0)
1027 next_line_ptr = line_end;
1028 }
1029 next_screen_ptr = line_end;
1030 if (BUFFER_OOB(next_screen_ptr))
1031 next_screen_ptr = NULL;
1032
1033#ifdef HAVE_LCD_BITMAP
Zakk Roberts07fcf772006-05-01 05:45:18 +00001034 next_screen_to_draw_ptr = prefs.page_mode==OVERLAP? line_begin: next_screen_ptr;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001035
Zakk Roberts07fcf772006-05-01 05:45:18 +00001036 if (prefs.need_scrollbar)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001037 viewer_scrollbar();
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001038#else
1039 next_screen_to_draw_ptr = next_screen_ptr;
1040#endif
Jens Arnoldf9b90e92007-04-06 22:55:00 +00001041
1042 if (col != -1)
1043 rb->lcd_update();
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001044}
1045
1046static void viewer_top(void)
1047{
1048 /* Read top of file into buffer
1049 and point screen pointer to top */
Marcoen Hirschbergcb62c972007-11-19 16:46:39 +00001050 if (file_pos != 0)
1051 {
1052 file_pos = 0;
1053 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001054 fill_buffer(0, buffer, buffer_size);
Marcoen Hirschbergcb62c972007-11-19 16:46:39 +00001055 }
1056
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001057 screen_top_ptr = buffer;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001058}
1059
1060static void viewer_bottom(void)
1061{
1062 /* Read bottom of file into buffer
1063 and point screen pointer to bottom */
1064 long last_sectors;
1065
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001066 if (file_size > buffer_size) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001067 /* Find last buffer in file, round up to next sector boundary */
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001068 last_sectors = file_size - buffer_size + SMALL_BLOCK_SIZE;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001069 last_sectors /= SMALL_BLOCK_SIZE;
1070 last_sectors *= SMALL_BLOCK_SIZE;
1071 }
1072 else {
1073 last_sectors = 0;
1074 }
Marcoen Hirschbergcb62c972007-11-19 16:46:39 +00001075
1076 if (file_pos != last_sectors)
1077 {
1078 file_pos = last_sectors;
1079 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001080 fill_buffer(last_sectors, buffer, buffer_size);
Marcoen Hirschbergcb62c972007-11-19 16:46:39 +00001081 }
1082
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001083 screen_top_ptr = buffer_end-1;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001084}
1085
Jens Arnold2343a192006-05-03 23:16:53 +00001086#ifdef HAVE_LCD_BITMAP
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001087static void init_need_scrollbar(void) {
1088 /* Call viewer_draw in quiet mode to initialize next_screen_ptr,
1089 and thus ONE_SCREEN_FITS_ALL(), and thus NEED_SCROLLBAR() */
1090 viewer_draw(-1);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001091 prefs.need_scrollbar = NEED_SCROLLBAR();
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001092 draw_columns = prefs.need_scrollbar? display_columns-SCROLLBAR_WIDTH : display_columns;
1093 par_indent_spaces = draw_columns/(5*glyph_width(' '));
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001094}
Daniel Stenberg30dbb952006-01-18 11:30:46 +00001095#else
1096#define init_need_scrollbar()
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001097#endif
1098
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001099static bool viewer_init(void)
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001100{
1101#ifdef HAVE_LCD_BITMAP
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001102
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +00001103 pf = rb->font_get(FONT_UI);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001104
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +00001105 display_lines = LCD_HEIGHT / pf->height;
Peter D'Hoye20763632006-07-15 13:53:18 +00001106 draw_columns = display_columns = LCD_WIDTH;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001107#else
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +00001108 /* REAL fixed pitch :) all chars use up 1 cell */
Björn Stenbergf9759442002-10-02 11:37:37 +00001109 display_lines = 2;
Linus Nielsen Feltzingeec2b7e2005-05-13 13:32:57 +00001110 draw_columns = display_columns = 11;
1111 par_indent_spaces = 2;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001112#endif
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001113
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001114 fd = rb->open(file_name, O_RDONLY);
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001115 if (fd==-1)
1116 return false;
1117
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001118 file_size = rb->filesize(fd);
1119 if (file_size==-1)
1120 return false;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001121
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001122 /* Init mac_text value used in processing buffer */
1123 mac_text = false;
1124
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001125 return true;
1126}
1127
Marcoen Hirschberg3f6461a2007-11-23 09:11:09 +00001128static void viewer_default_settings(void)
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001129{
Zakk Roberts07fcf772006-05-01 05:45:18 +00001130 prefs.word_mode = WRAP;
1131 prefs.line_mode = NORMAL;
1132 prefs.view_mode = NARROW;
1133 prefs.scroll_mode = PAGE;
1134#ifdef HAVE_LCD_BITMAP
1135 prefs.page_mode = NO_OVERLAP;
1136 prefs.scrollbar_mode = SB_OFF;
1137#endif
Jens Arnold2343a192006-05-03 23:16:53 +00001138 prefs.autoscroll_speed = 1;
Marcoen Hirschberg3f6461a2007-11-23 09:11:09 +00001139 /* Set codepage to system default */
1140 prefs.encoding = rb->global_settings->default_codepage;
Zakk Roberts07fcf772006-05-01 05:45:18 +00001141}
1142
1143static void viewer_load_settings(void) /* same name as global, but not the same file.. */
1144{
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001145 int settings_fd, i;
1146 struct bookmark_file_data *data;
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001147 struct bookmarked_file_info this_bookmark;
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001148
1149 /* read settings file */
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001150 settings_fd=rb->open(SETTINGS_FILE, O_RDONLY);
Dave Chapman14ac7ca2007-11-22 00:32:50 +00001151 if ((settings_fd >= 0) && (rb->filesize(settings_fd) == sizeof(struct preferences)))
Zakk Roberts07fcf772006-05-01 05:45:18 +00001152 {
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001153 rb->read(settings_fd, &prefs, sizeof(struct preferences));
1154 rb->close(settings_fd);
Marcoen Hirschberg3f6461a2007-11-23 09:11:09 +00001155 }
1156 else
1157 {
1158 /* load default settings if there is no settings file */
1159 viewer_default_settings();
1160 }
1161
1162 rb->memcpy(&old_prefs, &prefs, sizeof(struct preferences));
Zakk Roberts07fcf772006-05-01 05:45:18 +00001163
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001164 data = (struct bookmark_file_data*)buffer; /* grab the text buffer */
1165 data->bookmarked_files_count = 0;
1166
1167 /* read bookmarks if file exists */
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001168 settings_fd = rb->open(BOOKMARKS_FILE, O_RDONLY);
1169 if (settings_fd >= 0)
1170 {
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001171 /* figure out how many items to read */
1172 rb->read(settings_fd, &data->bookmarked_files_count, sizeof(signed int));
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001173 if (data->bookmarked_files_count > MAX_BOOKMARKED_FILES)
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001174 data->bookmarked_files_count = MAX_BOOKMARKED_FILES;
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001175 rb->read(settings_fd, data->bookmarks,
1176 sizeof(struct bookmarked_file_info) * data->bookmarked_files_count);
1177 rb->close(settings_fd);
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001178 }
1179
1180 file_pos = 0;
1181 screen_top_ptr = buffer;
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001182
1183 /* check if current file is in list */
1184 for (i=0; i < data->bookmarked_files_count; i++)
1185 {
1186 if (!rb->strcmp(file_name, data->bookmarks[i].filename))
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001187 {
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001188 int screen_pos = data->bookmarks[i].file_position + data->bookmarks[i].top_ptr_pos;
1189 int screen_top = screen_pos % buffer_size;
1190 file_pos = screen_pos - screen_top;
1191 screen_top_ptr = buffer + screen_top;
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001192 break;
1193 }
1194 }
1195
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001196 this_bookmark.file_position = file_pos;
1197 this_bookmark.top_ptr_pos = screen_top_ptr - buffer;
1198
1199 rb->memset(&this_bookmark.filename[0],0,MAX_PATH);
1200 rb->strcpy(this_bookmark.filename,file_name);
1201
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001202 /* prevent potential slot overflow */
1203 if (i >= data->bookmarked_files_count)
1204 {
1205 if (i < MAX_BOOKMARKED_FILES)
1206 data->bookmarked_files_count++;
1207 else
1208 i = MAX_BOOKMARKED_FILES-1;
1209 }
1210
1211 /* write bookmark file with spare slot in first position
1212 to be filled in by viewer_save_settings */
1213 settings_fd = rb->open(BOOKMARKS_FILE, O_WRONLY|O_CREAT);
1214 if (settings_fd >=0 )
1215 {
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001216 /* write count */
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001217 rb->write (settings_fd, &data->bookmarked_files_count, sizeof(signed int));
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001218
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001219 /* write the current bookmark */
1220 rb->write (settings_fd, &this_bookmark, sizeof(struct bookmarked_file_info));
1221
1222 /* write everything that was before this bookmark */
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001223 rb->write (settings_fd, data->bookmarks, sizeof(struct bookmarked_file_info)*i);
Marcoen Hirschberg77af93b2007-11-19 20:51:38 +00001224
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001225 rb->close(settings_fd);
1226 }
1227
Zakk Roberts07fcf772006-05-01 05:45:18 +00001228 buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
1229
Robert Kuklac9a00ab2007-09-13 00:18:28 +00001230 if (BUFFER_OOB(screen_top_ptr))
1231 {
Zakk Roberts07fcf772006-05-01 05:45:18 +00001232 screen_top_ptr = buffer;
1233 }
1234
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001235 fill_buffer(file_pos, buffer, buffer_size);
Marcoen Hirschberg4c62c002007-11-19 16:02:45 +00001236
1237 /* remember the current position */
1238 start_position = file_pos + screen_top_ptr - buffer;
Marcoen Hirschberg3f6461a2007-11-23 09:11:09 +00001239
1240 init_need_scrollbar();
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001241}
Zakk Robertsde236792006-02-16 01:18:21 +00001242
Zakk Roberts07fcf772006-05-01 05:45:18 +00001243static void viewer_save_settings(void)/* same name as global, but not the same file.. */
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001244{
Zakk Roberts07fcf772006-05-01 05:45:18 +00001245 int settings_fd;
Robert Kukla2ae0d632007-08-13 13:53:33 +00001246
Marcoen Hirschberg2b30bf92007-11-19 20:51:42 +00001247 /* save the viewer settings if they have been changed */
1248 if (rb->memcmp(&prefs, &old_prefs, sizeof(struct preferences)))
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001249 {
Marcoen Hirschberg2b30bf92007-11-19 20:51:42 +00001250 settings_fd = rb->creat(SETTINGS_FILE); /* create the settings file */
1251
1252 if (settings_fd >= 0 )
1253 {
1254 rb->write (settings_fd, &prefs, sizeof(struct preferences));
1255 rb->close(settings_fd);
1256 }
1257 }
1258
1259 /* save the bookmark if the position has changed */
1260 if (file_pos + screen_top_ptr - buffer != start_position)
1261 {
1262 settings_fd = rb->open(BOOKMARKS_FILE, O_WRONLY|O_CREAT);
1263
1264 if (settings_fd >= 0 )
1265 {
1266 struct bookmarked_file_info b;
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001267 b.file_position = file_pos + screen_top_ptr - buffer;
1268 b.top_ptr_pos = 0; /* this is only kept for legassy reasons */
Marcoen Hirschberg2b30bf92007-11-19 20:51:42 +00001269 rb->memset(&b.filename[0],0,MAX_PATH);
1270 rb->strcpy(b.filename,file_name);
1271 rb->PREFIX(lseek)(settings_fd,sizeof(signed int),SEEK_SET);
1272 rb->write (settings_fd, &b, sizeof(struct bookmarked_file_info));
1273 rb->close(settings_fd);
1274 }
Jonathan Gordon09a990c2006-09-18 15:31:51 +00001275 }
Zakk Robertsde236792006-02-16 01:18:21 +00001276}
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001277
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001278static void viewer_exit(void *parameter)
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001279{
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001280 (void)parameter;
1281
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001282 viewer_save_settings();
Björn Stenbergba371fb2003-06-29 16:33:04 +00001283 rb->close(fd);
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001284}
1285
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001286static int col_limit(int col)
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001287{
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001288 if (col < 0)
1289 col = 0;
1290 else
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001291 if (col > max_line_len - 2*glyph_width('o'))
1292 col = max_line_len - 2*glyph_width('o');
Björn Stenbergf9759442002-10-02 11:37:37 +00001293
1294 return col;
1295}
Jens Arnold2343a192006-05-03 23:16:53 +00001296
1297/* settings helper functions */
1298
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001299static bool encoding_setting(void)
1300{
1301 static const struct opt_items names[] = {
1302 {"ISO-8859-1", -1},
1303 {"ISO-8859-7", -1},
1304 {"ISO-8859-8", -1},
1305 {"CP1251", -1},
1306 {"ISO-8859-11", -1},
1307 {"ISO-8859-6", -1},
1308 {"ISO-8859-9", -1},
1309 {"ISO-8859-2", -1},
Marcoen Hirschbergded94e62007-10-01 17:16:31 +00001310 {"CP1250", -1},
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001311 {"SJIS", -1},
1312 {"GB-2312", -1},
1313 {"KSX-1001", -1},
1314 {"BIG5", -1},
1315 {"UTF-8", -1},
1316 };
1317
1318 return rb->set_option("Encoding", &prefs.encoding, INT, names,
1319 sizeof(names) / sizeof(names[0]), NULL);
1320}
1321
Jens Arnold2343a192006-05-03 23:16:53 +00001322static bool word_wrap_setting(void)
1323{
1324 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001325 {"On", -1},
1326 {"Off (Chop Words)", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001327 };
1328
1329 return rb->set_option("Word Wrap", &prefs.word_mode, INT,
1330 names, 2, NULL);
1331}
1332
1333static bool line_mode_setting(void)
1334{
1335 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001336 {"Normal", -1},
1337 {"Join Lines", -1},
1338 {"Expand Lines", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001339#ifdef HAVE_LCD_BITMAP
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001340 {"Reflow Lines", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001341#endif
1342 };
1343
1344 return rb->set_option("Line Mode", &prefs.line_mode, INT, names,
1345 sizeof(names) / sizeof(names[0]), NULL);
1346}
1347
1348static bool view_mode_setting(void)
1349{
1350 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001351 {"No (Narrow)", -1},
1352 {"Yes", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001353 };
Jonathan Gordonef6d3942006-09-17 14:04:58 +00001354 bool ret;
1355 ret = rb->set_option("Wide View", &prefs.view_mode, INT,
Jens Arnold2343a192006-05-03 23:16:53 +00001356 names , 2, NULL);
Jonathan Gordonef6d3942006-09-17 14:04:58 +00001357 if (prefs.view_mode == NARROW)
1358 col = 0;
1359 return ret;
Jens Arnold2343a192006-05-03 23:16:53 +00001360}
1361
1362static bool scroll_mode_setting(void)
1363{
1364 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001365 {"Scroll by Page", -1},
1366 {"Scroll by Line", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001367 };
1368
1369 return rb->set_option("Scroll Mode", &prefs.scroll_mode, INT,
1370 names, 2, NULL);
1371}
1372
1373#ifdef HAVE_LCD_BITMAP
1374static bool page_mode_setting(void)
1375{
1376 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001377 {"No", -1},
1378 {"Yes", -1},
Jens Arnold2343a192006-05-03 23:16:53 +00001379 };
1380
1381 return rb->set_option("Overlap Pages", &prefs.page_mode, INT,
1382 names, 2, NULL);
1383}
1384
1385static bool scrollbar_setting(void)
1386{
1387 static const struct opt_items names[] = {
Jens Arnoldb4efbdc2006-05-05 17:49:27 +00001388 {"Off", -1},
1389 {"On", -1}
Jens Arnold2343a192006-05-03 23:16:53 +00001390 };
1391
1392 return rb->set_option("Show Scrollbar", &prefs.scrollbar_mode, INT,
1393 names, 2, NULL);
1394}
Zakk Roberts07fcf772006-05-01 05:45:18 +00001395#endif
Björn Stenbergba371fb2003-06-29 16:33:04 +00001396
Jens Arnold2343a192006-05-03 23:16:53 +00001397static bool autoscroll_speed_setting(void)
Zakk Roberts07fcf772006-05-01 05:45:18 +00001398{
Jens Arnold2343a192006-05-03 23:16:53 +00001399 return rb->set_int("Auto-scroll Speed", "", UNIT_INT,
1400 &prefs.autoscroll_speed, NULL, 1, 1, 10, NULL);
1401}
1402
1403static bool viewer_options_menu(void)
1404{
1405 int m;
1406 bool result;
Hristo Kovacheve16339e2006-04-04 12:04:15 +00001407
Zakk Roberts07fcf772006-05-01 05:45:18 +00001408 static const struct menu_item items[] = {
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001409 {"Encoding", encoding_setting },
Jens Arnold2343a192006-05-03 23:16:53 +00001410 {"Word Wrap", word_wrap_setting },
1411 {"Line Mode", line_mode_setting },
1412 {"Wide View", view_mode_setting },
Zakk Roberts07fcf772006-05-01 05:45:18 +00001413#ifdef HAVE_LCD_BITMAP
Jens Arnold2343a192006-05-03 23:16:53 +00001414 {"Show Scrollbar", scrollbar_setting },
1415 {"Overlap Pages", page_mode_setting },
Zakk Roberts07fcf772006-05-01 05:45:18 +00001416#endif
Jens Arnold2343a192006-05-03 23:16:53 +00001417 {"Scroll Mode", scroll_mode_setting},
1418 {"Auto-Scroll Speed", autoscroll_speed_setting },
Zakk Roberts07fcf772006-05-01 05:45:18 +00001419 };
Jonathan Gordon77a458a2007-05-08 11:55:43 +00001420 m = menu_init(rb, items, sizeof(items) / sizeof(*items),
Zakk Roberts07fcf772006-05-01 05:45:18 +00001421 NULL, NULL, NULL, NULL);
1422
Jonathan Gordon77a458a2007-05-08 11:55:43 +00001423 result = menu_run(m);
1424 menu_exit(m);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001425#ifdef HAVE_LCD_BITMAP
Jonathan Gordonf83d6eb2007-03-11 08:05:05 +00001426
Jens Arnold2343a192006-05-03 23:16:53 +00001427 /* Show-scrollbar mode for current view-width mode */
Marcoen Hirschbergb3f155d2007-11-23 15:42:08 +00001428 init_need_scrollbar();
Zakk Roberts07fcf772006-05-01 05:45:18 +00001429#endif
Jens Arnold2343a192006-05-03 23:16:53 +00001430 return result;
Zakk Roberts07fcf772006-05-01 05:45:18 +00001431}
Hristo Kovacheve16339e2006-04-04 12:04:15 +00001432
Jens Arnold2343a192006-05-03 23:16:53 +00001433static void viewer_menu(void)
Zakk Roberts07fcf772006-05-01 05:45:18 +00001434{
1435 int m;
1436 int result;
1437 static const struct menu_item items[] = {
1438 {"Quit", NULL },
1439 {"Viewer Options", NULL },
1440 {"Show Playback Menu", NULL },
1441 {"Return", NULL },
1442 };
1443
Jonathan Gordon77a458a2007-05-08 11:55:43 +00001444 m = menu_init(rb, items, sizeof(items) / sizeof(*items), NULL, NULL, NULL, NULL);
1445 result=menu_show(m);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001446 switch (result)
1447 {
1448 case 0: /* quit */
Jonathan Gordon77a458a2007-05-08 11:55:43 +00001449 menu_exit(m);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001450 viewer_exit(NULL);
1451 done = true;
1452 break;
1453 case 1: /* change settings */
Jens Arnold2343a192006-05-03 23:16:53 +00001454 done = viewer_options_menu();
Zakk Roberts07fcf772006-05-01 05:45:18 +00001455 break;
1456 case 2: /* playback control */
Jonathan Gordon33b785e2008-04-23 10:28:34 +00001457 playback_control(rb, NULL);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001458 break;
1459 case 3: /* return */
1460 break;
1461 }
Jonathan Gordon77a458a2007-05-08 11:55:43 +00001462 menu_exit(m);
Zakk Roberts07fcf772006-05-01 05:45:18 +00001463 viewer_draw(col);
1464}
Hristo Kovacheve16339e2006-04-04 12:04:15 +00001465
Steve Bavin65265772008-05-13 09:57:56 +00001466enum plugin_status plugin_start(const struct plugin_api* api, const void* file)
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001467{
Zakk Roberts07fcf772006-05-01 05:45:18 +00001468 int button, i, ok;
Jens Arnold2343a192006-05-03 23:16:53 +00001469 int lastbutton = BUTTON_NONE;
Zakk Roberts07fcf772006-05-01 05:45:18 +00001470 bool autoscroll = false;
Jens Arnold15a0a172006-05-04 19:53:26 +00001471 long old_tick;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001472
Björn Stenbergba371fb2003-06-29 16:33:04 +00001473 rb = api;
Jens Arnold15a0a172006-05-04 19:53:26 +00001474 old_tick = *rb->current_tick;
Björn Stenbergba371fb2003-06-29 16:33:04 +00001475
Marcoen Hirschbergf8232e72007-11-23 09:11:11 +00001476 /* get the plugin buffer */
1477 buffer = rb->plugin_get_buffer((size_t *)&buffer_size);
1478
Björn Stenbergba371fb2003-06-29 16:33:04 +00001479 if (!file)
1480 return PLUGIN_ERROR;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001481
Linus Nielsen Feltzing7ee41032005-05-17 13:14:09 +00001482 file_name = file;
1483 ok = viewer_init();
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001484 if (!ok) {
Robert Kukla2ae0d632007-08-13 13:53:33 +00001485 rb->splash(HZ, "Error opening file.");
1486 return PLUGIN_ERROR;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001487 }
1488
Marcoen Hirschberg3f6461a2007-11-23 09:11:09 +00001489 viewer_load_settings(); /* load the preferences and bookmark */
Jonathan Gordonc4c05832006-09-17 10:32:49 +00001490
Nils Wallméniusd969a422007-09-23 19:15:56 +00001491#if LCD_DEPTH > 1
1492 rb->lcd_set_backdrop(NULL);
1493#endif
1494
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001495 viewer_draw(col);
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001496
Zakk Roberts07fcf772006-05-01 05:45:18 +00001497 while (!done) {
1498
1499 if(autoscroll)
1500 {
1501 if(old_tick <= *rb->current_tick - (110-prefs.autoscroll_speed*10))
1502 {
1503 viewer_scroll_down();
1504 viewer_draw(col);
1505 old_tick = *rb->current_tick;
1506 }
1507 }
Jonathan Gordonc4c05832006-09-17 10:32:49 +00001508
Zakk Roberts07fcf772006-05-01 05:45:18 +00001509 button = rb->button_get_w_tmo(HZ/10);
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001510 switch (button) {
Hristo Kovacheve16339e2006-04-04 12:04:15 +00001511 case VIEWER_MENU:
Jens Arnold2343a192006-05-03 23:16:53 +00001512 viewer_menu();
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001513 break;
1514
Zakk Roberts07fcf772006-05-01 05:45:18 +00001515 case VIEWER_AUTOSCROLL:
Jens Arnold2343a192006-05-03 23:16:53 +00001516#ifdef VIEWER_AUTOSCROLL_PRE
1517 if (lastbutton != VIEWER_AUTOSCROLL_PRE)
1518 break;
1519#endif
Zakk Roberts07fcf772006-05-01 05:45:18 +00001520 autoscroll = !autoscroll;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001521 break;
1522
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001523 case VIEWER_PAGE_UP:
1524 case VIEWER_PAGE_UP | BUTTON_REPEAT:
Zakk Roberts07fcf772006-05-01 05:45:18 +00001525 if (prefs.scroll_mode == PAGE)
1526 {
1527 /* Page up */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001528#ifdef HAVE_LCD_BITMAP
Zakk Roberts07fcf772006-05-01 05:45:18 +00001529 for (i = prefs.page_mode==OVERLAP? 1:0; i < display_lines; i++)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001530#else
Zakk Roberts07fcf772006-05-01 05:45:18 +00001531 for (i = 0; i < display_lines; i++)
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001532#endif
Zakk Roberts07fcf772006-05-01 05:45:18 +00001533 viewer_scroll_up();
1534 }
1535 else
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001536 viewer_scroll_up();
Zakk Roberts07fcf772006-05-01 05:45:18 +00001537 old_tick = *rb->current_tick;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001538 viewer_draw(col);
1539 break;
1540
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001541 case VIEWER_PAGE_DOWN:
1542 case VIEWER_PAGE_DOWN | BUTTON_REPEAT:
Zakk Roberts07fcf772006-05-01 05:45:18 +00001543 if (prefs.scroll_mode == PAGE)
1544 {
1545 /* Page down */
1546 if (next_screen_ptr != NULL)
1547 screen_top_ptr = next_screen_to_draw_ptr;
1548 }
1549 else
1550 viewer_scroll_down();
1551 old_tick = *rb->current_tick;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001552 viewer_draw(col);
1553 break;
1554
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001555 case VIEWER_SCREEN_LEFT:
1556 case VIEWER_SCREEN_LEFT | BUTTON_REPEAT:
Zakk Roberts07fcf772006-05-01 05:45:18 +00001557 if (prefs.view_mode == WIDE) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001558 /* Screen left */
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001559 col -= draw_columns;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001560 col = col_limit(col);
1561 }
Zakk Roberts07fcf772006-05-01 05:45:18 +00001562 else { /* prefs.view_mode == NARROW */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001563 /* Top of file */
1564 viewer_top();
1565 }
1566
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001567 viewer_draw(col);
1568 break;
1569
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001570 case VIEWER_SCREEN_RIGHT:
1571 case VIEWER_SCREEN_RIGHT | BUTTON_REPEAT:
Zakk Roberts07fcf772006-05-01 05:45:18 +00001572 if (prefs.view_mode == WIDE) {
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001573 /* Screen right */
Marcoen Hirschberg5725b8c2006-05-11 20:34:37 +00001574 col += draw_columns;
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001575 col = col_limit(col);
1576 }
Zakk Roberts07fcf772006-05-01 05:45:18 +00001577 else { /* prefs.view_mode == NARROW */
Daniel Stenbergdf9b04c2003-07-24 09:47:46 +00001578 /* Bottom of file */
1579 viewer_bottom();
1580 }
1581
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001582 viewer_draw(col);
1583 break;
Björn Stenbergf9759442002-10-02 11:37:37 +00001584
Daniel Stenberg1ca465a2006-01-27 13:30:57 +00001585#ifdef VIEWER_LINE_UP
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001586 case VIEWER_LINE_UP:
1587 case VIEWER_LINE_UP | BUTTON_REPEAT:
1588 /* Scroll up one line */
1589 viewer_scroll_up();
Zakk Roberts07fcf772006-05-01 05:45:18 +00001590 old_tick = *rb->current_tick;
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001591 viewer_draw(col);
1592 break;
1593
1594 case VIEWER_LINE_DOWN:
1595 case VIEWER_LINE_DOWN | BUTTON_REPEAT:
1596 /* Scroll down one line */
1597 if (next_screen_ptr != NULL)
1598 screen_top_ptr = next_line_ptr;
Zakk Roberts07fcf772006-05-01 05:45:18 +00001599 old_tick = *rb->current_tick;
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001600 viewer_draw(col);
1601 break;
Daniel Stenberg1ca465a2006-01-27 13:30:57 +00001602#endif
1603#ifdef VIEWER_COLUMN_LEFT
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001604 case VIEWER_COLUMN_LEFT:
1605 case VIEWER_COLUMN_LEFT | BUTTON_REPEAT:
Mark Arigo073d73b2006-07-25 20:49:53 +00001606 if (prefs.view_mode == WIDE) {
1607 /* Scroll left one column */
1608 col -= glyph_width('o');
1609 col = col_limit(col);
1610 viewer_draw(col);
1611 }
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001612 break;
1613
1614 case VIEWER_COLUMN_RIGHT:
1615 case VIEWER_COLUMN_RIGHT | BUTTON_REPEAT:
Mark Arigo073d73b2006-07-25 20:49:53 +00001616 if (prefs.view_mode == WIDE) {
1617 /* Scroll right one column */
1618 col += glyph_width('o');
1619 col = col_limit(col);
1620 viewer_draw(col);
1621 }
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001622 break;
1623#endif
Zakk Robertsa90f0922006-05-01 06:01:17 +00001624
Kevin Ferrare0e027bd2006-06-30 16:43:47 +00001625#ifdef VIEWER_RC_QUIT
1626 case VIEWER_RC_QUIT:
1627#endif
Zakk Roberts07fcf772006-05-01 05:45:18 +00001628 case VIEWER_QUIT:
1629 viewer_exit(NULL);
1630 done = true;
1631 break;
Jens Arnoldcc8cff22004-10-16 00:07:43 +00001632
1633 default:
1634 if (rb->default_event_handler_ex(button, viewer_exit, NULL)
1635 == SYS_USB_CONNECTED)
1636 return PLUGIN_USB_CONNECTED;
1637 break;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001638 }
Jens Arnold2343a192006-05-03 23:16:53 +00001639 if (button != BUTTON_NONE)
Jonathan Gordona7d98592006-09-17 14:37:59 +00001640 {
Jens Arnold2343a192006-05-03 23:16:53 +00001641 lastbutton = button;
Jonathan Gordona7d98592006-09-17 14:37:59 +00001642 rb->yield();
1643 }
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001644 }
Björn Stenbergba371fb2003-06-29 16:33:04 +00001645 return PLUGIN_OK;
Daniel Stenberg773e7a72002-09-30 19:05:03 +00001646}
Hristo Kovacheve16339e2006-04-04 12:04:15 +00001647
Rob Purchase297e0502008-04-27 15:30:19 +00001648