/* Copyright (C) 2001-2002 Kenichi Suto
*
* 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 program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "defs.h"
#include "global.h"
#include "eb.h"
#include "jcode.h"
#include "dictheading.h"
#include "dialog.h"
#ifdef __FreeBSD__
#include <pthread.h>
#endif
#include <iconv.h>
#include <langinfo.h>
#include <wchar.h>
#define MAX_HITS 50
#define MAXLEN_HEADING 65535
#define MAXLEN_TEXT 65535
#define EBOOK_MAX_KEYWORDS 256
#define MAX_BUFSIZE 65535
extern GList *group_list;
extern GList *book_list;
extern gint global_multi_code;
static GtkWidget *cancel_dialog;
static GtkWidget *label_match;
static GtkWidget *progress;
static pthread_t tid;
static gint tag_timeout;
static gint thread_running = 0;
static gint hit_count=0;
static gfloat search_progress;
gint ebook_simple_search(BOOK_INFO *binfo, char *word, gint method);
static gint ebook_ending_search(BOOK_INFO *binfo, char *word, gint method);
static EB_Hookset text_hookset;
static EB_Hookset heading_hookset;
static EB_Hookset candidate_hookset;
static gboolean ebook_initialized = FALSE;
EB_Error_Code ebook_set_subbook(BOOK_INFO *binfo);
static EB_Error_Code hook_initialize(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_narrow_font(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_wide_font(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_indent(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_newline(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_no_newline(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_reference(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_candidate(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_narrow(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_superscript(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_subscript(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_emphasis(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_keyword(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_modification(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_euc_to_ascii(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_color(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_mono(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_gray(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_wave(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_mpeg(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Error_Code hook_graphic_reference(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv);
static EB_Hook text_hooks[] = {
// {EB_HOOK_INITIALIZE, hook_initialize},
// {EB_HOOK_STOP_CODE, eb_hook_stop_code},
// {EB_HOOK_STOP_CODE, hook_stopcode},
{EB_HOOK_SET_INDENT, hook_indent},
{EB_HOOK_NEWLINE, hook_newline},
{EB_HOOK_NARROW_FONT, hook_narrow_font},
{EB_HOOK_WIDE_FONT, hook_wide_font},
{EB_HOOK_BEGIN_REFERENCE, hook_reference},
{EB_HOOK_END_REFERENCE, hook_reference},
{EB_HOOK_BEGIN_CANDIDATE, hook_candidate},
{EB_HOOK_END_CANDIDATE_LEAF, hook_candidate},
{EB_HOOK_END_CANDIDATE_GROUP, hook_candidate},
// {EB_HOOK_NARROW_JISX0208, hook_euc_to_ascii},
{EB_HOOK_BEGIN_COLOR_BMP, hook_color},
{EB_HOOK_BEGIN_COLOR_JPEG, hook_color},
{EB_HOOK_END_COLOR_GRAPHIC, hook_color},
{EB_HOOK_BEGIN_MONO_GRAPHIC, hook_mono},
{EB_HOOK_END_MONO_GRAPHIC, hook_mono},
{EB_HOOK_BEGIN_GRAY_GRAPHIC, hook_gray},
{EB_HOOK_END_GRAY_GRAPHIC, hook_gray},
{EB_HOOK_BEGIN_WAVE, hook_wave},
{EB_HOOK_END_WAVE, hook_wave},
{EB_HOOK_BEGIN_MPEG, hook_mpeg},
{EB_HOOK_END_MPEG, hook_mpeg},
// {EB_HOOK_BEGIN_GRAPHIC_REFERENCE,hook_graphic_reference},
// {EB_HOOK_END_GRAPHIC_REFERENCE, hook_graphic_reference},
// {EB_HOOK_GRAPHIC_REFERENCE, hook_graphic_reference},
// {EB_HOOK_BEGIN_NO_NEWLINE, hook_no_newline},
// {EB_HOOK_END_NO_NEWLINE, hook_no_newline},
// {EB_HOOK_BEGIN_NARROW, hook_narrow},
// {EB_HOOK_END_NARROW, hook_narrow},
{EB_HOOK_BEGIN_SUPERSCRIPT, hook_superscript},
{EB_HOOK_END_SUPERSCRIPT, hook_superscript},
{EB_HOOK_BEGIN_SUBSCRIPT, hook_subscript},
{EB_HOOK_END_SUBSCRIPT, hook_subscript},
{EB_HOOK_BEGIN_EMPHASIS, hook_emphasis},
{EB_HOOK_END_EMPHASIS, hook_emphasis},
{EB_HOOK_BEGIN_KEYWORD, hook_keyword},
{EB_HOOK_END_KEYWORD, hook_keyword},
#ifdef EB_HOOK_BEGIN_DECORATION
{EB_HOOK_BEGIN_DECORATION, hook_modification},
#endif
#ifdef EB_HOOK_END_DECORATION
{EB_HOOK_END_DECORATION, hook_modification},
#endif
{EB_HOOK_NULL, NULL},
};
static EB_Hook heading_hooks[] = {
{EB_HOOK_NEWLINE, hook_newline},
{EB_HOOK_NARROW_FONT, hook_narrow_font},
{EB_HOOK_WIDE_FONT, hook_wide_font},
// {EB_HOOK_BEGIN_CANDIDATE, hook_candidate},
// {EB_HOOK_END_CANDIDATE_LEAF, hook_candidate},
// {EB_HOOK_END_CANDIDATE_GROUP, hook_candidate},
{EB_HOOK_NARROW_JISX0208, eb_hook_euc_to_ascii},
{EB_HOOK_BEGIN_SUPERSCRIPT, hook_superscript},
{EB_HOOK_END_SUPERSCRIPT, hook_superscript},
{EB_HOOK_BEGIN_SUBSCRIPT, hook_subscript},
{EB_HOOK_END_SUBSCRIPT, hook_subscript},
{EB_HOOK_NULL, NULL},
};
static EB_Hook candidate_hooks[] = {
{EB_HOOK_NARROW_FONT, hook_narrow_font},
{EB_HOOK_WIDE_FONT, hook_wide_font},
{EB_HOOK_BEGIN_CANDIDATE, hook_candidate},
{EB_HOOK_END_CANDIDATE_LEAF, hook_candidate},
{EB_HOOK_END_CANDIDATE_GROUP, hook_candidate},
{EB_HOOK_NULL, NULL},
};
static EB_Error_Code hook_initialize(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
return EB_SUCCESS;
}
static EB_Error_Code hook_narrow_font(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
char text[64];
sprintf (text, "<gaiji code=h%04x>", argv[0]);
eb_write_text_string(book, text);
return EB_SUCCESS;
}
static EB_Error_Code hook_wide_font(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
char text[64];
sprintf (text, "<gaiji code=z%04x>", argv[0]);
eb_write_text_string(book, text);
return EB_SUCCESS;
}
static EB_Error_Code hook_indent(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
char text[64];
sprintf (text, "<indent position=%d>", argv[1]);
eb_write_text_string(book, text);
/*
for(i = 0 ; i < argv[1] ; i ++){
eb_write_text_string(book, " ");
}
*/
return EB_SUCCESS;
}
static EB_Error_Code hook_newline(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
eb_write_text_string(book, "\n");
return EB_SUCCESS;
}
static EB_Error_Code hook_narrow(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
switch (code) {
case EB_HOOK_BEGIN_NARROW:
// eb_write_text_string(book, "<narrow>");
break;
case EB_HOOK_END_NARROW:
// eb_write_text_string(book, "</narrow>");
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_no_newline(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
switch (code) {
case EB_HOOK_BEGIN_NO_NEWLINE:
// eb_write_text_string(book, "<nonewline>");
break;
case EB_HOOK_END_NO_NEWLINE:
// eb_write_text_string(book, "</nonewline>");
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_reference(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_REFERENCE:
eb_write_text_string(book, "<reference>");
break;
case EB_HOOK_END_REFERENCE:
sprintf (text, "</reference page=0x%x offset=0x%x>", argv[1], argv[2]);
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_candidate(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_CANDIDATE:
eb_write_text_string(book, "<candidate>");
break;
case EB_HOOK_END_CANDIDATE_LEAF:
sprintf (text, "</candidate>", argv[1], argv[2]);
eb_write_text_string(book, text);
break;
case EB_HOOK_END_CANDIDATE_GROUP:
sprintf (text, "</candidate page=0x%x offset=0x%x>", argv[1], argv[2]);
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_superscript(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_SUPERSCRIPT:
eb_write_text_string(book, "<superscript>");
break;
case EB_HOOK_END_SUPERSCRIPT:
sprintf (text, "</superscript>");
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_subscript(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_SUBSCRIPT:
eb_write_text_string(book, "<subscript>");
break;
case EB_HOOK_END_SUBSCRIPT:
sprintf (text, "</subscript>");
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_emphasis(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_EMPHASIS:
eb_write_text_string(book, "<emphasis>");
break;
case EB_HOOK_END_EMPHASIS:
sprintf (text, "</emphasis>");
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_keyword(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_KEYWORD:
sprintf (text, "<keyword argv1=%x>", argv[1]);
eb_write_text_string(book, text);
break;
case EB_HOOK_END_KEYWORD:
sprintf (text, "</keyword>");
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
static EB_Error_Code hook_modification(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
#ifdef EB_HOOK_BEGIN_DECORATION
#ifdef EB_HOOK_END_DECORATION
switch (code) {
case EB_HOOK_BEGIN_DECORATION:
sprintf (text, "<modification method=%d>", argv[1]);
eb_write_text_string(book, text);
break;
case EB_HOOK_END_DECORATION:
sprintf (text, "</modification>");
eb_write_text_string(book, text);
break;
}
#endif
#endif
return EB_SUCCESS;
}
/*
* Hook for a reference to color graphic data.
*/
static EB_Error_Code hook_color(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_COLOR_JPEG:
sprintf (text, "<jpeg page=0x%x offset=0x%x>", argv[2], argv[3]);
eb_write_text_string(book, text);
break;
case EB_HOOK_BEGIN_COLOR_BMP:
sprintf (text, "<bmp page=0x%x offset=0x%x>", argv[2], argv[3]);
eb_write_text_string(book, text);
break;
/*
case EB_HOOK_END_COLOR_GRAPHIC:
sprintf (text, "</jpeg=0x%x:0x%x>", argv[2], argv[3]);
eb_write_text_string(book, text);
break;
*/
}
return EB_SUCCESS;
}
/*
* Hook for a reference to MONO graphic data.
*/
static EB_Error_Code hook_mono(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_MONO_GRAPHIC:
// argv[2] : height
// argv[3] : width
sprintf (text, "<mono width=%d height=%d>", argv[3], argv[2]);
eb_write_text_string(book, text);
break;
case EB_HOOK_END_MONO_GRAPHIC:
// argv[1] : block
// argv[2] : offset
sprintf (text, "</mono page=0x%x offset=0x%x>", argv[1], argv[2]);
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
/*
* Hook for a reference to GRAY graphic data.
*/
static EB_Error_Code hook_gray(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
gchar text[64];
switch (code) {
case EB_HOOK_BEGIN_GRAY_GRAPHIC:
sprintf (text, "<gray page=0x%x offset=0x%x>", argv[2], argv[3]);
eb_write_text_string(book, text);
break;
/*
case EB_HOOK_END_GRAY_GRAPHIC:
sprintf (text, "</gray=0x%x:0x%x>", argv[2], argv[3]);
eb_write_text_string(book, text);
break;
*/
}
return EB_SUCCESS;
}
/*
* Hook for a reference to WAVE sound data.
*/
static EB_Error_Code hook_wave(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
off_t start_location;
off_t end_location;
size_t data_size;
gchar text[64];
/*
* Set binary context.
*/
start_location = (off_t)(argv[2] - 1) * EB_SIZE_PAGE + argv[3];
end_location = (off_t)(argv[4] - 1) * EB_SIZE_PAGE + argv[5];
data_size = end_location - start_location;
switch (code) {
case EB_HOOK_BEGIN_WAVE:
eb_write_text_string(book, "<wave>");
break;
case EB_HOOK_END_WAVE:
// sprintf (text, "</wave start_page=0x%x start_offset=0x%x end_page=0x%x end_offset=0x%x>", argv[2], argv[3], argv[4], argv[5]);
sprintf (text, "</wave page=0x%x offset=0x%x size=%d>", argv[2], argv[3], data_size);
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
/*
* Hook for a reference to MPEG sound data.
*/
static EB_Error_Code hook_mpeg(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
char file_name[EB_MAX_DIRECTORY_NAME_LENGTH + 1];
char text[256];
switch (code) {
case EB_HOOK_BEGIN_MPEG:
break;
case EB_HOOK_END_MPEG:
if (eb_compose_movie_file_name(argv + 2, file_name) != EB_SUCCESS)
return EB_SUCCESS;
sprintf(text, "<mpeg filename=%s>", file_name);
eb_write_text_string(book, text);
break;
}
return EB_SUCCESS;
}
/*
* Hook for a reference to graphic reference.
*/
static EB_Error_Code hook_graphic_reference(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
/* char file_name[EB_MAX_DIRECTORY_NAME_LENGTH + 1]; */
char text[256];
switch (code) {
case EB_HOOK_GRAPHIC_REFERENCE:
case EB_HOOK_BEGIN_GRAPHIC_REFERENCE:
sprintf (text, "<graphic_reference page=0x%x offset=0x%x>", argv[1], argv[2]);
eb_write_text_string(book, text);
break;
case EB_HOOK_END_GRAPHIC_REFERENCE:
break;
}
return EB_SUCCESS;
}
/*
* EUC JP to ASCII conversion table.
*/
#define EUC_TO_ASCII_TABLE_START 0xa0
#define EUC_TO_ASCII_TABLE_END 0xff
static const unsigned char euc_a1_to_ascii_table[] = {
0x00, 0x20, 0x00, 0x00, 0x2c, 0x2e, 0x00, 0x3a, /* 0xa0 */
0x3b, 0x3f, 0x21, 0x00, 0x00, 0x00, 0x60, 0x00, /* 0xa8 */
0x5e, 0x7e, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x2f, /* 0xb8 */
0x5c, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x27, /* 0xc0 */
0x00, 0x22, 0x28, 0x29, 0x00, 0x00, 0x5b, 0x5d, /* 0xc8 */
0x7b, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0 */
0x00, 0x00, 0x00, 0x00, 0x2b, 0x2d, 0x00, 0x00, /* 0xd8 */
0x00, 0x3d, 0x00, 0x3c, 0x3e, 0x00, 0x00, 0x00, /* 0xe0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, /* 0xe8 */
0x24, 0x00, 0x00, 0x25, 0x23, 0x26, 0x2a, 0x40, /* 0xf0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8 */
};
static const unsigned char euc_a3_to_ascii_table[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8 */
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* 0xb0 */
0x38, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8 */
0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* 0xc0 */
0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, /* 0xc8 */
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* 0xd0 */
0x58, 0x59, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8 */
0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 0xe0 */
0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, /* 0xe8 */
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, /* 0xf0 */
0x78, 0x79, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8 */
};
/*
* Latin-1 character to entity reference table.
* (e.g. 'a --> á)
*/
const char *latin1_entity_name_table[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x00 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x08 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x10 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x18 */
NULL, NULL, "quot", NULL, NULL, NULL, "amp", NULL, /* 0x20 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x28 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x30 */
NULL, NULL, NULL, NULL, "lt", NULL, "gt", NULL, /* 0x38 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x40 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x48 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x50 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x58 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x60 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x68 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x70 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x78 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x80 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x88 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x90 */
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 0x98 */
"nbsp", "iexcl", "cent", "pound", /* 0xa0 */
"curren", "yen", "brvbar", "sect", /* 0xa4 */
"uml", "copy", "ordf", "laquo", /* 0xa8 */
"not", "shy", "reg", "macr", /* 0xac */
"deg", "plusmn", "sup2", "sup3", /* 0xb0 */
"acute", "micro", "para", "middot", /* 0xb4 */
"cedil", "sup1", "ordm", "requo", /* 0xb8 */
"frac14", "frac12", "farc34", "iquest", /* 0xbc */
"Agrave", "Aacute", "Acirc", "Atilde", /* 0xc0 */
"Auml", "Aring", "AElig", "Ccedil", /* 0xc4 */
"Egrave", "Eacute", "Ecirc", "Euml", /* 0xc8 */
"Igrave", "Iacute", "Icirc", "Iuml", /* 0xcc */
"ETH", "Ntilde", "Ograve", "Oacute", /* 0xd0 */
"Ocirc", "Otilde", "Ouml", "times", /* 0xd4 */
"Oslash", "Ugrave", "Uacute", "Ucirc", /* 0xd8 */
"Uuml", "Yacute", "THORN", "szlig", /* 0xdc */
"agrave", "aacute", "acirc", "atilde", /* 0xe0 */
"auml", "aring", "aelig", "ccedil", /* 0xe4 */
"egrave", "eacute", "ecirc", "euml", /* 0xe8 */
"igrave", "iacute", "icirc", "iuml", /* 0xec */
"eth", "ntilde", "ograve", "oacute", /* 0xf0 */
"ocirc", "otilde", "ouml", "divide", /* 0xf4 */
"oslash", "ugrave", "uacute", "ucirc", /* 0xf8 */
"uuml", "yacute", "thorn", "yuml" /* 0xfc */
};
/*
* Hook which converts a character from EUC-JP to ASCII.
*/
static EB_Error_Code hook_euc_to_ascii(EB_Book *book, EB_Appendix *appendix, void *container, EB_Hook_Code code, int argc, const unsigned int *argv)
{
int in_code1, in_code2;
int out_code = 0;
const char *entity;
in_code1 = argv[0] >> 8;
in_code2 = argv[0] & 0xff;
if (in_code2 < EUC_TO_ASCII_TABLE_START
|| EUC_TO_ASCII_TABLE_END < in_code2) {
out_code = 0;
} else if (in_code1 == 0xa1) {
out_code = euc_a1_to_ascii_table[in_code2 - EUC_TO_ASCII_TABLE_START];
} else if (in_code1 == 0xa3) {
out_code = euc_a3_to_ascii_table[in_code2 - EUC_TO_ASCII_TABLE_START];
}
if (out_code == 0)
eb_write_text_byte2(book, in_code1, in_code2);
else {
entity = latin1_entity_name_table[out_code];
if (entity != NULL) {
eb_write_text_byte1(book, '&');
eb_write_text_string(book, entity);
eb_write_text_byte1(book, ';');
} else {
eb_write_text_byte1(book, out_code);
}
}
return EB_SUCCESS;
}
gint ebook_search_method(){
char *text;
int i;
text = gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(combo_method)->entry));
for(i=0 ; search_method[i].name != 0 ; i ++){
if(strcmp(text, search_method[i].name) == 0)
return(search_method[i].code);
}
return(SEARCH_METHOD_UNKNOWN);
}
BOOK_INFO *load_book(char *book_path, int subbook_no, char *appendix_path, int appendix_subbook_no)
{
EB_Error_Code error_code;
BOOK_INFO *binfo;
EB_Subbook_Code sublist[EB_MAX_SUBBOOKS];
/* EB_Multi_Search_Code multi_list[EB_MAX_MULTI_SEARCHES]; */
/* int multi_count; */
int subcount /* , i */;
char buff[512];
GList *book_item;
// $B$9$G$KF1$8=q@R$,$J$$$+8!:w$9$k(B
// g_print("load_book(%s, %d, %s, %d\n", book_path, subbook_no, appendix_path, appendix_subbook_no);
book_item = g_list_first(book_list);
while(book_item != NULL){
binfo = (BOOK_INFO *)(book_item->data);
if((strcmp(binfo->book_path, book_path) == 0) &&
(binfo->subbook_no == subbook_no)) {
if((binfo->appendix_path != NULL) &&
(appendix_path != NULL) &&
(strcmp(binfo->appendix_path, appendix_path) == 0) &&
(binfo->appendix_subbook_no == appendix_subbook_no)) {
return(binfo);
} else {
unload_book(binfo);
g_free(binfo);
break;
}
}
book_item = g_list_next(book_item);
}
binfo = (BOOK_INFO *)calloc(sizeof(BOOK_INFO),1);
if(binfo == NULL){
fprintf(stderr, "No memory\n");
exit(1);
}
binfo->book_path = strdup(book_path);
binfo->subbook_no = subbook_no;
if(appendix_path){
binfo->appendix_path = strdup(appendix_path);
binfo->appendix_subbook_no = appendix_subbook_no;
}
binfo->book = (EB_Book *) malloc(sizeof(EB_Book));
eb_initialize_book(binfo->book);
error_code = eb_bind(binfo->book,
binfo->book_path);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to bind the book : %s\n",
eb_error_message(error_code));
goto FAILED;
}
error_code = eb_subbook_list(
binfo->book,
sublist,
&subcount);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to get a subbook list : %s\n",
eb_error_message(error_code));
goto FAILED;
}
error_code = eb_subbook_directory2(
binfo->book,
sublist[binfo->subbook_no],
buff);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to get the directory : %s\n",
eb_error_message(error_code));
goto FAILED;
}
binfo->subbook_dir = strdup(buff);
error_code = eb_subbook_title2(
binfo->book,
sublist[binfo->subbook_no],
buff);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to get the title : %s\n",
eb_error_message(error_code));
goto FAILED;
}
binfo->subbook_title = strdup(buff);
if(binfo->appendix_path != NULL){
binfo->appendix = (EB_Appendix *) malloc(sizeof(EB_Appendix));
eb_initialize_appendix(binfo->appendix);
error_code = eb_bind_appendix(binfo->appendix,
binfo->appendix_path);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to bind appendix : %s\n",
eb_error_message(error_code));
goto FAILED;
}
}
ebook_set_subbook(binfo);
binfo->available = TRUE;
if(eb_have_word_search(binfo->book)){
binfo->search_method[SEARCH_METHOD_WORD] = TRUE;
}
if(eb_have_endword_search(binfo->book)){
binfo->search_method[SEARCH_METHOD_ENDWORD] = TRUE;
}
if(eb_have_exactword_search(binfo->book)){
binfo->search_method[SEARCH_METHOD_EXACTWORD] = TRUE;
}
if(eb_have_keyword_search(binfo->book)){
binfo->search_method[SEARCH_METHOD_KEYWORD] = TRUE;
}
/*
eb_multi_search_list(binfo->book, multi_list, &multi_count);
for (i = 0; i < multi_count; i++) {
binfo->search_method[SEARCH_METHOD_MULTI1+i] = TRUE;
}
*/
if(eb_have_multi_search(binfo->book)){
binfo->search_method[SEARCH_METHOD_MULTI] = TRUE;
}
if(eb_have_menu(binfo->book)){
binfo->search_method[SEARCH_METHOD_MENU] = TRUE;
}
if(eb_have_copyright(binfo->book)){
binfo->search_method[SEARCH_METHOD_COPYRIGHT] = TRUE;
}
if (eb_have_font(binfo->book, EB_FONT_16)){
error_code = eb_set_font(binfo->book, EB_FONT_16);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to set font : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
// return(error_code);
}
}
book_list = g_list_append(book_list, binfo);
return(binfo);
FAILED:
// if((binfo != NULL) && (binfo->book_path != NULL))
// free(binfo->book_path);
// if((binfo != NULL) && (binfo->book != NULL))
// free(binfo->book);
// if(binfo != NULL)
// free(binfo);
binfo->available = FALSE;
return(binfo);
}
static void free_gaiji(BOOK_INFO *binfo){
/* GAIJI_CACHE *gaiji , *tmp_g ; */
GList *lists[8];
GList *item;
gint i;
lists[0] = binfo->gaiji_narrow16;
lists[1] = binfo->gaiji_narrow24;
lists[2] = binfo->gaiji_narrow30;
lists[3] = binfo->gaiji_narrow48;
lists[4] = binfo->gaiji_wide16;
lists[5] = binfo->gaiji_wide24;
lists[6] = binfo->gaiji_wide30;
lists[7] = binfo->gaiji_wide48;
for(i=0; i < 8 ; i ++){
item = g_list_first(lists[i]);
while(item){
free(item->data);
item = g_list_next(item);
}
g_list_free(lists[i]);
}
binfo->gaiji_narrow16 = NULL;
binfo->gaiji_narrow24 = NULL;
binfo->gaiji_narrow30 = NULL;
binfo->gaiji_narrow48 = NULL;
binfo->gaiji_wide16 = NULL;
binfo->gaiji_wide24 = NULL;
binfo->gaiji_wide30 = NULL;
binfo->gaiji_wide48 = NULL;
}
void unload_book(BOOK_INFO *binfo)
{
/* GAIJI_CACHE *gaiji, *tmp_g */;
eb_unset_subbook(binfo->book);
eb_finalize_book(binfo->book);
free(binfo->book_path);
free(binfo->appendix_path);
free(binfo->subbook_dir);
free(binfo->subbook_title);
free_gaiji(binfo);
book_list = g_list_remove(book_list, binfo);
return;
}
void check_search_method()
{
BOOK_INFO *binfo;
GList *book_item;
gint method_count=0;
/* char buff[512]; */
/* int i; */
menu_word_search = FALSE;
menu_endword_search = FALSE;
menu_exactword_search = FALSE;
menu_keyword_search = FALSE;
menu_menu = FALSE;
menu_copyright = FALSE;
menu_multi_search = FALSE;
book_item = g_list_first(book_list);
while(book_item != NULL){
binfo = (BOOK_INFO *)(book_item->data);
if(binfo->search_method[SEARCH_METHOD_WORD] == TRUE)
menu_word_search = TRUE;
if(binfo->search_method[SEARCH_METHOD_ENDWORD] == TRUE)
menu_endword_search = TRUE;
if(binfo->search_method[SEARCH_METHOD_EXACTWORD] == TRUE)
menu_exactword_search = TRUE;
if(binfo->search_method[SEARCH_METHOD_KEYWORD] == TRUE)
menu_keyword_search = TRUE;
if(binfo->search_method[SEARCH_METHOD_MENU] == TRUE)
menu_menu = TRUE;
if(binfo->search_method[SEARCH_METHOD_COPYRIGHT] == TRUE)
menu_copyright = TRUE;
if(binfo->search_method[SEARCH_METHOD_MULTI] == TRUE)
menu_multi_search = TRUE;
book_item = g_list_next(book_item);
}
method_count = 0;
search_method[method_count].code = SEARCH_METHOD_AUTOMATIC;
search_method[method_count].name = strdup(_("Automatic Search"));
method_count ++;
if(menu_exactword_search == TRUE){
search_method[method_count].code = SEARCH_METHOD_EXACTWORD;
search_method[method_count].name = strdup(_("Exactword Search"));
method_count ++;
}
if(menu_word_search == TRUE){
search_method[method_count].code = SEARCH_METHOD_WORD;
search_method[method_count].name = strdup(_("Forward Search"));
method_count ++;
}
if(menu_endword_search == TRUE){
search_method[method_count].code = SEARCH_METHOD_ENDWORD;
search_method[method_count].name = strdup(_("Backward Search"));
method_count ++;
}
if(menu_keyword_search == TRUE){
search_method[method_count].code = SEARCH_METHOD_KEYWORD;
search_method[method_count].name = strdup(_("Keyword Search"));
method_count ++;
}
if(menu_multi_search == TRUE){
search_method[method_count].code = SEARCH_METHOD_MULTI;
search_method[method_count].name = strdup(_("Multiword Search"));
method_count ++;
}
/*
if(menu_menu == TRUE){
search_method[method_count].code = SEARCH_METHOD_MENU;
search_method[method_count].name = strdup(_("Menu"));
method_count ++;
}
if(menu_copyright == TRUE){
search_method[method_count].code = SEARCH_METHOD_COPYRIGHT;
search_method[method_count].name = strdup(_("Copyright"));
method_count ++;
}
*/
search_method[method_count].code = SEARCH_METHOD_FULL_TEXT;
search_method[method_count].name = strdup(_("Full Text Search"));
method_count ++;
search_method[method_count].code = SEARCH_METHOD_INTERNET;
search_method[method_count].name = strdup(_("Internet Search"));
method_count ++;
search_method[method_count].name = NULL;
}
gint ebook_start(){
EB_Error_Code error_code;
error_code = eb_initialize_library();
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to initialize library : %s\n",
eb_error_message(error_code));
return(1);
}
eb_initialize_hookset (&text_hookset);
error_code = eb_set_hooks (&text_hookset, text_hooks);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to set hookset(text) : %s\n",
eb_error_message(error_code));
return(1);
}
eb_initialize_hookset (&heading_hookset);
error_code = eb_set_hooks (&heading_hookset, heading_hooks);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to set hookset(heading) : %s\n",
eb_error_message(error_code));
return(1);
}
eb_initialize_hookset (&candidate_hookset);
error_code = eb_set_hooks (&candidate_hookset, candidate_hooks);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to set hookset(candidate) : %s\n",
eb_error_message(error_code));
return(1);
}
ebook_initialized = TRUE;
return(0);
}
gint ebook_end(){
/* GAIJI_CACHE *gaiji, *tmp_g ; */
BOOK_INFO *binfo;
GList *book_item;
if(ebook_initialized == TRUE) {
return(0);
}
book_item = g_list_first(book_list);
while(book_item != NULL){
binfo = (BOOK_INFO *)(book_item->data);
eb_unset_subbook(binfo->book);
eb_finalize_book(binfo->book);
free(binfo->book_path);
free(binfo->appendix_path);
free(binfo->subbook_dir);
free(binfo->subbook_title);
free_gaiji(binfo);
g_list_remove(book_list, book_item->data);
book_item = g_list_next(book_item);
}
book_list = NULL;
ebook_initialized = FALSE;
return(0);
}
void split_word(gchar *word, gchar **keywords)
{
gint i,j;
gchar *p;
gchar buff[512];
p = word;
i = 0;
j = 0;
keywords[0] = NULL;
if(strlen(word) > 512){
return;
}
while(1){
switch(*p){
case ' ':
case '\t':
case '\n':
case '\0':
// if(j != 0){
buff[j] = '\0';
keywords[i] = strdup(buff);
i ++;
keywords[i] = NULL;
j = 0;
// }
break;
default:
buff[j] = *p;
j ++;
}
p++;
if((*p == '\0') || (i == EBOOK_MAX_KEYWORDS))
break;
}
buff[j] = '\0';
if(strlen(buff) != 0){
keywords[i] = strdup(buff);
i ++;
}
keywords[i] = NULL;
}
void cat_word(char *string, char **words){
gint i;
gint len = 0;
sprintf(string, "%s", words[0]);
len = strlen(words[0]);
for(i=1 ; words[i] != NULL ; i++){
strcat(string, " ");
strcat(string, words[i]);
len = len + strlen(words[i]) + 1;
}
string[len] = '\0';
}
void free_words(char **words){
gint i;
for(i=0; words[i] != NULL ; i++)
free(words[i]);
}
gboolean iseuckanji(guchar *buff){
g_assert(buff != NULL);
if((buff[0] >= 0xb0) && (buff[0] <= 0xf4) &&
(buff[1] >= 0xa1) && (buff[1] <= 0xfe))
return(TRUE);
return(FALSE);
}
gboolean iseuc(guchar *buff){
g_assert(buff != NULL);
if((buff[0] >= 0xa1) && (buff[0] <= 0xf4) &&
(buff[1] >= 0xa1) && (buff[1] <= 0xfe))
return(TRUE);
return(FALSE);
}
static gchar *locale2jis(gchar *inbuf){
iconv_t cd;
const char* ocode = "euc-jp";
const char* icode;
// const char* ocode = "iso-2022-jp";
// const char* ocode = "shift_jis";
int r = 0;
size_t isize;
size_t osize;
char *outbuf;
guchar *eucbuf=NULL;
guchar *euc_p;
guchar *jisbuf=NULL;
guchar *jis_p;
gint i;
icode = nl_langinfo(CODESET);
if((strcasecmp(icode, "EUC-JP") == 0) ||
(strcasecmp(icode, "EUCJP") == 0) ){
euc_p = inbuf;
} else {
cd = iconv_open( ocode, icode );
if( (int)cd == -1 )
return(NULL);
isize = strlen(inbuf);
osize = isize * 4;
eucbuf = outbuf = malloc(osize);
#ifdef __FreeBSD__
r = iconv(cd, (const char **)&inbuf, &isize, &outbuf, &osize);
#else
r = iconv(cd, &inbuf, &isize, &outbuf, &osize);
#endif
iconv_close(cd);
if(r == 1){
perror("iconv");
return(NULL);
}
euc_p = eucbuf;
}
jis_p = jisbuf = malloc(strlen(euc_p)*2);
while(*euc_p != '\0'){
if(isalnum(*euc_p)){
*jis_p = 0x23;
jis_p ++;
*jis_p = *euc_p;
jis_p ++;
}
else if(iseuc(euc_p)){
*jis_p = *euc_p - 0x80;
jis_p ++;
euc_p++;
*jis_p = *euc_p - 0x80;
jis_p ++;
}
else if(*euc_p == 0x20){
*jis_p = 0x21;
jis_p ++;
*jis_p = 0x21;
jis_p ++;
}
else {
*jis_p = 0x21;
jis_p ++;
*jis_p = 0x29;
jis_p ++;
}
euc_p ++;
}
*jis_p = '\0';
if(eucbuf != NULL)
free(eucbuf);
for(i=0;;i++){
if(jisbuf[i] == '\0')
break;
}
return(jisbuf);
}
static int check_match(char *haystack, char *needle){
/* wchar_t *l_haystack; */
/* wchar_t *l_needle; */
char *rp;
gint len;
len = strlen(needle);
rp = haystack;
while(*rp != '\0'){
if(strncasecmp(rp, needle, len) == 0)
return(0);
if(isascii(*rp))
rp += 1;
else
rp += 2;
}
return(1);
/*
l_haystack = any_to_utf8(haystack);
l_needle = any_to_utf8(needle);
rp = wcsstr(l_haystack, l_needle);
free(l_haystack);
free(l_needle);
if(rp == NULL)
return(1);
else
return(0);
*/
}
gboolean full_text_search_ignore_case = TRUE;
static int jiscmp(unsigned char *haystack, unsigned char *needle){
unsigned char *p1, *p2;
p1 = haystack;
p2 = needle;
while(1) {
if(isjisp(p1) != TRUE){
p1 +=2;
continue;
}
if(*p2 == '\0')
return(0);
else if(*p1 == '\0')
return(1);
else if((*p1 == *p2) && (*(p1+1) == *(p2+1))) {
p1 +=2;
p2 +=2;
continue;
} else if(full_text_search_ignore_case){
guint c1, c2;
c1 = eb_uint2(p1);
c2 = eb_uint2(p2);
if ((0x2341 <= c1) && (c1 <= 0x237a) &&
(0x2341 <= c2) && (c2 <= 0x237a)){
if(((0x2361 <= c1) ? (c1 - 0x20) : c1) == ((0x2361 <= c2) ? (c2 - 0x20) : c2)){
p1 += 2;
p2 += 2;
continue;
}
}
return(1);
} else {
return(1);
}
}
}
static gboolean check_duplicate_hit(EB_Position pos){
GList *l;
SEARCH_RESULT *rp;
l = search_result;
while(l != NULL){
rp = (SEARCH_RESULT *)(l->data);
if((rp->pos_text.page == pos.page) &&
(rp->pos_text.offset == pos.offset))
return(TRUE);
l = g_list_next(l);
}
return(FALSE);
}
static gint count_result(GList *result)
{
return(g_list_length(result));
}
EB_Error_Code ebook_my_backward_text(BOOK_INFO *binfo)
{
EB_Error_Code error_code=EB_SUCCESS;
EB_Position text_position;
char data[EB_SIZE_PAGE+4];
/* char *jisword; */
/* char *word_p; */
int i, length;
/* char *p; */
/* char heading[MAXLEN_TEXT + 1]; */
/* SEARCH_RESULT *rp; */
int start_page;
int end_page;
int current_page;
int current_offset;
int offset;
int read_page;
int stop_code;
/* int page_count=0; */
error_code = ebook_set_subbook(binfo);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to set subbook : %s\n",
eb_error_message(error_code));
return(error_code);
}
start_page = binfo->book->subbook_current->text.start_page;
end_page = binfo->book->subbook_current->text.end_page;
error_code = eb_tell_text(binfo->book, &text_position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to tell text : %s\n",
eb_error_message(error_code));
return(error_code);
}
current_page = text_position.page;
current_offset = text_position.offset;
offset = current_offset;
stop_code = binfo->book->text_context.auto_stop_code;
for(read_page = current_page ; read_page >= start_page ; read_page --){
text_position.page = read_page;
text_position.offset = 0;
error_code = eb_seek_text(binfo->book, &text_position);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to seek text, %s\n",
eb_error_message(error_code));
return(error_code);
}
memset(data, 0, EB_SIZE_PAGE + 4);
error_code = eb_read_rawtext(binfo->book,
EB_SIZE_PAGE+2,
data,
&length);
if (error_code != EB_SUCCESS || length != EB_SIZE_PAGE+2){
fprintf(stderr, "failed to read rawtext, %s\n",
eb_error_message(error_code));
return(error_code);
}
if(stop_code != -1)
binfo->book->text_context.auto_stop_code = stop_code;
for(i=offset-2 ; i >= 0 ; i -=2){
if(((binfo->appendix != NULL) &&
(eb_uint2(&data[i]) == binfo->appendix->subbook_current->stop_code0) &&
(eb_uint2(&data[i+2]) == binfo->appendix->subbook_current->stop_code1)) ||
((binfo->appendix == NULL) &&
(eb_uint2(&data[i]) == 0x1f41) &&
(eb_uint1(&data[i+2]) == 0x01)) ||
(eb_uint2(&data[i]) == 0x1f02))
#if 0
((eb_uint2(&data[i]) == 0x1f41) &&
(eb_uint2(&data[i+2]) == binfo->book->text_context.auto_stop_code)))
#endif
{
text_position.page = read_page;
text_position.offset = i;
error_code = eb_seek_text(binfo->book, &text_position);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to seek text, %s\n",
eb_error_message(error_code));
return(error_code);
}
if(stop_code != -1)
binfo->book->text_context.auto_stop_code = stop_code;
return(EB_SUCCESS);
}
}
offset = EB_SIZE_PAGE + 2;
}
text_position.page = current_page;
text_position.offset = current_offset;
error_code = eb_seek_text(binfo->book, &text_position);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to seek text, %s\n",
eb_error_message(error_code));
return(error_code);
}
return(EB_ERR_FAIL_SEEK_TEXT);
}
static gint ebook_full_search(BOOK_INFO *binfo, char *word, gint method)
{
EB_Error_Code error_code=EB_SUCCESS;
EB_Position text_position;
char data[EB_SIZE_PAGE];
char *jisword;
char *word_p;
int i, length;
char *p;
char heading[MAXLEN_TEXT + 1];
SEARCH_RESULT *rp;
int start_page;
int end_page;
int current_page;
int stop_code;
int page_count=0;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
start_page = binfo->book->subbook_current->text.start_page;
end_page = binfo->book->subbook_current->text.end_page;
// g_print("start_page = 0x%0x end_page = 0x%0x\n",
// start_page, end_page);
// auto_stop_code $B$r<hF@$9$k$?$a$K$$$C$?$sFI$`(B
p = ebook_get_text(binfo, start_page, 0);
if(p)
free(p);
stop_code = binfo->book->text_context.auto_stop_code;
jisword = locale2jis(word);
word_p = jisword;
for(current_page = start_page ; current_page <= end_page ; current_page ++){
search_progress = (float)(current_page - start_page) / (end_page - start_page + 1);
page_count ++;
text_position.page = current_page;
text_position.offset = 0;
error_code = eb_seek_text(binfo->book, &text_position);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to seek text, %s\n",
eb_error_message(error_code));
return(error_code);
}
error_code = eb_read_rawtext(binfo->book,
EB_SIZE_PAGE,
data,
&length);
if (error_code != EB_SUCCESS || length != EB_SIZE_PAGE){
fprintf(stderr, "failed to read rawtext, %s\n",
eb_error_message(error_code));
return(error_code);
}
for(i=0 ; i < EB_SIZE_PAGE ; i +=2){
// $B@)8fJ8;z$OFI$_$H$P$9(B
if(isjisp(&data[i]) != TRUE){
continue;
// $B0lCW(B
} else if((data[i] == *word_p) &&
(data[i+1] == *(word_p+1))){
// $B8!:w8l$O$^$@B3$$$F$$$k$+(B
if (*(word_p+2) != '\0'){
word_p += 2;
continue;
}
// $BBgJ8;z$H>.J8;z$r6hJL$7$J$$>l9g(B
} else if(full_text_search_ignore_case){
guint c1, c2;
c1 = eb_uint2(&data[i]);
c2 = eb_uint2(word_p);
// $B%"%k%U%!%Y%C%H$J$i(B
if ((0x2341 <= c1) && (c1 <= 0x237a) &&
(0x2341 <= c2) && (c2 <= 0x237a)){
// $B>.J8;z$K$7$F$+$i%^%C%A$5$;$k(B
if(((0x2361 <= c1) ? (c1 - 0x20) : c1) == ((0x2361 <= c2) ? (c2 - 0x20) : c2)){
// $B8!:w8l$O$^$@B3$$$F$$$k$+(B
if (*(word_p+2) != '\0'){
word_p += 2;
continue;
}
} else {
goto NO_MATCH;
}
} else {
goto NO_MATCH;
}
} else {
goto NO_MATCH;
}
// $B0lCW$7$?>l9g(B
// $BFI$_9~$_=hM}(B
text_position.page = current_page;
text_position.offset = i;
// g_print("found at (0x%x, 0x%x)0x%x\n", current_page, i, (current_page - 1) * EB_SIZE_PAGE + i);
error_code = eb_seek_text(binfo->book, &text_position);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to seek text, %s\n",
eb_error_message(error_code));
// $B$J$+$C$?$3$H$K(B...
goto NO_MATCH;
}
// eb_seek_text() $B$G(B auto_stop_code$B$,%/%j%"$5$l$k$?$a!"(B
// $B0JA0$NCM$rI|85$9$k!#(B
if(stop_code != -1)
binfo->book->text_context.auto_stop_code = stop_code;
// error_code = eb_backward_text(binfo->book, binfo->appendix);
error_code = ebook_my_backward_text(binfo);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to back text : %s\n",
eb_error_message(error_code));
// $B$J$+$C$?$3$H$K(B...
goto NO_MATCH;
}
error_code = eb_tell_text(binfo->book, &text_position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to tell text : %s\n",
eb_error_message(error_code));
// $B$J$+$C$?$3$H$K(B...
goto NO_MATCH;
}
// g_print("rewind to (0x%x, 0x%x)\n", text_position.page, text_position.offset);
if(check_duplicate_hit(text_position) == TRUE){
// $B$J$+$C$?$3$H$K(B...
// g_print("duplicate\n");
goto NO_MATCH;
}
error_code = eb_read_text(binfo->book, binfo->appendix, &heading_hookset,
NULL, MAXLEN_TEXT, heading, &length);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read text : %s\n",
eb_error_message(error_code));
// $B$J$+$C$?$3$H$K(B...
goto NO_MATCH;
}
heading[length] = '\0';
p = strchr(heading, '\n');
if(p != NULL)
*p = '\0';
rp = (SEARCH_RESULT *)calloc(sizeof(SEARCH_RESULT),1);
if(rp == NULL){
fprintf(stderr, "No memory\n");
exit(1);
}
rp->heading = strdup(heading);
rp->book_info = binfo;
rp->search_method = method;
rp->pos_heading = text_position;
rp->pos_text = text_position;
search_result = g_list_append(search_result, rp);
if((binfo->book->text_context.auto_stop_code != stop_code) &&
(binfo->book->text_context.auto_stop_code != -1))
stop_code = binfo->book->text_context.auto_stop_code;
hit_count ++;
NO_MATCH:
word_p = jisword;
continue;
}
}
free(jisword);
return(error_code);
}
static gint ebook_full_heading_search(binfo, word){
return 0 ;
}
gint ebook_search2(char *g_word, DICT_GROUP *group){
int j;
int method;
EB_Error_Code error_code=EB_SUCCESS;
BOOK_INFO *binfo;
DICT_MEMBER *member;
GList *member_item=NULL;
gchar *word = strdup(g_word);
clear_search_result();
method = ebook_search_method();
member_item = group->member;
while(member_item != NULL){
member = (DICT_MEMBER *)(member_item->data);
if(member->active != TRUE) {
member_item = g_list_next(member_item);
continue;
}
if(member->binfo == NULL) {
member_item = g_list_next(member_item);
continue;
}
if(member->binfo->available == FALSE) {
member_item = g_list_next(member_item);
continue;
}
binfo = member->binfo;
if(method == SEARCH_METHOD_AUTOMATIC){
for(j=SEARCH_METHOD_MIN ; j<=SEARCH_METHOD_MAX ; j++){
//$BA0J}0lCW!"8eJ}0lCW$O$N$>$/(B
if((j == SEARCH_METHOD_WORD) ||
(j == SEARCH_METHOD_ENDWORD))
continue;
if(binfo->search_method[j] == TRUE){
if(bending_correction == 0){
error_code = ebook_simple_search(binfo, word, j);
} else {
error_code = ebook_ending_search(binfo, word, j);
}
if (error_code != EB_SUCCESS){
if(error_code == EB_ERR_TOO_MANY_WORDS)
continue;
fprintf(stderr, "failed to search : %s\n",
eb_error_message(error_code));
// return(error_code);
}
}
}
} else if((method == SEARCH_METHOD_FULL_TEXT) ||
(method == SEARCH_METHOD_FULL_HEADING)){
error_code = ebook_full_search(binfo, word, method);
} else {
if(binfo->search_method[method] == TRUE){
if(bending_correction == 0){
ebook_simple_search(binfo, word, method);
} else {
ebook_ending_search(binfo, word, method); }
}
}
member_item = g_list_next(member_item);
}
return 0;
}
static void *ebook_search_thread(void *arg)
{
GList *group_item;
DICT_GROUP *group;
char word[MAX_BUFSIZE];
strncpy(word, arg, sizeof(word)-1);
group_item = g_list_first(group_list);
while(group_item != NULL){
group = (DICT_GROUP *)(group_item->data);
if(group->active == TRUE){
break;
}
group_item = g_list_next(group_item);
}
if(group_item == NULL) {
return(0);
}
ebook_search2(word, group);
thread_running = 0;
return NULL ;
}
static void cancel_thread(GtkWidget *widget, gpointer *data)
{
gtk_timeout_remove(tag_timeout);
gtk_grab_remove(cancel_dialog);
gtk_widget_destroy(cancel_dialog);
pthread_cancel(tid);
thread_running = 0;
show_result_tree();
}
static gint show_cancel_dialog()
{
GtkWidget *button;
GtkWidget *label;
GtkAdjustment *adj;
/* int i; */
cancel_dialog = gtk_dialog_new();
gtk_widget_set_usize(cancel_dialog, 200, -1);
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG(cancel_dialog)->vbox), 10);
button = gtk_button_new_with_label(_("Cancel"));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cancel_dialog)->action_area), button,
TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (button), "clicked",
GTK_SIGNAL_FUNC (cancel_thread), (gpointer)NULL);
label = gtk_label_new (_("Searching"));
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cancel_dialog)->vbox), label, TRUE,TRUE, 5);
// progress = gtk_progress_bar_new();
adj = (GtkAdjustment *) gtk_adjustment_new (0, 0, 1, 0, 0, 0);
progress = gtk_progress_bar_new_with_adjustment (adj);
/*
gtk_progress_set_activity_mode(GTK_PROGRESS(progress), TRUE);
gtk_progress_bar_set_activity_step(GTK_PROGRESS_BAR(progress), 5);
gtk_progress_bar_set_activity_blocks(GTK_PROGRESS_BAR(progress), 5);
*/
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cancel_dialog)->vbox), progress, TRUE,TRUE, 5);
label_match = gtk_label_new ("0 hit");
gtk_box_pack_start (GTK_BOX (GTK_DIALOG (cancel_dialog)->vbox), label_match, TRUE,TRUE, 5);
// gtk_window_set_position(GTK_WINDOW(cancel_dialog), GTK_WIN_POS_CENTER_ALWAYS);
gtk_widget_show_all(cancel_dialog);
center_dialog(window, cancel_dialog);
gtk_grab_add(cancel_dialog);
return 0 ;
}
static gint watch_thread(gpointer data){
char msg[256];
/* gchar *label; */
GtkAdjustment *adj;
gfloat new_val;
if(thread_running){
sprintf(msg, _("%d hit"), hit_count);
gtk_label_set_text(GTK_LABEL(label_match), msg);
adj = GTK_PROGRESS (progress)->adjustment;
new_val = adj->value + 1;
if (new_val > adj->upper)
new_val = adj->lower;
// gtk_progress_set_value (GTK_PROGRESS (progress), new_val);
gtk_progress_set_value (GTK_PROGRESS (progress), search_progress);
return(1);
}
gtk_timeout_remove(tag_timeout);
show_result_tree();
gtk_grab_remove(cancel_dialog);
gtk_widget_destroy(cancel_dialog);
return(0);
}
gint ebook_search(char *word)
{
gint rc;
gint method;
void *p ;
size_t size ;
pthread_attr_t thread_attr ;
thread_running = 1;
hit_count = 0;
pthread_attr_init (&thread_attr) ;
pthread_attr_setstacksize (&thread_attr, 512*1024) ;
rc = pthread_create(&tid, &thread_attr, ebook_search_thread, (void *)word);
if(rc != 0){
perror("pthread_create");
exit(1);
}
pthread_attr_destroy(&thread_attr);
method = ebook_search_method();
if(method == SEARCH_METHOD_FULL_TEXT){
show_cancel_dialog();
tag_timeout = gtk_timeout_add(100, watch_thread, NULL);
} else {
pthread_join(tid, &p);
thread_running = 0;
show_result_tree();
}
return 0 ;
}
gint ebook_search_auto(char *g_word)
{
GList *group_item;
DICT_GROUP *group;
gint method;
method = ebook_search_method();
if(method == SEARCH_METHOD_FULL_TEXT)
return(0);
group_item = g_list_first(group_list);
while(group_item != NULL){
group = (DICT_GROUP *)(group_item->data);
if(strcasecmp(group->name, "selection") == 0){
break;
}
group_item = g_list_next(group_item);
}
if(group_item == NULL) {
group_item = g_list_first(group_list);
while(group_item != NULL){
group = (DICT_GROUP *)(group_item->data);
if(group->active == TRUE){
break;
}
group_item = g_list_next(group_item);
}
}
if(group_item == NULL)
return(0);
return ebook_search2(g_word, group);
}
gint ebook_simple_search(BOOK_INFO *binfo, char *word, gint method)
{
EB_Error_Code error_code=EB_SUCCESS;
int i, len, total_hits=0;
EB_Hit hits[MAX_HITS];
int hitcount;
char heading[MAXLEN_HEADING + 1];
char *keywords[EBOOK_MAX_KEYWORDS + 1];
SEARCH_RESULT *rp;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
switch(method){
case SEARCH_METHOD_WORD:
error_code = eb_search_word(binfo->book, word);
break;
case SEARCH_METHOD_ENDWORD:
error_code = eb_search_endword(binfo->book, word);
break;
case SEARCH_METHOD_EXACTWORD:
error_code = eb_search_exactword(binfo->book, word);
break;
case SEARCH_METHOD_KEYWORD:
split_word(word, keywords);
error_code = eb_search_keyword(binfo->book,
(const char * const *)keywords);
free_words(keywords);
break;
case SEARCH_METHOD_MULTI:
split_word(word, keywords);
for(i=0;i<EBOOK_MAX_KEYWORDS;i++){
if(keywords[i] == NULL)
break;
}
error_code = eb_search_multi(binfo->book,
global_multi_code,
(const char * const *)keywords);
free_words(keywords);
break;
default:
error_code = EB_ERR_NO_SUCH_SEARCH;
break;
}
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to search : %s\n",
eb_error_message(error_code));
return(error_code);
}
total_hits = count_result(search_result);
while(1){
error_code = eb_hit_list(binfo->book,
MAX_HITS,
hits,
&hitcount);
if(error_code != EB_SUCCESS){
/*
fprintf(stderr, "an error occurred. : %s\n",
eb_error_message(error_code));
*/
return(error_code);
}
if(hitcount == 0)
break;
for(i = 0 ; i < hitcount ; i ++){
if(total_hits >= max_search)
return(EB_SUCCESS);
if(check_duplicate_hit(hits[i].text) == TRUE)
continue;
rp = (SEARCH_RESULT *)calloc(sizeof(SEARCH_RESULT),1);
if(rp == NULL){
fprintf(stderr, "No memory\n");
exit(1);
}
error_code = eb_seek_text(binfo->book,
&(hits[i].heading));
if(error_code != EB_SUCCESS){
/*
fprintf(stderr, "failed to seek the subbook, %s\n",
eb_error_message(error_code));
*/
return(error_code);
}
error_code = eb_read_heading(binfo->book,
binfo->appendix,
&heading_hookset,
NULL,
MAXLEN_HEADING,
heading,
&len);
if (error_code != EB_SUCCESS) {
/*
fprintf(stderr, "failed to read the subbook, %s\n",
eb_error_message(error_code));
*/
return(error_code);
}
heading[len] = '\0';
rp->heading = strdup(heading);
rp->book_info = binfo;
rp->search_method = method;
rp->pos_heading = hits[i].heading;
rp->pos_text = hits[i].text;
search_result = g_list_append(search_result, rp);
total_hits ++;
}
}
return(error_code);
}
static gint ebook_ending_search(BOOK_INFO *binfo, char *word, gint method)
{
EB_Error_Code error_code=EB_SUCCESS;
gint i;
gint len_word, len_ending;
char *keywords[EBOOK_MAX_KEYWORDS + 1];
char new_word[MAX_BUFSIZE];
char new_key[256];
char *save_key;
ENDING *ending;
GList *list;
g_assert(binfo != NULL);
g_assert(word != NULL);
error_code = ebook_simple_search(binfo, word, method);
if((bending_only_nohit == 1) && (search_result != NULL)){
return(error_code);
}
split_word(word, keywords);
for(i=0; keywords[i] != NULL ; i++){
list = g_list_first(ending_list);
while(list){
ending = (ENDING *)(list->data);
len_word = strlen(keywords[i]);
len_ending = strlen(ending->pattern);
if(len_word < len_ending){
list = g_list_next(list);
continue;
}
if(strcmp(&keywords[i][len_word - len_ending],ending->pattern) == 0){
memcpy(new_key, keywords[i], len_word - len_ending);
sprintf(&new_key[len_word - len_ending],"%s", ending->normal);
save_key = keywords[i];
keywords[i] = new_key;
cat_word(new_word, keywords);
error_code = ebook_simple_search(binfo, new_word, method);
keywords[i] = save_key;
if(error_code != EB_SUCCESS){
return(error_code);
}
}
list = g_list_next(list);
}
}
// $BF|K\8l$N8lHxJd@5(B
// $BF|K\8l$OJ#?t$NC18l$K$O$J$C$F$$$J$$$O$:(B
if((keywords[1] == NULL) &&
(iseuc(keywords[0]))){
if((count_result(search_result) != 0) &&
(bending_only_nohit == 1))
goto END;
list = g_list_first(ending_list_ja);
while(list){
ending = (ENDING *)(list->data);
len_word = strlen(keywords[0]);
len_ending = strlen(ending->pattern);
if(len_word < len_ending){
list = g_list_next(list);
continue;
}
for(i=0; i<len_word; i+=2){
if(strncmp(&keywords[0][i], ending->pattern, len_ending) == 0){
memcpy(new_key, keywords[0], i);
sprintf(&new_key[i],"%s", ending->normal);
error_code = ebook_simple_search(binfo, new_key, method);
if(error_code != EB_SUCCESS){
return(error_code);
}
}
}
list = g_list_next(list);
}
// $B$=$l$G$b0l7o$b%^%C%A$7$J$+$C$?$i!"4A;z$NItJ,$@$1$G8!:w$9$k!#(B
if((count_result(search_result) == 0) &&
(iseuckanji(keywords[0]))){
len_word = strlen(keywords[0]);
strcpy(new_key, keywords[0]);
for(i=0; i<len_word; i+=2){
if(!iseuckanji(&new_key[i])) {
new_key[i] = '\0';
break;
}
}
error_code = ebook_simple_search(binfo, new_key, method);
if(error_code != EB_SUCCESS){
return(error_code);
}
}
}
END:
free_words(keywords);
return(error_code);
}
void clear_search_result()
{
SEARCH_RESULT *rp;
GList *l;
if (!search_result)
return ;
l = g_list_first(search_result);
while(l != NULL){
rp = (SEARCH_RESULT *)(l->data);
if(rp->heading != NULL)
free(rp->heading);
l = g_list_next(l);
}
search_result = NULL;
}
gchar *ebook_get_heading(BOOK_INFO *binfo, int page, int offset)
{
EB_Error_Code error_code;
int len;
char heading[MAXLEN_HEADING + 1];
EB_Position position;
gchar *p;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(NULL);
error_code = eb_seek_text(binfo->book, &position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "Failed to seek text : %s\n",
eb_error_message(error_code));
exit(1);
}
error_code = eb_read_heading(binfo->book, binfo->appendix, &text_hookset, NULL, MAXLEN_HEADING, heading, &len);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "Failed to read heading : %s\n",
eb_error_message(error_code));
exit(1);
}
heading[len] = '\0';
p = malloc(len+1);
memcpy(p, heading, len+1);
return(p);
}
gchar *ebook_get_text(BOOK_INFO *binfo, int page, int offset)
{
EB_Error_Code error_code;
int len;
char text[MAXLEN_TEXT + 1];
EB_Position position;
gchar *p;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(NULL);
position.page = page;
position.offset = offset;
error_code = eb_seek_text(binfo->book, &position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to seek text : %s\n",
eb_error_message(error_code));
return(NULL);
}
error_code = eb_read_text(binfo->book, binfo->appendix, &text_hookset,
NULL, MAXLEN_TEXT, text, &len);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read text : %s\n",
eb_error_message(error_code));
return(NULL);
}
text[len] = '\0';
p = malloc(len+1);
memcpy(p, text, len+1);
return(p);
}
gchar *ebook_get_candidate(BOOK_INFO *binfo, int page, int offset)
{
EB_Error_Code error_code;
int len;
char text[MAXLEN_TEXT + 1];
EB_Position position;
gchar *p;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(NULL);
position.page = page;
position.offset = offset;
error_code = eb_seek_text(binfo->book, &position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to seek text : %s\n",
eb_error_message(error_code));
return(NULL);
}
error_code = eb_read_text(binfo->book, binfo->appendix, &candidate_hookset,
NULL, MAXLEN_TEXT, text, &len);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read text : %s\n",
eb_error_message(error_code));
return(NULL);
}
text[len] = '\0';
p = malloc(len+1);
memcpy(p, text, len+1);
return(p);
}
EB_Error_Code ebook_forward_text(BOOK_INFO *binfo)
{
EB_Error_Code error_code;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
error_code = eb_seek_text(binfo->book, ¤t_position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to seek text : %s\n",
eb_error_message(error_code));
return(error_code);
}
error_code = eb_forward_text(binfo->book, binfo->appendix);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to forward text : %s\n",
eb_error_message(error_code));
return(error_code);
}
return(EB_SUCCESS);
}
EB_Error_Code ebook_backward_text(BOOK_INFO *binfo)
{
EB_Error_Code error_code;
int stop_code = -1;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
stop_code = binfo->book->text_context.auto_stop_code;
error_code = eb_seek_text(binfo->book, ¤t_position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to seek text : %s\n",
eb_error_message(error_code));
return(error_code);
}
if(stop_code != -1)
binfo->book->text_context.auto_stop_code = stop_code;
// error_code = eb_backward_text(binfo->book, binfo->appendix);
error_code = ebook_my_backward_text(binfo);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to back text : %s\n",
eb_error_message(error_code));
return(error_code);
}
return(EB_SUCCESS);
}
void ebook_tell_text(BOOK_INFO *binfo, gint *page, gint *offset)
{
EB_Error_Code error_code;
EB_Position position;
// if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
// return;
error_code = eb_tell_text(binfo->book, &position);
if(error_code != EB_SUCCESS){
fprintf(stderr, "failed to tell text : %s\n",
eb_error_message(error_code));
exit(1);
}
*page = position.page;
*offset = position.offset;
return;
}
void ebook_menu(BOOK_INFO *binfo, EB_Position *pos)
{
EB_Error_Code error_code=EB_SUCCESS;
error_code = eb_menu(binfo->book, pos);
if(error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get menu position : %s\n",
eb_error_message(error_code));
}
}
void ebook_copyright(BOOK_INFO *binfo, EB_Position *pos)
{
EB_Error_Code error_code=EB_SUCCESS;
error_code = eb_copyright(binfo->book, pos);
if(error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get copyright position : %s\n",
eb_error_message(error_code));
}
}
static void ebook_bitmap_to_xbm(const char *bitmap, int width, int height, char *xbm, size_t *xbm_length)
{
char *xbm_p = xbm;
const unsigned char *bitmap_p = (const unsigned char *)bitmap;
int bitmap_size = (width + 7) / 8 * height;
int hex;
int i;
for (i = 0; i < bitmap_size; i++) {
hex = 0;
if (*bitmap_p & 0x80)
hex |= 0x01;
if (*bitmap_p & 0x40)
hex |= 0x02;
if (*bitmap_p & 0x20)
hex |= 0x04;
if (*bitmap_p & 0x10)
hex |= 0x08;
if (*bitmap_p & 0x08)
hex |= 0x10;
if (*bitmap_p & 0x04)
hex |= 0x20;
if (*bitmap_p & 0x02)
hex |= 0x40;
if (*bitmap_p & 0x01)
hex |= 0x80;
bitmap_p++;
*xbm_p = hex;
xbm_p ++;
}
*xbm_length = (xbm_p - xbm);
}
gint check_gaiji_size(BOOK_INFO *binfo, gint prefered_size){
gint size;
size = prefered_size;
switch(size){
case 48:
if (eb_have_font(binfo->book, EB_FONT_48)){
size = 48;
break;
}
size = 30;
case 30:
if (eb_have_font(binfo->book, EB_FONT_30)){
size = 30;
break;
}
size = 24;
case 24:
if (eb_have_font(binfo->book, EB_FONT_24)){
size = 24;
break;
}
size = 16;
case 16:
if (eb_have_font(binfo->book, EB_FONT_16)){
size = 16;
break;
}
fprintf(stderr, "failed to find 16 dot gaiji : subbook=%s\n",
binfo->subbook_title);
return(-1);
}
if(size != prefered_size){
fprintf(stderr, "Cannot find %d dot gaiji. Use %d dot instead\n",
prefered_size, size);
}
return(size);
}
void set_gaiji_size(gint font_size){
BOOK_INFO *binfo;
GList *book_item;
book_item = g_list_first(book_list);
while(book_item != NULL){
binfo = (BOOK_INFO *)(book_item->data);
book_item = g_list_next(book_item);
}
}
guchar *read_gaiji_as_bitmap(BOOK_INFO *binfo, gchar *name, gint size, gint *width, gint *height)
{
EB_Error_Code error_code;
gint char_no;
gchar bitmap_data[EB_SIZE_WIDE_FONT_48];
// char image_data[EB_SIZE_FONT_IMAGE];
guchar *image_data;
size_t image_size;
int image_width;
int image_height;
EB_Subbook *subbook;
// *pixmap = NULL;
// *bitmap = NULL;
char_no = strtol(&name[1], NULL, 16);
subbook = binfo->book->subbook_current;
switch (size) {
case 16:
error_code = eb_set_font(binfo->book, EB_FONT_16);
break;
case 24:
error_code = eb_set_font(binfo->book, EB_FONT_24);
break;
case 30:
error_code = eb_set_font(binfo->book, EB_FONT_30);
break;
case 48:
error_code = eb_set_font(binfo->book, EB_FONT_48);
break;
}
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to set font : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
error_code = eb_font_height(binfo->book, &image_height);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font height : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
if(name[0] == 'h'){
if (!eb_have_narrow_font(binfo->book)){
fprintf(stderr, "%s does not have narrow font\n",
binfo->subbook_title);
return(NULL);
}
error_code = eb_narrow_font_width(binfo->book, &image_width);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font width : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
error_code = eb_narrow_font_character_bitmap(
binfo->book,
char_no,
bitmap_data);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read narrow font : subbook=%s, character=0x%04x\n%s\n",
binfo->subbook_title,
char_no,
eb_error_message(error_code));
return(NULL);
}
} else {
if (!eb_have_wide_font(binfo->book)){
fprintf(stderr, "%s does not have wide font\n",
binfo->subbook_title);
return(NULL);
}
error_code = eb_wide_font_width(binfo->book, &image_width);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font width : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
error_code = eb_wide_font_character_bitmap(
binfo->book,
char_no,
bitmap_data);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read wide font : subbook=%s, character=0x%04x\n%s\n",
binfo->subbook_title,
char_no,
eb_error_message(error_code));
return(NULL);
}
}
image_data = malloc(image_width * image_height / 8);
ebook_bitmap_to_xbm(bitmap_data, image_width,
image_height, image_data, &image_size);
*width = image_width;
*height = image_height;
return(image_data);
}
#define GIF_PREAMBLE_LENGTH 38
static const unsigned char gif_preamble[GIF_PREAMBLE_LENGTH] = {
/*
* Header. (6 bytes)
*/
'G', 'I', 'F', '8', '9', 'a',
/*
* Logical Screen Descriptor. (7 bytes)
* global color table flag = 1.
* color resolution = 1 - 1 = 0.
* sort flag = 0.
* size of global color table = 1 - 1 = 0.
* background color index = 0.
* the pixel aspect ratio = 0 (unused)
* Logical screen width and height are set at run time.
*/
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00,
/*
* Global Color Table. (6 bytes)
* These are set at run time.
*/
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/*
* Graphic Control Extension. (8 bytes)
* disposal method = 0.
* user input flag = 0.
* transparency flag = 1.
* delay time = 0.
* transparent color index = 0.
*/
0x21, 0xf9, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
/*
* Image Descriptor. (10 bytes)
* image left position = 0.
* image top position = 0.
* local color table flag = 0.
* interlace flag = 0.
* sort flag = 0.
* size of local color table = 0.
* Image width and height are set at run time.
*/
0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/*
* Code size. (1byte)
*/
0x03
};
static void ebook_bitmap_to_gif(bitmap, width, height, gif, gif_length, fg, bg)
const char *bitmap;
int width;
int height;
char *gif;
size_t *gif_length;
uint fg;
uint bg;
{
unsigned char *gif_p = (unsigned char *)gif;
const unsigned char *bitmap_p = (const unsigned char *)bitmap;
int i, j;
/*
* Copy the default preamble.
*/
memcpy(gif_p, gif_preamble, GIF_PREAMBLE_LENGTH);
/*
* Set logical screen width and height.
*/
gif_p[6] = width & 0xff;
gif_p[7] = (width >> 8) & 0xff;
gif_p[8] = height & 0xff;
gif_p[9] = (height >> 8) & 0xff;
/*
* Set global colors.
*/
gif_p[13] = (bg >> 16) & 0xff;
gif_p[14] = (bg >> 8) & 0xff;
gif_p[15] = bg & 0xff;
gif_p[16] = (fg >> 16) & 0xff;
gif_p[17] = (fg >> 8) & 0xff;
gif_p[18] = fg & 0xff;
/*
* Set image width and height.
*/
gif_p[32] = width & 0xff;
gif_p[33] = (width >> 8) & 0xff;
gif_p[34] = height & 0xff;
gif_p[35] = (height >> 8) & 0xff;
gif_p += GIF_PREAMBLE_LENGTH;
/*
* Output image data.
*/
for (i = 0; i < height; i++) {
*gif_p++ = (unsigned char)width;
for (j = 0; j + 7 < width; j += 8, bitmap_p++) {
*gif_p++ = (*bitmap_p & 0x80) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x40) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x20) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x10) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x08) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x04) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x02) ? 0x81 : 0x80;
*gif_p++ = (*bitmap_p & 0x01) ? 0x81 : 0x80;
}
if (j < width) {
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x80) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x40) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x20) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x10) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x08) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x04) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x02) ? 0x81 : 0x80;
if (j++ < width)
*gif_p++ = (*bitmap_p & 0x01) ? 0x81 : 0x80;
bitmap_p++;
}
}
/*
* Output a trailer.
*/
memcpy(gif_p, "\001\011\000\073", 4);
gif_p += 4;
if (gif_length != NULL)
*gif_length = ((char *)gif_p - gif);
}
guchar *read_gaiji_as_xbm(BOOK_INFO *binfo, gchar *name, gchar *fname, guint fg, guint bg)
{
EB_Error_Code error_code;
gint char_no;
gchar bitmap_data[EB_SIZE_WIDE_FONT_48];
guchar image_data[EB_SIZE_FONT_IMAGE];
// guchar *image_data;
size_t image_size;
int image_width;
int image_height;
EB_Subbook *subbook;
FILE *fp;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(NULL);
char_no = strtol(&name[1], NULL, 16);
subbook = binfo->book->subbook_current;
error_code = eb_font_height(binfo->book, &image_height);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font height : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
if(name[0] == 'h'){
if (!eb_have_narrow_font(binfo->book)){
fprintf(stderr, "%s does not have narrow font\n",
binfo->subbook_title);
return(NULL);
}
error_code = eb_narrow_font_width(binfo->book, &image_width);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font width : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
error_code = eb_narrow_font_character_bitmap(
binfo->book,
char_no,
bitmap_data);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read narrow font : subbook=%s, character=0x%04x\n%s\n",
binfo->subbook_title,
char_no,
eb_error_message(error_code));
return(NULL);
}
} else {
if (!eb_have_wide_font(binfo->book)){
fprintf(stderr, "%s does not have wide font\n",
binfo->subbook_title);
return(NULL);
}
error_code = eb_wide_font_width(binfo->book, &image_width);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to get font width : subbook=%s\n%s\n",
binfo->subbook_title,
eb_error_message(error_code));
return(NULL);
}
error_code = eb_wide_font_character_bitmap(
binfo->book,
char_no,
bitmap_data);
if (error_code != EB_SUCCESS) {
fprintf(stderr, "failed to read wide font : subbook=%s, character=0x%04x\n%s\n",
binfo->subbook_title,
char_no,
eb_error_message(error_code));
return(NULL);
}
}
ebook_bitmap_to_gif(bitmap_data, image_width,
image_height, image_data, &image_size, fg, bg);
fp = fopen(fname, "w");
if(fp == NULL){
fprintf(stderr, "file open failed : %s\n", fname);
}
fwrite(image_data, image_size, 1, fp);
fclose(fp);
return(NULL);
}
EB_Error_Code ebook_output_wave(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint size)
//EB_Error_Code ebook_output_wave(BOOK_INFO *binfo, gchar *filename, gint start_page, gint start_offset, gint end_page, gint end_offset)
{
EB_Position pos;
char binary_data[EB_SIZE_PAGE];
EB_Error_Code error_code;
EB_Position end_position;
ssize_t read_length;
FILE *fp;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
fp = fopen(filename, "w");
if(fp == NULL){
fprintf(stderr, "failed to open file : %s\n",
filename);
return(EB_ERR_BAD_FILE_NAME);
}
pos.page = page;
pos.offset = offset;
end_position.page = pos.page
+ (size / EB_SIZE_PAGE);
end_position.offset = pos.offset
+ (size % EB_SIZE_PAGE);
if (EB_SIZE_PAGE <= end_position.offset) {
end_position.offset -= EB_SIZE_PAGE;
end_position.page++;
}
/*
* Read sound data.
*/
error_code = eb_set_binary_wave(binfo->book,
&pos, &end_position);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set binary wave : %s\n",
eb_error_message(error_code));
return(error_code);
}
for (;;) {
error_code = eb_read_binary(binfo->book,
EB_SIZE_PAGE,
binary_data, &read_length);
if (error_code != EB_SUCCESS || read_length == 0){
fclose(fp);
return(error_code);
}
// fmt$B%A%c%s%/$NA0$KITMW$J%G!<%?(B(32$B%P%$%H(B)$B$,$"$C$?$i:o=|$9$k(B
if((strncmp("fmt ", &binary_data[44], 4) == 0) &&
(strncmp("fmt ", &binary_data[12], 4) != 0)){
fprintf(stderr, "Warning: extra header found in WAVE data.\n");
fwrite(binary_data, 12, 1, fp);
fwrite(&binary_data[44], read_length - 44, 1, fp);
} else {
fwrite(binary_data, read_length, 1, fp);
}
}
/* not reached */
return(EB_SUCCESS);
}
EB_Error_Code ebook_output_mpeg(BOOK_INFO *binfo, gchar *srcname, gchar *destname)
{
char binary_data[EB_SIZE_PAGE];
guint argv[4];
EB_Error_Code error_code;
ssize_t read_length;
FILE *fp;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
if((error_code = eb_decompose_movie_file_name(argv, srcname)) != EB_SUCCESS)
return(error_code);
fp = fopen(destname, "w");
if(fp == NULL){
fprintf(stderr, "failed to open file : %s\n",
destname);
return(EB_ERR_BAD_FILE_NAME);
}
/*
* Read sound data.
*/
error_code = eb_set_binary_mpeg(binfo->book, argv);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set binary mpeg : %s\n",
eb_error_message(error_code));
return(error_code);
}
for (;;) {
error_code = eb_read_binary(binfo->book,
EB_SIZE_PAGE,
binary_data, &read_length);
if (error_code != EB_SUCCESS || read_length == 0){
fclose(fp);
return(error_code);
}
fwrite(binary_data, read_length, 1, fp);
}
/* not reached */
return(EB_SUCCESS);
}
EB_Error_Code ebook_output_color(BOOK_INFO *binfo, gchar *filename, gint page, gint offset)
{
EB_Position pos;
char binary_data[EB_SIZE_PAGE];
EB_Error_Code error_code;
ssize_t read_length;
FILE *fp;
fp = fopen(filename, "w");
if(fp == NULL){
fprintf(stderr, "failed to open file : %s\n",
filename);
return(EB_ERR_BAD_FILE_NAME);
}
pos.page = page;
pos.offset = offset;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
error_code = eb_set_binary_color_graphic(binfo->book,
&pos);
// $B%9!<%Q!<E}9g<-=q(B2000$B$N4A;z8;$N>l9g$K$O?^HG%G!<%?$,(B
// Honmon2$B$KF~$C$F$$$k$h$&$J$N$G!"(BNO_SUCH_BINARY$B$H$J$k!#(B
// $B$H$j$"$($:$O<+NO$GFI$`$3$H$K$9$k!#(B
if (error_code == EB_ERR_NO_SUCH_BINARY){
gchar *data;
gint file_size;
eb_seek_text(binfo->book, &pos);
error_code = eb_read_rawtext(binfo->book,
8,
binary_data,
&read_length);
if (error_code != EB_SUCCESS || read_length == 0){
return(error_code);
}
if(strncmp(binary_data, "data", 4) == 0){
file_size = *(gint *)&binary_data[4];
data = malloc(file_size);
error_code = eb_read_rawtext(binfo->book,
file_size,
data,
&read_length);
if (error_code != EB_SUCCESS || read_length == 0){
return(error_code);
}
fwrite(data, read_length, 1, fp);
fclose(fp);
free(data);
}
return(EB_SUCCESS);
}
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set binary color graphic : %s\n",
eb_error_message(error_code));
return(error_code);
}
for (;;) {
error_code = eb_read_binary(binfo->book, EB_SIZE_PAGE,
binary_data, &read_length);
if (error_code != EB_SUCCESS || read_length == 0){
fclose(fp);
return(error_code);
}
// output_data(property, binary_data, read_length);
fwrite(binary_data, read_length, 1, fp);
}
/* not reached */
return(EB_SUCCESS);
}
EB_Error_Code ebook_output_gray(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint width, gint height)
{
EB_Position pos;
char binary_data[EB_SIZE_PAGE];
EB_Error_Code error_code;
ssize_t read_length;
FILE *fp;
fp = fopen(filename, "w");
if(fp == NULL){
fprintf(stderr, "failed to open file : %s\n",
filename);
return(EB_ERR_BAD_FILE_NAME);
}
pos.page = page;
pos.offset = offset;
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
error_code = eb_set_binary_gray_graphic(binfo->book,
&pos, width, height);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set binary gray graphic : %s\n",
eb_error_message(error_code));
return(error_code);
}
for (;;) {
error_code = eb_read_binary(binfo->book, EB_SIZE_PAGE,
binary_data, &read_length);
if (error_code != EB_SUCCESS || read_length == 0){
fclose(fp);
return(error_code);
}
// output_data(property, binary_data, read_length);
fwrite(binary_data, read_length, 1, fp);
}
/* not reached */
return(EB_SUCCESS);
}
extern CONTENT_AREA *dict_area;
EB_Error_Code ebook_output_mono(BOOK_INFO *binfo, gchar *filename, gint page, gint offset, gint width, gint height)
{
FILE *fp;
EB_Error_Code error_code;
EB_Position pos;
char *binary_data;
ssize_t read_length;
gint data_size;
gchar *bmp_data;
gint bmp_length;
#ifdef COLOR_HACK
guchar fg[4];
guchar bg[4];
GdkColor color;
// color = window->style->fg[GTK_STATE_NORMAL];
color = dict_area->area->style->fg[GTK_STATE_NORMAL];
fg[0] = (guchar)color.red;
fg[1] = (guchar)color.green;
fg[2] = (guchar)color.blue;
fg[3] = 0x0;
// fg = ((guchar)color.red << 16) | ((guchar)color.green << 8) | ((guchar)color.blue) ;
// color = window->style->bg[GTK_STATE_NORMAL];
color = dict_area->area->style->bg[GTK_STATE_NORMAL];
bg[0] = (guchar)color.red;
bg[1] = (guchar)color.green;
bg[2] = (guchar)color.blue;
bg[3] = 0x0;
// bg = ((guchar)color.red << 16) | ((guchar)color.green << 8) | ((guchar)color.blue) ;
#endif
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(error_code);
fp = fopen(filename, "w");
if(fp == NULL){
fprintf(stderr, "failed to open file : %s\n",
filename);
return(EB_ERR_BAD_FILE_NAME);
}
pos.page = page;
pos.offset = offset;
eb_seek_text(binfo->book, &pos);
error_code = eb_set_binary_mono_graphic(binfo->book,
&pos, width, height);
// &pos, 0, 0);
// $B%9!<%Q!<E}9g<-=q(B2000$B$N4A;z8;$N>l9g$K$O?^HG%G!<%?$,(B
// Honmon2$B$KF~$C$F$$$k$h$&$J$N$G!"(BNO_SUCH_BINARY$B$H$J$k!#(B
// $B$H$j$"$($:$O<+NO$GFI$`$3$H$K$9$k!#(B
// eb-3.3$B$G$O=$@5:Q$_(B
// if ((error_code == EB_ERR_NO_SUCH_BINARY) ||
// (error_code == EB_ERR_FAIL_READ_BINARY)){
if (error_code != EB_SUCCESS){
if((width % 8) != 0)
width = (width / 8)*8 + 8;
data_size = width * height / 8;
binary_data = malloc(data_size);
bmp_data = malloc(data_size*10);
pos.page = page;
pos.offset = offset;
eb_seek_text(binfo->book, &pos);
error_code = eb_read_rawtext(binfo->book,
data_size,
binary_data,
&read_length);
if (error_code != EB_SUCCESS || read_length == 0){
return(error_code);
}
// eb_bitmap_to_xbm(binary_data,
eb_bitmap_to_bmp(binary_data,
width,
height,
bmp_data,
&bmp_length);
fwrite(bmp_data, bmp_length, 1, fp);
#ifdef COLOR_HACK
fseek(fp, 54, SEEK_SET);
fwrite(bg, 4, 1, fp);
fseek(fp, 58, SEEK_SET);
fwrite(fg, 4, 1, fp);
#endif
fclose(fp);
free(binary_data);
free(bmp_data);
return(EB_SUCCESS);
}
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set binary mono : %s\n",
eb_error_message(error_code));
return(error_code);
}
for (;;) {
char binary_data[EB_SIZE_PAGE];
error_code = eb_read_binary(binfo->book,
EB_SIZE_PAGE,
binary_data, &read_length);
if (error_code != EB_SUCCESS || read_length == 0){
fclose(fp);
return(error_code);
}
#ifdef COLOR_HACK
memcpy(&binary_data[54], bg, 4);
memcpy(&binary_data[58], fg, 4);
#endif
fwrite(binary_data, read_length, 1, fp);
}
/* not reached */
fclose(fp);
return(EB_SUCCESS);
}
gchar *ebook_get_rawtext(BOOK_INFO *binfo, gint page, gint offset)
{
EB_Position pos;
char *binary_data;
EB_Error_Code error_code;
ssize_t read_length;
binary_data = malloc(EB_SIZE_PAGE);
if((error_code = ebook_set_subbook(binfo)) != EB_SUCCESS)
return(NULL);
pos.page = page;
pos.offset = offset;
eb_seek_text(binfo->book, &pos);
error_code = eb_read_rawtext(binfo->book,
EB_SIZE_PAGE,
binary_data,
&read_length);
if (error_code != EB_SUCCESS || read_length == 0){
return(NULL);
}
return(binary_data);
}
EB_Error_Code ebook_set_subbook(BOOK_INFO *binfo)
{
EB_Error_Code error_code;
error_code = eb_set_subbook(binfo->book, binfo->subbook_no);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set subbook %s, %d: %s\n",
binfo->book_path, binfo->subbook_no,
eb_error_message(error_code));
return(error_code);
}
if(binfo->appendix != NULL){
error_code = eb_set_appendix_subbook(binfo->appendix,
binfo->appendix_subbook_no);
if (error_code != EB_SUCCESS){
fprintf(stderr, "failed to set appendix subbook : %s\n",
eb_error_message(error_code));
return(error_code);
}
}
return(EB_SUCCESS);
}
syntax highlighted by Code2HTML, v. 0.9.1