summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--FL/Fl_HelpDialog.H54
-rw-r--r--FL/Fl_HelpView.H212
-rw-r--r--configh.in19
-rw-r--r--configure.in34
-rw-r--r--documentation/index.html17
-rw-r--r--documentation/preface.html8
-rw-r--r--makeinclude.in5
-rw-r--r--src/Fl_HelpDialog.cxx223
-rw-r--r--src/Fl_HelpDialog.fl192
-rw-r--r--src/Fl_HelpView.cxx3139
-rw-r--r--src/Makefile10
-rw-r--r--test/Makefile12
-rw-r--r--test/demo.menu1
-rw-r--r--test/help.cxx67
14 files changed, 3967 insertions, 26 deletions
diff --git a/FL/Fl_HelpDialog.H b/FL/Fl_HelpDialog.H
new file mode 100644
index 000000000..05756cbe0
--- /dev/null
+++ b/FL/Fl_HelpDialog.H
@@ -0,0 +1,54 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0100
+
+#ifndef Fl_HelpDialog_H
+#define Fl_HelpDialog_H
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <string.h>
+#include <FL/Fl_HelpView.H>
+#include <FL/Fl_Button.H>
+
+class Fl_HelpDialog {
+ int index_;
+ int max_;
+ int line_[100];
+ char file_[100][256];
+public:
+ Fl_HelpDialog();
+private:
+ Fl_Window *window_;
+ Fl_HelpView *view_;
+ inline void cb_view__i(Fl_HelpView*, void*);
+ static void cb_view_(Fl_HelpView*, void*);
+ inline void cb_Close_i(Fl_Button*, void*);
+ static void cb_Close(Fl_Button*, void*);
+ Fl_Button *back_;
+ inline void cb_back__i(Fl_Button*, void*);
+ static void cb_back_(Fl_Button*, void*);
+ Fl_Button *forward_;
+ inline void cb_forward__i(Fl_Button*, void*);
+ static void cb_forward_(Fl_Button*, void*);
+ Fl_Button *smaller_;
+ inline void cb_smaller__i(Fl_Button*, void*);
+ static void cb_smaller_(Fl_Button*, void*);
+ Fl_Button *larger_;
+ inline void cb_larger__i(Fl_Button*, void*);
+ static void cb_larger_(Fl_Button*, void*);
+public:
+ ~Fl_HelpDialog();
+ int h();
+ void hide();
+ void load(const char *f);
+ void position(int xx, int yy);
+ void resize(int xx, int yy, int ww, int hh);
+ void show();
+ void textsize(uchar s);
+ uchar textsize();
+ void topline(const char *n);
+ void topline(int n);
+ int visible();
+ int w();
+ int x();
+ int y();
+};
+#endif
diff --git a/FL/Fl_HelpView.H b/FL/Fl_HelpView.H
new file mode 100644
index 000000000..6ed53a4a2
--- /dev/null
+++ b/FL/Fl_HelpView.H
@@ -0,0 +1,212 @@
+//
+// "$Id: Fl_HelpView.H,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $"
+//
+// Help Viewer widget definitions.
+//
+// Copyright 1997-2001 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+
+#ifndef _Fl_HelpView_H_
+# define _Fl_HelpView_H_
+
+//
+// Include necessary header files...
+//
+
+# include <stdio.h>
+# include <FL/Fl.H>
+# include <FL/Fl_Group.H>
+# include <FL/Fl_Scrollbar.H>
+# include <FL/fl_draw.H>
+
+
+//
+// Fl_HelpFunc type - link callback function for files...
+//
+
+
+typedef const char *(Fl_HelpFunc)(const char *);
+
+
+//
+// Fl_HelpBlock structure...
+//
+
+struct Fl_HelpBlock
+{
+ const char *start, // Start of text
+ *end; // End of text
+ uchar font, // Text font
+ size, // Text size
+ border; // Draw border?
+ int x, // Indentation/starting X coordinate
+ y, // Starting Y coordinate
+ w, // Width
+ h; // Height
+ int line[32]; // Left starting position for each line
+};
+
+//
+// Fl_HelpLink structure...
+//
+
+struct Fl_HelpLink
+{
+ char filename[192], // Reference filename
+ name[32]; // Link target (blank if none)
+ int x, // X offset of link text
+ y, // Y offset of link text
+ w, // Width of link text
+ h; // Height of link text
+};
+
+//
+// Fl_HelpTarget structure...
+//
+
+struct Fl_HelpTarget
+{
+ char name[32]; // Target name
+ int y; // Y offset of target
+};
+
+//
+// Fl_HelpImage structure...
+//
+
+struct Fl_Pixmap;
+struct Fl_Image;
+
+struct Fl_HelpImage
+{
+ char *name, // Path and name of the image
+ wattr[8], // Width attribute
+ hattr[8]; // Height attribute
+ Fl_Image *image; // FLTK image representation
+ unsigned char *data; // Raw image data
+ int w, h, d; // Image size & depth
+};
+
+//
+// Fl_HelpView class...
+//
+
+class Fl_HelpView : public Fl_Group //// Help viewer widget
+{
+ enum { RIGHT = -1, CENTER, LEFT }; // Alignments
+
+ char title_[1024]; // Title string
+ Fl_Color defcolor_, // Default text color
+ bgcolor_, // Background color
+ textcolor_, // Text color
+ linkcolor_; // Link color
+ uchar textfont_, // Default font for text
+ textsize_; // Default font size
+ const char *value_; // HTML text value
+
+ int nblocks_, // Number of blocks/paragraphs
+ ablocks_; // Allocated blocks
+ Fl_HelpBlock *blocks_; // Blocks
+
+ int nfonts_; // Number of fonts in stack
+ uchar fonts_[100][2]; // Font stack
+
+ Fl_HelpFunc *link_; // Link transform function
+
+ int nlinks_, // Number of links
+ alinks_; // Allocated links
+ Fl_HelpLink *links_; // Links
+
+ int ntargets_, // Number of targets
+ atargets_; // Allocated targets
+ Fl_HelpTarget *targets_; // Targets
+
+ char directory_[1024]; // Directory for current file
+ char filename_[1024]; // Current filename
+ int topline_, // Top line in document
+ size_; // Total document length
+ Fl_Scrollbar scrollbar_; // Vertical scrollbar for document
+
+ int nimage_, // Number of images in a page
+ aimage_; // Allocated blocks
+ Fl_HelpImage *image_; // list of image descriptors
+
+ Fl_HelpImage *add_image(const char *name, const char *wattr,
+ const char *hattr, int make = 1);
+ Fl_HelpImage *find_image(const char *name, const char *wattr,
+ const char *hattr);
+ int load_gif(Fl_HelpImage *img, FILE *fp);
+ int load_jpeg(Fl_HelpImage *img, FILE *fp);
+ int load_png(Fl_HelpImage *img, FILE *fp);
+
+ Fl_HelpBlock *add_block(const char *s, int xx, int yy, int ww, int hh, uchar border = 0);
+ void add_link(const char *n, int xx, int yy, int ww, int hh);
+ void add_target(const char *n, int yy);
+ static int compare_targets(const Fl_HelpTarget *t0, const Fl_HelpTarget *t1);
+ int do_align(Fl_HelpBlock *block, int line, int xx, int a, int &l);
+ void draw();
+ void format();
+ int get_align(const char *p, int a);
+ const char *get_attr(const char *p, const char *n, char *buf, int bufsize);
+ Fl_Color get_color(const char *n, Fl_Color c);
+ int handle(int);
+
+ void initfont(uchar &f, uchar &s) { nfonts_ = 0;
+ fl_font(f = fonts_[0][0] = textfont_,
+ s = fonts_[0][1] = textsize_); }
+ void pushfont(uchar f, uchar s) { if (nfonts_ < 99) nfonts_ ++;
+ fl_font(fonts_[nfonts_][0] = f,
+ fonts_[nfonts_][1] = s); }
+ void popfont(uchar &f, uchar &s) { if (nfonts_ > 0) nfonts_ --;
+ fl_font(f = fonts_[nfonts_][0],
+ s = fonts_[nfonts_][1]); }
+
+ public:
+
+ Fl_HelpView(int xx, int yy, int ww, int hh, const char *l = 0);
+ ~Fl_HelpView();
+ const char *directory() const { if (directory_[0]) return (directory_);
+ else return ((const char *)0); }
+ const char *filename() const { if (filename_[0]) return (filename_);
+ else return ((const char *)0); }
+ void link(Fl_HelpFunc *fn) { link_ = fn; }
+ int load(const char *f);
+ void resize(int,int,int,int);
+ int size() const { return (size_); }
+ void textcolor(Fl_Color c) { if (textcolor_ == defcolor_) textcolor_ = c; defcolor_ = c; }
+ Fl_Color textcolor() const { return (defcolor_); }
+ void textfont(uchar f) { textfont_ = f; format(); }
+ uchar textfont() const { return (textfont_); }
+ void textsize(uchar s) { textsize_ = s; format(); }
+ uchar textsize() const { return (textsize_); }
+ const char *title() { return (title_); }
+ void topline(const char *n);
+ void topline(int);
+ int topline() const { return (topline_); }
+ void value(const char *v);
+ const char *value() const { return (value_); }
+};
+
+#endif // !_Fl_HelpView_H_
+
+//
+// End of "$Id: Fl_HelpView.H,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $".
+//
diff --git a/configh.in b/configh.in
index 22e9a0c49..0785b6ebe 100644
--- a/configh.in
+++ b/configh.in
@@ -1,5 +1,5 @@
/*
- * "$Id: configh.in,v 1.11.2.11 2001/04/30 17:17:01 easysw Exp $"
+ * "$Id: configh.in,v 1.11.2.11.2.1 2001/08/02 19:43:49 easysw Exp $"
*
* Configuration file for the Fast Light Tool Kit (FLTK).
* @configure_input@
@@ -177,5 +177,20 @@
#define USE_POLL 0
/*
- * End of "$Id: configh.in,v 1.11.2.11 2001/04/30 17:17:01 easysw Exp $".
+ * Do we have various image libraries?
+ */
+
+#undef HAVE_LIBPNG
+#undef HAVE_LIBZ
+#undef HAVE_LIBJPEG
+
+/*
+ * Do we have the png_get_valid() function?
+ */
+
+#undef HAVE_PNG_GET_VALID
+
+
+/*
+ * End of "$Id: configh.in,v 1.11.2.11.2.1 2001/08/02 19:43:49 easysw Exp $".
*/
diff --git a/configure.in b/configure.in
index a750e4a10..9ab9704eb 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
dnl -*- sh -*-
dnl the "configure" script is made from this by running GNU "autoconf"
dnl
-dnl "$Id: configure.in,v 1.33.2.31.2.2 2001/08/02 18:15:44 easysw Exp $"
+dnl "$Id: configure.in,v 1.33.2.31.2.3 2001/08/02 19:43:49 easysw Exp $"
dnl
dnl Configuration script for the Fast Light Tool Kit (FLTK).
dnl
@@ -159,6 +159,36 @@ AC_CHECK_FUNCS(vsprintf)
AC_CHECK_HEADER(strings.h,AC_DEFINE(HAVE_STRINGS_H))
AC_CHECK_FUNCS(strcasecmp)
+dnl Check for image libraries...
+SAVELIBS="$LIBS"
+IMAGELIBS=""
+
+AC_SUBST(IMAGELIBS)
+
+AC_CHECK_HEADER(jpeglib.h,
+ AC_CHECK_LIB(jpeg, jpeg_destroy_decompress,
+ AC_DEFINE(HAVE_LIBJPEG)
+ IMAGELIBS="$IMAGELIBS -ljpeg"))
+
+AC_CHECK_HEADER(zlib.h,
+ AC_CHECK_LIB(z, gzopen,
+ AC_DEFINE(HAVE_LIBZ)
+ IMAGELIBS="$IMAGELIBS -lz"
+ LIBS="$LIBS -lz"))
+
+dnl PNG library uses math library functions...
+AC_CHECK_LIB(m, pow)
+
+AC_CHECK_HEADER(png.h,
+ AC_CHECK_LIB(png, png_read_rows,
+ AC_DEFINE(HAVE_LIBPNG)
+ IMAGELIBS="-lpng -lm$IMAGELIBS"
+ LIBS="-lpng -lm $LIBS"
+ AC_CHECK_FUNCS(png_get_valid)))
+
+dnl Restore original LIBS settings...
+LIBS="$SAVELIBS"
+
dnl Check for X11...
AC_PATH_XTRA
@@ -403,5 +433,5 @@ AC_CONFIG_HEADER(config.h:configh.in)
AC_OUTPUT(makeinclude)
dnl
-dnl End of "$Id: configure.in,v 1.33.2.31.2.2 2001/08/02 18:15:44 easysw Exp $".
+dnl End of "$Id: configure.in,v 1.33.2.31.2.3 2001/08/02 19:43:49 easysw Exp $".
dnl
diff --git a/documentation/index.html b/documentation/index.html
index a9ea4d072..90e20318c 100644
--- a/documentation/index.html
+++ b/documentation/index.html
@@ -1,20 +1,21 @@
<HTML>
<HEAD><meta name="robots" content="noindex">
- <TITLE>FLTK 1.0.11 Programming Manual</TITLE>
+ <TITLE>FLTK 1.1.0 Programming Manual</TITLE>
</HEAD>
<BODY>
<CENTER><TABLE WIDTH=90% BGCOLOR=#9f9f9f CELLPADDING=8 CELLSPACING=0 SUMMARY="TITLE BAR">
<TR>
-<TD ALIGN=CENTER VALIGN=MIDDLE><IMG SRC="FL.gif" ALIGN="ABSMIDDLE" ALT="FL"></TD>
-<TD ALIGN=CENTER VALIGN=MIDDLE>
-<H1>FLTK 1.0.11 Programming Manual</H1>
-Revision 18 by Michael Sweet, Craig P. Earls, and Bill Spitzak<BR>
+<TD ALIGN=CENTER VALIGN=MIDDLE WIDTH=100><IMG SRC="FL.gif" WIDTH=100 HEIGHT=70 ALIGN="ABSMIDDLE" ALT="FL"></TD>
+<TD ALIGN=CENTER VALIGN=MIDDLE WIDTH=500>
+<H1>FLTK 1.1.0 Programming Manual</H1>
+Revision 0 by Michael Sweet, Craig P. Earls, and Bill Spitzak<BR>
Copyright 1998-2001 by Bill Spitzak and others.<BR>
</TD>
</TR>
+<TABLE WIDTH=90% BGCOLOR=#9f9f9f CELLPADDING=8 CELLSPACING=0 SUMMARY="TITLE BAR">
<TR>
-<TD ALIGN=CENTER COLSPAN=2>
+<TD ALIGN=CENTER WIDTH=600>
This software is provided under the terms of the GNU Library General
Public License.
</TD>
@@ -23,7 +24,7 @@ Public License.
<CENTER><TABLE WIDTH=90% COLS=2 BGCOLOR=#9f9fef CELLPADDING=8 CELLSPACING=0 SUMMARY="Table of Contents">
<TR>
-<TD ALIGN=LEFT VALIGN=TOP>
+<TD ALIGN=LEFT VALIGN=TOP WIDTH=300>
<B><A HREF=preface.html#preface>Preface</A></B>
<BR>
<BR>
@@ -55,7 +56,7 @@ Public License.
<B><A HREF=subclassing.html#subclassing>7 - Adding and Extending
Widgets</A></B>
</TD>
-<TD ALIGN=LEFT VALIGN=TOP>
+<TD ALIGN=LEFT VALIGN=TOP WIDTH=300>
<B><A HREF=fluid.html#FLUID>8 - Programming with FLUID</A></B>
<UL>
<LI><A HREF=fluid.html#widget_attributes>Widget Attributes</A></LI>
diff --git a/documentation/preface.html b/documentation/preface.html
index 7d24de52d..9635d16d8 100644
--- a/documentation/preface.html
+++ b/documentation/preface.html
@@ -2,13 +2,13 @@
<HEAD>
<META CONTENT="Written by Michael Sweet, Craig P. Earls, and Bill Spitzak" NAME="Author">
<META CONTENT="Copyright 1998-2001 by Bill Spitzak and Others." NAME="Copyright">
- <META CONTENT="Revision 18" NAME="DocNumber">
- <TITLE>FLTK 1.0.11 Programming Manual</TITLE>
+ <META CONTENT="Revision 0" NAME="DocNumber">
+ <TITLE>FLTK 1.1.0 Programming Manual</TITLE>
</HEAD>
<BODY>
<H1 ALIGN=RIGHT><A NAME=preface>Preface</A></H1>
This manual describes the Fast Light Tool Kit (&quot;FLTK&quot;)
-version 1.0.11, a C++ Graphical User Interface
+version 1.1.0, a C++ Graphical User Interface
(&quot;GUI&quot;) toolkit for UNIX and Microsoft Windows. Each
of the chapters in this manual is designed as a tutorial for
using FLTK, while the appendices provide a convenient reference
@@ -57,7 +57,7 @@ Reference</A></LI>
<DD>The Microsoft Windows 32-bit Application Programmer's Interface.</DD>
</DL>
<H2>Copyrights and Trademarks</H2>
- FLTK is Copyright 1998-2000 by Bill Spitzak and others. Use and
+ FLTK is Copyright 1998-2001 by Bill Spitzak and others. Use and
distribution of FLTK is governed by the GNU Library General Public
License, located in <A HREF=license.html#license>Appendix G</A>.
<P>UNIX is a registered trademark of the X Open Group, Inc. Microsoft
diff --git a/makeinclude.in b/makeinclude.in
index 97d543bd9..e48b94f07 100644
--- a/makeinclude.in
+++ b/makeinclude.in
@@ -1,5 +1,5 @@
#
-# "$Id: makeinclude.in,v 1.7.2.11.2.2 2001/08/02 18:15:44 easysw Exp $"
+# "$Id: makeinclude.in,v 1.7.2.11.2.3 2001/08/02 19:43:49 easysw Exp $"
#
# Make include file for the Fast Light Tool Kit (FLTK).
# @configure_input@
@@ -61,6 +61,7 @@ LDLIBS =@LDFLAGS@ @LIBS@ -lX11 -lXext @X_EXTRA_LIBS@ -lm
GLDLIBS =@LDFLAGS@ @LIBS@ @GLLIB@ -lX11 -lXext @X_EXTRA_LIBS@ -lm
LINKFLTK =-L../lib @LINKFLTK@
LINKFLTKGL =-L../lib @LINKFLTKGL@
+IMAGELIBS =@IMAGELIBS@
# Do we build the OpenGL demos?
GLDEMOS =@GLDEMOS@
@@ -100,5 +101,5 @@ CAT3EXT =@CAT3EXT@
mv t.z $@
#
-# End of "$Id: makeinclude.in,v 1.7.2.11.2.2 2001/08/02 18:15:44 easysw Exp $".
+# End of "$Id: makeinclude.in,v 1.7.2.11.2.3 2001/08/02 19:43:49 easysw Exp $".
#
diff --git a/src/Fl_HelpDialog.cxx b/src/Fl_HelpDialog.cxx
new file mode 100644
index 000000000..731961d24
--- /dev/null
+++ b/src/Fl_HelpDialog.cxx
@@ -0,0 +1,223 @@
+// generated by Fast Light User Interface Designer (fluid) version 1.0100
+
+#include "../FL/Fl_HelpDialog.H"
+
+inline void Fl_HelpDialog::cb_view__i(Fl_HelpView*, void*) {
+ if (view_->changed())
+{
+ index_ ++;
+
+ if (index_ >= 100)
+ {
+ memcpy(line_, line_ + 10, sizeof(line_[0]) * 90);
+ memcpy(file_, file_ + 10, sizeof(file_[0]) * 90);
+ index_ -= 10;
+ }
+
+ max_ = index_;
+
+ strcpy(file_[index_], view_->filename());
+ line_[index_] = view_->topline();
+
+ if (index_ > 0)
+ back_->activate();
+ else
+ back_->deactivate();
+
+ forward_->deactivate();
+ window_->label(view_->title());
+}
+else if (view_->filename())
+{
+ strncpy(file_[index_], view_->filename(), 255);
+ file_[index_][255] = '\0';
+ line_[index_] = view_->topline();
+};
+}
+void Fl_HelpDialog::cb_view_(Fl_HelpView* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_view__i(o,v);
+}
+
+inline void Fl_HelpDialog::cb_Close_i(Fl_Button*, void*) {
+ window_->hide();
+}
+void Fl_HelpDialog::cb_Close(Fl_Button* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_Close_i(o,v);
+}
+
+inline void Fl_HelpDialog::cb_back__i(Fl_Button*, void*) {
+ if (index_ > 0)
+ index_ --;
+
+if (index_ == 0)
+ back_->deactivate();
+
+forward_->activate();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+ view_->load(file_[index_]);
+
+view_->topline(line_[index_]);
+}
+void Fl_HelpDialog::cb_back_(Fl_Button* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_back__i(o,v);
+}
+
+inline void Fl_HelpDialog::cb_forward__i(Fl_Button*, void*) {
+ if (index_ < max_)
+ index_ ++;
+
+if (index_ >= max_)
+ forward_->deactivate();
+
+back_->activate();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+ view_->load(file_[index_]);
+
+view_->topline(line_[index_]);
+}
+void Fl_HelpDialog::cb_forward_(Fl_Button* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_forward__i(o,v);
+}
+
+inline void Fl_HelpDialog::cb_smaller__i(Fl_Button*, void*) {
+ if (view_->textsize() > 8)
+ view_->textsize(view_->textsize() - 2);
+
+if (view_->textsize() <= 8)
+ smaller_->deactivate();
+larger_->activate();
+}
+void Fl_HelpDialog::cb_smaller_(Fl_Button* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_smaller__i(o,v);
+}
+
+inline void Fl_HelpDialog::cb_larger__i(Fl_Button*, void*) {
+ if (view_->textsize() < 18)
+ view_->textsize(view_->textsize() + 2);
+
+if (view_->textsize() >= 18)
+ larger_->deactivate();
+smaller_->activate();
+}
+void Fl_HelpDialog::cb_larger_(Fl_Button* o, void* v) {
+ ((Fl_HelpDialog*)(o->parent()->user_data()))->cb_larger__i(o,v);
+}
+
+Fl_HelpDialog::Fl_HelpDialog() {
+ Fl_Window* w;
+ { Fl_Window* o = window_ = new Fl_Window(530, 385, "Help Dialog");
+ w = o;
+ o->user_data((void*)(this));
+ { Fl_HelpView* o = view_ = new Fl_HelpView(10, 10, 510, 330);
+ o->box(FL_DOWN_BOX);
+ o->callback((Fl_Callback*)cb_view_);
+ o->end();
+ Fl_Group::current()->resizable(o);
+ }
+ { Fl_Button* o = new Fl_Button(425, 350, 95, 25, "Close");
+ o->callback((Fl_Callback*)cb_Close);
+ }
+ { Fl_Button* o = back_ = new Fl_Button(365, 350, 25, 25, "@<-");
+ o->shortcut(0xff51);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(2);
+ o->callback((Fl_Callback*)cb_back_);
+ }
+ { Fl_Button* o = forward_ = new Fl_Button(395, 350, 25, 25, "@->");
+ o->shortcut(0xff53);
+ o->labeltype(FL_SYMBOL_LABEL);
+ o->labelcolor(2);
+ o->callback((Fl_Callback*)cb_forward_);
+ }
+ { Fl_Button* o = smaller_ = new Fl_Button(305, 350, 25, 25, "F");
+ o->labelfont(1);
+ o->labelsize(10);
+ o->callback((Fl_Callback*)cb_smaller_);
+ }
+ { Fl_Button* o = larger_ = new Fl_Button(335, 350, 25, 25, "F");
+ o->labelfont(1);
+ o->labelsize(16);
+ o->callback((Fl_Callback*)cb_larger_);
+ }
+ o->end();
+ }
+ back_->deactivate();
+forward_->deactivate();
+
+index_ = -1;
+max_ = 0;
+}
+
+Fl_HelpDialog::~Fl_HelpDialog() {
+ delete window_;
+}
+
+int Fl_HelpDialog::h() {
+ return (window_->h());
+}
+
+void Fl_HelpDialog::hide() {
+ window_->hide();
+}
+
+void Fl_HelpDialog::load(const char *f) {
+ view_->set_changed();
+view_->load(f);
+window_->label(view_->title());
+}
+
+void Fl_HelpDialog::position(int xx, int yy) {
+ window_->position(xx, yy);
+}
+
+void Fl_HelpDialog::resize(int xx, int yy, int ww, int hh) {
+ window_->resize(xx, yy, ww, hh);
+}
+
+void Fl_HelpDialog::show() {
+ window_->show();
+}
+
+void Fl_HelpDialog::textsize(uchar s) {
+ view_->textsize(s);
+
+if (s <= 8)
+ smaller_->deactivate();
+else
+ smaller_->activate();
+
+if (s >= 18)
+ larger_->deactivate();
+else
+ larger_->activate();
+}
+
+uchar Fl_HelpDialog::textsize() {
+ return (view_->textsize());
+}
+
+void Fl_HelpDialog::topline(const char *n) {
+ view_->topline(n);
+}
+
+void Fl_HelpDialog::topline(int n) {
+ view_->topline(n);
+}
+
+int Fl_HelpDialog::visible() {
+ return (window_->visible());
+}
+
+int Fl_HelpDialog::w() {
+ return (window_->w());
+}
+
+int Fl_HelpDialog::x() {
+ return (window_->x());
+}
+
+int Fl_HelpDialog::y() {
+ return (window_->y());
+}
diff --git a/src/Fl_HelpDialog.fl b/src/Fl_HelpDialog.fl
new file mode 100644
index 000000000..a9fc18c71
--- /dev/null
+++ b/src/Fl_HelpDialog.fl
@@ -0,0 +1,192 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0100
+header_name {../FL/Fl_HelpDialog.H}
+code_name {.cxx}
+gridx 5
+gridy 5
+snap 3
+class Fl_HelpDialog {open
+} {
+ decl {int index_;} {}
+ decl {int max_;} {}
+ decl {int line_[100];} {}
+ decl {char file_[100][256];} {}
+ Function {Fl_HelpDialog()} {open
+ } {
+ Fl_Window window_ {
+ label {Help Dialog} open
+ private xywh {470 402 530 385} resizable
+ code0 {\#include <string.h>} visible
+ } {
+ Fl_Group view_ {
+ callback {if (view_->changed())
+{
+ index_ ++;
+
+ if (index_ >= 100)
+ {
+ memcpy(line_, line_ + 10, sizeof(line_[0]) * 90);
+ memcpy(file_, file_ + 10, sizeof(file_[0]) * 90);
+ index_ -= 10;
+ }
+
+ max_ = index_;
+
+ strcpy(file_[index_], view_->filename());
+ line_[index_] = view_->topline();
+
+ if (index_ > 0)
+ back_->activate();
+ else
+ back_->deactivate();
+
+ forward_->deactivate();
+ window_->label(view_->title());
+}
+else if (view_->filename())
+{
+ strncpy(file_[index_], view_->filename(), 255);
+ file_[index_][255] = '\\0';
+ line_[index_] = view_->topline();
+}} open
+ private xywh {10 10 510 330} box DOWN_BOX resizable
+ code0 {\#include <FL/Fl_HelpView.H>}
+ class Fl_HelpView
+ } {}
+ Fl_Button {} {
+ label Close
+ callback {window_->hide();}
+ xywh {425 350 95 25}
+ }
+ Fl_Button back_ {
+ label {@<-}
+ callback {if (index_ > 0)
+ index_ --;
+
+if (index_ == 0)
+ back_->deactivate();
+
+forward_->activate();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+ view_->load(file_[index_]);
+
+view_->topline(line_[index_]);}
+ private xywh {365 350 25 25} shortcut 0xff51 labeltype SYMBOL_LABEL labelcolor 2
+ }
+ Fl_Button forward_ {
+ label {@->}
+ callback {if (index_ < max_)
+ index_ ++;
+
+if (index_ >= max_)
+ forward_->deactivate();
+
+back_->activate();
+
+if (strcmp(view_->filename(), file_[index_]) != 0)
+ view_->load(file_[index_]);
+
+view_->topline(line_[index_]);}
+ private xywh {395 350 25 25} shortcut 0xff53 labeltype SYMBOL_LABEL labelcolor 2
+ }
+ Fl_Button smaller_ {
+ label F
+ callback {if (view_->textsize() > 8)
+ view_->textsize(view_->textsize() - 2);
+
+if (view_->textsize() <= 8)
+ smaller_->deactivate();
+larger_->activate();}
+ private xywh {305 350 25 25} labelfont 1 labelsize 10
+ }
+ Fl_Button larger_ {
+ label F
+ callback {if (view_->textsize() < 18)
+ view_->textsize(view_->textsize() + 2);
+
+if (view_->textsize() >= 18)
+ larger_->deactivate();
+smaller_->activate();}
+ private xywh {335 350 25 25} labelfont 1 labelsize 16
+ }
+ }
+ code {back_->deactivate();
+forward_->deactivate();
+
+index_ = -1;
+max_ = 0;} {}
+ }
+ Function {~Fl_HelpDialog()} {selected
+ } {
+ code {delete window_;} {}
+ }
+ Function {h()} {return_type int
+ } {
+ code {return (window_->h());} {}
+ }
+ Function {hide()} {return_type void
+ } {
+ code {window_->hide();} {}
+ }
+ Function {load(const char *f)} {return_type void
+ } {
+ code {view_->set_changed();
+view_->load(f);
+window_->label(view_->title());} {}
+ }
+ Function {position(int xx, int yy)} {return_type void
+ } {
+ code {window_->position(xx, yy);} {}
+ }
+ Function {resize(int xx, int yy, int ww, int hh)} {return_type void
+ } {
+ code {window_->resize(xx, yy, ww, hh);} {}
+ }
+ Function {show()} {return_type void
+ } {
+ code {window_->show();} {}
+ }
+ Function {textsize(uchar s)} {return_type void
+ } {
+ code {view_->textsize(s);
+
+if (s <= 8)
+ smaller_->deactivate();
+else
+ smaller_->activate();
+
+if (s >= 18)
+ larger_->deactivate();
+else
+ larger_->activate();} {}
+ }
+ Function {textsize()} {return_type uchar
+ } {
+ code {return (view_->textsize());} {}
+ }
+ Function {topline(const char *n)} {return_type void
+ } {
+ code {view_->topline(n);} {}
+ }
+ Function {topline(int n)} {return_type void
+ } {
+ code {view_->topline(n);} {}
+ }
+ Function {visible()} {return_type int
+ } {
+ code {return (window_->visible());} {}
+ }
+ Function {w()} {return_type int
+ } {
+ code {return (window_->w());} {}
+ }
+ Function {x()} {return_type int
+ } {
+ code {return (window_->x());} {}
+ }
+ Function {y()} {return_type int
+ } {
+ code {return (window_->y());} {}
+ }
+}
diff --git a/src/Fl_HelpView.cxx b/src/Fl_HelpView.cxx
new file mode 100644
index 000000000..6b074f932
--- /dev/null
+++ b/src/Fl_HelpView.cxx
@@ -0,0 +1,3139 @@
+//
+// "$Id: Fl_HelpView.cxx,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $"
+//
+// Fl_HelpView widget routines.
+//
+// Copyright 1997-2001 by Easy Software Products.
+// Image support donated by Matthias Melcher, Copyright 2000.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+// Contents:
+//
+// Fl_HelpView::add_block() - Add a text block to the list.
+// Fl_HelpView::add_image() - Add an image to the image cache.
+// Fl_HelpView::add_link() - Add a new link to the list.
+// Fl_HelpView::add_target() - Add a new target to the list.
+// Fl_HelpView::compare_targets() - Compare two targets.
+// Fl_HelpView::do_align() - Compute the alignment for a line in
+// a block.
+// Fl_HelpView::draw() - Draw the Fl_HelpView widget.
+// Fl_HelpView::find_image() - Find an image by name
+// Fl_HelpView::format() - Format the help text.
+// Fl_HelpView::get_align() - Get an alignment attribute.
+// Fl_HelpView::get_attr() - Get an attribute value from the string.
+// Fl_HelpView::get_color() - Get an alignment attribute.
+// Fl_HelpView::handle() - Handle events in the widget.
+// Fl_HelpView::Fl_HelpView() - Build a Fl_HelpView widget.
+// Fl_HelpView::~Fl_HelpView() - Destroy a Fl_HelpView widget.
+// Fl_HelpView::load() - Load the specified file.
+// Fl_HelpView::load_gif() - Load a GIF image file...
+// Fl_HelpView::load_jpeg() - Load a JPEG image file.
+// Fl_HelpView::load_png() - Load a PNG image file.
+// Fl_HelpView::resize() - Resize the help widget.
+// Fl_HelpView::topline() - Set the top line to the named target.
+// Fl_HelpView::topline() - Set the top line by number.
+// Fl_HelpView::value() - Set the help text directly.
+// gif_read_cmap() - Read the colormap from a GIF file...
+// gif_get_block() - Read a GIF data block...
+// gif_get_code() - Get a LZW code from the file...
+// gif_read_lzw() - Read a byte from the LZW stream...
+// gif_read_image() - Read a GIF image stream...
+// scrollbar_callback() - A callback for the scrollbar.
+//
+
+//
+// Include necessary header files...
+//
+
+#include <FL/Fl_HelpView.H>
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+
+#include <FL/Fl_Image.H>
+#include <FL/Fl_Pixmap.H>
+
+#if defined(WIN32)
+# include <io.h>
+# include <direct.h>
+# define strcasecmp(s,t) stricmp((s), (t))
+# define strncasecmp(s,t,n) strnicmp((s), (t), (n))
+#elif defined(__EMX__)
+# define strcasecmp(s,t) stricmp((s), (t))
+# define strncasecmp(s,t,n) strnicmp((s), (t), (n))
+#else
+# include <unistd.h>
+#endif // WIN32
+
+extern "C"
+{
+#ifdef HAVE_LIBPNG
+# include <zlib.h>
+# include <png.h>
+#endif // HAVE_LIBPNG
+
+#ifdef HAVE_LIBJPEG
+# include <jpeglib.h>
+#endif // HAVE_LIBJPEG
+}
+
+//
+// Typedef the C API sort function type the only way I know how...
+//
+
+extern "C"
+{
+ typedef int (*compare_func_t)(const void *, const void *);
+}
+
+//
+// GIF definitions...
+//
+
+#define GIF_INTERLACE 0x40
+#define GIF_COLORMAP 0x80
+
+typedef unsigned char gif_cmap_t[256][3];
+
+
+//
+// Local globals...
+//
+
+static const char *broken_xpm[] =
+ {
+ "16 24 4 1",
+ "@ c #000000",
+ " c #ffffff",
+ "+ c none",
+ "x c #ff0000",
+ // pixels
+ "@@@@@@@+++++++++",
+ "@ @++++++++++",
+ "@ @+++++++++++",
+ "@ @++@++++++++",
+ "@ @@+++++++++",
+ "@ @+++@+++++",
+ "@ @++@@++++@",
+ "@ xxx @@ @++@@",
+ "@ xxx xx@@ @",
+ "@ xxx xxx @",
+ "@ xxxxxx @",
+ "@ xxxx @",
+ "@ xxxxxx @",
+ "@ xxx xxx @",
+ "@ xxx xxx @",
+ "@ xxx xxx @",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@ @",
+ "@@@@@@@@@@@@@@@@",
+ NULL
+ };
+
+static Fl_Pixmap *broken_image = (Fl_Pixmap *)0;
+static int gif_eof = 0; // Did we hit EOF?
+static unsigned fltk_colors[] =
+ {
+ 0x00000000,
+ 0xff000000,
+ 0x00ff0000,
+ 0xffff0000,
+ 0x0000ff00,
+ 0xff00ff00,
+ 0x00ffff00,
+ 0xffffff00,
+ 0x55555500,
+ 0xc6717100,
+ 0x71c67100,
+ 0x8e8e3800,
+ 0x7171c600,
+ 0x8e388e00,
+ 0x388e8e00,
+ 0xaaaaaa00,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x55555500,
+ 0x00000000,
+ 0x0d0d0d00,
+ 0x1a1a1a00,
+ 0x26262600,
+ 0x31313100,
+ 0x3d3d3d00,
+ 0x48484800,
+ 0x55555500,
+ 0x5f5f5f00,
+ 0x6a6a6a00,
+ 0x75757500,
+ 0x80808000,
+ 0x8a8a8a00,
+ 0x95959500,
+ 0xa0a0a000,
+ 0xaaaaaa00,
+ 0xb5b5b500,
+ 0xc0c0c000,
+ 0xcbcbcb00,
+ 0xd5d5d500,
+ 0xe0e0e000,
+ 0xeaeaea00,
+ 0xf5f5f500,
+ 0xffffff00,
+ 0x00000000,
+ 0x00240000,
+ 0x00480000,
+ 0x006d0000,
+ 0x00910000,
+ 0x00b60000,
+ 0x00da0000,
+ 0x00ff0000,
+ 0x3f000000,
+ 0x3f240000,
+ 0x3f480000,
+ 0x3f6d0000,
+ 0x3f910000,
+ 0x3fb60000,
+ 0x3fda0000,
+ 0x3fff0000,
+ 0x7f000000,
+ 0x7f240000,
+ 0x7f480000,
+ 0x7f6d0000,
+ 0x7f910000,
+ 0x7fb60000,
+ 0x7fda0000,
+ 0x7fff0000,
+ 0xbf000000,
+ 0xbf240000,
+ 0xbf480000,
+ 0xbf6d0000,
+ 0xbf910000,
+ 0xbfb60000,
+ 0xbfda0000,
+ 0xbfff0000,
+ 0xff000000,
+ 0xff240000,
+ 0xff480000,
+ 0xff6d0000,
+ 0xff910000,
+ 0xffb60000,
+ 0xffda0000,
+ 0xffff0000,
+ 0x00003f00,
+ 0x00243f00,
+ 0x00483f00,
+ 0x006d3f00,
+ 0x00913f00,
+ 0x00b63f00,
+ 0x00da3f00,
+ 0x00ff3f00,
+ 0x3f003f00,
+ 0x3f243f00,
+ 0x3f483f00,
+ 0x3f6d3f00,
+ 0x3f913f00,
+ 0x3fb63f00,
+ 0x3fda3f00,
+ 0x3fff3f00,
+ 0x7f003f00,
+ 0x7f243f00,
+ 0x7f483f00,
+ 0x7f6d3f00,
+ 0x7f913f00,
+ 0x7fb63f00,
+ 0x7fda3f00,
+ 0x7fff3f00,
+ 0xbf003f00,
+ 0xbf243f00,
+ 0xbf483f00,
+ 0xbf6d3f00,
+ 0xbf913f00,
+ 0xbfb63f00,
+ 0xbfda3f00,
+ 0xbfff3f00,
+ 0xff003f00,
+ 0xff243f00,
+ 0xff483f00,
+ 0xff6d3f00,
+ 0xff913f00,
+ 0xffb63f00,
+ 0xffda3f00,
+ 0xffff3f00,
+ 0x00007f00,
+ 0x00247f00,
+ 0x00487f00,
+ 0x006d7f00,
+ 0x00917f00,
+ 0x00b67f00,
+ 0x00da7f00,
+ 0x00ff7f00,
+ 0x3f007f00,
+ 0x3f247f00,
+ 0x3f487f00,
+ 0x3f6d7f00,
+ 0x3f917f00,
+ 0x3fb67f00,
+ 0x3fda7f00,
+ 0x3fff7f00,
+ 0x7f007f00,
+ 0x7f247f00,
+ 0x7f487f00,
+ 0x7f6d7f00,
+ 0x7f917f00,
+ 0x7fb67f00,
+ 0x7fda7f00,
+ 0x7fff7f00,
+ 0xbf007f00,
+ 0xbf247f00,
+ 0xbf487f00,
+ 0xbf6d7f00,
+ 0xbf917f00,
+ 0xbfb67f00,
+ 0xbfda7f00,
+ 0xbfff7f00,
+ 0xff007f00,
+ 0xff247f00,
+ 0xff487f00,
+ 0xff6d7f00,
+ 0xff917f00,
+ 0xffb67f00,
+ 0xffda7f00,
+ 0xffff7f00,
+ 0x0000bf00,
+ 0x0024bf00,
+ 0x0048bf00,
+ 0x006dbf00,
+ 0x0091bf00,
+ 0x00b6bf00,
+ 0x00dabf00,
+ 0x00ffbf00,
+ 0x3f00bf00,
+ 0x3f24bf00,
+ 0x3f48bf00,
+ 0x3f6dbf00,
+ 0x3f91bf00,
+ 0x3fb6bf00,
+ 0x3fdabf00,
+ 0x3fffbf00,
+ 0x7f00bf00,
+ 0x7f24bf00,
+ 0x7f48bf00,
+ 0x7f6dbf00,
+ 0x7f91bf00,
+ 0x7fb6bf00,
+ 0x7fdabf00,
+ 0x7fffbf00,
+ 0xbf00bf00,
+ 0xbf24bf00,
+ 0xbf48bf00,
+ 0xbf6dbf00,
+ 0xbf91bf00,
+ 0xbfb6bf00,
+ 0xbfdabf00,
+ 0xbfffbf00,
+ 0xff00bf00,
+ 0xff24bf00,
+ 0xff48bf00,
+ 0xff6dbf00,
+ 0xff91bf00,
+ 0xffb6bf00,
+ 0xffdabf00,
+ 0xffffbf00,
+ 0x0000ff00,
+ 0x0024ff00,
+ 0x0048ff00,
+ 0x006dff00,
+ 0x0091ff00,
+ 0x00b6ff00,
+ 0x00daff00,
+ 0x00ffff00,
+ 0x3f00ff00,
+ 0x3f24ff00,
+ 0x3f48ff00,
+ 0x3f6dff00,
+ 0x3f91ff00,
+ 0x3fb6ff00,
+ 0x3fdaff00,
+ 0x3fffff00,
+ 0x7f00ff00,
+ 0x7f24ff00,
+ 0x7f48ff00,
+ 0x7f6dff00,
+ 0x7f91ff00,
+ 0x7fb6ff00,
+ 0x7fdaff00,
+ 0x7fffff00,
+ 0xbf00ff00,
+ 0xbf24ff00,
+ 0xbf48ff00,
+ 0xbf6dff00,
+ 0xbf91ff00,
+ 0xbfb6ff00,
+ 0xbfdaff00,
+ 0xbfffff00,
+ 0xff00ff00,
+ 0xff24ff00,
+ 0xff48ff00,
+ 0xff6dff00,
+ 0xff91ff00,
+ 0xffb6ff00,
+ 0xffdaff00,
+ 0xffffff00
+ };
+
+
+//
+// Local functions...
+//
+
+static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap);
+static int gif_get_block(FILE *fp, unsigned char *buffer);
+static int gif_get_code (FILE *fp, int code_size, int first_time);
+static int gif_read_lzw(FILE *fp, int first_time, int input_code_size);
+static int gif_read_image(FILE *fp, Fl_HelpImage *img, gif_cmap_t cmap,
+ int interlace);
+static void scrollbar_callback(Fl_Widget *s, void *);
+
+
+//
+// 'Fl_HelpView::add_block()' - Add a text block to the list.
+//
+
+Fl_HelpBlock * // O - Pointer to new block
+Fl_HelpView::add_block(const char *s, // I - Pointer to start of block text
+ int xx, // I - X position of block
+ int yy, // I - Y position of block
+ int ww, // I - Right margin of block
+ int hh, // I - Height of block
+ unsigned char border) // I - Draw border?
+{
+ Fl_HelpBlock *temp; // New block
+
+
+ if (nblocks_ >= ablocks_)
+ {
+ ablocks_ += 16;
+
+ if (ablocks_ == 16)
+ blocks_ = (Fl_HelpBlock *)malloc(sizeof(Fl_HelpBlock) * ablocks_);
+ else
+ blocks_ = (Fl_HelpBlock *)realloc(blocks_, sizeof(Fl_HelpBlock) * ablocks_);
+ }
+
+ temp = blocks_ + nblocks_;
+ temp->start = s;
+ temp->x = xx;
+ temp->y = yy;
+ temp->w = ww;
+ temp->h = hh;
+ temp->border = border;
+ nblocks_ ++;
+
+ return (temp);
+}
+
+
+//
+// 'Fl_HelpView::add_image()' - Add an image to the image cache.
+//
+
+Fl_HelpImage * // O - Image or NULL if not found
+Fl_HelpView::add_image(const char *name, // I - Path of image
+ const char *wattr, // I - Width attribute
+ const char *hattr, // I - Height attribute
+ int make) // I - Make the image?
+{
+ Fl_HelpImage *img, // New image
+ *orig; // Original image
+ FILE *fp; // File pointer
+ unsigned char header[16]; // First 16 bytes of file
+ int status; // Status of load...
+ const char *localname; // Local filename
+ char dir[1024]; // Current directory
+ char temp[1024], // Temporary filename
+ *tempptr; // Pointer into temporary name
+ int width, // Desired width of image
+ height; // Desired height of image
+
+
+ // See if the image has already been loaded...
+ if ((img = find_image(name, wattr, hattr)) != (Fl_HelpImage *)0)
+ {
+ // Make the image if needed...
+ if (!img->image)
+ img->image = new Fl_Image(img->data, img->w, img->h, img->d);
+
+ return (img);
+ }
+
+ // See if the image exists with the default size info...
+ orig = find_image(name, "", "");
+
+ // Allocate memory as needed...
+ if (aimage_ == nimage_)
+ {
+ aimage_ += 16;
+ image_ = (Fl_HelpImage *)realloc(image_, sizeof(Fl_HelpImage) * aimage_);
+ }
+
+ img = image_ + nimage_;
+ img->name = strdup(name);
+
+ if (!orig)
+ {
+ // See if the image can be found...
+ if (strchr(directory_, ':') != NULL && strchr(name, ':') == NULL)
+ {
+ if (name[0] == '/')
+ {
+ strcpy(temp, directory_);
+ if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL)
+ strcpy(tempptr, name);
+ else
+ strcat(temp, name);
+ }
+ else
+ sprintf(temp, "%s/%s", directory_, name);
+
+ if (link_)
+ localname = (*link_)(temp);
+ else
+ localname = temp;
+ }
+ else if (name[0] != '/' && strchr(name, ':') == NULL)
+ {
+ if (directory_[0])
+ sprintf(temp, "%s/%s", directory_, name);
+ else
+ {
+ getcwd(dir, sizeof(dir));
+ sprintf(temp, "file:%s/%s", dir, name);
+ }
+
+ if (link_)
+ localname = (*link_)(temp);
+ else
+ localname = temp;
+ }
+ else if (link_)
+ localname = (*link_)(name);
+ else
+ localname = name;
+
+ if (!localname)
+ return ((Fl_HelpImage *)0);
+
+ if (strncmp(localname, "file:", 5) == 0)
+ localname += 5;
+
+ // Figure out the file type...
+ if ((fp = fopen(localname, "rb")) == NULL)
+ return ((Fl_HelpImage *)0);
+
+ if (fread(header, 1, sizeof(header), fp) == 0)
+ return ((Fl_HelpImage *)0);
+
+ rewind(fp);
+
+ // Load the image as appropriate...
+ if (memcmp(header, "GIF87a", 6) == 0 ||
+ memcmp(header, "GIF89a", 6) == 0)
+ status = load_gif(img, fp);
+ #ifdef HAVE_LIBPNG
+ else if (memcmp(header, "\211PNG", 4) == 0)
+ status = load_png(img, fp);
+ #endif // HAVE_LIBPNG
+ #ifdef HAVE_LIBJPEG
+ else if (memcmp(header, "\377\330\377", 3) == 0 && // Start-of-Image
+ header[3] >= 0xe0 && header[3] <= 0xef) // APPn
+ status = load_jpeg(img, fp);
+ #endif // HAVE_LIBJPEG
+ else
+ status = 0;
+
+ fclose(fp);
+
+ if (!status)
+ {
+ free(img->name);
+ return ((Fl_HelpImage *)0);
+ }
+
+ img->wattr[0] = '\0';
+ img->hattr[0] = '\0';
+
+ nimage_ ++;
+
+ // Allocate memory as needed for the new copy...
+ if (aimage_ == nimage_)
+ {
+ aimage_ += 16;
+ image_ = (Fl_HelpImage *)realloc(image_, sizeof(Fl_HelpImage) * aimage_);
+ }
+
+ orig = image_ + nimage_ - 1;
+ img = image_ + nimage_;
+ img->name = strdup(name);
+ }
+
+ // Copy image data from original image...
+ img->data = orig->data;
+ img->w = orig->w;
+ img->h = orig->h;
+ img->d = orig->d;
+
+ // Figure out the size of the image...
+ if (wattr[0])
+ {
+ if (wattr[strlen(wattr) - 1] == '%')
+ width = atoi(wattr) * (w() - 24) / 100;
+ else
+ width = atoi(wattr);
+ }
+ else
+ width = 0;
+
+ if (hattr[0])
+ {
+ if (hattr[strlen(hattr) - 1] == '%')
+ height = atoi(hattr) * h() / 100;
+ else
+ height = atoi(hattr);
+ }
+ else
+ height = 0;
+
+ if (width == 0 && height == 0)
+ {
+ // Use image size...
+ width = img->w;
+ height = img->h;
+ }
+ else if (width == 0)
+ // Scale width to height
+ width = img->w * height / img->h;
+ else if (height == 0)
+ // Scale height to width
+ height = img->h * width / img->w;
+
+ // Scale the image as needed...
+ if (width != img->w && height != img->h)
+ {
+ unsigned char *scaled, // Scaled image data
+ *sptr, // Source image data pointer
+ *dptr; // Destination image data pointer
+ int sy, // Source coordinates
+ dx, dy, // Destination coordinates
+ xerr, yerr, // X & Y errors
+ xmod, ymod, // X & Y moduli
+ xstep, ystep; // X & Y step increments
+
+
+ xmod = img->w % width;
+ xstep = (img->w / width) * img->d;
+ ymod = img->h % height;
+ ystep = img->h / height;
+
+ if ((scaled = (unsigned char *)malloc(width * height * img->d)) != NULL)
+ {
+ // Scale the image...
+ for (dy = height, sy = 0, yerr = height / 2, dptr = scaled; dy > 0; dy --)
+ {
+ for (dx = width, xerr = width / 2,
+ sptr = img->data + sy * img->w * img->d;
+ dx > 0;
+ dx --)
+ {
+ *dptr++ = sptr[0];
+ if (img->d > 1)
+ {
+ *dptr++ = sptr[1];
+ *dptr++ = sptr[2];
+ }
+
+ sptr += xstep;
+ xerr -= xmod;
+ if (xerr <= 0)
+ {
+ xerr += width;
+ sptr += img->d;
+ }
+ }
+
+ sy += ystep;
+ yerr -= ymod;
+ if (yerr <= 0)
+ {
+ yerr += height;
+ sy ++;
+ }
+ }
+
+ // Finally, copy the new size and data to the image structure...
+ if (!orig)
+ free(img->data);
+
+ img->w = width;
+ img->h = height;
+ img->data = scaled;
+ }
+ }
+
+ strncpy(img->wattr, wattr, sizeof(img->wattr) - 1);
+ img->wattr[sizeof(img->wattr) - 1] = '\0';
+ strncpy(img->hattr, hattr, sizeof(img->hattr) - 1);
+ img->hattr[sizeof(img->hattr) - 1] = '\0';
+
+ if (make)
+ img->image = new Fl_Image(img->data, img->w, img->h, img->d);
+ else
+ img->image = (Fl_Image *)0;
+
+ nimage_ ++;
+
+ return (img);
+}
+
+
+//
+// 'Fl_HelpView::add_link()' - Add a new link to the list.
+//
+
+void
+Fl_HelpView::add_link(const char *n, // I - Name of link
+ int xx, // I - X position of link
+ int yy, // I - Y position of link
+ int ww, // I - Width of link text
+ int hh) // I - Height of link text
+{
+ Fl_HelpLink *temp; // New link
+ char *target; // Pointer to target name
+
+
+ if (nlinks_ >= alinks_)
+ {
+ alinks_ += 16;
+
+ if (alinks_ == 16)
+ links_ = (Fl_HelpLink *)malloc(sizeof(Fl_HelpLink) * alinks_);
+ else
+ links_ = (Fl_HelpLink *)realloc(links_, sizeof(Fl_HelpLink) * alinks_);
+ }
+
+ temp = links_ + nlinks_;
+
+ temp->x = xx;
+ temp->y = yy;
+ temp->w = xx + ww;
+ temp->h = yy + hh;
+
+ strncpy(temp->filename, n, sizeof(temp->filename));
+ temp->filename[sizeof(temp->filename) - 1] = '\0';
+
+ if ((target = strrchr(temp->filename, '#')) != NULL)
+ {
+ *target++ = '\0';
+ strncpy(temp->name, target, sizeof(temp->name));
+ temp->name[sizeof(temp->name) - 1] = '\0';
+ }
+ else
+ temp->name[0] = '\0';
+
+ nlinks_ ++;
+}
+
+
+//
+// 'Fl_HelpView::add_target()' - Add a new target to the list.
+//
+
+void
+Fl_HelpView::add_target(const char *n, // I - Name of target
+ int yy) // I - Y position of target
+{
+ Fl_HelpTarget *temp; // New target
+
+
+ if (ntargets_ >= atargets_)
+ {
+ atargets_ += 16;
+
+ if (atargets_ == 16)
+ targets_ = (Fl_HelpTarget *)malloc(sizeof(Fl_HelpTarget) * atargets_);
+ else
+ targets_ = (Fl_HelpTarget *)realloc(targets_, sizeof(Fl_HelpTarget) * atargets_);
+ }
+
+ temp = targets_ + ntargets_;
+
+ temp->y = yy;
+ strncpy(temp->name, n, sizeof(temp->name));
+ temp->name[sizeof(temp->name) - 1] = '\0';
+
+ ntargets_ ++;
+}
+
+
+//
+// 'Fl_HelpView::compare_targets()' - Compare two targets.
+//
+
+int // O - Result of comparison
+Fl_HelpView::compare_targets(const Fl_HelpTarget *t0, // I - First target
+ const Fl_HelpTarget *t1) // I - Second target
+{
+ return (strcasecmp(t0->name, t1->name));
+}
+
+
+//
+// 'Fl_HelpView::do_align()' - Compute the alignment for a line in a block.
+//
+
+int // O - New line
+Fl_HelpView::do_align(Fl_HelpBlock *block, // I - Block to add to
+ int line, // I - Current line
+ int xx, // I - Current X position
+ int a, // I - Current alignment
+ int &l) // IO - Starting link
+{
+ int offset; // Alignment offset
+
+
+ switch (a)
+ {
+ case RIGHT : // Right align
+ offset = block->w - xx;
+ break;
+ case CENTER : // Center
+ offset = (block->w - xx) / 2;
+ break;
+ default : // Left align
+ offset = 0;
+ break;
+ }
+
+ block->line[line] = block->x + offset;
+
+ if (line < 31)
+ line ++;
+
+ while (l < nlinks_)
+ {
+ links_[l].x += offset;
+ links_[l].w += offset;
+ l ++;
+ }
+
+ return (line);
+}
+
+
+//
+// 'Fl_HelpView::draw()' - Draw the Fl_HelpView widget.
+//
+
+void
+Fl_HelpView::draw()
+{
+ int i; // Looping var
+ const Fl_HelpBlock *block; // Pointer to current block
+ const char *ptr, // Pointer to text in block
+ *attrs; // Pointer to start of element attributes
+ char *s, // Pointer into buffer
+ buf[1024], // Text buffer
+ attr[1024]; // Attribute buffer
+ int xx, yy, ww, hh; // Current positions and sizes
+ int line; // Current line
+ unsigned char font, size; // Current font and size
+ int head, pre, // Flags for text
+ needspace; // Do we need whitespace?
+ Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
+ // Box to draw...
+ Fl_Color tc, c; // Table/cell background color
+
+
+ // Draw the scrollbar and box first...
+ if (scrollbar_.visible())
+ {
+ draw_child(scrollbar_);
+ draw_box(b, x(), y(), w() - 17, h(), bgcolor_);
+ }
+ else
+ draw_box(b, x(), y(), w(), h(), bgcolor_);
+
+ if (!value_)
+ return;
+
+ // Clip the drawing to the inside of the box...
+ fl_push_clip(x() + 4, y() + 4, w() - 28, h() - 8);
+ fl_color(textcolor_);
+
+ tc = c = bgcolor_;
+
+ // Draw all visible blocks...
+ for (i = 0, block = blocks_; i < nblocks_ && (block->y - topline_) < h(); i ++, block ++)
+ if ((block->y + block->h) >= topline_)
+ {
+ line = 0;
+ xx = block->line[line];
+ yy = block->y - topline_;
+ hh = 0;
+ pre = 0;
+ head = 0;
+ needspace = 0;
+
+ initfont(font, size);
+
+ for (ptr = block->start, s = buf; ptr < block->end;)
+ {
+ if ((*ptr == '<' || isspace(*ptr)) && s > buf)
+ {
+ if (!head && !pre)
+ {
+ // Check width...
+ *s = '\0';
+ s = buf;
+ ww = (int)fl_width(buf);
+
+ if (needspace && xx > block->x)
+ xx += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += hh;
+ hh = 0;
+ }
+
+ fl_draw(buf, xx + x(), yy + y());
+
+ xx += ww;
+ if ((size + 2) > hh)
+ hh = size + 2;
+
+ needspace = 0;
+ }
+ else if (pre)
+ {
+ while (isspace(*ptr))
+ {
+ if (*ptr == '\n')
+ {
+ *s = '\0';
+ s = buf;
+
+ fl_draw(buf, xx + x(), yy + y());
+
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += hh;
+ hh = size + 2;
+ }
+ else if (*ptr == '\t')
+ {
+ // Do tabs every 8 columns...
+ while (((s - buf) & 7))
+ *s++ = ' ';
+ }
+ else
+ *s++ = ' ';
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+
+ ptr ++;
+ }
+
+ if (s > buf)
+ {
+ *s = '\0';
+ s = buf;
+
+ fl_draw(buf, xx + x(), yy + y());
+ xx += (int)fl_width(buf);
+ }
+
+ needspace = 0;
+ }
+ else
+ {
+ s = buf;
+
+ while (isspace(*ptr))
+ ptr ++;
+ }
+ }
+
+ if (*ptr == '<')
+ {
+ ptr ++;
+ while (*ptr && *ptr != '>' && !isspace(*ptr))
+ if (s < (buf + sizeof(buf) - 1))
+ *s++ = *ptr++;
+ else
+ ptr ++;
+
+ *s = '\0';
+ s = buf;
+
+ attrs = ptr;
+ while (*ptr && *ptr != '>')
+ ptr ++;
+
+ if (*ptr == '>')
+ ptr ++;
+
+ if (strcasecmp(buf, "HEAD") == 0)
+ head = 1;
+ else if (strcasecmp(buf, "BR") == 0)
+ {
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += hh;
+ hh = 0;
+ }
+ else if (strcasecmp(buf, "HR") == 0)
+ {
+ fl_line(block->x + x(), yy + y(), block->w + x(),
+ yy + y());
+
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += 2 * hh;
+ hh = 0;
+ }
+ else if (strcasecmp(buf, "CENTER") == 0 ||
+ strcasecmp(buf, "P") == 0 ||
+ strcasecmp(buf, "H1") == 0 ||
+ strcasecmp(buf, "H2") == 0 ||
+ strcasecmp(buf, "H3") == 0 ||
+ strcasecmp(buf, "H4") == 0 ||
+ strcasecmp(buf, "H5") == 0 ||
+ strcasecmp(buf, "H6") == 0 ||
+ strcasecmp(buf, "UL") == 0 ||
+ strcasecmp(buf, "OL") == 0 ||
+ strcasecmp(buf, "DL") == 0 ||
+ strcasecmp(buf, "LI") == 0 ||
+ strcasecmp(buf, "DD") == 0 ||
+ strcasecmp(buf, "DT") == 0 ||
+ strcasecmp(buf, "PRE") == 0)
+ {
+ if (tolower(buf[0]) == 'h')
+ {
+ font = FL_HELVETICA_BOLD;
+ size = textsize_ + '7' - buf[1];
+ }
+ else if (strcasecmp(buf, "DT") == 0)
+ {
+ font = textfont_ | FL_ITALIC;
+ size = textsize_;
+ }
+ else if (strcasecmp(buf, "PRE") == 0)
+ {
+ font = FL_COURIER;
+ size = textsize_;
+ pre = 1;
+ }
+
+ if (strcasecmp(buf, "LI") == 0)
+ {
+ fl_font(FL_SYMBOL, size);
+ fl_draw("\267", xx - size + x(), yy + y());
+ }
+
+ pushfont(font, size);
+
+ if (c != bgcolor_)
+ {
+ fl_color(c);
+ fl_rectf(block->x + x() - 4,
+ block->y - topline_ + y() - size - 3,
+ block->w - block->x + 7, block->h + size - 5);
+ fl_color(textcolor_);
+ }
+ }
+ else if (strcasecmp(buf, "A") == 0 &&
+ get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL)
+ fl_color(linkcolor_);
+ else if (strcasecmp(buf, "/A") == 0)
+ fl_color(textcolor_);
+ else if (strcasecmp(buf, "B") == 0)
+ pushfont(font |= FL_BOLD, size);
+ else if (strcasecmp(buf, "TABLE") == 0)
+ tc = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), bgcolor_);
+ else if (strcasecmp(buf, "TD") == 0 ||
+ strcasecmp(buf, "TH") == 0)
+ {
+ if (tolower(buf[1]) == 'h')
+ pushfont(font |= FL_BOLD, size);
+ else
+ pushfont(font = textfont_, size);
+
+ c = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)), tc);
+
+ if (c != bgcolor_)
+ {
+ fl_color(c);
+ fl_rectf(block->x + x() - 4,
+ block->y - topline_ + y() - size - 3,
+ block->w - block->x + 7, block->h + size - 5);
+ fl_color(textcolor_);
+ }
+
+ if (block->border)
+ fl_rect(block->x + x() - 4,
+ block->y - topline_ + y() - size - 3,
+ block->w - block->x + 7, block->h + size - 5);
+ }
+ else if (strcasecmp(buf, "I") == 0)
+ pushfont(font |= FL_ITALIC, size);
+ else if (strcasecmp(buf, "CODE") == 0)
+ pushfont(font = FL_COURIER, size);
+ else if (strcasecmp(buf, "KBD") == 0)
+ pushfont(font = FL_COURIER_BOLD, size);
+ else if (strcasecmp(buf, "VAR") == 0)
+ pushfont(font = FL_COURIER_ITALIC, size);
+ else if (strcasecmp(buf, "/HEAD") == 0)
+ head = 0;
+ else if (strcasecmp(buf, "/H1") == 0 ||
+ strcasecmp(buf, "/H2") == 0 ||
+ strcasecmp(buf, "/H3") == 0 ||
+ strcasecmp(buf, "/H4") == 0 ||
+ strcasecmp(buf, "/H5") == 0 ||
+ strcasecmp(buf, "/H6") == 0 ||
+ strcasecmp(buf, "/B") == 0 ||
+ strcasecmp(buf, "/I") == 0 ||
+ strcasecmp(buf, "/CODE") == 0 ||
+ strcasecmp(buf, "/KBD") == 0 ||
+ strcasecmp(buf, "/VAR") == 0)
+ popfont(font, size);
+ else if (strcasecmp(buf, "/TABLE") == 0)
+ tc = c = bgcolor_;
+ else if (strcasecmp(buf, "/TD") == 0 ||
+ strcasecmp(buf, "/TH") == 0)
+ c = tc;
+ else if (strcasecmp(buf, "/PRE") == 0)
+ {
+ popfont(font, size);
+ pre = 0;
+ }
+ else if (strcasecmp(buf, "IMG") == 0)
+ {
+ Fl_HelpImage *img = (Fl_HelpImage *)0;
+ int width = 16;
+ int height = 24;
+ char wattr[8], hattr[8];
+
+
+ get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+ get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+
+ if (get_attr(attrs, "SRC", attr, sizeof(attr)))
+ if ((img = find_image(attr, wattr, hattr)) != NULL && !img->image)
+ img = (Fl_HelpImage *)0;
+
+ if (img)
+ {
+ width = img->w;
+ height = img->h;
+ }
+ else if (get_attr(attrs, "ALT", attr, sizeof(attr)) == NULL)
+ strcpy(attr, "IMG");
+
+ ww = width;
+
+ if (needspace && xx > block->x)
+ xx += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ if (line < 31)
+ line ++;
+
+ xx = block->line[line];
+ yy += hh;
+ hh = 0;
+ }
+
+ if (img)
+ img->image->draw(xx + x(),
+ yy + y() - fl_height() + fl_descent() + 2);
+ else
+ broken_image->draw(xx + x(),
+ yy + y() - fl_height() + fl_descent() + 2);
+
+ xx += ww;
+ if ((height + 2) > hh)
+ hh = height + 2;
+
+ needspace = 0;
+ }
+ }
+ else if (*ptr == '\n' && pre)
+ {
+ *s = '\0';
+ s = buf;
+
+ fl_draw(buf, xx + x(), yy + y());
+
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += hh;
+ hh = size + 2;
+ needspace = 0;
+
+ ptr ++;
+ }
+ else if (isspace(*ptr))
+ {
+ if (pre)
+ {
+ if (*ptr == ' ')
+ *s++ = ' ';
+ else
+ {
+ // Do tabs every 8 columns...
+ while (((s - buf) & 7))
+ *s++ = ' ';
+ }
+ }
+
+ ptr ++;
+ needspace = 1;
+ }
+ else if (*ptr == '&')
+ {
+ ptr ++;
+
+ if (strncasecmp(ptr, "amp;", 4) == 0)
+ {
+ *s++ = '&';
+ ptr += 4;
+ }
+ else if (strncasecmp(ptr, "lt;", 3) == 0)
+ {
+ *s++ = '<';
+ ptr += 3;
+ }
+ else if (strncasecmp(ptr, "gt;", 3) == 0)
+ {
+ *s++ = '>';
+ ptr += 3;
+ }
+ else if (strncasecmp(ptr, "nbsp;", 5) == 0)
+ {
+ *s++ = ' ';
+ ptr += 5;
+ }
+ else if (strncasecmp(ptr, "copy;", 5) == 0)
+ {
+ *s++ = '\251';
+ ptr += 5;
+ }
+ else if (strncasecmp(ptr, "reg;", 4) == 0)
+ {
+ *s++ = '\256';
+ ptr += 4;
+ }
+ else if (strncasecmp(ptr, "quot;", 5) == 0)
+ {
+ *s++ = '\"';
+ ptr += 5;
+ }
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+ }
+ else
+ {
+ *s++ = *ptr++;
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+ }
+ }
+
+ *s = '\0';
+
+ if (s > buf && !pre && !head)
+ {
+ ww = (int)fl_width(buf);
+
+ if (needspace && xx > block->x)
+ xx += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ if (line < 31)
+ line ++;
+ xx = block->line[line];
+ yy += hh;
+ hh = 0;
+ }
+ }
+
+ if (s > buf && !head)
+ fl_draw(buf, xx + x(), yy + y());
+ }
+
+ fl_pop_clip();
+}
+
+
+//
+// 'Fl_HelpView::find_image()' - Find an image by name
+//
+
+Fl_HelpImage * // O - Image or NULL if not found
+Fl_HelpView::find_image(const char *name, // I - Path and name of image
+ const char *wattr, // I - Width attribute of image
+ const char *hattr) // I - Height attribute of image
+{
+ int i; // Looping var
+ Fl_HelpImage *img; // Current image
+
+
+ for (i = nimage_, img = image_; i > 0; i --, img ++)
+ if (strcmp(img->name, name) == 0 &&
+ strcmp(img->wattr, wattr) == 0 &&
+ strcmp(img->hattr, hattr) == 0)
+ return (img);
+
+ return ((Fl_HelpImage *)0);
+}
+
+
+//
+// 'Fl_HelpView::format()' - Format the help text.
+//
+
+void
+Fl_HelpView::format()
+{
+ int i; // Looping var
+ Fl_HelpBlock *block, // Current block
+ *cell; // Current table cell
+ int row; // Current table row (block number)
+ const char *ptr, // Pointer into block
+ *start, // Pointer to start of element
+ *attrs; // Pointer to start of element attributes
+ char *s, // Pointer into buffer
+ buf[1024], // Text buffer
+ attr[1024], // Attribute buffer
+ wattr[1024], // Width attribute buffer
+ hattr[1024], // Height attribute buffer
+ link[1024]; // Link destination
+ int xx, yy, ww, hh; // Size of current text fragment
+ int line; // Current line in block
+ int links; // Links for current line
+ unsigned char font, size; // Current font and size
+ unsigned char border; // Draw border?
+ int align, // Current alignment
+ newalign, // New alignment
+ head, // In the <HEAD> section?
+ pre, // <PRE> text?
+ needspace; // Do we need whitespace?
+ int table_width; // Width of table
+ int column, // Current table column number
+ columns[200]; // Column widths
+
+
+ // Reset state variables...
+ nblocks_ = 0;
+ nlinks_ = 0;
+ ntargets_ = 0;
+ size_ = 0;
+ bgcolor_ = color();
+ textcolor_ = textcolor();
+ linkcolor_ = selection_color();
+
+ strcpy(title_, "Untitled");
+
+ if (!value_)
+ return;
+
+ // Flush images that are scaled by percentage...
+ for (i = 0; i < nimage_; i ++)
+ if (strchr(image_[i].wattr, '%') != NULL ||
+ strchr(image_[i].hattr, '%') != NULL)
+ {
+ // Flush this one...
+ free(image_[i].name);
+ free(image_[i].data);
+ delete image_[i].image;
+ nimage_ --;
+ if (i < nimage_)
+ memcpy(image_ + i, image_ + i + 1, (nimage_ - i) * sizeof(Fl_HelpImage));
+ i --;
+ }
+
+ // Setup for formatting...
+ initfont(font, size);
+
+ line = 0;
+ links = 0;
+ xx = 4;
+ yy = size + 2;
+ ww = 0;
+ column = 0;
+ border = 0;
+ hh = 0;
+ block = add_block(value_, xx, yy, w() - 24, 0);
+ row = 0;
+ head = 0;
+ pre = 0;
+ align = LEFT;
+ newalign = LEFT;
+ needspace = 0;
+ link[0] = '\0';
+
+ for (ptr = value_, s = buf; *ptr;)
+ {
+ if ((*ptr == '<' || isspace(*ptr)) && s > buf)
+ {
+ if (!head && !pre)
+ {
+ // Check width...
+ *s = '\0';
+ ww = (int)fl_width(buf);
+
+ if (needspace && xx > block->x)
+ ww += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ yy += hh;
+ block->h += hh;
+ hh = 0;
+ }
+
+ if (link[0])
+ add_link(link, xx, yy - size, ww, size);
+
+ xx += ww;
+ if ((size + 2) > hh)
+ hh = size + 2;
+
+ needspace = 0;
+ }
+ else if (pre)
+ {
+ // Handle preformatted text...
+ while (isspace(*ptr))
+ {
+ if (*ptr == '\n')
+ {
+ if (link[0])
+ add_link(link, xx, yy - hh, ww, hh);
+
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ yy += hh;
+ block->h += hh;
+ hh = size + 2;
+ }
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+
+ ptr ++;
+ }
+
+ needspace = 0;
+ }
+ else
+ {
+ // Handle normal text or stuff in the <HEAD> section...
+ while (isspace(*ptr))
+ ptr ++;
+ }
+
+ s = buf;
+ }
+
+ if (*ptr == '<')
+ {
+ start = ptr;
+ ptr ++;
+ while (*ptr && *ptr != '>' && !isspace(*ptr))
+ if (s < (buf + sizeof(buf) - 1))
+ *s++ = *ptr++;
+ else
+ ptr ++;
+
+ *s = '\0';
+ s = buf;
+
+ attrs = ptr;
+ while (*ptr && *ptr != '>')
+ ptr ++;
+
+ if (*ptr == '>')
+ ptr ++;
+
+ if (strcasecmp(buf, "HEAD") == 0)
+ head = 1;
+ else if (strcasecmp(buf, "/HEAD") == 0)
+ head = 0;
+ else if (strcasecmp(buf, "TITLE") == 0)
+ {
+ // Copy the title in the document...
+ for (s = title_;
+ *ptr != '<' && *ptr && s < (title_ + sizeof(title_) - 1);
+ *s++ = *ptr++);
+
+ *s = '\0';
+ s = buf;
+ }
+ else if (strcasecmp(buf, "A") == 0)
+ {
+ if (get_attr(attrs, "NAME", attr, sizeof(attr)) != NULL)
+ add_target(attr, yy - size - 2);
+ else if (get_attr(attrs, "HREF", attr, sizeof(attr)) != NULL)
+ {
+ strncpy(link, attr, sizeof(link) - 1);
+ link[sizeof(link) - 1] = '\0';
+ }
+ }
+ else if (strcasecmp(buf, "/A") == 0)
+ link[0] = '\0';
+ else if (strcasecmp(buf, "BODY") == 0)
+ {
+ bgcolor_ = get_color(get_attr(attrs, "BGCOLOR", attr, sizeof(attr)),
+ color());
+ textcolor_ = get_color(get_attr(attrs, "TEXT", attr, sizeof(attr)),
+ textcolor());
+ linkcolor_ = get_color(get_attr(attrs, "LINK", attr, sizeof(attr)),
+ selection_color());
+ }
+ else if (strcasecmp(buf, "BR") == 0)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ block->h += hh;
+ yy += hh;
+ hh = 0;
+ }
+ else if (strcasecmp(buf, "CENTER") == 0 ||
+ strcasecmp(buf, "P") == 0 ||
+ strcasecmp(buf, "H1") == 0 ||
+ strcasecmp(buf, "H2") == 0 ||
+ strcasecmp(buf, "H3") == 0 ||
+ strcasecmp(buf, "H4") == 0 ||
+ strcasecmp(buf, "H5") == 0 ||
+ strcasecmp(buf, "H6") == 0 ||
+ strcasecmp(buf, "UL") == 0 ||
+ strcasecmp(buf, "OL") == 0 ||
+ strcasecmp(buf, "DL") == 0 ||
+ strcasecmp(buf, "LI") == 0 ||
+ strcasecmp(buf, "DD") == 0 ||
+ strcasecmp(buf, "DT") == 0 ||
+ strcasecmp(buf, "HR") == 0 ||
+ strcasecmp(buf, "PRE") == 0 ||
+ strcasecmp(buf, "TABLE") == 0)
+ {
+ block->end = start;
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ block->h += hh;
+
+ if (!block->h && nblocks_ > 1)
+ {
+ nblocks_ --;
+ block --;
+ }
+
+ if (strcasecmp(buf, "UL") == 0 ||
+ strcasecmp(buf, "OL") == 0 ||
+ strcasecmp(buf, "DL") == 0)
+ {
+ xx += 4 * size;
+ block->h += size + 2;
+ }
+ else if (strcasecmp(buf, "TABLE") == 0)
+ {
+ if (get_attr(attrs, "BORDER", attr, sizeof(attr)))
+ border = atoi(attr);
+ else
+ border = 0;
+
+ block->h += size + 2;
+
+ if (get_attr(attrs, "WIDTH", attr, sizeof(attr)))
+ {
+ if (attr[strlen(attr) - 1] == '%')
+ table_width = atoi(attr) * w() / 100;
+ else
+ table_width = atoi(attr);
+ }
+ else
+ table_width = w();
+
+ for (column = 0; column < 200; column ++)
+ columns[column] = table_width / 3;
+
+ column = 0;
+ }
+
+ if (tolower(buf[0]) == 'h' && isdigit(buf[1]))
+ {
+ font = FL_HELVETICA_BOLD;
+ size = textsize_ + '7' - buf[1];
+ }
+ else if (strcasecmp(buf, "DT") == 0)
+ {
+ font = textfont_ | FL_ITALIC;
+ size = textsize_;
+ }
+ else if (strcasecmp(buf, "PRE") == 0)
+ {
+ font = FL_COURIER;
+ size = textsize_;
+ pre = 1;
+ }
+ else
+ {
+ font = textfont_;
+ size = textsize_;
+ }
+
+ pushfont(font, size);
+
+ yy = block->y + block->h;
+ hh = 0;
+
+ if ((tolower(buf[0]) == 'h' && isdigit(buf[1])) ||
+ strcasecmp(buf, "DD") == 0 ||
+ strcasecmp(buf, "DT") == 0 ||
+ strcasecmp(buf, "UL") == 0 ||
+ strcasecmp(buf, "OL") == 0 ||
+ strcasecmp(buf, "P") == 0)
+ yy += size + 2;
+ else if (strcasecmp(buf, "HR") == 0)
+ {
+ hh += 2 * size;
+ yy += size;
+ }
+
+ if (row)
+ block = add_block(start, block->x, yy, block->w, 0);
+ else
+ block = add_block(start, xx, yy, w() - 24, 0);
+
+ needspace = 0;
+ line = 0;
+
+ if (strcasecmp(buf, "CENTER") == 0)
+ newalign = align = CENTER;
+ else
+ newalign = get_align(attrs, align);
+ }
+ else if (strcasecmp(buf, "/CENTER") == 0 ||
+ strcasecmp(buf, "/P") == 0 ||
+ strcasecmp(buf, "/H1") == 0 ||
+ strcasecmp(buf, "/H2") == 0 ||
+ strcasecmp(buf, "/H3") == 0 ||
+ strcasecmp(buf, "/H4") == 0 ||
+ strcasecmp(buf, "/H5") == 0 ||
+ strcasecmp(buf, "/H6") == 0 ||
+ strcasecmp(buf, "/PRE") == 0 ||
+ strcasecmp(buf, "/UL") == 0 ||
+ strcasecmp(buf, "/OL") == 0 ||
+ strcasecmp(buf, "/DL") == 0 ||
+ strcasecmp(buf, "/TABLE") == 0)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ block->end = ptr;
+
+ if (strcasecmp(buf, "/UL") == 0 ||
+ strcasecmp(buf, "/OL") == 0 ||
+ strcasecmp(buf, "/DL") == 0)
+ {
+ xx -= 4 * size;
+ block->h += size + 2;
+ }
+ else if (strcasecmp(buf, "/TABLE") == 0)
+ block->h += size + 2;
+ else if (strcasecmp(buf, "/PRE") == 0)
+ {
+ pre = 0;
+ hh = 0;
+ }
+ else if (strcasecmp(buf, "/CENTER") == 0)
+ align = LEFT;
+
+ initfont(font, size);
+
+ while (isspace(*ptr))
+ ptr ++;
+
+ block->h += hh;
+ yy += hh;
+
+ if (tolower(buf[2]) == 'l')
+ yy += size + 2;
+
+ block = add_block(ptr, xx, yy, w() - 24, 0);
+ needspace = 0;
+ hh = 0;
+ line = 0;
+ newalign = align;
+ }
+ else if (strcasecmp(buf, "TR") == 0)
+ {
+ block->end = start;
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ block->h += hh;
+
+ if (row)
+ {
+ yy = blocks_[row].y + blocks_[row].h;
+
+ for (cell = blocks_ + row + 1; cell <= block; cell ++)
+ if ((cell->y + cell->h) > yy)
+ yy = cell->y + cell->h;
+
+ block->h = yy - block->y + 2;
+
+ for (cell = blocks_ + row + 1; cell < block; cell ++)
+ cell->h = block->h;
+ }
+
+ yy = block->y + block->h - 4;
+ hh = 0;
+ block = add_block(start, xx, yy, w() - 24, 0);
+ row = block - blocks_;
+ needspace = 0;
+ column = 0;
+ line = 0;
+ }
+ else if (strcasecmp(buf, "/TR") == 0 && row)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ block->end = start;
+ block->h += hh;
+
+ xx = blocks_[row].x;
+
+ if (block->end == block->start && nblocks_ > 1)
+ {
+ nblocks_ --;
+ block --;
+ }
+
+ yy = blocks_[row].y + blocks_[row].h;
+
+ for (cell = blocks_ + row + 1; cell <= block; cell ++)
+ if ((cell->y + cell->h) > yy)
+ yy = cell->y + cell->h;
+
+ block->h = yy - block->y + 2;
+
+ for (cell = blocks_ + row + 1; cell < block; cell ++)
+ cell->h = block->h;
+
+ yy = block->y + block->h - 4;
+ block = add_block(start, xx, yy, w() - 24, 0);
+ needspace = 0;
+ row = 0;
+ line = 0;
+ }
+ else if ((strcasecmp(buf, "TD") == 0 ||
+ strcasecmp(buf, "TH") == 0) && row)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ block->end = start;
+ block->h += hh;
+
+ if (strcasecmp(buf, "TH") == 0)
+ font = textfont_ | FL_BOLD;
+ else
+ font = textfont_;
+
+ size = textsize_;
+
+ if (column == 0)
+ xx = block->x + size + 3;
+ else
+ xx = block->w + 6;
+
+ if (block->end == block->start && nblocks_ > 1)
+ {
+ nblocks_ --;
+ block --;
+ }
+
+ pushfont(font, size);
+
+ if (get_attr(attrs, "WIDTH", attr, sizeof(attr)) != NULL)
+ {
+ ww = atoi(attr);
+
+ if (attr[strlen(attr) - 1] == '%')
+ ww = ww * w() / 100;
+
+ columns[column] = ww;
+ }
+ else
+ ww = columns[column];
+
+ yy = blocks_[row].y;
+ hh = 0;
+ block = add_block(start, xx, yy, xx + ww, 0, border);
+ needspace = 0;
+ line = 0;
+ newalign = get_align(attrs, tolower(buf[1]) == 'h' ? CENTER : LEFT);
+
+ column ++;
+ }
+ else if ((strcasecmp(buf, "/TD") == 0 ||
+ strcasecmp(buf, "/TH") == 0) && row)
+ popfont(font, size);
+ else if (strcasecmp(buf, "B") == 0)
+ pushfont(font |= FL_BOLD, size);
+ else if (strcasecmp(buf, "I") == 0)
+ pushfont(font |= FL_ITALIC, size);
+ else if (strcasecmp(buf, "CODE") == 0)
+ pushfont(font = FL_COURIER, size);
+ else if (strcasecmp(buf, "KBD") == 0)
+ pushfont(font = FL_COURIER_BOLD, size);
+ else if (strcasecmp(buf, "VAR") == 0)
+ pushfont(font = FL_COURIER_ITALIC, size);
+ else if (strcasecmp(buf, "/B") == 0 ||
+ strcasecmp(buf, "/I") == 0 ||
+ strcasecmp(buf, "/CODE") == 0 ||
+ strcasecmp(buf, "/KBD") == 0 ||
+ strcasecmp(buf, "/VAR") == 0)
+ popfont(font, size);
+ else if (strcasecmp(buf, "IMG") == 0)
+ {
+ Fl_HelpImage *img = (Fl_HelpImage *)0;
+ int width = 16;
+ int height = 24;
+
+
+ get_attr(attrs, "WIDTH", wattr, sizeof(wattr));
+ get_attr(attrs, "HEIGHT", hattr, sizeof(hattr));
+
+ if (get_attr(attrs, "SRC", attr, sizeof(attr)))
+ if ((img = add_image(attr, wattr, hattr)) != (Fl_HelpImage *)0 &&
+ img->image == NULL)
+ img = (Fl_HelpImage *)0;
+
+ if (img)
+ {
+ width = img->w;
+ height = img->h;
+ }
+ else if (get_attr(attrs, "ALT", attr, sizeof(attr)) == NULL)
+ strcpy(attr, "IMG");
+
+ ww = width;
+
+ if (needspace && xx > block->x)
+ ww += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ yy += hh;
+ block->h += hh;
+ hh = 0;
+ }
+
+ if (link[0])
+ add_link(link, xx, yy - height, ww, height);
+
+ xx += ww;
+ if ((height + 2) > hh)
+ hh = height + 2;
+
+ needspace = 0;
+ }
+ }
+ else if (*ptr == '\n' && pre)
+ {
+ if (link[0])
+ add_link(link, xx, yy - hh, ww, hh);
+
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ yy += hh;
+ block->h += hh;
+ needspace = 0;
+ ptr ++;
+ }
+ else if (isspace(*ptr))
+ {
+ needspace = 1;
+
+ ptr ++;
+ }
+ else if (*ptr == '&' && s < (buf + sizeof(buf) - 1))
+ {
+ ptr ++;
+
+ if (strncasecmp(ptr, "amp;", 4) == 0)
+ {
+ *s++ = '&';
+ ptr += 4;
+ }
+ else if (strncasecmp(ptr, "lt;", 3) == 0)
+ {
+ *s++ = '<';
+ ptr += 3;
+ }
+ else if (strncasecmp(ptr, "gt;", 3) == 0)
+ {
+ *s++ = '>';
+ ptr += 3;
+ }
+ else if (strncasecmp(ptr, "nbsp;", 5) == 0)
+ {
+ *s++ = '\240';
+ ptr += 5;
+ }
+ else if (strncasecmp(ptr, "copy;", 5) == 0)
+ {
+ *s++ = '\251';
+ ptr += 5;
+ }
+ else if (strncasecmp(ptr, "reg;", 4) == 0)
+ {
+ *s++ = '\256';
+ ptr += 4;
+ }
+ else if (strncasecmp(ptr, "quot;", 5) == 0)
+ {
+ *s++ = '\"';
+ ptr += 5;
+ }
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+ }
+ else
+ {
+ if (s < (buf + sizeof(buf) - 1))
+ *s++ = *ptr++;
+ else
+ ptr ++;
+
+ if ((size + 2) > hh)
+ hh = size + 2;
+ }
+ }
+
+ if (s > buf && !pre && !head)
+ {
+ *s = '\0';
+ ww = (int)fl_width(buf);
+
+ if (needspace && xx > block->x)
+ ww += (int)fl_width(' ');
+
+ if ((xx + ww) > block->w)
+ {
+ line = do_align(block, line, xx, newalign, links);
+ xx = block->x;
+ yy += hh;
+ block->h += hh;
+ hh = 0;
+ }
+
+ if (link[0])
+ add_link(link, xx, yy - size, ww, size);
+
+ xx += ww;
+ if ((size + 2) > hh)
+ hh = size + 2;
+
+ needspace = 0;
+ }
+
+ block->end = ptr;
+ size_ = yy + hh;
+
+ if (ntargets_ > 1)
+ qsort(targets_, ntargets_, sizeof(Fl_HelpTarget),
+ (compare_func_t)compare_targets);
+
+ if (size_ < (h() - 8))
+ scrollbar_.hide();
+ else
+ scrollbar_.show();
+
+ topline(topline_);
+}
+
+
+//
+// 'Fl_HelpView::get_align()' - Get an alignment attribute.
+//
+
+int // O - Alignment
+Fl_HelpView::get_align(const char *p, // I - Pointer to start of attrs
+ int a) // I - Default alignment
+{
+ char buf[255]; // Alignment value
+
+
+ if (get_attr(p, "ALIGN", buf, sizeof(buf)) == NULL)
+ return (a);
+
+ if (strcasecmp(buf, "CENTER") == 0)
+ return (CENTER);
+ else if (strcasecmp(buf, "RIGHT") == 0)
+ return (RIGHT);
+ else
+ return (LEFT);
+}
+
+
+//
+// 'Fl_HelpView::get_attr()' - Get an attribute value from the string.
+//
+
+const char * // O - Pointer to buf or NULL
+Fl_HelpView::get_attr(const char *p, // I - Pointer to start of attributes
+ const char *n, // I - Name of attribute
+ char *buf, // O - Buffer for attribute value
+ int bufsize) // I - Size of buffer
+{
+ char name[255], // Name from string
+ *ptr, // Pointer into name or value
+ quote; // Quote
+
+
+ buf[0] = '\0';
+
+ while (*p && *p != '>')
+ {
+ while (isspace(*p))
+ p ++;
+
+ if (*p == '>' || !*p)
+ return (NULL);
+
+ for (ptr = name; *p && !isspace(*p) && *p != '=' && *p != '>';)
+ if (ptr < (name + sizeof(name) - 1))
+ *ptr++ = *p++;
+ else
+ p ++;
+
+ *ptr = '\0';
+
+ if (isspace(*p) || !*p || *p == '>')
+ buf[0] = '\0';
+ else
+ {
+ if (*p == '=')
+ p ++;
+
+ for (ptr = buf; *p && !isspace(*p) && *p != '>';)
+ if (*p == '\'' || *p == '\"')
+ {
+ quote = *p++;
+
+ while (*p && *p != quote)
+ if ((ptr - buf + 1) < bufsize)
+ *ptr++ = *p++;
+ else
+ p ++;
+
+ if (*p == quote)
+ p ++;
+ }
+ else if ((ptr - buf + 1) < bufsize)
+ *ptr++ = *p++;
+ else
+ p ++;
+
+ *ptr = '\0';
+ }
+
+ if (strcasecmp(n, name) == 0)
+ return (buf);
+ else
+ buf[0] = '\0';
+
+ if (*p == '>')
+ return (NULL);
+ }
+
+ return (NULL);
+}
+
+
+//
+// 'Fl_HelpView::get_color()' - Get an alignment attribute.
+//
+
+Fl_Color // O - Color value
+Fl_HelpView::get_color(const char *n, // I - Color name
+ Fl_Color c) // I - Default color value
+{
+ int rgb, r, g, b; // RGB values
+
+
+ if (!n)
+ return (c);
+
+ if (n[0] == '#')
+ {
+ // Do hex color lookup
+ rgb = strtol(n + 1, NULL, 16);
+
+ r = rgb >> 16;
+ g = (rgb >> 8) & 255;
+ b = rgb & 255;
+
+ if (r == g && g == b)
+ return (fl_gray_ramp(FL_NUM_GRAY * r / 256));
+ else
+ return (fl_color_cube((FL_NUM_RED - 1) * r / 255,
+ (FL_NUM_GREEN - 1) * g / 255,
+ (FL_NUM_BLUE - 1) * b / 255));
+ }
+ else if (strcasecmp(n, "black") == 0)
+ return (FL_BLACK);
+ else if (strcasecmp(n, "red") == 0)
+ return (FL_RED);
+ else if (strcasecmp(n, "green") == 0)
+ return (fl_color_cube(0, 4, 0));
+ else if (strcasecmp(n, "yellow") == 0)
+ return (FL_YELLOW);
+ else if (strcasecmp(n, "blue") == 0)
+ return (FL_BLUE);
+ else if (strcasecmp(n, "magenta") == 0 || strcasecmp(n, "fuchsia") == 0)
+ return (FL_MAGENTA);
+ else if (strcasecmp(n, "cyan") == 0 || strcasecmp(n, "aqua") == 0)
+ return (FL_CYAN);
+ else if (strcasecmp(n, "white") == 0)
+ return (FL_WHITE);
+ else if (strcasecmp(n, "gray") == 0 || strcasecmp(n, "grey") == 0)
+ return (FL_GRAY);
+ else if (strcasecmp(n, "lime") == 0)
+ return (FL_GREEN);
+ else if (strcasecmp(n, "maroon") == 0)
+ return (fl_color_cube(2, 0, 0));
+ else if (strcasecmp(n, "navy") == 0)
+ return (fl_color_cube(0, 0, 2));
+ else if (strcasecmp(n, "olive") == 0)
+ return (fl_color_cube(2, 4, 0));
+ else if (strcasecmp(n, "purple") == 0)
+ return (fl_color_cube(2, 0, 2));
+ else if (strcasecmp(n, "silver") == 0)
+ return (FL_LIGHT2);
+ else if (strcasecmp(n, "teal") == 0)
+ return (fl_color_cube(0, 4, 2));
+ else
+ return (c);
+}
+
+
+//
+// 'Fl_HelpView::handle()' - Handle events in the widget.
+//
+
+int // O - 1 if we handled it, 0 otherwise
+Fl_HelpView::handle(int event) // I - Event to handle
+{
+ int i; // Looping var
+ int xx, yy; // Adjusted mouse position
+ Fl_HelpLink *link; // Current link
+ char target[32]; // Current target
+
+
+ switch (event)
+ {
+ case FL_MOVE :
+ case FL_PUSH :
+ if (Fl::event_button() == 4)
+ {
+ // XFree86 maps button 4 to the "wheel up" motion...
+ topline(topline() - textsize_ * 3);
+ return (1);
+ }
+ else if (Fl::event_button() == 5)
+ {
+ // XFree86 maps button 5 to the "wheel down" motion...
+ topline(topline() + textsize_ * 3);
+ return (1);
+ }
+
+ xx = Fl::event_x() - x();
+ yy = Fl::event_y() - y() + topline_;
+ if (!scrollbar_.visible() || xx < (w() - 20))
+ break;
+
+ default :
+ // Use the Fl_Group handler...
+ return (Fl_Group::handle(event));
+ }
+
+ // Handle mouse clicks on links...
+ for (i = nlinks_, link = links_; i > 0; i --, link ++)
+ if (xx >= link->x && xx < link->w &&
+ yy >= link->y && yy < link->h)
+ break;
+
+ if (!i)
+ {
+ fl_cursor(FL_CURSOR_DEFAULT);
+ return (1);
+ }
+
+ // Change the cursor for FL_MOTION events, and go to the link for
+ // clicks...
+ if (event == FL_MOVE)
+ fl_cursor(FL_CURSOR_HAND);
+ else
+ {
+ fl_cursor(FL_CURSOR_DEFAULT);
+
+ strncpy(target, link->name, sizeof(target) - 1);
+ target[sizeof(target) - 1] = '\0';
+
+ set_changed();
+
+ if (strcmp(link->filename, filename_) != 0 && link->filename[0])
+ {
+ char dir[1024]; // Current directory
+ char temp[1024], // Temporary filename
+ *tempptr; // Pointer into temporary filename
+
+
+ if (strchr(directory_, ':') != NULL && strchr(link->filename, ':') == NULL)
+ {
+ if (link->filename[0] == '/')
+ {
+ strcpy(temp, directory_);
+ if ((tempptr = strrchr(strchr(directory_, ':') + 3, '/')) != NULL)
+ strcpy(tempptr, link->filename);
+ else
+ strcat(temp, link->filename);
+ }
+ else
+ sprintf(temp, "%s/%s", directory_, link->filename);
+
+ load(temp);
+ }
+ else if (link->filename[0] != '/' && strchr(link->filename, ':') == NULL)
+ {
+ if (directory_[0])
+ sprintf(temp, "%s/%s", directory_, link->filename);
+ else
+ {
+ getcwd(dir, sizeof(dir));
+ sprintf(temp, "file:%s/%s", dir, link->filename);
+ }
+
+ load(temp);
+ }
+ else
+ load(link->filename);
+ }
+ else if (target[0])
+ topline(target);
+ else
+ topline(0);
+ }
+
+ return (1);
+}
+
+
+//
+// 'Fl_HelpView::Fl_HelpView()' - Build a Fl_HelpView widget.
+//
+
+Fl_HelpView::Fl_HelpView(int xx, // I - Left position
+ int yy, // I - Top position
+ int ww, // I - Width in pixels
+ int hh, // I - Height in pixels
+ const char *l)
+ : Fl_Group(xx, yy, ww, hh, l),
+ scrollbar_(xx + ww - 17, yy, 17, hh)
+{
+ link_ = (Fl_HelpFunc *)0;
+
+ filename_[0] = '\0';
+ value_ = NULL;
+
+ ablocks_ = 0;
+ nblocks_ = 0;
+ blocks_ = (Fl_HelpBlock *)0;
+
+ nimage_ = 0;
+ aimage_ = 0;
+ image_ = (Fl_HelpImage *)0;
+
+ if (!broken_image)
+ broken_image = new Fl_Pixmap((char **)broken_xpm);
+
+ alinks_ = 0;
+ nlinks_ = 0;
+ links_ = (Fl_HelpLink *)0;
+
+ atargets_ = 0;
+ ntargets_ = 0;
+ targets_ = (Fl_HelpTarget *)0;
+
+ nfonts_ = 0;
+ textfont_ = FL_TIMES;
+ textsize_ = 12;
+
+ topline_ = 0;
+ size_ = 0;
+
+ color(FL_WHITE);
+ textcolor(FL_BLACK);
+ selection_color(FL_BLUE);
+
+ scrollbar_.value(0, hh, 0, 1);
+ scrollbar_.step(8.0);
+ scrollbar_.show();
+ scrollbar_.callback(scrollbar_callback);
+
+ end();
+}
+
+
+//
+// 'Fl_HelpView::~Fl_HelpView()' - Destroy a Fl_HelpView widget.
+//
+
+Fl_HelpView::~Fl_HelpView()
+{
+ int i; // Looping var
+ Fl_HelpImage *img; // Current image
+
+
+ if (nblocks_)
+ free(blocks_);
+ if (nlinks_)
+ free(links_);
+ if (ntargets_)
+ free(targets_);
+ if (value_)
+ free((void *)value_);
+ if (image_)
+ {
+ for (i = nimage_, img = image_; i > 0; i --, img ++)
+ {
+ delete img->image;
+ free(img->data);
+ free(img->name);
+ }
+ }
+}
+
+
+//
+// 'Fl_HelpView::load()' - Load the specified file.
+//
+
+int // O - 0 on success, -1 on error
+Fl_HelpView::load(const char *f) // I - Filename to load (may also have target)
+{
+ FILE *fp; // File to read from
+ long len; // Length of file
+ char *target; // Target in file
+ char *slash; // Directory separator
+ const char *localname; // Local filename
+ char error[1024]; // Error buffer
+
+
+ strcpy(filename_, f);
+ strcpy(directory_, filename_);
+
+ if ((slash = strrchr(directory_, '/')) == NULL)
+ directory_[0] = '\0';
+ else if (slash > directory_ && slash[-1] != '/')
+ *slash = '\0';
+
+ if ((target = strrchr(filename_, '#')) != NULL)
+ *target++ = '\0';
+
+ if (link_)
+ localname = (*link_)(filename_);
+ else
+ localname = filename_;
+
+ if (localname != NULL &&
+ (strncmp(localname, "ftp:", 4) == 0 ||
+ strncmp(localname, "http:", 5) == 0 ||
+ strncmp(localname, "https:", 6) == 0 ||
+ strncmp(localname, "ipp:", 4) == 0 ||
+ strncmp(localname, "mailto:", 7) == 0 ||
+ strncmp(localname, "news:", 5) == 0))
+ localname = NULL; // Remote link wasn't resolved...
+ else if (localname != NULL &&
+ strncmp(localname, "file:", 5) == 0)
+ localname += 5; // Adjust for local filename...
+
+ if (value_ != NULL)
+ {
+ free((void *)value_);
+ value_ = NULL;
+ }
+
+ if (localname)
+ {
+ if ((fp = fopen(localname, "rb")) != NULL)
+ {
+ fseek(fp, 0, SEEK_END);
+ len = ftell(fp);
+ rewind(fp);
+
+ value_ = (const char *)calloc(len + 1, 1);
+ fread((void *)value_, 1, len, fp);
+ fclose(fp);
+ }
+ else
+ {
+ sprintf(error, "%s: %s\n", localname, strerror(errno));
+ value_ = strdup(error);
+ }
+ }
+ else
+ {
+ sprintf(error, "%s: %s\n", filename_, strerror(errno));
+ value_ = strdup(error);
+ }
+
+ format();
+
+ if (target)
+ topline(target);
+ else
+ topline(0);
+
+ return (0);
+}
+
+
+//
+// 'Fl_HelpView::load_gif()' - Load a GIF image file...
+//
+
+int // O - 0 = success, -1 = fail
+Fl_HelpView::load_gif(Fl_HelpImage *img, // I - Image pointer
+ FILE *fp) // I - File to load from
+{
+ unsigned char buf[1024]; // Input buffer
+ gif_cmap_t cmap; // Colormap
+ int ncolors, // Bits per pixel
+ transparent; // Transparent color index
+
+
+ // Read the header; we already know it is a GIF file...
+ fread(buf, 13, 1, fp);
+
+ img->w = (buf[7] << 8) | buf[6];
+ img->h = (buf[9] << 8) | buf[8];
+ ncolors = 2 << (buf[10] & 0x07);
+
+ if (buf[10] & GIF_COLORMAP)
+ if (!gif_read_cmap(fp, ncolors, cmap))
+ return (0);
+
+ transparent = -1;
+
+ for (;;)
+ {
+ switch (getc(fp))
+ {
+ case ';' : // End of image
+ return (0); // Early end of file
+
+ case '!' : // Extension record
+ buf[0] = getc(fp);
+ if (buf[0] == 0xf9) // Graphic Control Extension
+ {
+ gif_get_block(fp, buf);
+ if (buf[0] & 1) // Get transparent color index
+ transparent = buf[3];
+ }
+
+ while (gif_get_block(fp, buf) != 0);
+ break;
+
+ case ',' : // Image data
+ fread(buf, 9, 1, fp);
+
+ if (buf[8] & GIF_COLORMAP)
+ {
+ ncolors = 2 << (buf[8] & 0x07);
+
+ if (!gif_read_cmap(fp, ncolors, cmap))
+ return (0);
+ }
+
+ if (transparent >= 0)
+ {
+ unsigned rgba = fltk_colors[bgcolor_];
+
+
+ // Map transparent color to background color...
+ cmap[transparent][0] = rgba >> 24;
+ cmap[transparent][1] = rgba >> 16;
+ cmap[transparent][2] = rgba >> 8;
+ }
+
+ img->w = (buf[5] << 8) | buf[4];
+ img->h = (buf[7] << 8) | buf[6];
+ img->d = 3;
+ img->data = (unsigned char *)malloc(img->w * img->h * img->d);
+ if (img->data == NULL)
+ return (0);
+
+ return (gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE));
+ }
+ }
+}
+
+
+#ifdef HAVE_LIBJPEG
+//
+// 'Fl_HelpView::load_jpeg()' - Load a JPEG image file.
+//
+
+int // O - 0 = success, -1 = fail
+Fl_HelpView::load_jpeg(Fl_HelpImage *img, // I - Image pointer
+ FILE *fp) // I - File to load from
+{
+ struct jpeg_decompress_struct cinfo; // Decompressor info
+ struct jpeg_error_mgr jerr; // Error handler info
+ JSAMPROW row; // Sample row pointer
+
+
+ cinfo.err = jpeg_std_error(&jerr);
+ jpeg_create_decompress(&cinfo);
+ jpeg_stdio_src(&cinfo, fp);
+ jpeg_read_header(&cinfo, 1);
+
+ cinfo.quantize_colors = 0;
+ cinfo.out_color_space = JCS_RGB;
+ cinfo.out_color_components = 3;
+ cinfo.output_components = 3;
+
+ jpeg_calc_output_dimensions(&cinfo);
+
+ img->w = cinfo.output_width;
+ img->h = cinfo.output_height;
+ img->d = cinfo.output_components;
+ img->data = (unsigned char *)malloc(img->w * img->h * img->d);
+
+ if (img->data == NULL)
+ {
+ jpeg_destroy_decompress(&cinfo);
+ return (0);
+ }
+
+ jpeg_start_decompress(&cinfo);
+
+ while (cinfo.output_scanline < cinfo.output_height)
+ {
+ row = (JSAMPROW)(img->data +
+ cinfo.output_scanline * cinfo.output_width *
+ cinfo.output_components);
+ jpeg_read_scanlines(&cinfo, &row, (JDIMENSION)1);
+ }
+
+ jpeg_finish_decompress(&cinfo);
+ jpeg_destroy_decompress(&cinfo);
+
+ return (1);
+}
+#endif // HAVE_LIBJPEG
+
+
+#ifdef HAVE_LIBPNG
+//
+// 'Fl_HelpView::load_png()' - Load a PNG image file.
+//
+
+int // O - 0 = success, -1 = fail
+Fl_HelpView::load_png(Fl_HelpImage *img, // I - Image pointer
+ FILE *fp) // I - File to read from
+{
+ int i; // Looping var
+ png_structp pp; // PNG read pointer
+ png_infop info; // PNG info pointers
+ png_bytep *rows; // PNG row pointers
+ png_color_16 bg; // Background color
+
+
+ // Setup the PNG data structures...
+ pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info = png_create_info_struct(pp);
+
+ // Initialize the PNG read "engine"...
+ png_init_io(pp, fp);
+
+ // Get the image dimensions and convert to grayscale or RGB...
+ png_read_info(pp, info);
+
+ if (info->color_type == PNG_COLOR_TYPE_PALETTE)
+ png_set_expand(pp);
+
+ if (info->color_type == PNG_COLOR_TYPE_GRAY)
+ img->d = 1;
+ else
+ img->d = 3;
+
+ img->w = (int)info->width;
+ img->h = (int)info->height;
+ img->data = (unsigned char *)malloc(img->w * img->h * 3);
+
+ if (info->bit_depth < 8)
+ {
+ png_set_packing(pp);
+ png_set_expand(pp);
+
+ if (info->valid & PNG_INFO_sBIT)
+ png_set_shift(pp, &(info->sig_bit));
+ }
+ else if (info->bit_depth == 16)
+ png_set_strip_16(pp);
+
+#ifdef HAVE_PNG_GET_VALID
+ // Handle transparency...
+ if (png_get_valid(pp, info, PNG_INFO_tRNS))
+ png_set_tRNS_to_alpha(pp);
+#endif // HAVE_PNG_GET_VALID
+
+ // Background color...
+ unsigned rgba = fltk_colors[bgcolor_];
+
+ bg.red = 65535 * (rgba >> 24) / 255;
+ bg.green = 65535 * ((rgba >> 16) & 255) / 255;
+ bg.blue = 65535 * ((rgba >> 8) & 255) / 255;
+
+ png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
+
+ // Allocate pointers...
+ rows = (png_bytep *)calloc(info->height, sizeof(png_bytep));
+
+ for (i = 0; i < (int)info->height; i ++)
+ if (info->color_type == PNG_COLOR_TYPE_GRAY)
+ rows[i] = img->data + i * img->w;
+ else
+ rows[i] = img->data + i * img->w * 3;
+
+ // Read the image, handling interlacing as needed...
+ for (i = png_set_interlace_handling(pp); i > 0; i --)
+ png_read_rows(pp, rows, NULL, img->h);
+
+ // Free memory and return...
+ free(rows);
+
+ png_read_end(pp, info);
+ png_read_destroy(pp, info, NULL);
+
+ return (1);
+}
+#endif // HAVE_LIBPNG
+
+
+//
+// 'Fl_HelpView::resize()' - Resize the help widget.
+//
+
+void
+Fl_HelpView::resize(int xx, // I - New left position
+ int yy, // I - New top position
+ int ww, // I - New width
+ int hh) // I - New height
+{
+ Fl_Widget::resize(xx, yy, ww, hh);
+ scrollbar_.resize(xx + ww - 17, yy, 17, hh);
+
+ format();
+}
+
+
+//
+// 'Fl_HelpView::topline()' - Set the top line to the named target.
+//
+
+void
+Fl_HelpView::topline(const char *n) // I - Target name
+{
+ Fl_HelpTarget key, // Target name key
+ *target; // Pointer to matching target
+
+
+ if (ntargets_ == 0)
+ return;
+
+ strncpy(key.name, n, sizeof(key.name) - 1);
+ key.name[sizeof(key.name) - 1] = '\0';
+
+ target = (Fl_HelpTarget *)bsearch(&key, targets_, ntargets_, sizeof(Fl_HelpTarget),
+ (compare_func_t)compare_targets);
+
+ if (target != NULL)
+ topline(target->y);
+}
+
+
+//
+// 'Fl_HelpView::topline()' - Set the top line by number.
+//
+
+void
+Fl_HelpView::topline(int t) // I - Top line number
+{
+ if (!value_)
+ return;
+
+ if (size_ < (h() - 8) || t < 0)
+ t = 0;
+ else if (t > size_)
+ t = size_;
+
+ topline_ = t;
+
+ scrollbar_.value(topline_, h(), 0, size_);
+
+ do_callback();
+ clear_changed();
+
+ redraw();
+}
+
+
+//
+// 'Fl_HelpView::value()' - Set the help text directly.
+//
+
+void
+Fl_HelpView::value(const char *v) // I - Text to view
+{
+ if (!v)
+ return;
+
+ if (value_ != NULL)
+ free((void *)value_);
+
+ value_ = strdup(v);
+
+ format();
+
+ set_changed();
+ topline(0);
+}
+
+
+//
+// 'gif_read_cmap()' - Read the colormap from a GIF file...
+//
+
+static int // O - -1 = error, 0 = success
+gif_read_cmap(FILE *fp, // I - File to read from
+ int ncolors, // I - Number of colors
+ gif_cmap_t cmap) // O - Colormap
+{
+ // Read the colormap...
+ if (fread(cmap, 3, ncolors, fp) < (size_t)ncolors)
+ return (0);
+
+ return (1);
+}
+
+
+//
+// 'gif_get_block()' - Read a GIF data block...
+//
+
+static int // O - Number characters read
+gif_get_block(FILE *fp, // I - File to read from
+ unsigned char *buf) // I - Input buffer
+{
+ int count; // Number of character to read
+
+
+ // Read the count byte followed by the data from the file...
+ if ((count = getc(fp)) == EOF)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else if (count == 0)
+ gif_eof = 1;
+ else if (fread(buf, 1, count, fp) < (size_t)count)
+ {
+ gif_eof = 1;
+ return (-1);
+ }
+ else
+ gif_eof = 0;
+
+ return (count);
+}
+
+
+//
+// 'gif_get_code()' - Get a LZW code from the file...
+//
+
+static int // O - LZW code
+gif_get_code(FILE *fp, // I - File to read from
+ int code_size, // I - Size of code in bits
+ int first_time) // I - 1 = first time, 0 = not first time
+{
+ unsigned i, j, // Looping vars
+ ret; // Return value
+ int count; // Number of bytes read
+ static unsigned char buf[280]; // Input buffer
+ static unsigned curbit, // Current bit
+ lastbit, // Last bit in buffer
+ done, // Done with this buffer?
+ last_byte; // Last byte in buffer
+ static unsigned bits[8] = // Bit masks for codes
+ {
+ 0x01, 0x02, 0x04, 0x08,
+ 0x10, 0x20, 0x40, 0x80
+ };
+
+
+ if (first_time)
+ {
+ // Just initialize the input buffer...
+ curbit = 0;
+ lastbit = 0;
+ done = 0;
+
+ return (0);
+ }
+
+
+ if ((curbit + code_size) >= lastbit)
+ {
+ // Don't have enough bits to hold the code...
+ if (done)
+ return (-1); // Sorry, no more...
+
+ // Move last two bytes to front of buffer...
+ if (last_byte > 1)
+ {
+ buf[0] = buf[last_byte - 2];
+ buf[1] = buf[last_byte - 1];
+ last_byte = 2;
+ }
+ else if (last_byte == 1)
+ {
+ buf[0] = buf[last_byte - 1];
+ last_byte = 1;
+ }
+
+ // Read in another buffer...
+ if ((count = gif_get_block (fp, buf + last_byte)) <= 0)
+ {
+ // Whoops, no more data!
+ done = 1;
+ return (-1);
+ }
+
+ // Update buffer state...
+ curbit = (curbit - lastbit) + 8 * last_byte;
+ last_byte += count;
+ lastbit = last_byte * 8;
+ }
+
+ ret = 0;
+ for (ret = 0, i = curbit + code_size - 1, j = code_size;
+ j > 0;
+ i --, j --)
+ ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0);
+
+ curbit += code_size;
+
+ return ret;
+}
+
+
+//
+// 'gif_read_lzw()' - Read a byte from the LZW stream...
+//
+
+static int // I - Byte from stream
+gif_read_lzw(FILE *fp, // I - File to read from
+ int first_time, // I - 1 = first time, 0 = not first time
+ int input_code_size) // I - Code size in bits
+{
+ int i, // Looping var
+ code, // Current code
+ incode; // Input code
+ static short fresh = 0, // 1 = empty buffers
+ code_size, // Current code size
+ set_code_size, // Initial code size set
+ max_code, // Maximum code used
+ max_code_size, // Maximum code size
+ firstcode, // First code read
+ oldcode, // Last code read
+ clear_code, // Clear code for LZW input
+ end_code, // End code for LZW input
+ table[2][4096], // String table
+ stack[8192], // Output stack
+ *sp; // Current stack pointer
+
+
+ if (first_time)
+ {
+ // Setup LZW state...
+ set_code_size = input_code_size;
+ code_size = set_code_size + 1;
+ clear_code = 1 << set_code_size;
+ end_code = clear_code + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ // Initialize input buffers...
+ gif_get_code(fp, 0, 1);
+
+ // Wipe the decompressor table...
+ fresh = 1;
+
+ for (i = 0; i < clear_code; i ++)
+ {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+
+ for (; i < 4096; i ++)
+ table[0][i] = table[1][0] = 0;
+
+ sp = stack;
+
+ return (0);
+ }
+ else if (fresh)
+ {
+ fresh = 0;
+
+ do
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+ while (firstcode == clear_code);
+
+ return (firstcode);
+ }
+
+ if (sp > stack)
+ return (*--sp);
+
+ while ((code = gif_get_code (fp, code_size, 0)) >= 0)
+ {
+ if (code == clear_code)
+ {
+ for (i = 0; i < clear_code; i ++)
+ {
+ table[0][i] = 0;
+ table[1][i] = i;
+ }
+
+ for (; i < 4096; i ++)
+ table[0][i] = table[1][i] = 0;
+
+ code_size = set_code_size + 1;
+ max_code_size = 2 * clear_code;
+ max_code = clear_code + 2;
+
+ sp = stack;
+
+ firstcode = oldcode = gif_get_code(fp, code_size, 0);
+
+ return (firstcode);
+ }
+ else if (code == end_code)
+ {
+ unsigned char buf[260];
+
+
+ if (!gif_eof)
+ while (gif_get_block(fp, buf) > 0);
+
+ return (-2);
+ }
+
+ incode = code;
+
+ if (code >= max_code)
+ {
+ *sp++ = firstcode;
+ code = oldcode;
+ }
+
+ while (code >= clear_code)
+ {
+ *sp++ = table[1][code];
+ if (code == table[0][code])
+ return (255);
+
+ code = table[0][code];
+ }
+
+ *sp++ = firstcode = table[1][code];
+ code = max_code;
+
+ if (code < 4096)
+ {
+ table[0][code] = oldcode;
+ table[1][code] = firstcode;
+ max_code ++;
+
+ if (max_code >= max_code_size && max_code_size < 4096)
+ {
+ max_code_size *= 2;
+ code_size ++;
+ }
+ }
+
+ oldcode = incode;
+
+ if (sp > stack)
+ return (*--sp);
+ }
+
+ return (code);
+}
+
+
+//
+// 'gif_read_image()' - Read a GIF image stream...
+//
+
+static int // I - 0 = success, -1 = failure
+gif_read_image(FILE *fp, // I - Input file
+ Fl_HelpImage *img, // I - Image pointer
+ gif_cmap_t cmap, // I - Colormap
+ int interlace) // I - Non-zero = interlaced image
+{
+ unsigned char code_size, // Code size
+ *temp; // Current pixel
+ int xpos, // Current X position
+ ypos, // Current Y position
+ pass; // Current pass
+ int pixel; // Current pixel
+ static int xpasses[4] = { 8, 8, 4, 2 },
+ ypasses[5] = { 0, 4, 2, 1, 999999 };
+
+
+ xpos = 0;
+ ypos = 0;
+ pass = 0;
+ code_size = getc(fp);
+
+ if (gif_read_lzw(fp, 1, code_size) < 0)
+ return (0);
+
+ temp = img->data;
+
+ while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
+ {
+ temp[0] = cmap[pixel][0];
+
+ if (img->d > 1)
+ {
+ temp[1] = cmap[pixel][1];
+ temp[2] = cmap[pixel][2];
+ }
+
+ xpos ++;
+ temp += img->d;
+ if (xpos == img->w)
+ {
+ xpos = 0;
+
+ if (interlace)
+ {
+ ypos += xpasses[pass];
+ temp += (xpasses[pass] - 1) * img->w * img->d;
+
+ if (ypos >= img->h)
+ {
+ pass ++;
+
+ ypos = ypasses[pass];
+ temp = img->data + ypos * img->w * img->d;
+ }
+ }
+ else
+ ypos ++;
+ }
+
+ if (ypos >= img->h)
+ break;
+ }
+
+ return (1);
+}
+
+
+//
+// 'scrollbar_callback()' - A callback for the scrollbar.
+//
+
+static void
+scrollbar_callback(Fl_Widget *s, void *)
+{
+ ((Fl_HelpView *)(s->parent()))->topline(int(((Fl_Scrollbar*)s)->value()));
+}
+
+
+//
+// End of "$Id: Fl_HelpView.cxx,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $".
+//
diff --git a/src/Makefile b/src/Makefile
index 9ef41161e..96c2f8783 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile,v 1.18.2.14.2.6 2001/08/02 18:39:01 easysw Exp $"
+# "$Id: Makefile,v 1.18.2.14.2.7 2001/08/02 19:43:49 easysw Exp $"
#
# Library makefile for the Fast Light Tool Kit (FLTK).
#
@@ -45,6 +45,8 @@ CPPFILES = \
Fl_FileChooser2.cxx \
Fl_FileIcon.cxx \
Fl_Group.cxx \
+ Fl_HelpDialog.cxx \
+ Fl_HelpView.cxx \
Fl_Image.cxx \
Fl_Input.cxx \
Fl_Input_.cxx \
@@ -168,11 +170,11 @@ $(LIBNAME): $(OBJECTS)
libfltk.so.1.1 libfltk.sl.1.1: $(OBJECTS)
echo $(DSOCOMMAND) $@ ...
- $(DSOCOMMAND) $@ $(OBJECTS)
+ $(DSOCOMMAND) $@ $(OBJECTS) $(IMAGELIBS)
libfltk_s.a: $(OBJECTS)
echo $(DSOCOMMAND) libfltk_s.o ...
- $(DSOCOMMAND) libfltk_s.o $(OBJECTS)
+ $(DSOCOMMAND) libfltk_s.o $(OBJECTS) $(IMAGELIBS)
echo $(LIBCOMMAND) libfltk_s.a libfltk_s.o
$(LIBCOMMAND) libfltk_s.a libfltk_s.o
chmod +x libfltk_s.a
@@ -251,5 +253,5 @@ install: $(LIBNAME) $(DSONAME) $(GLLIBNAME) $(GLDSONAME)
ln -s FL $(includedir)/Fl
#
-# End of "$Id: Makefile,v 1.18.2.14.2.6 2001/08/02 18:39:01 easysw Exp $".
+# End of "$Id: Makefile,v 1.18.2.14.2.7 2001/08/02 19:43:49 easysw Exp $".
#
diff --git a/test/Makefile b/test/Makefile
index b32d59c55..da2f3b07d 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,5 +1,5 @@
#
-# "$Id: Makefile,v 1.19.2.7.2.3 2001/08/02 18:15:44 easysw Exp $"
+# "$Id: Makefile,v 1.19.2.7.2.4 2001/08/02 19:43:49 easysw Exp $"
#
# Test/example program makefile for the Fast Light Tool Kit (FLTK).
#
@@ -30,7 +30,7 @@ CPPFILES =\
color_chooser.cxx cube.cxx cursor.cxx curve.cxx demo.cxx \
doublebuffer.cxx editor.cxx file_chooser.cxx fonts.cxx \
forms.cxx fractals.cxx fullscreen.cxx gl_overlay.cxx \
- glpuzzle.cxx hello.cxx iconize.cxx image.cxx input.cxx \
+ glpuzzle.cxx hello.cxx help.cxx iconize.cxx image.cxx input.cxx \
keyboard.cxx label.cxx list_visuals.cxx mandelbrot.cxx \
menubar.cxx message.cxx minimum.cxx navigation.cxx \
output.cxx overlay.cxx pixmap.cxx pixmap_browser.cxx \
@@ -42,7 +42,7 @@ CPPFILES =\
ALL = adjuster arc ask bitmap boxtype browser button buttons \
checkers clock colbrowser color_chooser cursor curve \
demo doublebuffer editor file_chooser fonts forms hello \
- iconize image input keyboard label list_visuals \
+ help iconize image input keyboard label list_visuals \
mandelbrot menubar message minimum navigation output \
overlay pixmap pixmap_browser radio resizebox scroll \
subwindow symbols tabs tile valuators fast_slow resize \
@@ -70,6 +70,10 @@ include ../makeinclude
$(ALL): ../lib/$(LIBNAME)
# Programs needing special instructions...
+help: help.cxx
+ echo Compiling and linking $@...
+ echo $(CXX) -I.. $(CXXFLAGS) help.cxx -o $@ $(LINKFLTK) $(LDLIBS) $(IMAGELIBS)
+ $(CXX) -I.. $(CXXFLAGS) help.cxx -o $@ $(LINKFLTK) $(LDLIBS) $(IMAGELIBS)
keyboard: keyboard.cxx keyboard_ui.cxx
echo Compiling and linking $@...
$(CXX) -I.. $(CXXFLAGS) keyboard.cxx $(LINKFLTK) $(LDLIBS) -o $@
@@ -124,5 +128,5 @@ install:
@echo Nothing to install in test directory.
#
-# End of "$Id: Makefile,v 1.19.2.7.2.3 2001/08/02 18:15:44 easysw Exp $".
+# End of "$Id: Makefile,v 1.19.2.7.2.4 2001/08/02 19:43:49 easysw Exp $".
#
diff --git a/test/demo.menu b/test/demo.menu
index ae377e4ca..caf2282a7 100644
--- a/test/demo.menu
+++ b/test/demo.menu
@@ -64,6 +64,7 @@
@o:file chooser:file_chooser
@o:XForms Emulation:forms
@o:fonts:fonts
+ @o:HelpDialog:help
@main:Tutorial\nfrom\nManual:@j
@j:ask\n(modified):ask
diff --git a/test/help.cxx b/test/help.cxx
new file mode 100644
index 000000000..04a0be6c1
--- /dev/null
+++ b/test/help.cxx
@@ -0,0 +1,67 @@
+//
+// "$Id: help.cxx,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $"
+//
+// Fl_HelpDialog test program.
+//
+// Copyright 1999-2001 by Easy Software Products.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library 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
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+// Contents:
+//
+// main() - Display the help GUI...
+//
+
+//
+// Include necessary headers...
+//
+
+#include <FL/Fl_HelpDialog.H>
+
+
+//
+// 'main()' - Display the help GUI...
+//
+
+int // O - Exit status
+main(int argc, // I - Number of command-line arguments
+ char *argv[]) // I - Command-line arguments
+{
+ Fl_HelpDialog *help; // Help dialog
+
+
+ help = new Fl_HelpDialog;
+
+ if (argc < 2)
+ help->load("../documentation/index.html");
+ else
+ help->load(argv[1]);
+
+ help->show();
+
+ Fl::run();
+
+ delete help;
+
+ return (0);
+}
+
+
+//
+// End of "$Id: help.cxx,v 1.1.2.1 2001/08/02 19:43:49 easysw Exp $".
+//