dslinux/user/pixil/libs/flnx/src Fl.cxx Fl_Adjuster.cxx Fl_Animator.cxx Fl_Bitmap.cxx Fl_Box.cxx Fl_Browser.cxx Fl_Browser_.cxx Fl_Browser_load.cxx Fl_Button.cxx Fl_Chart.cxx Fl_Check_Button.cxx Fl_Choice.cxx Fl_Clock.cxx Fl_Color_Chooser.cxx Fl_Counter.cxx Fl_Dial.cxx Fl_Double_Window.cxx Fl_Font.H Fl_Gl_Choice.H Fl_Gl_Choice.cxx Fl_Gl_Overlay.cxx Fl_Gl_Window.cxx Fl_Group.cxx Fl_Image.cxx Fl_Input.cxx Fl_Input_.cxx Fl_Light_Button.cxx Fl_Menu.cxx Fl_Menu_.cxx Fl_Menu_Bar.cxx Fl_Menu_Button.cxx Fl_Menu_Window.cxx Fl_Menu_add.cxx Fl_Menu_global.cxx Fl_Multi_Label.cxx Fl_Output.cxx Fl_Overlay_Window.cxx Fl_Pack.cxx Fl_Pixmap.cxx Fl_Positioner.cxx Fl_Repeat_Button.cxx Fl_Return_Button.cxx Fl_Roller.cxx Fl_Round_Button.cxx Fl_Scroll.cxx Fl_Scrollbar.cxx Fl_Single_Window.cxx Fl_Slider.cxx Fl_Tabs.cxx Fl_Tile.cxx Fl_Valuator.cxx Fl_Value_Input.cxx Fl_Value_Output.cxx Fl_Value_Slider.cxx Fl_Widget.cxx Fl_Window.cxx Fl_Window_fullscreen.cxx Fl_Window_hotspot.cxx Fl_Window_! iconize.cxx Fl_XColor.H Fl_abort.cxx Fl_add_idle.cxx Fl_arg.cxx Fl_cutpaste.cxx Fl_cutpaste_win32.cxx Fl_display.cxx Fl_get_key.cxx Fl_get_key_win32.cxx Fl_get_system_colors.cxx Fl_grab.cxx Fl_own_colormap.cxx Fl_visual.cxx Fl_win32.cxx Fl_x.cxx Makefile cmap.cxx d1.xbm d1_mask.xbm dump_compose.c ew.xbm ew_mask.xbm fastarrow.h filename_absolute.cxx filename_expand.cxx filename_ext.cxx filename_isdir.cxx filename_list.cxx filename_match.cxx filename_setext.cxx fl_arc.cxx fl_arci.cxx fl_ask.cxx fl_boxtype.cxx fl_call_main.c fl_cmap.h fl_color.cxx fl_color_win32.cxx fl_cursor.cxx fl_curve.cxx fl_diamond_box.cxx fl_draw.cxx fl_draw_image.cxx fl_draw_image_win32.cxx fl_draw_pixmap.cxx fl_engraved_label.cxx fl_file_chooser.cxx fl_font.cxx fl_font_win32.cxx fl_labeltype.cxx fl_oval_box.cxx fl_overlay.cxx fl_overlay_visual.cxx fl_rect.cxx fl_round_box.cxx fl_rounded_box.cxx fl_scroll_area.cxx fl_set_font.cxx fl_set_fonts.cxx fl_set_fonts_win32.cxx fl_set_gray.cxx fl_shadow_box.cxx ! fl_shortcut.cxx fl_show_colormap.cxx fl_symbols.cxx fl_vertex.cxx form

amadeus dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:25:18 CEST 2006


Update of /cvsroot/dslinux/dslinux/user/pixil/libs/flnx/src
In directory antilope:/tmp/cvs-serv11916/libs/flnx/src

Added Files:
	Fl.cxx Fl_Adjuster.cxx Fl_Animator.cxx Fl_Bitmap.cxx 
	Fl_Box.cxx Fl_Browser.cxx Fl_Browser_.cxx Fl_Browser_load.cxx 
	Fl_Button.cxx Fl_Chart.cxx Fl_Check_Button.cxx Fl_Choice.cxx 
	Fl_Clock.cxx Fl_Color_Chooser.cxx Fl_Counter.cxx Fl_Dial.cxx 
	Fl_Double_Window.cxx Fl_Font.H Fl_Gl_Choice.H Fl_Gl_Choice.cxx 
	Fl_Gl_Overlay.cxx Fl_Gl_Window.cxx Fl_Group.cxx Fl_Image.cxx 
	Fl_Input.cxx Fl_Input_.cxx Fl_Light_Button.cxx Fl_Menu.cxx 
	Fl_Menu_.cxx Fl_Menu_Bar.cxx Fl_Menu_Button.cxx 
	Fl_Menu_Window.cxx Fl_Menu_add.cxx Fl_Menu_global.cxx 
	Fl_Multi_Label.cxx Fl_Output.cxx Fl_Overlay_Window.cxx 
	Fl_Pack.cxx Fl_Pixmap.cxx Fl_Positioner.cxx 
	Fl_Repeat_Button.cxx Fl_Return_Button.cxx Fl_Roller.cxx 
	Fl_Round_Button.cxx Fl_Scroll.cxx Fl_Scrollbar.cxx 
	Fl_Single_Window.cxx Fl_Slider.cxx Fl_Tabs.cxx Fl_Tile.cxx 
	Fl_Valuator.cxx Fl_Value_Input.cxx Fl_Value_Output.cxx 
	Fl_Value_Slider.cxx Fl_Widget.cxx Fl_Window.cxx 
	Fl_Window_fullscreen.cxx Fl_Window_hotspot.cxx 
	Fl_Window_iconize.cxx Fl_XColor.H Fl_abort.cxx Fl_add_idle.cxx 
	Fl_arg.cxx Fl_cutpaste.cxx Fl_cutpaste_win32.cxx 
	Fl_display.cxx Fl_get_key.cxx Fl_get_key_win32.cxx 
	Fl_get_system_colors.cxx Fl_grab.cxx Fl_own_colormap.cxx 
	Fl_visual.cxx Fl_win32.cxx Fl_x.cxx Makefile cmap.cxx d1.xbm 
	d1_mask.xbm dump_compose.c ew.xbm ew_mask.xbm fastarrow.h 
	filename_absolute.cxx filename_expand.cxx filename_ext.cxx 
	filename_isdir.cxx filename_list.cxx filename_match.cxx 
	filename_setext.cxx fl_arc.cxx fl_arci.cxx fl_ask.cxx 
	fl_boxtype.cxx fl_call_main.c fl_cmap.h fl_color.cxx 
	fl_color_win32.cxx fl_cursor.cxx fl_curve.cxx 
	fl_diamond_box.cxx fl_draw.cxx fl_draw_image.cxx 
	fl_draw_image_win32.cxx fl_draw_pixmap.cxx 
	fl_engraved_label.cxx fl_file_chooser.cxx fl_font.cxx 
	fl_font_win32.cxx fl_labeltype.cxx fl_oval_box.cxx 
	fl_overlay.cxx fl_overlay_visual.cxx fl_rect.cxx 
	fl_round_box.cxx fl_rounded_box.cxx fl_scroll_area.cxx 
	fl_set_font.cxx fl_set_fonts.cxx fl_set_fonts_win32.cxx 
	fl_set_gray.cxx fl_shadow_box.cxx fl_shortcut.cxx 
	fl_show_colormap.cxx fl_symbols.cxx fl_vertex.cxx 
	forms_bitmap.cxx forms_compatability.cxx forms_free.cxx 
	forms_fselect.cxx forms_pixmap.cxx forms_timer.cxx gl_draw.cxx 
	gl_start.cxx glut_compatability.cxx glut_font.cxx makedepend 
	mediumarrow.h ns.xbm ns_mask.xbm numericsort.c scandir.c 
	scandir_win32.c slowarrow.h vsnprintf.c 
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it

--- NEW FILE: Fl_arg.cxx ---
//
// "$Id: Fl_arg.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Optional argument initialization code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// OPTIONAL initialization code for a program using fltk.
// You do not need to call this!  Feel free to make up your own switches.

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <FL/filename.H>
#include <FL/fl_draw.H>
#include <ctype.h>
#include <string.h>

#ifdef WIN32
int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
#define NoValue		0x0000
#define XValue  	0x0001
#define YValue		0x0002
#define WidthValue  	0x0004
#define HeightValue  	0x0008
#define AllValues 	0x000F
#define XNegative 	0x0010
#define YNegative 	0x0020
#endif

static int match(const char *a, const char *match, int atleast = 1) {
  const char *b = match;
  while (*a && (*a == *b || tolower(*a) == *b)) {a++; b++;}
  return !*a && b >= match+atleast;
}

// flags set by previously parsed arguments:
extern char fl_show_iconic; // in Fl_x.C
static char arg_called;
static char return_i;
static const char *name;
static const char *geometry;
static const char *title;
// these are in Fl_get_system_colors and are set by the switches:
extern const char *fl_fg;
extern const char *fl_bg;
extern const char *fl_bg2;

// consume a switch from argv.  Returns number of words eaten, 0 on error:
int Fl::arg(int argc, char **argv, int &i) {
  arg_called = 1;
  const char *s = argv[i];

  if (!s) {i++; return 1;}	// something removed by calling program?

  // a word that does not start with '-', or a word after a '--', or
  // the word '-' by itself all start the "non-switch arguments" to
  // a program.  Return 0 to indicate that we don't understand the
  // word, but set a flag (return_i) so that args() will return at
  // that point:
  if (s[0] != '-' || s[1] == '-' || !s[1]) {return_i = 1; return 0;}
  s++; // point after the dash

  if (match(s, "iconic")) {
    fl_show_iconic = 1;
    i++;
    return 1;
  }

  const char *v = argv[i+1];
  if (i >= argc-1 || !v)
    return 0;	// all the rest need an argument, so if missing it is an error

  if (match(s, "geometry")) {

#ifndef NANO_X	//tanghao
    int flags, gx, gy; unsigned int gw, gh;
    flags = XParseGeometry(v, &gx, &gy, &gw, &gh);
    if (!flags) return 0;
#endif
    geometry = v;

#ifndef WIN32
  } else if (match(s, "display")) {
    Fl::display(v);
#endif

  } else if (match(s, "title")) {
    title = v;

  } else if (match(s, "name")) {
    name = v;

  } else if (match(s, "bg2", 3) || match(s, "background2", 11)) {
    fl_bg2 = v;

  } else if (match(s, "bg") || match(s, "background")) {
    fl_bg = v;

  } else if (match(s, "fg") || match(s, "foreground")) {
    fl_fg = v;

  } else return 0; // unrecognized

  i += 2;
  return 2;
}

// consume all switches from argv.  Returns number of words eaten.
// Returns zero on error.  'i' will either point at first word that
// does not start with '-', at the error word, or after a '--', or at
// argc.  If your program does not take any word arguments you can
// report an error if i < argc.

int Fl::args(int argc, char** argv, int& i, int (*cb)(int,char**,int&)) {
  arg_called = 1;
  i = 1; // skip argv[0]
  while (i < argc) {
    if (cb && cb(argc,argv,i)) continue;
    if (!arg(argc,argv,i)) return return_i ? i : 0;
  }
  return i;
}


// show a main window, use any parsed arguments
void Fl_Window::show(int argc, char **argv) {
  if (!argc) {show(); return;}
  if (!arg_called) Fl::args(argc,argv);

  // set colors first, so background_pixel is correct:
  static char beenhere;
  if (!beenhere) {
    beenhere = 1;
    Fl::get_system_colors(); // opens display!  May call Fl::fatal()
    if (geometry) {
      int flags = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
#ifndef NANO_X
      flags = XParseGeometry(geometry, &gx, &gy, &gw, &gh);
      if (flags & XNegative) gx = Fl::w()-w()+gx;
      if (flags & YNegative) gy = Fl::h()-h()+gy;
#endif
      //  int mw,mh; minsize(mw,mh);
      //  if (mw > gw) gw = mw;
      //  if (mh > gh) gh = mh;
      Fl_Widget *r = resizable();
      if (!r) resizable(this);
      // for WIN32 we assumme window is not mapped yet:
#ifndef NANO_X
      if (flags & (XValue | YValue))
	x(-1), resize(gx,gy,gw,gh);
      else
	size(gw,gh);
#endif
    resizable(r);
    }
  }

  if (name) {xclass(name); name = 0;}
  else if (!xclass()) xclass(filename_name(argv[0]));
  if (title) {label(title); title = 0;}
  else if (!label()) label(xclass());
  show();

#ifndef WIN32
  // set the command string, used by state-saving window managers:
  int i;
  int n=0; for (i=0; i<argc; i++) n += strlen(argv[i])+1;
#ifdef __GNUC__
  char buffer[n];
#else
  char *buffer = new char[n];
#endif
  char *p = buffer;
  for (i=0; i<argc; i++) for (const char *q = argv[i]; (*p++ = *q++););
#ifndef NANO_X
  XChangeProperty(fl_display, fl_xid(this), XA_WM_COMMAND, XA_STRING, 8, 0,
		  (unsigned char *)buffer, p-buffer-1);
#endif
#ifndef __GNUC__
  delete[] buffer;
#endif
#endif

}

// Calls useful for simple demo programs, with automatic help message:

static const char * const helpmsg =
"options are:\n"
" -d[isplay] host:n.n\n"
" -g[eometry] WxH+X+Y\n"
" -t[itle] windowtitle\n"
" -n[ame] classname\n"
" -i[conic]\n"
" -fg color\n"
" -bg color\n"
" -bg2 color";

const char * const Fl::help = helpmsg+13;

void Fl::args(int argc, char **argv) {
  int i; if (Fl::args(argc,argv,i) < argc) Fl::error(helpmsg);
}

#ifdef WIN32

/* the following function was stolen from the X sources as indicated. */

/* Copyright 	Massachusetts Institute of Technology  1985, 1986, 1987 */
/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */

/*
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of M.I.T. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission.  M.I.T. makes no representations about the
suitability of this software for any purpose.  It is provided "as is"
without express or implied warranty.
*/

/*
 *    XParseGeometry parses strings of the form
 *   "=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
 *   width, height, xoffset, and yoffset are unsigned integers.
 *   Example:  "=80x24+300-49"
 *   The equal sign is optional.
 *   It returns a bitmask that indicates which of the four values
 *   were actually found in the string.  For each value found,
 *   the corresponding argument is updated;  for each value
 *   not found, the corresponding argument is left unchanged. 
 */

static int ReadInteger(char* string, char** NextString)
{
  register int Result = 0;
  int Sign = 1;
    
  if (*string == '+')
    string++;
  else if (*string == '-') {
    string++;
    Sign = -1;
  }
  for (; (*string >= '0') && (*string <= '9'); string++) {
    Result = (Result * 10) + (*string - '0');
  }
  *NextString = string;
  if (Sign >= 0)
    return (Result);
  else
    return (-Result);
}

int XParseGeometry(const char* string, int* x, int* y,
		   unsigned int* width, unsigned int* height)
{
  int mask = NoValue;
  register char *strind;
  unsigned int tempWidth, tempHeight;
  int tempX, tempY;
  char *nextCharacter;

  if ( (string == NULL) || (*string == '\0')) return(mask);
  if (*string == '=')
    string++;  /* ignore possible '=' at beg of geometry spec */

  strind = (char *)string;
  if (*strind != '+' && *strind != '-' && *strind != 'x') {
    tempWidth = ReadInteger(strind, &nextCharacter);
    if (strind == nextCharacter) 
      return (0);
    strind = nextCharacter;
    mask |= WidthValue;
  }

  if (*strind == 'x' || *strind == 'X') {	
    strind++;
    tempHeight = ReadInteger(strind, &nextCharacter);
    if (strind == nextCharacter)
      return (0);
    strind = nextCharacter;
    mask |= HeightValue;
  }

  if ((*strind == '+') || (*strind == '-')) {
    if (*strind == '-') {
      strind++;
      tempX = -ReadInteger(strind, &nextCharacter);
      if (strind == nextCharacter)
	return (0);
      strind = nextCharacter;
      mask |= XNegative;

    } else {
      strind++;
      tempX = ReadInteger(strind, &nextCharacter);
      if (strind == nextCharacter)
	return(0);
      strind = nextCharacter;
      }
    mask |= XValue;
    if ((*strind == '+') || (*strind == '-')) {
      if (*strind == '-') {
	strind++;
	tempY = -ReadInteger(strind, &nextCharacter);
	if (strind == nextCharacter)
	  return(0);
	strind = nextCharacter;
	mask |= YNegative;

      } else {
	strind++;
	tempY = ReadInteger(strind, &nextCharacter);
	if (strind == nextCharacter)
	  return(0);
	strind = nextCharacter;
      }
      mask |= YValue;
    }
  }
	
  /* If strind isn't at the end of the string the it's an invalid
     geometry specification. */

  if (*strind != '\0') return (0);

  if (mask & XValue)
    *x = tempX;
  if (mask & YValue)
    *y = tempY;
  if (mask & WidthValue)
    *width = tempWidth;
  if (mask & HeightValue)
    *height = tempHeight;
  return (mask);
}

#endif // ifdef WIN32

//
// End of "$Id: Fl_arg.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_color_win32.cxx ---
//
// "$Id: fl_color_win32.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// WIN32 color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// The fltk "colormap".  This allows ui colors to be stored in 8-bit
// locations, and provides a level of indirection so that global color
// changes can be made.  Not to be confused with the X colormap, which
// I try to hide completely.

// SGI compiler seems to have problems with unsigned char arguments
// being used to index arrays.  So I always copy them to an integer
// before use.

#include <config.h>
#include <FL/Fl.H>
#include <FL/win32.H>
#include <FL/fl_draw.H>

static unsigned fl_cmap[256] = {
#include "fl_cmap.h" // this is a file produced by "cmap.cxx":
};

// Translations to win32 data structures:
Fl_XMap fl_xmap[256];

Fl_XMap* fl_current_xmap;

HPALETTE fl_palette;
HPEN tmppen=0;
HBRUSH tmpbrush=0;

static void clear_xmap(Fl_XMap& xmap) {
  if (xmap.pen) {
    if(!tmppen) tmppen = CreatePen(PS_SOLID, 1, 0);
    if(!tmpbrush) tmpbrush = CreateSolidBrush(0);
    HPEN oldpen = (HPEN)SelectObject(fl_gc, tmppen); // Push out the current pen of the gc
    if(oldpen != xmap.pen) SelectObject(fl_gc, oldpen); // Put it back if it is not the one we are about to delete
    SelectObject(fl_gc, tmpbrush); // Push out the old pen of the gc
    //fl_current_xmap = 0;
    DeleteObject((HGDIOBJ)(xmap.pen));
    xmap.pen = 0;
    xmap.brush = -1;
  }
}

static void set_xmap(Fl_XMap& xmap, COLORREF c) {
  xmap.rgb = c;
  xmap.pen = CreatePen(PS_SOLID, 1, xmap.rgb);
  xmap.brush = -1;
}

Fl_Color fl_color_;

void fl_color(Fl_Color i) {
  fl_color_ = i;
  Fl_XMap &xmap = fl_xmap[i];
  if (!xmap.pen) {
#if USE_COLORMAP
    if (fl_palette) {
      set_xmap(xmap, PALETTEINDEX(i));
    } else {
#endif
      unsigned c = fl_cmap[i];
      set_xmap(xmap, RGB(uchar(c>>24), uchar(c>>16), uchar(c>>8)));
#if USE_COLORMAP
    }
#endif
  }
  fl_current_xmap = &xmap;
  SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
}

void fl_color(uchar r, uchar g, uchar b) {
  static Fl_XMap xmap;
  COLORREF c = RGB(r,g,b);
  if (!xmap.pen || c != xmap.rgb) {
    clear_xmap(xmap);
    set_xmap(xmap, c);
  }
  fl_current_xmap = &xmap;
  SelectObject(fl_gc, (HGDIOBJ)(xmap.pen));
}

HBRUSH fl_brush() {
  Fl_XMap *xmap = fl_current_xmap;
  // Wonko: we use some statistics to cache only a limited number
  // of brushes:
#define FL_N_BRUSH 16
  static struct Fl_Brush {
    HBRUSH brush;
    unsigned short usage;
    Fl_XMap* backref;
  } brushes[FL_N_BRUSH];

  int i = xmap->brush; // find the associated brush
  if (i != -1) { // if the brush was allready allocated
    if (brushes[i].brush == NULL) goto CREATE_BRUSH;
    if ( (++brushes[i].usage) > 32000 ) { // keep a usage statistic
      for (int j=0; j<FL_N_BRUSH; j++) {
	if (brushes[j].usage>16000)
	  brushes[j].usage -= 16000;
	else 
	  brushes[j].usage = 0;
      }
    }
    return brushes[i].brush;
  } else {
    int umin = 32000, imin = 0;
    for (i=0; i<FL_N_BRUSH; i++) {
      if (brushes[i].brush == NULL) goto CREATE_BRUSH;
      if (brushes[i].usage<umin) {
	umin = brushes[i].usage;
	imin = i;
      }
    }
    i = imin;
    DeleteObject(brushes[i].brush);
    brushes[i].brush = NULL;
    brushes[i].backref->brush = -1;
  }
CREATE_BRUSH:
  brushes[i].brush = CreateSolidBrush(xmap->rgb);
  brushes[i].usage = 0;
  brushes[i].backref = xmap;
  xmap->brush = i;
  return brushes[i].brush;
}

void Fl::free_color(Fl_Color i, int overlay) {
  if (overlay) return; // do something about GL overlay?
  clear_xmap(fl_xmap[i]);
}

void Fl::set_color(Fl_Color i, unsigned c) {
  if (fl_cmap[i] != c) {
    clear_xmap(fl_xmap[i]);
    fl_cmap[i] = c;
  }
}

#if USE_COLORMAP

// 'fl_select_palette()' - Make a color palette for 8-bit displays if necessary
// Thanks to Michael Sweet @ Easy Software Products for this

HPALETTE
fl_select_palette(void)
{
  static char beenhere;
  if (!beenhere) {
    beenhere = 1;

    //if (GetDeviceCaps(fl_gc, BITSPIXEL) > 8) return NULL;
    int nColors = GetDeviceCaps(fl_gc, SIZEPALETTE);
    if (nColors <= 0 || nColors > 256) return NULL;
    // this will try to work on < 256 color screens, but will probably
    // come out quite badly.

    // I lamely try to get this variable-sized object allocated on stack:
    ulong foo[(sizeof(LOGPALETTE)+256*sizeof(PALETTEENTRY))/sizeof(ulong)+1];
    LOGPALETTE *pPal = (LOGPALETTE*)foo;

    pPal->palVersion    = 0x300;
    pPal->palNumEntries = nColors;

    // Build 256 colors from the standard FLTK colormap...

    for (int i = 0; i < nColors; i ++) {
      pPal->palPalEntry[i].peRed   = (fl_cmap[i] >> 24) & 255;
      pPal->palPalEntry[i].peGreen = (fl_cmap[i] >> 16) & 255;
      pPal->palPalEntry[i].peBlue  = (fl_cmap[i] >>  8) & 255;
      pPal->palPalEntry[i].peFlags = 0;
    };

    // Create the palette:
    fl_palette = CreatePalette(pPal);
  }
  if (fl_palette) {
    SelectPalette(fl_gc, fl_palette, FALSE);
    RealizePalette(fl_gc);
  }
  return fl_palette;
}

#endif

//
// End of "$Id: fl_color_win32.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Roller.cxx ---
//
// "$Id: Fl_Roller.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Roller widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Rapid-App style knob

#include <FL/Fl.H>
#include <FL/Fl_Roller.H>
#include <FL/fl_draw.H>
#include <math.h>

int Fl_Roller::handle(int event) {
  static int ipos;
  int newpos = horizontal() ? Fl::event_x() : Fl::event_y();
  switch (event) {
  case FL_PUSH:
    handle_push();
    ipos = newpos;
    return 1;
  case FL_DRAG:
    handle_drag(clamp(round(increment(previous_value(),newpos-ipos))));
    return 1;
  case FL_RELEASE:
    handle_release();
    return 1;
  default:
    return 0;
  }
}

void Fl_Roller::draw() {
  if (damage()&FL_DAMAGE_ALL) draw_box();
  int X = x()+Fl::box_dx(box());
  int Y = y()+Fl::box_dy(box());
  int W = w()-Fl::box_dw(box())-1;
  int H = h()-Fl::box_dh(box())-1;
  if (W<=0 || H <=0) return;
  int offset = step() ? int(value()/step()) : 0;
  const double ARC = 1.5; // 1/2 the number of radians visible
  const double delta = .2; // radians per knurl
  if (horizontal()) { // horizontal one
    // draw shaded ends of wheel:
    int h1 = W/4+1; // distance from end that shading starts
    fl_color(color()); fl_rectf(X+h1,Y,W-2*h1,H);
    for (int i=0; h1; i++) {
      fl_color((Fl_Color)(FL_GRAY-i-1));
      int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
      fl_rectf(X+h2,Y,h1-h2,H);
      fl_rectf(X+W-h1,Y,h1-h2,H);
      h1 = h2;
    }
    if (active_r()) {
      // draw ridges:
      double junk;
      for (double y = -ARC+modf(offset*sin(ARC)/(W/2)/delta,&junk)*delta;;
	   y += delta) {
	int y1 = int((sin(y)/sin(ARC)+1)*W/2);
	if (y1 <= 0) continue; else if (y1 >= W-1) break;
	fl_color(FL_DARK3); fl_yxline(X+y1,Y+1,Y+H-1);
	if (y < 0) y1--; else y1++;
	fl_color(FL_LIGHT1);fl_yxline(X+y1,Y+1,Y+H-1);
      }
      // draw edges:
      h1 = W/8+1; // distance from end the color inverts
      fl_color(FL_DARK2);
      fl_xyline(X+h1,Y+H-1,X+W-h1);
      fl_color(FL_DARK3);
      fl_yxline(X,Y+H,Y,X+h1);
      fl_xyline(X+W-h1,Y,X+W);
      fl_color(FL_LIGHT2);
      fl_xyline(X+h1,Y-1,X+W-h1);
      fl_yxline(X+W,Y,Y+H,X+W-h1);
      fl_xyline(X+h1,Y+H,X);
    }
  } else { // vertical one
    // draw shaded ends of wheel:
    int h1 = H/4+1; // distance from end that shading starts
    fl_color(color()); fl_rectf(X,Y+h1,W,H-2*h1);
    for (int i=0; h1; i++) {
      fl_color((Fl_Color)(FL_GRAY-i-1));
      int h2 = FL_GRAY-i-1 > FL_DARK3 ? 2*h1/3+1 : 0;
      fl_rectf(X,Y+h2,W,h1-h2);
      fl_rectf(X,Y+H-h1,W,h1-h2);
      h1 = h2;
    }
    if (active_r()) {
      // draw ridges:
      double junk;
      for (double y = -ARC+modf(offset*sin(ARC)/(H/2)/delta,&junk)*delta;
	   ; y += delta) {
	int y1 = int((sin(y)/sin(ARC)+1)*H/2);
	if (y1 <= 0) continue; else if (y1 >= H-1) break;
	fl_color(FL_DARK3); fl_xyline(X+1,Y+y1,X+W-1);
	if (y < 0) y1--; else y1++;
	fl_color(FL_LIGHT1);fl_xyline(X+1,Y+y1,X+W-1);
      }
      // draw edges:
      h1 = H/8+1; // distance from end the color inverts
      fl_color(FL_DARK2);
      fl_yxline(X+W-1,Y+h1,Y+H-h1);
      fl_color(FL_DARK3);
      fl_xyline(X+W,Y,X,Y+h1);
      fl_yxline(X,Y+H-h1,Y+H);
      fl_color(FL_LIGHT2);
      fl_yxline(X,Y+h1,Y+H-h1);
      fl_xyline(X,Y+H,X+W,Y+H-h1);
      fl_yxline(X+W,Y+h1,Y);
    }
  }
}

Fl_Roller::Fl_Roller(int X,int Y,int W,int H,const char* L)
  : Fl_Valuator(X,Y,W,H,L) {
  box(FL_UP_FRAME);
  step(1,1000);
}

//
// End of "$Id: Fl_Roller.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Window_iconize.cxx ---
//
// "$Id: Fl_Window_iconize.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Window minification code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/x.H>

extern char fl_show_iconic; // in Fl_x.C

void Fl_Window::iconize() {
  if (!shown()) {
    fl_show_iconic = 1;
    show();
  } else {
#ifdef WIN32
    ShowWindow(i->xid, SW_SHOWMINNOACTIVE);
#else
#ifdef NANO_X //tanghao
	GrUnmapWindow(i->xid);
#else 
    XIconifyWindow(fl_display, i->xid, fl_screen);
#endif //tanghao
#endif
  }
}

//
// End of "$Id: Fl_Window_iconize.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Widget.cxx ---
//
// "$Id: Fl_Widget.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Base widget class for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Group.H>

////////////////////////////////////////////////////////////////
// for compatability with Forms, all widgets without callbacks are
// inserted into a "queue" when they are activated, and the forms
// compatability interaction functions (fl_do_events, etc) will
// read one widget at a time from this queue and return it:

const int QUEUE_SIZE = 20;

static Fl_Widget *obj_queue[QUEUE_SIZE];
static int obj_head, obj_tail;

void Fl_Widget::default_callback(Fl_Widget *o, void * /*v*/) {
#if 0
  // This is necessary for strict forms compatability but is confusing.
  // Use the parent's callback if this widget does not have one.
  for (Fl_Widget *p = o->parent(); p; p = p->parent())
    if (p->callback() != default_callback) {
      p->do_callback(o,v);
      return;
    }
#endif
  obj_queue[obj_head++] = o;
  if (obj_head >= QUEUE_SIZE) obj_head = 0;
  if (obj_head == obj_tail) {
    obj_tail++;
    if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
  }
}

Fl_Widget *Fl::readqueue() {
  if (obj_tail==obj_head) return 0;
  Fl_Widget *o = obj_queue[obj_tail++];
  if (obj_tail >= QUEUE_SIZE) obj_tail = 0;
  return o;
}
    
////////////////////////////////////////////////////////////////

int Fl_Widget::handle(int) {return 0;}

Fl_Widget::Fl_Widget(int X, int Y, int W, int H, const char* L) {

  x_ = X; y_ = Y; w_ = W; h_ = H;

  label_.value	= L;
  label_.type	= FL_NORMAL_LABEL;
  label_.font	= FL_HELVETICA;
  label_.size	= FL_NORMAL_SIZE;
  label_.color	= FL_BLACK;
  callback_	= default_callback;
  user_data_ 	= 0;
  type_		= 0;
  flags_	= 0;
  damage_	= 0;
  box_		= FL_NO_BOX;
  color_	= FL_GRAY;
  color2_	= FL_GRAY;
  align_	= FL_ALIGN_CENTER;
  when_		= FL_WHEN_RELEASE;

  parent_ = 0;
  if (Fl_Group::current()) Fl_Group::current()->add(this);
}

void Fl_Widget::resize(int X, int Y, int W, int H) {
  x_ = X; y_ = Y; w_ = W; h_ = H;
}

// this is useful for parent widgets to call to resize children:
int Fl_Widget::damage_resize(int X, int Y, int W, int H) {
  if (x() == X && y() == Y && w() == W && h() == H) return 0;
  resize(X, Y, W, H);
  redraw();
  return 1;
}

int Fl_Widget::take_focus() {
  if (!takesevents()) return 0;
  if (!handle(FL_FOCUS)) return 0; // see if it wants it
  if (contains(Fl::focus())) return 1; // it called Fl::focus for us
  Fl::focus(this);
  return 1;
}

extern void fl_throw_focus(Fl_Widget*); // in Fl_x.C

// Destruction does not remove from any parent group!  And groups when
// destroyed destroy all their children.  This is convienent and fast.
// However, it is only legal to destroy a "root" such as an Fl_Window,
// and automatic destructors may be called.
Fl_Widget::~Fl_Widget() {
  parent_ = 0; // kludge to prevent ~Fl_Group from destroying again
  fl_throw_focus(this);
}

// redraw this, plus redraw opaque object if there is an outside label
static void redraw_label(Fl_Widget* w) {
  w->redraw();
  if (w->label() && (w->align()&15) && !(w->align() & FL_ALIGN_INSIDE)) {
    for (Fl_Widget *p = w->parent(); p; p = p->parent())
      if (p->box() || !p->parent()) {p->redraw(); break;}
  }
}

void Fl_Widget::activate() {
  if (!active()) {
    clear_flag(INACTIVE);
    if (active_r()) {
      redraw_label(this);
      handle(FL_ACTIVATE);
      if (inside(Fl::focus())) Fl::focus()->take_focus();
    }
  }
}

void Fl_Widget::deactivate() {
  if (active_r()) {
    set_flag(INACTIVE);
    redraw_label(this);
    handle(FL_DEACTIVATE);
    fl_throw_focus(this);
  } else {
    set_flag(INACTIVE);
  }
}

int Fl_Widget::active_r() const {
  for (const Fl_Widget* o = this; o; o = o->parent())
    if (!o->active()) return 0;
  return 1;
}

void Fl_Widget::show() {
  if (!visible()) {
    clear_flag(INVISIBLE);
    if (visible_r()) {
      redraw_label(this);
      handle(FL_SHOW);
      if (inside(Fl::focus())) Fl::focus()->take_focus();
    }
  }
}

void Fl_Widget::hide() {
  if (visible_r()) {
    set_flag(INVISIBLE);
    for (Fl_Widget *p = parent(); p; p = p->parent())
      if (p->box() || !p->parent()) {p->redraw(); break;}
    handle(FL_HIDE);
    fl_throw_focus(this);
  } else {
    set_flag(INVISIBLE);
  }
}

int Fl_Widget::visible_r() const {
  for (const Fl_Widget* o = this; o; o = o->parent())
    if (!o->visible()) return 0;
  return 1;
}

// return true if widget is inside (or equal to) this:
// Returns false for null widgets.
int Fl_Widget::contains(const Fl_Widget *o) const {
  for (; o; o = o->parent_) if (o == this) return 1;
  return 0;
}

//
// End of "$Id: Fl_Widget.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_cursor.cxx ---
//
// "$Id: fl_cursor.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Mouse cursor support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Change the current cursor.
// Under X the cursor is attached to the X window.  I tried to hide
// this and pretend that changing the cursor is a drawing function.
// This avoids a field in the Fl_Window, and I suspect is more
// portable to other systems.

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
#if !defined(WIN32) && !defined(NANO_X)
#include <X11/cursorfont.h>
#endif
#include <FL/fl_draw.H>

void
fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg)
{
    if (Fl::first_window())
	Fl::first_window()->cursor(c, fg, bg);
}

#ifdef WIN32

#  ifndef IDC_HAND
#    define IDC_HAND	MAKEINTRESOURCE(32649)
#  endif // !IDC_HAND

void
Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color)
{
    if (!shown())
	return;
    if (c > FL_CURSOR_NESW) {
	i->cursor = 0;
    } else if (c == FL_CURSOR_DEFAULT) {
	i->cursor = fl_default_cursor;
    } else {
	LPSTR n;
	switch (c) {
	case FL_CURSOR_ARROW:
	    n = IDC_ARROW;
	    break;
	case FL_CURSOR_CROSS:
	    n = IDC_CROSS;
	    break;
	case FL_CURSOR_WAIT:
	    n = IDC_WAIT;
	    break;
	case FL_CURSOR_INSERT:
	    n = IDC_IBEAM;
	    break;
	case FL_CURSOR_HELP:
	    n = IDC_HELP;
	    break;
	case FL_CURSOR_HAND:{
		OSVERSIONINFO osvi;

		// Get the OS version: Windows 98 and 2000 have a standard
		// hand cursor.
		memset(&osvi, 0, sizeof(OSVERSIONINFO));
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		GetVersionEx(&osvi);

		if (osvi.dwMajorVersion > 4 ||
		    (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 &&
		     osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS))
		    n = IDC_HAND;
		else
		    n = IDC_UPARROW;
	    }
	    break;
	case FL_CURSOR_MOVE:
	    n = IDC_SIZEALL;
	    break;
	case FL_CURSOR_N:
	case FL_CURSOR_S:
	case FL_CURSOR_NS:
	    n = IDC_SIZENS;
	    break;
	case FL_CURSOR_NE:
	case FL_CURSOR_SW:
	case FL_CURSOR_NESW:
	    n = IDC_SIZENESW;
	    break;
	case FL_CURSOR_E:
	case FL_CURSOR_W:
	case FL_CURSOR_WE:
	    n = IDC_SIZEWE;
	    break;
	case FL_CURSOR_SE:
	case FL_CURSOR_NW:
	case FL_CURSOR_NWSE:
	    n = IDC_SIZENWSE;
	    break;
	default:
	    n = IDC_NO;
	    break;
	}
	i->cursor = LoadCursor(NULL, n);
    }
    SetCursor(i->cursor);
}

#else

// I like the MSWindows resize cursors, so I duplicate them here:

#define CURSORSIZE 16
#define HOTXY 7
struct TableEntry
{
    uchar bits[CURSORSIZE * CURSORSIZE / 8];
    uchar mask[CURSORSIZE * CURSORSIZE / 8];
    Cursor cursor;
}
table[] =
{
    { {				// FL_CURSOR_NS
    0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80,
		0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
		0x80, 0x01, 0x80, 0x01, 0xe0, 0x07, 0xc0, 0x03, 0x80,
		0x01, 0x00, 0x00}
    , {
    0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0,
	    0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0,
	    0x03, 0xf0, 0x0f, 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}
    }
    , { {			// FL_CURSOR_EW
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08,
		0x10, 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30,
		0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00}
    , {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c,
	    0x38, 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c,
	    0x38, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
    }
    , { {			// FL_CURSOR_NWSE
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78,
		0x00, 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17,
		0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00}
    , {
    0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc,
	    0x00, 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00,
	    0x3f, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}
    }
    , { {			// FL_CURSOR_NESW
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00,
		0x1e, 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00,
		0x78, 0x00, 0x38, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00}
    , {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00,
	    0x3f, 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc,
	    0x00, 0x7c, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}
    }
    , { {
    0}
    , {
    0}
    }				// FL_CURSOR_NONE & unknown
};

#ifdef NANO_X
// Microwindows default cursor
static MWIMAGEBITS cursorbits[16] = {
    0xe000, 0x9800, 0x8600, 0x4180,
    0x4060, 0x2018, 0x2004, 0x107c,
    0x1020, 0x0910, 0x0988, 0x0544,
    0x0522, 0x0211, 0x000a, 0x0004
};
static MWIMAGEBITS cursormask[16] = {
    0xe000, 0xf800, 0xfe00, 0x7f80,
    0x7fe0, 0x3ff8, 0x3ffc, 0x1ffc,
    0x1fe0, 0x0ff0, 0x0ff8, 0x077c,
    0x073e, 0x021f, 0x000e, 0x0004
};
#endif

void
Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg)
{
    if (!shown())
	return;
    uchar fg_r, fg_g, fg_b, bg_r, bg_g, bg_b;
    Cursor cursor;
#ifndef NANO_X
    int deleteit = 0;
#endif
    if (!c) {
	cursor = None;

#ifdef NANO_X
	//TableEntry *q = table;
	GrSetCursor(fl_window, CURSORSIZE, CURSORSIZE, HOTXY, HOTXY, WHITE,
		    BLACK, cursorbits, cursormask);
#endif

    } else {
	if (c >= FL_CURSOR_NS) {
	    TableEntry *q =
		(c > FL_CURSOR_NESW) ? table + 4 : table + (c - FL_CURSOR_NS);
	    if (!(q->cursor)) {
#ifdef NANO_X			//tanghao
		Fl::get_color(fg, fg_r, fg_g, fg_b);
		Fl::get_color(bg, bg_r, bg_g, bg_b);
		GrSetCursor(fl_window, CURSORSIZE, CURSORSIZE, HOTXY, HOTXY,
			    fl_xpixel(bg_r, bg_g, bg_b), fl_xpixel(fg_r, fg_g,
								   fg_b),
			    (GR_BITMAP *) (q->bits), (GR_BITMAP *) (q->mask));
		//GrSetCursor(fl_window,CURSORSIZE,CURSORSIZE,HOTXY,HOTXY,BLACK,WHITE,( GR_BITMAP*)(q->bits),( GR_BITMAP*)(q->mask));
		//(GR_WINDOW_ID wid, GR_SIZE width, GR_SIZE height,
		//GR_COORD hotx, GR_COORD hoty, GR_COLOR foreground,
		//GR_COLOR background, GR_BITMAP *fbbitmap,
		//GR_BITMAP *bgbitmap);
#else
		XColor dummy;
		Pixmap p = XCreateBitmapFromData(fl_display,
						 RootWindow(fl_display,
							    fl_screen),
						 (const char *) (q->bits),
						 CURSORSIZE, CURSORSIZE);
		Pixmap m = XCreateBitmapFromData(fl_display,
						 RootWindow(fl_display,
							    fl_screen),
						 (const char *) (q->mask),
						 CURSORSIZE, CURSORSIZE);
		q->cursor =
		    XCreatePixmapCursor(fl_display, p, m, &dummy, &dummy,
					HOTXY, HOTXY);
		XFreePixmap(fl_display, m);
		XFreePixmap(fl_display, p);
#endif //tanghao
	    }
	    cursor = q->cursor;
	} else {
#ifndef NANO_X			//tanghao
	    cursor = XCreateFontCursor(fl_display, (c - 1) * 2);
	    deleteit = 1;
#endif //tanghao
	}
#ifndef NANO_X			//tanghao
	XColor fgc;
	uchar r, g, b;
	Fl::get_color(fg, r, g, b);
	fgc.red = r << 8;
	fgc.green = g << 8;
	fgc.blue = b << 8;
	XColor bgc;
	Fl::get_color(bg, r, g, b);
	bgc.red = r << 8;
	bgc.green = g << 8;
	bgc.blue = b << 8;
	XRecolorCursor(fl_display, cursor, &fgc, &bgc);
#endif //tanghao
    }
#ifndef NANO_X			//tanghao
    XDefineCursor(fl_display, fl_xid(this), cursor);
    if (deleteit)
	XFreeCursor(fl_display, cursor);
#endif //tanghao
}

#endif

//
// End of "$Id: fl_cursor.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: cmap.cxx ---
//
// "$Id: cmap.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Colormap generation program for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This program produces the contents of "fl_cmap.h" as stdout

// #include <gl/gl.h>
#include <stdio.h>

// This table is initialized with color values I got by reading the
// colormap on an IRIX 4.3 machine:

// "full intensity colors" have been turned down some to make white
// background less intense by default.  The hope is that this will make
// fltk programs more friendly on color-adjusted screens.  If you want
// pure colors you should get them out of the colormap.

//#define III 244 // maximum intensity of the basic colors

// that results in errors and unshared colormap entries, so full intensity:
#define III 255 // maximum intensity of the basic colors

static short cmap[256][3] = {
// 3-bit colormap:
  {  0,  0,  0},	// black
  {III,  0,  0},	// red
  {  0,III,  0},	// green
  {III,III,  0},	// yellow
  {  0,  0,III},	// blue
  {III,  0,III},	// magenta
  {  0,III,III},	// cyan
  {III,III,III},	// white
// pastel versions of those colors:
  { 85, 85, 85},	// 1/3 gray
  {198,113,113},	// salmon? pale red?
  {113,198,113},	// pale green
  {142,142, 56},	// khaki
  {113,113,198},	// pale blue
  {142, 56,142},	// purple, orchid, pale magenta
  { 56,142,142},	// cadet blue, aquamarine, pale cyan
  {170,170,170},	// 2/3 gray
// These next 16 are the FL_FREE_COLOR area.  For compatability with
// some existing DD programs, I prefill them with the random colors
// you get on a 5.3 machine:
  { 16, 16, 16},
  {128, 40,128},
  {198, 30, 30},
  { 66, 30, 30},
  {176,140,140},
  {  0, 20, 20},
  { 20, 10, 10},
  { 40, 20, 20},
  { 60, 30, 30},
  {  0, 80, 80},
  {  0, 40, 40},
  { 20, 20,  0},
  { 40, 40,  0},
  { 80, 80, 10},
  {150,150, 20},
  {160, 10, 10},
// The rest of the colormap is a gray ramp and table, filled in below:
};

// This is Fl::background from Fl_get_system_colors.C, with modifications:

#define FL_GRAY_RAMP 32
#define FL_NUM_GRAY  24
#define FL_GRAY 49 // old value is 47
typedef unsigned char uchar;
#include <math.h>

void background(uchar r, uchar g, uchar b) {
  // replace the gray ramp so that color 47 (by default 2/3) is this color
  if (!r) r = 1; else if (r==255) r = 254;
  double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  if (!g) g = 1; else if (g==255) g = 254;
  double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  if (!b) b = 1; else if (b==255) b = 254;
  double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  for (int i = 0; i < FL_NUM_GRAY; i++) {
    double gray = i/(FL_NUM_GRAY-1.0);
    cmap[i+FL_GRAY_RAMP][0] = uchar(pow(gray,powr)*255+.5);
    cmap[i+FL_GRAY_RAMP][1] = uchar(pow(gray,powg)*255+.5);
    cmap[i+FL_GRAY_RAMP][2] = uchar(pow(gray,powb)*255+.5);
  }
}

int main() {
  int i,r,g,b;
#if 0
  /* Read colormap colors into internal table */
  long cmwin;
  noport();
  cmwin = winopen("CM");
  for (i=0; i<256; i++)
    getmcolor(i,&cmap[i][0],&cmap[i][1],&cmap[i][2]);
  winclose(cmwin);
#endif
// overwrite the X allocation area with one color so people are
// discouraged from using it:
  for (i=16; i<32; i++) {cmap[i][0]=cmap[i][1]=cmap[i][2] = 85;}

  // fill in the gray ramp:
  background(0xc0, 0xc0, 0xc0); // microsoft colors
  // background(cmap[15][0],cmap[15][1],cmap[15][2]); // old fltk colors
  // copy the 1/3 and 2/3 gray to the closest locations in gray ramp:
  cmap[39][0] = cmap[39][1] = cmap[39][2] = cmap[8][0];
  cmap[47][0] = cmap[47][1] = cmap[47][2] = cmap[15][0];

  // fill in the color cube
  i = 56;
  for (b=0; b<5; b++)
    for (r=0; r<5; r++)
      for (g=0; g<8; g++) {
	cmap[i][0] = r*255/4;
	cmap[i][1] = g*255/7;
	cmap[i][2] = b*255/4;
	i++;
      }

  for (i=0; i<256; i++) {
    printf("\t0x%02x%02x%02x00",cmap[i][0],cmap[i][1],cmap[i][2]);
    if (i < 255) printf(",\n");
  }
  printf("\n");
  return 0;
}

//
// End of "$Id: cmap.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_show_colormap.cxx ---
//
// "$Id: fl_show_colormap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Colormap color selection dialog for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Select a color from the colormap.
// Pretty much unchanged from Forms.

#include <FL/Fl.H>
#include <FL/Fl_Single_Window.H>
#include <FL/fl_draw.H>
#include <FL/fl_show_colormap.H>
#include <config.h>

#define BOXSIZE 14
#define BORDER 4

class ColorMenu : public Fl_Window {
  Fl_Color initial;
  Fl_Color which, previous;
  int done;
  void drawbox(Fl_Color);
  void draw();
  int handle(int);
public:
  ColorMenu(Fl_Color oldcol);
  Fl_Color run();
};

ColorMenu::ColorMenu(Fl_Color oldcol) :
  Fl_Window(BOXSIZE*8+1+2*BORDER, BOXSIZE*32+1+2*BORDER) {
  clear_border();
  set_modal();
  initial = which = oldcol;
}

void ColorMenu::drawbox(Fl_Color c) {
  if (c < 0 || c > 255) return;
  int x = (c%8)*BOXSIZE+BORDER;
  int y = (c/8)*BOXSIZE+BORDER;
#if BORDER_WIDTH < 3
  if (c == which) fl_draw_box(FL_DOWN_BOX, x+1, y+1, BOXSIZE-1, BOXSIZE-1, c);
  else fl_draw_box(FL_BORDER_BOX, x, y, BOXSIZE+1, BOXSIZE+1, c);
#else
  fl_draw_box(c == which ? FL_DOWN_BOX : FL_BORDER_BOX,
	      x, y, BOXSIZE+1, BOXSIZE+1, c);
#endif
}

void ColorMenu::draw() {
  if (damage() != FL_DAMAGE_CHILD) {
    fl_draw_box(FL_UP_BOX,0,0,w(),h(),color());
    for (int c = 0; c < 256; c++) drawbox((Fl_Color)c);
  } else {
    drawbox(previous);
    drawbox(which);
  }
  previous = which;
}

int ColorMenu::handle(int e) {
  int c = which;
  switch (e) {
  case FL_PUSH:
  case FL_DRAG: {
    int X = (Fl::event_x_root() - x() - BORDER);
    if (X >= 0) X = X/BOXSIZE;
    int Y = (Fl::event_y_root() - y() - BORDER);
    if (Y >= 0) Y = Y/BOXSIZE;
    if (X >= 0 && X < 8 && Y >= 0 && Y < 32)
      c = 8*Y + X;
    else
      c = initial;
    } break;
  case FL_RELEASE:
    done = 1;
    return 1;
  case FL_KEYBOARD:
    switch (Fl::event_key()) {
    case FL_Up: if (c > 7) c -= 8; break;
    case FL_Down: if (c < 256-8) c += 8; break;
    case FL_Left: if (c > 0) c--; break;
    case FL_Right: if (c < 255) c++; break;
    case FL_Escape: which = initial; done = 1; return 1;
    case FL_Enter: done = 1; return 1;
    default: return 0;
    }
    break;
  default:
    return 0;
  }
  if (c != which) {
    which = (Fl_Color)c; damage(FL_DAMAGE_CHILD);
    int bx = (c%8)*BOXSIZE+BORDER;
    int by = (c/8)*BOXSIZE+BORDER;
    int px = x();
    int py = y();
    if (px+bx+BOXSIZE+BORDER >= Fl::w()) px = Fl::w()-bx-BOXSIZE-BORDER;
    if (py+by+BOXSIZE+BORDER >= Fl::h()) py = Fl::h()-by-BOXSIZE-BORDER;
    if (px+bx < BORDER) px = BORDER-bx;
    if (py+by < BORDER) py = BORDER-by;
    position(px,py);
  }
  return 1;
}

extern char fl_override_redirect; // hack for menus

Fl_Color ColorMenu::run() {
  if (which < 0 || which > 255) {
    position(Fl::event_x_root()-w()/2, Fl::event_y_root()-y()/2);
  } else {
    position(Fl::event_x_root()-(initial%8)*BOXSIZE-BOXSIZE/2-BORDER,
	     Fl::event_y_root()-(initial/8)*BOXSIZE-BOXSIZE/2-BORDER);
  }
  Fl::grab(*this);
  show();
  done = 0;
  while (!done) Fl::wait();
  Fl::release();
  return which;
}

Fl_Color fl_show_colormap(Fl_Color oldcol) {
  ColorMenu m(oldcol);
  return m.run();
}

//
// End of "$Id: fl_show_colormap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_labeltype.cxx ---
//
// "$Id: fl_labeltype.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $"
//
// Label drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Drawing code for the (one) common label types.
// Other label types (symbols) are in their own source files
// to avoid linking if not used.

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Group.H>
#include <FL/fl_draw.H>
#include <stdio.h>

void
fl_no_label(const Fl_Label*,int,int,int,int,Fl_Align) {}

void
fl_normal_label(const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
  fl_font(o->font, o->size);
  fl_color((Fl_Color)o->color);
  fl_draw(o->value, X, Y, W, H, align);
}

void
fl_normal_measure(const Fl_Label* o, int& W, int& H) {
  fl_font(o->font, o->size);
  fl_measure(o->value, W, H);
}

#define MAX_LABELTYPE 16

static Fl_Label_Draw_F* table[MAX_LABELTYPE] = {
  fl_normal_label,
  fl_no_label,
  fl_normal_label,	// _FL_SYMBOL_LABEL,
  fl_normal_label,	// _FL_SHADOW_LABEL,
  fl_normal_label,	// _FL_ENGRAVED_LABEL,
  fl_normal_label,	// _FL_EMBOSSED_LABEL,
  fl_no_label,		// _FL_BITMAP_LABEL,
  fl_no_label,		// _FL_PIXMAP_LABEL,
  fl_no_label,		// _FL_IMAGE_LABEL,
  // FL_FREE_LABELTYPE+n:
  fl_no_label, fl_no_label, fl_no_label,
  fl_no_label, fl_no_label, fl_no_label, fl_no_label,
};

static Fl_Label_Measure_F* measure[MAX_LABELTYPE];

void Fl::set_labeltype(Fl_Labeltype t,Fl_Label_Draw_F* f,Fl_Label_Measure_F*m) 
{
  table[t] = f; measure[t] = m;
}

////////////////////////////////////////////////////////////////

// draw label with arbitrary alignment in arbitrary box:
void Fl_Label::draw(int X, int Y, int W, int H, Fl_Align align) const {
  if (!value) return;
  table[type](this, X, Y, W, H, align);
}

void Fl_Label::measure(int& W, int& H) const {
  if (!value) return;
  Fl_Label_Measure_F* f = ::measure[type]; if (!f) f = fl_normal_measure;
  f(this, W, H);
}

// The normal call for a draw() method:
void Fl_Widget::draw_label() const {
  int X = x_+Fl::box_dx(box());
  int W = w_-Fl::box_dw(box());
  if (W > 11 && align()&(FL_ALIGN_LEFT|FL_ALIGN_RIGHT)) {X += 3; W -= 6;}
  draw_label(X, y_+Fl::box_dy(box()), W, h_-Fl::box_dh(box()));
}

// draw() can use this instead to change the bounding box:
void Fl_Widget::draw_label(int X, int Y, int W, int H) const {
  // quit if we are not drawing a label inside the widget:
  if ((align()&15) && !(align() & FL_ALIGN_INSIDE)) return;
  draw_label(X,Y,W,H,align());
}

// Anybody can call this to force the label to draw anywhere:
extern char fl_draw_shortcut;
void Fl_Widget::draw_label(int X, int Y, int W, int H, Fl_Align a) const {
  if (flags()&SHORTCUT_LABEL) fl_draw_shortcut = 1;
  Fl_Label l1 = label_;
  if (!active_r()) l1.color = inactive((Fl_Color)l1.color);
  l1.draw(X,Y,W,H,a);
  fl_draw_shortcut = 0;
}

// include these vars here so they can be referenced without including
// Fl_Input_ code:
#include <FL/Fl_Input_.H>

//
// End of "$Id: fl_labeltype.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_XColor.H ---
//
// "$Id: Fl_XColor.H,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// X-specific color definitions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#include <FL/Enumerations.H>

// one of these for each color in fltk's "colormap":
// if overlays are enabled, another one for the overlay
struct Fl_XColor {
  unsigned char r,g,b;	// actual color used by X
  unsigned char mapped;	// true when XAllocColor done
  unsigned long pixel;	// the X pixel to use
};
extern FL_EXPORT Fl_XColor fl_xmap[/*overlay*/][256];

// mask & shifts to produce xcolor for truecolor visuals:
extern FL_EXPORT unsigned char fl_redmask, fl_greenmask, fl_bluemask;
extern FL_EXPORT int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;

//
// End of "$Id: Fl_XColor.H,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_set_fonts.cxx ---
//
// "$Id: fl_set_fonts.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// More font utilities for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This function fills in the fltk font table with all the fonts that
// are found on the X server.  It tries to place the fonts into families
// and to sort them so the first 4 in a family are normal, bold, italic,
// and bold italic.

#ifdef WIN32
#include "fl_set_fonts_win32.cxx"
#else

// Standard X fonts are matched by a pattern that is always of
// this form, and this pattern is put in the table:
// "-*-family-weight-slant-width1-style-*-registry-encoding"

// Non-standard font names (those not starting with '-') are matched
// by a pattern of the form "prefix*suffix", where the '*' is where
// fltk thinks the point size is, or by the actual font name if no
// point size is found.

// Fltk knows how to pull an "attribute" out of a font name, such as
// bold or italic, by matching known x font field values.  All words
// that don't match a known attribute are combined into the "name"
// of the font.  Names are compared before attributes for sorting, this
// makes the bold and plain version of a font come out next to each
// other despite the poor X font naming scheme.

// By default fl_set_fonts() only does iso8859-1 encoded fonts.  You can
// do all normal X fonts by passing "-*" or every possible font with "*".

// Fl::set_font will take strings other than the ones this stores
// and can identify any font on X that way.  You may want to write your
// own system of font management and not use this code.

#include <FL/Fl.H>
#include <FL/x.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

// turn word N of a X font name into either some attribute bits
// (right now 0, FL_BOLD, or FL_ITALIC), or into -1 indicating that
// the word should be put into the name:

static int attribute(int n, const char *p) {
  // don't put blank things into name:
  if (!*p || *p=='-' || *p=='*') return 0;
  if (n == 3) { // weight
    if (!strncmp(p,"normal",6) ||
	!strncmp(p,"light",5) ||
	!strncmp(p,"medium",6) ||
	!strncmp(p,"book",4)) return 0;
    if (!strncmp(p,"bold",4) || !strncmp(p,"demi",4)) return FL_BOLD;
  } else if (n == 4) { // slant
    if (*p == 'r') return 0;
    if (*p == 'i' || *p == 'o') return FL_ITALIC;
  } else if (n == 5) { // sWidth
    if (!strncmp(p,"normal",6)) return 0;
  }
  return -1;
}

// return non-zero if the registry-encoding should be used:
extern const char* fl_encoding;
static int use_registry(const char *p) {
  return *p && *p!='*' && strcmp(p,fl_encoding);
}

// turn a stored (with *'s) X font name into a pretty name:
const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
  const char* p = fl_fonts[fnum].name;
  if (!p) return "";
  static char *buffer; if (!buffer) buffer = new char[128];
  char *o = buffer;

  if (*p != '-') { // non-standard font, just replace * with spaces:
    if (ap) {
      int type = 0;
      if (strstr(p,"bold")) type = FL_BOLD;
      if (strstr(p,"ital")) type |= FL_ITALIC;
      *ap = type;
    }
    for (;*p; p++) {
      if (*p == '*' || *p == ' ' || *p == '-') {
	do p++; while (*p == '*' || *p == ' ' || *p == '-');
	if (!*p) break;
	*o++ = ' ';
      }
      *o++ = *p;
    }
    *o = 0;
    return buffer;
  }

  // get the family:
  const char *x = fl_font_word(p,2); if (*x) x++; if (*x=='*') x++;
  if (!*x) return p;
  const char *e = fl_font_word(x,1);
  strncpy(o,x,e-x); o += e-x;

  // collect all the attribute words:
  int type = 0;
  for (int n = 3; n <= 6; n++) {
    // get the next word:
    if (*e) e++; x = e; e = fl_font_word(x,1);
    int t = attribute(n,x);
    if (t < 0) {*o++ = ' '; strncpy(o,x,e-x); o += e-x;}
    else type |= t;
  }

  // skip over the '*' for the size and get the registry-encoding:
  x = fl_font_word(e,2);
  if (*x) {x++; *o++ = '('; while (*x) *o++ = *x++; *o++ = ')';}

  *o = 0;
  if (type & FL_BOLD) {strcpy(o, " bold"); o += 5;}
  if (type & FL_ITALIC) {strcpy(o, " italic"); o += 7;}

  if (ap) *ap = type;

  return buffer;
}

// sort raw (non-'*') X font names into perfect order:

static int ultrasort(const void *aa, const void *bb) {
  const char *a = *(char **)aa;
  const char *b = *(char **)bb;

  // sort all non x-fonts at the end:
  if (*a != '-') {
    if (*b == '-') return 1;
    // 2 non-x fonts are matched by "numeric sort"
    int ret = 0;
    for (;;) {
      if (isdigit(*a) && isdigit(*b)) {
	int na = strtol(a, (char **)&a, 10);
	int nb = strtol(b, (char **)&b, 10);
	if (!ret) ret = na-nb;
      } else if (*a != *b) {
	return (*a-*b);
      } else if (!*a) {
	return ret;
      } else {
	a++; b++;
      }
    }
  } else {
    if (*b != '-') return -1;
  }

  // skip the foundry (assumme equal):
  for (a++; *a && *a++!='-';);
  for (b++; *b && *b++!='-';);

  // compare the family and all the attribute words:
  int atype = 0;
  int btype = 0;
  for (int n = 2; n <= 6; n++) {
    int at = attribute(n,a);
    int bt = attribute(n,b);
    if (at < 0) {
      if (bt >= 0) return 1;
      for (;;) {if (*a!=*b) return *a-*b; b++; if (!*a || *a++=='-') break;}
    } else {
      if (bt < 0) return -1;
      a = fl_font_word(a,1); if (*a) a++;
      b = fl_font_word(b,1); if (*b) b++;
      atype |= at; btype |= bt;
    }
  }

  // remember the pixel size:
  int asize = atoi(a);
  int bsize = atoi(b);

  // compare the registry/encoding:
  a = fl_font_word(a,6); if (*a) a++;
  b = fl_font_word(b,6); if (*b) b++;
  if (use_registry(a)) {
    if (!use_registry(b)) return 1;
    int r = strcmp(a,b); if (r) return r;
  } else {
    if (use_registry(b)) return -1;
  }

  if (atype != btype) return atype-btype;
  if (asize != bsize) return asize-bsize;

  // something wrong, just do a string compare...
  return strcmp(*(char**)aa, *(char**)bb);
}

// converts a X font name to a standard starname, returns point size:
static int to_canonical(char *to, const char *from) {
  char* c = fl_find_fontsize((char*)from);
  if (!c) return -1; // no point size found...
  char* endptr;
  int size = strtol(c,&endptr,10);
  if (from[0] == '-') {
    // replace the "foundry" with -*-:
    *to++ = '-'; *to++ = '*';
    for (from++; *from && *from != '-'; from++);
    // skip to the registry-encoding:
    endptr = (char*)fl_font_word(endptr,6);
    if (*endptr && !use_registry(endptr+1)) endptr = "";
  }
  int n = c-from;
  strncpy(to,from,n);
  to[n++] = '*';
  strcpy(to+n,endptr);
  return size;
}

static int fl_free_font = FL_FREE_FONT;

Fl_Font Fl::set_fonts(const char* xstarname) {
  fl_open_display();
  int xlistsize;
  char buf[20];
  if (!xstarname) {
    strcpy(buf,"-*-"); strcpy(buf+3,fl_encoding);
    xstarname = buf;
  }
#ifndef NANO_X
  char **xlist = XListFonts(fl_display, xstarname, 10000, &xlistsize);
#else
  char **xlist = 0;
#endif
  if (!xlist) return (Fl_Font)fl_free_font;
  qsort(xlist, xlistsize, sizeof(*xlist), ultrasort);
  int used_xlist = 0;
  for (int i=0; i<xlistsize;) {
    int first_xlist = i;
    const char *p = xlist[i++];
    char canon[1024];
    int size = to_canonical(canon, p);
    if (size >= 0) {
      for (;;) { // find all matching fonts:
	if (i >= xlistsize) break;
	const char *q = xlist[i];
	char this_canon[1024];
	if (to_canonical(this_canon, q) < 0) break;
	if (strcmp(canon, this_canon)) break;
	i++;
      }
      /*if (*p=='-' || i > first_xlist+1)*/ p = canon;
    }
    int j;
    for (j = 0;; j++) {
      if (j < FL_FREE_FONT) {
	// see if it is one of our built-in fonts:
	// if so, set the list of x fonts, since we have it anyway
	if (fl_fonts[j].name && !strcmp(fl_fonts[j].name, p)) break;
      } else {
	j = fl_free_font++;
	if (p == canon) p = strdup(p); else used_xlist = 1;
	Fl::set_font((Fl_Font)j, p);
	break;
      }
    }
    if (!fl_fonts[j].xlist) {
      fl_fonts[j].xlist = xlist+first_xlist;
      fl_fonts[j].n = -(i-first_xlist);
      used_xlist = 1;
    }
  }
#ifndef NANO_X
  if (!used_xlist) XFreeFontNames(xlist);
#endif
  return (Fl_Font)fl_free_font;
}

int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
  Fl_Fontdesc *s = fl_fonts+fnum;
  if (!s->name) s = fl_fonts; // empty slot in table, use entry 0
  if (!s->xlist) {
    fl_open_display();
#ifndef NANO_X
    s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
#endif
    if (!s->xlist) return 0;
  }
  int listsize = s->n; if (listsize<0) listsize = -listsize;
  static int sizes[128];
  int numsizes = 0;
  for (int i = 0; i < listsize; i++) {
    char *q = s->xlist[i];
    char *d = fl_find_fontsize(q);
    if (!d) continue;
    int s = strtol(d,0,10);
    if (!numsizes || sizes[numsizes-1] < s) {
      sizes[numsizes++] = s;
    } else {
      // insert-sort the new size into list:
      int n;
      for (n = numsizes-1; n > 0; n--) if (sizes[n-1] < s) break;
      if (sizes[n] != s) {
	for (int m = numsizes; m > n; m--) sizes[m] = sizes[m-1];
	sizes[n] = s;
	numsizes++;
      }
    }
  }
  sizep = sizes;
  return numsizes;
}

#endif

//
// End of "$Id: fl_set_fonts.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Return_Button.cxx ---
//
// "$Id: Fl_Return_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Return button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Return_Button.H>
#include <FL/fl_draw.H>

int fl_return_arrow(int x, int y, int w, int h) {
  int size = w; if (h<size) size = h;
  int d = (size+2)/4; if (d<3) d = 3;
  int t = (size+9)/12; if (t<1) t = 1;
  int x0 = x+(w-2*d-2*t-1)/2;
  int x1 = x0+d;
  int y0 = y+h/2;
//#ifdef PDA
//  if ( !value() ) {
//     fl_color(FL_BLACK);
//  }
//  else {
//     fl_color(FL_WHITE);
//  }
//#else  
  fl_color(FL_LIGHT3);
//#endif
  fl_line(x0, y0, x1, y0+d);
  fl_yxline(x1, y0+d, y0+t, x1+d+2*t, y0-d);
  fl_yxline(x1, y0-t, y0-d);
//#ifdef PDA
//  if ( !value ) {
//     fl_color(FL_BLACK);
//  }
//  else {
//     fl_color(FL_WHITE);
//  }
//#else
  fl_color(fl_gray_ramp(0));
//#endif
  fl_line(x0, y0, x1, y0-d);
//#ifdef PDA
//  if ( !value ) {
//     fl_color(FL_BLACK);
//  }
//  else {
//	  fl_color(FL_WHITE);
//  }
//#else
  fl_color(FL_DARK3);
//#endif
  fl_xyline(x1+1, y0-t, x1+d, y0-d, x1+d+2*t);
  return 1;
}

void Fl_Return_Button::draw() {
  if (type() == FL_HIDDEN_BUTTON) return;
#ifdef PDA
  if( !down_box()) {
     down_box(FL_BLACK_BOX);
  }
  if ( !value() ) {
     labelcolor(FL_BLACK);
  }
  else {
     labelcolor(FL_WHITE);
  }
#endif
  draw_box(value() ? (down_box()?down_box():down(box())) : box(),
	   value() ? selection_color() : color());
  int W = h();
  if (w()/3 < W) W = w()/3;
  fl_return_arrow(x()+w()-W-4, y(), W, h());
  draw_label(x(), y(), w()-W+4, h());
}

int Fl_Return_Button::handle(int event) {
  if (event == FL_SHORTCUT &&
      (Fl::event_key() == FL_Enter || Fl::event_key() == FL_KP_Enter)) {
    do_callback();
    return 1;
  } else
    return Fl_Button::handle(event);
}

//
// End of "$Id: Fl_Return_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Window_hotspot.cxx ---
//
// "$Id: Fl_Window_hotspot.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Common hotspot routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Window.H>

#ifdef WIN32
#include <FL/win32.H>
#endif

void Fl_Window::hotspot(int X, int Y, int /*offscreen*/) {
  int mx,my; Fl::get_mouse(mx,my);
  X = mx-X; Y = my-Y;
#if 0
  // Both the WIN32 and X versions do this to all windows all the time...
  if (!offscreen) {
#ifdef WIN32
    //These will be used by reference, so we must passed different variables
    int bt,bx,by;
    x(X);y(Y);
    Fl_X::fake_X_wm(this, X, Y, bt, bx, by);
    //force FL_FORCE_POSITION to be set in Fl_Window::resize()
    if (X==x()) x(X-1);
#else
    if (border()) {
      // ensure border is on screen:
      const int top = 20;
      const int left = 1;
      const int right = 1;
      const int bottom = 1;
      if (X+w()+right > Fl::w()) X = Fl::w()-right-w();
      if (X-left < 0) X = left;
      if (Y+h()+bottom > Fl::h()) Y = Fl::h()-bottom-h();
      if (Y-top < 0) Y = top;
    }
    // now insure contents are on-screen (more important than border):
    if (X+w() > Fl::w()) X = Fl::w()-w();
    if (X < 0) X = 0;
    if (Y+h() > Fl::h()) Y = Fl::h()-h();
    if (Y < 0) Y = 0;
#endif
  }
#endif
  position(X,Y);
}

void Fl_Window::hotspot(const Fl_Widget *o, int offscreen) {
  int X = o->w()/2;
  int Y = o->h()/2;
  while (o != this) {
    X += o->x(); Y += o->y();
    o = o->window();
  }
  hotspot(X,Y,offscreen);
}

//
// End of "$Id: Fl_Window_hotspot.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_font_win32.cxx ---
//
// "$Id: fl_font_win32.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $"
//
// WIN32 font selection routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/win32.H>
#include "Fl_Font.H"

#include <ctype.h>
#include <stdlib.h>
#include <string.h>

Fl_FontSize::Fl_FontSize(const char* name, int size) {
  int weight = FW_NORMAL;
  int italic = 0;
  switch (*name++) {
  case 'I': italic = 1; break;
  case 'P': italic = 1;
  case 'B': weight = FW_BOLD; break;
  case ' ': break;
  default: name--;
  }
  fid = CreateFont(
    -size, // negative makes it use "char size"
    0,	            // logical average character width 
    0,	            // angle of escapement 
    0,	            // base-line orientation angle 
    weight,
    italic,
    FALSE,	        // underline attribute flag 
    FALSE,	        // strikeout attribute flag 
    DEFAULT_CHARSET,    // character set identifier 
    OUT_DEFAULT_PRECIS,	// output precision 
    CLIP_DEFAULT_PRECIS,// clipping precision 
    DEFAULT_QUALITY,	// output quality 
    DEFAULT_PITCH,	// pitch and family 
    name	        // pointer to typeface name string 
    );
  if (!fl_gc) fl_GetDC(0);
  SelectObject(fl_gc, fid);
  GetTextMetrics(fl_gc, &metr);
//  BOOL ret = GetCharWidthFloat(fl_gc, metr.tmFirstChar, metr.tmLastChar, font->width+metr.tmFirstChar);
// ...would be the right call, but is not implemented into Window95! (WinNT?)
  GetCharWidth(fl_gc, 0, 255, width);
#if HAVE_GL
  listbase = 0;
#endif
  minsize = maxsize = size;
}

Fl_FontSize* fl_fontsize;

Fl_FontSize::~Fl_FontSize() {
#if HAVE_GL
// Delete list created by gl_draw().  This is not done by this code
// as it will link in GL unnecessarily.  There should be some kind
// of "free" routine pointer, or a subclass?
// if (listbase) {
//  int base = font->min_char_or_byte2;
//  int size = font->max_char_or_byte2-base+1;
//  int base = 0; int size = 256;
//  glDeleteLists(listbase+base,size);
// }
#endif
  if (this == fl_fontsize) fl_fontsize = 0;
  DeleteObject(fid);
}

////////////////////////////////////////////////////////////////

// WARNING: if you add to this table, you must redefine FL_FREE_FONT
// in Enumerations.H & recompile!!
static Fl_Fontdesc built_in_table[] = {
{" Arial"},
{"BArial"},
{"IArial"},
{"PArial"},
{" Courier New"},
{"BCourier New"},
{"ICourier New"},
{"PCourier New"},
{" Times New Roman"},
{"BTimes New Roman"},
{"ITimes New Roman"},
{"PTimes New Roman"},
{" Symbol"},
{" Terminal"},
{"BTerminal"},
{" Wingdings"},
};

Fl_Fontdesc* fl_fonts = built_in_table;

static Fl_FontSize* find(int fnum, int size) {
  Fl_Fontdesc* s = fl_fonts+fnum;
  if (!s->name) s = fl_fonts; // use 0 if fnum undefined
  Fl_FontSize* f;
  for (f = s->first; f; f = f->next)
    if (f->minsize <= size && f->maxsize >= size) return f;
  f = new Fl_FontSize(s->name, size);
  f->next = s->first;
  s->first = f;
  return f;
}

////////////////////////////////////////////////////////////////
// Public interface:

int fl_font_;
int fl_size_;
//static HDC font_gc;

void fl_font(int fnum, int size) {
  if (fnum == fl_font_ && size == fl_size_) return;
  fl_font_ = fnum; fl_size_ = size;
  fl_fontsize = find(fnum, size);
}

int fl_height() {
  return (fl_fontsize->metr.tmAscent + fl_fontsize->metr.tmDescent);
}

int fl_descent() {
  return fl_fontsize->metr.tmDescent;
}

double fl_width(const char* c) {
  double w = 0.0;
  while (*c) w += fl_fontsize->width[uchar(*c++)];
  return w;
}

double fl_width(const char* c, int n) {
  double w = 0.0;
  while (n--) w += fl_fontsize->width[uchar(*c++)];
  return w;
}

double fl_width(uchar c) {
  return fl_fontsize->width[c];
}

void fl_draw(const char* str, int n, int x, int y) {
  SetTextColor(fl_gc, fl_RGB());
  SelectObject(fl_gc, fl_fontsize->fid);
  TextOut(fl_gc, x, y, str, n);
}

void fl_draw(const char* str, int x, int y) {
  fl_draw(str, strlen(str), x, y);
}

//
// End of "$Id: fl_font_win32.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $".
//

--- NEW FILE: slowarrow.h ---
#define slowarrow_width 16
#define slowarrow_height 16
static unsigned char slowarrow_bits[] = {
   0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00,
   0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f,
   0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02};

--- NEW FILE: fl_cmap.h ---
	0x00000000,
	0xff000000,
	0x00ff0000,
	0xffff0000,
	0x0000ff00,
	0xff00ff00,
	0x00ffff00,
	0xffffff00,
	0x55555500,
	0xc6717100,
	0x71c67100,
	0x8e8e3800,
	0x7171c600,
	0x8e388e00,
	0x388e8e00,
	0xaaaaaa00,
	0xa8a89800,
	0xe8e8d800,
	0x68685800,
	0x98a8a800,
	0xd8e8e800,
	0x58686800,
	0x9c9ca800,
	0xdcdce800,
	0x5c5c6800,
	0x9ca89c00,
	0xdce8dc00,
	0x5c685c00,
	0x90909000,
	0xc0c0c000,
	0x50505000,
	0xa0a0a000,
	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

--- NEW FILE: fl_shortcut.cxx ---
//
// "$Id: fl_shortcut.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Shortcut support routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Code to test and parse fltk shortcut numbers.
//
// A shortcut is a keysym or'd with shift flags.  In the simplest
// sense a shortcut is matched if the shift state is exactly as
// given and the key returning that keysym is pressed.
//
// To make it easier to match some things it is more complex:
//
// Only FL_META, FL_ALT, FL_SHIFT, and FL_CTRL must be "off".  A
// zero in the other shift flags indicates "dont care".
//
// It also checks against the first character of Fl::event_text(),
// and zero for FL_SHIFT means "don't care".
// This allows punctuation shortcuts like "#" to work (rather than
// calling it "shift+3")

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include <ctype.h>
#include <string.h>
#ifndef WIN32
#include <FL/x.H>
#endif

int Fl::test_shortcut(int shortcut) {
  if (!shortcut) return 0;

  int shift = Fl::event_state();
  // see if any required shift flags are off:
  if ((shortcut&shift) != (shortcut&0x7fff0000)) return 0;
  // record shift flags that are wrong:
  int mismatch = (shortcut^shift)&0x7fff0000;
  // these three must always be correct:
  if (mismatch&(FL_META|FL_ALT|FL_CTRL)) return 0;

  int key = shortcut & 0xffff;

  // if shift is also correct, check for exactly equal keysyms:
  if (!(mismatch&(FL_SHIFT)) && key == Fl::event_key()) return 1;

  // try matching ascii, ignore shift:
  if (key == event_text()[0]) return 1;

  // kludge so that Ctrl+'_' works (as opposed to Ctrl+'^_'):
  if ((shift&FL_CTRL) && key >= 0x3f && key <= 0x5F
      && event_text()[0]==(key^0x40)) return 1;
  return 0;
}

const char * fl_shortcut_label(int shortcut) {
  static char buf[20];
  char *p = buf;
  if (!shortcut) {*p = 0; return buf;}
  if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
  if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;}
  if (shortcut & FL_SHIFT) {strcpy(p,"Shift+"); p += 6;}
  if (shortcut & FL_CTRL) {strcpy(p,"Ctrl+"); p += 5;}
  int key = shortcut & 0xFFFF;
#ifdef WIN32
  if (key >= FL_F && key <= FL_F_Last) {
    *p++ = 'F';
    if (key > FL_F+9) *p++ = (key-FL_F)/10+'0';
    *p++ = (key-FL_F)%10 + '0';
  } else {
    if (key == FL_Enter || key == '\r') {strcpy(p,"Enter"); return buf;}
    *p++ = uchar(key);
  }
  *p = 0;
  return buf;
#else

  const char* q;
  if (key == FL_Enter || key == '\r') q="Enter"; // don't use Xlib's "Return"
  else if (key > 32 && key < 0x100) q = 0;

  else
  {
#ifdef NANO_X
	q=(char *)&key;
#else
	q = XKeysymToString(key);
#endif //tanghao
  }
  if (!q) {*p++ = uchar(key); *p = 0; return buf;}
  if (p > buf) {strcpy(p,q); return buf;} else return q;
#endif
}

// Tests for &x shortcuts in button labels:

int Fl_Widget::test_shortcut(const char *label) {
  char c = Fl::event_text()[0];
  if (!c || !label) return 0;
  for (;;) {
    if (!*label) return 0;
    if (*label++ == '&' && *label) {
      if (*label == '&') label++;
      else if (*label == c) return 1;
      else return 0;
    }
  }
}

int Fl_Widget::test_shortcut() {
  if (!(flags()&SHORTCUT_LABEL)) return 0;
  return test_shortcut(label());
}

//
// End of "$Id: fl_shortcut.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: gl_draw.cxx ---
//
// "$Id: gl_draw.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Functions from <FL/gl.h>
// See also Fl_Gl_Window and gl_start.C

#include <config.h>
#if HAVE_GL

#include <FL/Fl.H>
#include <FL/gl.h>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include "Fl_Gl_Choice.H"
#include "Fl_Font.H"
#include <string.h>

void  gl_font(int fontid, int size) {fl_font(fontid, size);}
int   gl_height() {return fl_height();}
int   gl_descent() {return fl_descent();}
double gl_width(const char* s) {return fl_width(s);}
double gl_width(const char* s, int n) {return fl_width(s,n);}
double gl_width(uchar c) {return fl_width(c);}

void gl_draw(const char* str, int n) {
  if (!fl_fontsize->listbase) {
#ifdef WIN32
    int base = fl_fontsize->metr.tmFirstChar;
    int size = fl_fontsize->metr.tmLastChar-base+1;
    HFONT oldFid = (HFONT)SelectObject(fl_gc, fl_fontsize->fid);
    fl_fontsize->listbase = glGenLists(256);
    wglUseFontBitmaps(fl_gc, base, size, fl_fontsize->listbase+base); 
    SelectObject(fl_gc, oldFid);
#else
    int base = fl_xfont->min_char_or_byte2;
    int size = fl_xfont->max_char_or_byte2-base+1;
    fl_fontsize->listbase = glGenLists(256);
    glXUseXFont(fl_xfont->fid, base, size, fl_fontsize->listbase+base);
#endif
  }

  glPushAttrib(GL_LIST_BIT);
    glListBase(fl_fontsize->listbase);
    glCallLists(n, GL_UNSIGNED_BYTE, str);
  glPopAttrib();
}

void gl_draw(const char* str, int n, int x, int y) {
  glRasterPos2i(x, y);
  gl_draw(str, n);
}

void gl_draw(const char* str, int n, float x, float y) {
  glRasterPos2f(x, y);
  gl_draw(str, n);
}

void gl_draw(const char* str) {
  gl_draw(str, strlen(str));
}

void gl_draw(const char* str, int x, int y) {
  gl_draw(str, strlen(str), x, y);
}

void gl_draw(const char* str, float x, float y) {
  gl_draw(str, strlen(str), x, y);
}

static void gl_draw_invert(const char* str, int n, int x, int y) {
  glRasterPos2i(x, -y);
  gl_draw(str, n);
}

void gl_draw(
  const char* str, 	// the (multi-line) string
  int x, int y, int w, int h, 	// bounding box
  Fl_Align align) {
  fl_draw(str, x, -y-h, w, h, align, gl_draw_invert);
}

void gl_measure(const char* str, int& x, int& y) {fl_measure(str,x,y);}

void gl_rect(int x, int y, int w, int h) {
  if (w < 0) {w = -w; x = x-w;}
  if (h < 0) {h = -h; y = y-h;}
  glBegin(GL_LINE_STRIP);
  glVertex2i(x+w-1, y+h-1);
  glVertex2i(x+w-1, y);
  glVertex2i(x, y);
  glVertex2i(x, y+h-1);
  glVertex2i(x+w, y+h-1);
  glEnd();
}

#if HAVE_GL_OVERLAY
extern uchar fl_overlay;
#endif

void gl_color(Fl_Color i) {
#if HAVE_GL_OVERLAY
#ifdef WIN32
  if (fl_overlay) {glIndexi(i ? i : FL_GRAY_RAMP); return;}
#else
  if (fl_overlay) {glIndexi(int(fl_xpixel(i))); return;}
#endif
#endif
  uchar red, green, blue;
  Fl::get_color(i, red, green, blue);
  glColor3ub(red, green, blue);
}
  
void gl_draw_image(const uchar* b, int x, int y, int w, int h, int d, int ld) {
  if (!ld) ld = w*d;
  glPixelStorei(GL_UNPACK_ROW_LENGTH, ld/d);
  glRasterPos2i(x,y);
  glDrawPixels(w,h,d<4?GL_RGB:GL_RGBA,GL_UNSIGNED_BYTE,(const ulong*)b);
}

#endif

//
// End of "$Id: gl_draw.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_draw_image_win32.cxx ---
//
// "$Id: fl_draw_image_win32.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// WIN32 image drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// I hope a simple and portable method of drawing color and monochrome
// images.  To keep this simple, only a single storage type is
// supported: 8 bit unsigned data, byte order RGB, and pixels are
// stored packed into rows with the origin at the top-left.  It is
// possible to alter the size of pixels with the "delta" argument, to
// add alpha or other information per pixel.  It is also possible to
// change the origin and direction of the image data by messing with
// the "delta" and "linedelta", making them negative, though this may
// defeat some of the shortcuts in translating the image for X.

// Unbelievably (since it conflicts with how most PC software works)
// Micro$oft picked a bottom-up and BGR storage format for their
// DIB images.  I'm pretty certain there is a way around this, but
// I can't find any other than the brute-force method of drawing
// each line as a seperate image.  This may also need to be done
// if the delta is any amount other than 1, 3, or 4.

////////////////////////////////////////////////////////////////

#include <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>

#define MAXBUFFER 0x40000 // 256k

#if USE_COLORMAP

// error-diffusion dither into the fltk colormap
static void dither(uchar* to, const uchar* from, int w, int delta) {
  static int ri, gi, bi, dir;
  int r=ri, g=gi, b=bi;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    to = to+(w-1);
    d = -delta;
    td = -1;
  } else {
    dir = 1;
    d = delta;
    td = 1;
  }
  for (; w--; from += d, to += td) {
    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
    int rr = r*FL_NUM_RED/256;
    r -= rr*255/(FL_NUM_RED-1);
    g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
    int gg = g*FL_NUM_GREEN/256;
    g -= gg*255/(FL_NUM_GREEN-1);
    b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
    int bb = b*FL_NUM_BLUE/256;
    b -= bb*255/(FL_NUM_BLUE-1);
    *to = uchar(FL_COLOR_CUBE+(bb*FL_NUM_RED+rr)*FL_NUM_GREEN+gg);
  }
  ri = r; gi = g; bi = b;
}

// error-diffusion dither into the fltk colormap
static void monodither(uchar* to, const uchar* from, int w, int delta) {
  static int ri,dir;
  int r=ri;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    to = to+(w-1);
    d = -delta;
    td = -1;
  } else {
    dir = 1;
    d = delta;
    td = 1;
  }
  for (; w--; from += d, to += td) {
    r += *from; if (r < 0) r = 0; else if (r>255) r = 255;
    int rr = r*FL_NUM_GRAY/256;
    r -= rr*255/(FL_NUM_GRAY-1);
    *to = uchar(FL_GRAY_RAMP+rr);
  }
  ri = r;
}

#endif // USE_COLORMAP

static void innards(const uchar *buf, int X, int Y, int W, int H,
		    int delta, int linedelta, int mono,
		    Fl_Draw_Image_Cb cb, void* userdata)
{
#if USE_COLORMAP
  char indexed = (fl_palette != 0);
#endif

  if (!linedelta) linedelta = W*delta;

  int x, y, w, h;
  fl_clip_box(X,Y,W,H,x,y,w,h);
  if (w<=0 || h<=0) return;
  if (buf) buf += (x-X)*delta + (y-Y)*linedelta;

  static U32 bmibuffer[256+12];
  BITMAPINFO &bmi = *((BITMAPINFO*)bmibuffer);
  if (!bmi.bmiHeader.biSize) {
    bmi.bmiHeader.biSize = sizeof(bmi)-4; // does it use this to determine type?
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biXPelsPerMeter = 0;
    bmi.bmiHeader.biYPelsPerMeter = 0;
    bmi.bmiHeader.biClrUsed = 0;
    bmi.bmiHeader.biClrImportant = 0;
  }
#if USE_COLORMAP
  if (indexed) {
    for (int i=0; i<256; i++) {
      *((short*)(bmi.bmiColors)+i) = i;
    }
  } else
#endif
  if (mono) {
    for (int i=0; i<256; i++) {
      bmi.bmiColors[i].rgbBlue = i;
      bmi.bmiColors[i].rgbGreen = i;
      bmi.bmiColors[i].rgbRed = i;
      bmi.bmiColors[i].rgbReserved = i;
    }
  }
  bmi.bmiHeader.biWidth = w;
#if USE_COLORMAP
  bmi.bmiHeader.biBitCount = mono|indexed ? 8 : 24;
  int pixelsize = mono|indexed ? 1 : 3;
#else
  bmi.bmiHeader.biBitCount = mono ? 8 : 24;
  int pixelsize = mono ? 1 : 3;
#endif
  int linesize = (pixelsize*w+3)&~3;
  
  static U32* buffer;
  int blocking = h;
  {int size = linesize*h;
  if (size > MAXBUFFER) {
    size = MAXBUFFER;
    blocking = MAXBUFFER/linesize;
  }
  static long buffer_size;
  if (size > buffer_size) {
    delete[] buffer;
    buffer_size = size;
    buffer = new U32[(size+3)/4];
  }}
  bmi.bmiHeader.biHeight = blocking;
  static U32* line_buffer;
  if (!buf) {
    int size = W*delta;
    static int line_buf_size;
    if (size > line_buf_size) {
      delete[] line_buffer;
      line_buf_size = size;
      line_buffer = new U32[(size+3)/4];
    }
  }
  for (int j=0; j<h; ) {
    int k;
    for (k = 0; j<h && k<blocking; k++, j++) {
      const uchar* from;
      if (!buf) { // run the converter:
	cb(userdata, x-X, y-Y+j, w, (uchar*)line_buffer);
	from = (uchar*)line_buffer;
      } else {
	from = buf;
	buf += linedelta;
      }
      uchar *to = (uchar*)buffer+(blocking-k-1)*linesize;
#if USE_COLORMAP
      if (indexed) {
	if (mono)
	  monodither(to, from, w, delta);
	else 
	  dither(to, from, w, delta);
	to += w;
      } else
#endif
      if (mono) {
	for (int i=w; i--; from += delta) *to++ = *from;
      } else {
	for (int i=w; i--; from += delta, to += 3) {
	  uchar r = from[0];
	  to[0] = from[2];
	  to[1] = from[1];
	  to[2] = r;
        }
      }
    }
    SetDIBitsToDevice(fl_gc, x, y+j-k, w, k, 0, 0, 0, k,
		      (LPSTR)((uchar*)buffer+(blocking-k)*linesize),
		      &bmi,
#if USE_COLORMAP
		      indexed ? DIB_PAL_COLORS : DIB_RGB_COLORS
#else
		      DIB_RGB_COLORS
#endif
		      );
  }
}

void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
}
void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
		   int x, int y, int w, int h,int d) {
  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
}
void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
  innards(buf,x,y,w,h,d,l,1,0,0);
}
void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
		   int x, int y, int w, int h,int d) {
  innards(0,x,y,w,h,d,0,1,cb,data);
}

void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
#if USE_COLORMAP
  // use the error diffusion dithering code to produce a much nicer block:
  if (fl_palette) {
    uchar c[3];
    c[0] = r; c[1] = g; c[2] = b;
    innards(c,x,y,w,h,0,0,0,0,0);
    return;
  }
#endif
  fl_color(r,g,b);
  fl_rectf(x,y,w,h);
}

//
// End of "$Id: fl_draw_image_win32.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Gl_Choice.cxx ---
//
// "$Id: Fl_Gl_Choice.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// OpenGL visual selection code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#if HAVE_GL

#include <FL/Fl.H>
#include <FL/x.H>
#include <stdlib.h>

#include "Fl_Gl_Choice.H"

static Fl_Gl_Choice *first;
GLXContext fl_first_context;

// this assummes one of the two arguments is zero:
// We keep the list system in Win32 to stay compatible and interpret
// the list later...
Fl_Gl_Choice *Fl_Gl_Choice::find(int mode, const int *alist) {
  Fl_Gl_Choice *g;
  
  for (g = first; g; g = g->next)
    if (g->mode == mode && g->alist == alist) 
      return g;

#ifndef WIN32    
  const int *blist;
  int list[32];
    
  if (alist)
    blist = alist;
  else {
    int n = 0;
    if (mode & FL_INDEX) {
      list[n++] = GLX_BUFFER_SIZE;
      list[n++] = 8; // glut tries many sizes, but this should work...
    } else {
      list[n++] = GLX_RGBA;
      list[n++] = GLX_GREEN_SIZE;
      list[n++] = (mode & FL_RGB8) ? 8 : 1;
      if (mode & FL_ALPHA) {
	list[n++] = GLX_ALPHA_SIZE;
	list[n++] = 1;
      }
      if (mode & FL_ACCUM) {
	list[n++] = GLX_ACCUM_GREEN_SIZE;
	list[n++] = 1;
	if (mode & FL_ALPHA) {
	  list[n++] = GLX_ACCUM_ALPHA_SIZE;
	  list[n++] = 1;
	}
      }
    }
    if (mode & FL_DOUBLE) {
      list[n++] = GLX_DOUBLEBUFFER;
    }
    if (mode & FL_DEPTH) {
      list[n++] = GLX_DEPTH_SIZE; list[n++] = 1;
    }
    if (mode & FL_STENCIL) {
      list[n++] = GLX_STENCIL_SIZE; list[n++] = 1;
    }
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
    if (mode & FL_MULTISAMPLE) {
      list[n++] = GLX_SAMPLES_SGIS;
      list[n++] = 4; // value Glut uses
    }
#endif
    list[n] = 0;
    blist = list;
  }
    
  fl_open_display();
  XVisualInfo *vis = glXChooseVisual(fl_display, fl_screen, (int *)blist);
  if (!vis) {
# if defined(GLX_VERSION_1_1) && defined(GLX_SGIS_multisample)
    if (mode&FL_MULTISAMPLE) return find(mode&~FL_MULTISAMPLE,0);
# endif
    return 0;
  }

#else

  PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR), 1, 
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL,
    PFD_TYPE_RGBA, 8 };

  if (mode & FL_INDEX) {
    pfd.iPixelType = PFD_TYPE_COLORINDEX;
    pfd.cColorBits = 8;
  } else {
    if (mode & FL_ALPHA) pfd.cAlphaBits = 8;
    if (mode & FL_ACCUM) {
      pfd.cAccumBits = 6;	// Wonko: I didn't find any documentation on those bits
      pfd.cAccumGreenBits = 1;	// Wonko: They don't seem to get any support yet (4/98)
      if (mode & FL_ALPHA) pfd.cAccumAlphaBits = 1;
    }
  }
  if (mode & FL_DOUBLE) pfd.dwFlags |= PFD_DOUBLEBUFFER;
  if (mode & FL_DEPTH) pfd.cDepthBits = 16;
  if (mode & FL_STENCIL) pfd.cStencilBits = 1;
  pfd.bReserved = 1; // always ask for overlay

#endif

  g = new Fl_Gl_Choice;
  g->mode = mode;
  g->alist = alist;
  g->next = first;
  first = g;

#ifdef WIN32
  memcpy(&g->pfd, &pfd, sizeof(PIXELFORMATDESCRIPTOR));
  g->d = ((mode&FL_DOUBLE) != 0);
  g->r = (mode & FL_INDEX);
  g->o = 0; // not an overlay
#else
  g->vis = vis;
  g->colormap = 0;
  int i;
  glXGetConfig(fl_display, vis, GLX_DOUBLEBUFFER, &i); g->d = i;
  glXGetConfig(fl_display, vis, GLX_RGBA, &i); g->r = i;
  glXGetConfig(fl_display, vis, GLX_LEVEL, &i); g->o = i;

  if (/*MaxCmapsOfScreen(ScreenOfDisplay(fl_display,fl_screen))==1 && */
      vis->visualid == fl_visual->visualid &&
      !getenv("MESA_PRIVATE_CMAP"))
    g->colormap = fl_colormap;
  else
    g->colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
				  vis->visual, AllocNone);
#endif

  return g;
}

#ifdef WIN32

HDC fl_private_dc(Fl_Window* w, int mode, Fl_Gl_Choice **gp) {
  Fl_X* i = Fl_X::i(w);
  if (!i->private_dc) {
    i->private_dc = GetDCEx(i->xid, 0, DCX_CACHE);
    Fl_Gl_Choice *g = Fl_Gl_Choice::find(mode, 0);
	if (gp) *gp = g;
    int pixelFormat = ChoosePixelFormat(i->private_dc, &g->pfd);
    if (!pixelFormat) {Fl::error("Insufficient GL support"); return NULL;}
    SetPixelFormat(i->private_dc, pixelFormat, &g->pfd);
#if USE_COLORMAP
    if (fl_palette) SelectPalette(i->private_dc, fl_palette, FALSE);
#endif
  }
  return i->private_dc;
}

#endif

static GLXContext cached_context;

static Fl_Window* cached_window;

void fl_set_gl_context(Fl_Window* w, GLXContext c) {
  if (c != cached_context || w != cached_window) {
    cached_context = c;
    cached_window = w;
#ifdef WIN32
    wglMakeCurrent(Fl_X::i(w)->private_dc, c);
#else
    glXMakeCurrent(fl_display, fl_xid(w), c);
#endif
  }
}

void fl_no_gl_context() {
  cached_context = 0;
  cached_window = 0;
#ifdef WIN32
  wglMakeCurrent(0, 0);
#else
  glXMakeCurrent(fl_display, 0, 0);
#endif
}

#endif

//
// End of "$Id: Fl_Gl_Choice.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_display.cxx ---
//
// "$Id: Fl_display.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Display function for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Startup method to set what display to use.
// Using setenv makes programs that are exec'd use the same display.

#include <FL/Fl.H>
#include <stdlib.h>
#include <string.h>

void Fl::display(const char *d) {
  char *e = new char[strlen(d)+13];
  strcpy(e,"DISPLAY=");
  strcpy(e+8,d);
  for (char *c = e+8; *c!=':'; c++) if (!*c) {strcpy(c,":0.0"); break;}
  putenv(e);
}

//
// End of "$Id: Fl_display.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Check_Button.cxx ---
//
// "$Id: Fl_Check_Button.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Check button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Check_Button.H>

// A subclass of Fl_Button that always draws as a diamond box.  This
// diamond is smaller than the widget size and can be surchecked by
// another box type, for compatability with Forms.

Fl_Check_Button::Fl_Check_Button(int x, int y, int w, int h, const char *l)
: Fl_Light_Button(x, y, w, h, l) {
  box(FL_NO_BOX);
  down_box(FL_DIAMOND_DOWN_BOX);
  selection_color(FL_RED);
}

--- NEW FILE: Fl_Browser_.cxx ---
//
// "$Id: Fl_Browser_.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Base Browser widget class for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Browser_.H>
#include <FL/fl_draw.H>


// This is the base class for browsers.  To be useful it must be
// subclassed and several virtual functions defined.  The
// Forms-compatable browser and the file chooser's browser are
// subclassed off of this.

// Yes, I know this should be a template...

// This has been designed so that the subclass has complete control
// over the storage of the data, although because next() and prev()
// functions are used to index, it works best as a linked list or as a
// large block of characters in which the line breaks must be searched
// for.

// A great deal of work has been done so that the "height" of a data
// object does not need to be determined until it is drawn.  This was
// done for the file chooser, because the height requires doing stat()
// to see if the file is a directory, which can be annoyingly slow
// over the network.

/* redraw bits:
   1 = redraw children (the scrollbar)
   2 = redraw one or two items
   4 = redraw all items
*/

static void scrollbar_callback(Fl_Widget* s, void*) {
  ((Fl_Browser_*)(s->parent()))->position(int(((Fl_Scrollbar*)s)->value()));
}

static void hscrollbar_callback(Fl_Widget* s, void*) {
  ((Fl_Browser_*)(s->parent()))->hposition(int(((Fl_Scrollbar*)s)->value()));
}

int Fl_Browser_::scrollbar_width_ = 17;

// return where to draw the actual box:
void Fl_Browser_::bbox(int& X, int& Y, int& W, int& H) const {
  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
  X = x()+Fl::box_dx(b);
  Y = y()+Fl::box_dy(b);
  W = w()-Fl::box_dw(b);
  H = h()-Fl::box_dh(b);
  if (scrollbar.visible()) {
    W -= scrollbar_width_;
    if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar_width_;
  }
  if (W < 0) W = 0;
  if (hscrollbar.visible()) {
    H -= scrollbar_width_;
    if (scrollbar.align() & FL_ALIGN_TOP) Y += scrollbar_width_;
  }
  if (H < 0) H = 0;
}

int Fl_Browser_::leftedge() const {
  int X, Y, W, H; bbox(X, Y, W, H);
  return X;
}

// the scrollbars are resized & placed by draw(), since each one's size
// depends on whether the other is visible or not.  This skips over
// Fl_Group::resize since it moves the scrollbars uselessly.
void Fl_Browser_::resize(int X, int Y, int W, int H) {
  Fl_Widget::resize(X, Y, W, H);
}

// Cause minimal update to redraw the given item:
void Fl_Browser_::redraw_line(void* l) {
  if (!redraw1 || redraw1 == l) {redraw1 = l; damage(FL_DAMAGE_EXPOSE);}
  else if (!redraw2 || redraw2 == l) {redraw2 = l; damage(FL_DAMAGE_EXPOSE);}
  else damage(FL_DAMAGE_SCROLL);
}

// Figure out top() based on position():
void Fl_Browser_::update_top() {
  if (!top_) top_ = item_first();
  if (position_ != real_position_) {
    void* l;
    int ly;
    int y = position_;
    // start from either head or current position, whichever is closer:
    if (!top_ || y <= (real_position_/2)) {
      l = item_first();
      ly = 0;
    } else {
      l = top_;
      ly = real_position_-offset_;
    }
    if (!l) {
      top_ = 0;
      offset_ = 0;
      real_position_ = 0;
    } else {
      int h = item_quick_height(l);
      // step through list until we find line containing this point:
      while (ly > y) {
	void* l1 = item_prev(l);
	if (!l1) {ly = 0; break;} // hit the top
	l = l1;
	h = item_quick_height(l);
	ly -= h;
      }
      while ((ly+h) <= y) {
	void* l1 = item_next(l);
	if (!l1) {y = ly+h-1; break;}
	l = l1;
	ly += h;
	h = item_quick_height(l);
      }
      // top item must *really* be visible, use slow height:
      for (;;) {
	h = item_height(l);
	if ((ly+h) > y) break; // it is big enough to see
	// go up to top of previous item:
	void* l1 = item_prev(l);
	if (!l1) {ly = y = 0; break;} // hit the top
	l = l1; y = position_ = ly = ly-item_quick_height(l);
      }
      // use it:
      top_ = l;
      offset_ = y-ly;
      real_position_ = y;
    }
    damage(FL_DAMAGE_SCROLL);
  }
}

// Change position(), top() will update when update_top() is called
// (probably by draw() or handle()):
void Fl_Browser_::position(int y) {
  if (y < 0) y = 0;
  if (y == position_) return;
  position_ = y;
  if (y != real_position_) redraw_lines();
}

void Fl_Browser_::hposition(int x) {
  if (x < 0) x = 0;
  if (x == hposition_) return;
  hposition_ = x;
  if (x != real_hposition_) redraw_lines();
}

// Tell whether item is currently displayed:
int Fl_Browser_::displayed(void* x) const {
  int X, Y, W, H; bbox(X, Y, W, H);
  int yy = H+offset_;
  for (void* l = top_; l && yy > 0; l = item_next(l)) {
    if (l == x) return 1;
    yy -= item_height(l);
  }
  return 0;
}

// Insure this item is displayed:
// Messy because we have no idea if it is before top or after bottom:
void Fl_Browser_::display(void* x) {
  update_top();
  if (x == item_first()) {position(0); return;}
  int X, Y, W, H; bbox(X, Y, W, H);
  void* l = top_;
  Y = -offset_;
  // see if it is at the top or just above it:
  if (l == x) {position(real_position_+Y); return;} // scroll up a bit
  void* lp = item_prev(l);
  if (lp == x) {position(real_position_+Y-item_quick_height(lp)); return;}
  // search forward for it:
  for (; l; l = item_next(l)) {
    int h1 = item_quick_height(l);
    if (l == x) {
      if (Y <= H) { // it is visible or right at bottom
	Y = Y+h1-H; // find where bottom edge is
	if (Y > 0) position(real_position_+Y); // scroll down a bit
      } else {
	position(real_position_+Y-(H-h1)/2); // center it
      }
      return;
    }
    Y += h1;
  }
  // search backward for it, if found center it:
  l = lp;
  Y = -offset_;
  for (; l; l = item_prev(l)) {
    int h1 = item_quick_height(l);
    Y -= h1;
    if (l == x) {
      if ((Y + h1) >= 0) position(real_position_+Y);
      else position(real_position_+Y-(H-h1)/2);
      return;
    }
  }
}

// redraw, has side effect of updating top and setting scrollbar:

void Fl_Browser_::draw() {
  int drawsquare = 0;
  if (damage() & FL_DAMAGE_ALL) { // redraw the box if full redraw
    Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
    draw_box(b, x(), y(), w(), h(), color());
    drawsquare = 1;
   }

  update_top();
  int full_width_ = full_width();
  int full_height_ = full_height();
  int X, Y, W, H; bbox(X, Y, W, H);
  int dont_repeat = 0;
J1:
  // see if scrollbar needs to be switched on/off:
  if ((has_scrollbar_ & VERTICAL) && (
	(has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) {
    if (!scrollbar.visible()) {
      scrollbar.set_visible();
      drawsquare = 1;
      bbox(X, Y, W, H);
    }
  } else {
    top_ = item_first(); real_position_ = offset_ = 0;
    if (scrollbar.visible()) {
      scrollbar.clear_visible();
      clear_damage(damage()|FL_DAMAGE_SCROLL);
    }
  }

  if ((has_scrollbar_ & HORIZONTAL) && (
	(has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_ > W)) {
    if (!hscrollbar.visible()) {
      hscrollbar.set_visible();
      drawsquare = 1;
      bbox(X, Y, W, H);
    }
  } else {
    real_hposition_ = 0;
    if (hscrollbar.visible()) {
      hscrollbar.clear_visible();
      clear_damage(damage()|FL_DAMAGE_SCROLL);
    }
  }

  // Check the vertical scrollbar again, just in case it needs to be drawn
  // because the horizontal one is drawn.  There should be a cleaner way
  // to do this besides copying the same code...
  if ((has_scrollbar_ & VERTICAL) && (
	(has_scrollbar_ & ALWAYS_ON) || position_ || full_height_ > H)) {
    if (!scrollbar.visible()) {
      scrollbar.set_visible();
      drawsquare = 1;
      bbox(X, Y, W, H);
    }
  } else {
    top_ = item_first(); real_position_ = offset_ = 0;
    if (scrollbar.visible()) {
      scrollbar.clear_visible();
      clear_damage(damage()|FL_DAMAGE_SCROLL);
    }
  }

  bbox(X, Y, W, H);

  fl_clip(X, Y, W, H);
  // for each line, draw it if full redraw or scrolled.  Erase background
  // if not a full redraw or if it is selected:
  void* l = top();
  int yy = -offset_;
  for (; l && yy < H; l = item_next(l)) {
    int hh = item_height(l);
    if (hh <= 0) continue;
    if ((damage()&(FL_DAMAGE_SCROLL|FL_DAMAGE_ALL)) || l == redraw1 || l == redraw2) {
      if (item_selected(l)) {
	fl_color(active_r() ? selection_color() : inactive(selection_color()));
	fl_rectf(X, yy+Y, W, hh);
      } else if (!(damage()&FL_DAMAGE_ALL)) {
	fl_color(active_r() ? color() : inactive(color()));
	fl_rectf(X, yy+Y, W, hh);
      }
      if (type() == FL_MULTI_BROWSER && l == selection_) {
	fl_color(active_r() ? textcolor() : inactive(textcolor()));
	fl_rect(X+1, yy+Y, W-2, hh);
      }
      item_draw(l, X-hposition_, yy+Y, W+hposition_, hh);
      int w = item_width(l);
      if (w > max_width) {max_width = w; max_width_item = l;}
    }
    yy += hh;
  }
  // erase the area below last line:
  if (!(damage()&FL_DAMAGE_ALL) && yy < H) {
    fl_color(active_r() ? color() : inactive(color()));
    fl_rectf(X, yy+Y, W, H-yy);
  }
  fl_pop_clip();
  redraw1 = redraw2 = 0;

  if (!dont_repeat) {
    dont_repeat = 1;
    // see if changes to full_height caused by calls to slow_height
    // caused scrollbar state to change, in which case we have to redraw:
    full_height_ = full_height();
    full_width_ = full_width();
    if ((has_scrollbar_ & VERTICAL) &&
	((has_scrollbar_ & ALWAYS_ON) || position_ || full_height_>H)) {
      if (!scrollbar.visible()) goto J1;
    } else {
      if (scrollbar.visible()) goto J1;
    }
    if ((has_scrollbar_ & HORIZONTAL) &&
	((has_scrollbar_ & ALWAYS_ON) || hposition_ || full_width_>W)) {
      if (!hscrollbar.visible()) goto J1;
    } else {
      if (hscrollbar.visible()) goto J1;
    }
  }

  // update the scrollbars and redraw them:
  int dy = top_ ? item_quick_height(top_) : 0; if (dy < 10) dy = 10;
  if (scrollbar.visible()) {
    scrollbar.damage_resize(
	scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar_width_ : X+W,
	Y, scrollbar_width_, H);
    scrollbar.value(position_, H, 0, full_height_);
    scrollbar.linesize(dy);
    if (drawsquare) draw_child(scrollbar);
    else update_child(scrollbar);
  }
  if (hscrollbar.visible()) {
    hscrollbar.damage_resize(
	X, scrollbar.align()&FL_ALIGN_TOP ? Y-scrollbar_width_ : Y+H,
	W, scrollbar_width_);
    hscrollbar.value(hposition_, W, 0, full_width_);
    hscrollbar.linesize(dy);
    if (drawsquare) draw_child(hscrollbar);
    else update_child(hscrollbar);
  }

  // draw that little square between the scrollbars:
  if (drawsquare && scrollbar.visible() && hscrollbar.visible()) {
    fl_color(parent()->color());
    fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar_width_,scrollbar_width_);
  }

  real_hposition_ = hposition_;
#ifdef PDA
  draw_box(FL_BORDER_FRAME, x(), y(), w(), h(), FL_BLACK);
#endif
}

// Quick way to delete and reset everything:
void Fl_Browser_::new_list() {
  top_ = 0;
  position_ = real_position_ = 0;
  hposition_ = real_hposition_ = 0;
  selection_ = 0;
  offset_ = 0;
  max_width = 0;
  max_width_item = 0;
  redraw_lines();
}

// Tell it that this item is going away, and that this must remove
// all pointers to it:
void Fl_Browser_::deleting(void* l) {
  if (displayed(l)) redraw_lines();
  if (l == selection_) selection_ = 0;
  if (l == top_) {
    real_position_ -= offset_;
    offset_ = 0;
    top_ = item_next(l);
    if (!top_) top_ = item_prev(l);
  }
  if (l == max_width_item) {max_width_item = 0; max_width = 0;}
}

void Fl_Browser_::replacing(void* a, void* b) {
  redraw_line(a);
  if (a == selection_) selection_ = b;
  if (a == top_) top_ = b;
  if (a == max_width_item) {max_width_item = 0; max_width = 0;}
}

void Fl_Browser_::inserting(void* a, void* b) {
  if (displayed(a)) redraw_lines();
  if (a == top_) top_ = b;
}

void* Fl_Browser_::find_item(int my) {
  update_top();
  int X, Y, W, H; bbox(X, Y, W, H);
  void* l;
  int yy = Y-offset_;
  for (l = top_; l; l = item_next(l)) {
    int hh = item_height(l); if (hh <= 0) continue;
    yy += hh;
    if (my <= yy || yy>=(Y+H)) return l;
  }
  return 0;
}

int Fl_Browser_::select(void* l, int i, int docallbacks) {
  if (type() == FL_MULTI_BROWSER) {
    if (selection_ != l) {
      if (selection_) redraw_line(selection_);
      selection_ = l;
      redraw_line(l);
    }
    if ((!i)==(!item_selected(l))) return 0;
    item_select(l, i);
    redraw_line(l);
  } else {
    if (i && selection_ == l) return 0;
    if (!i && selection_ != l) return 0;
    if (selection_) {
      item_select(selection_, 0);
      redraw_line(selection_);
      selection_ = 0;
    }
    if (i) {
      item_select(l, 1);
      selection_ = l;
      redraw_line(l);
      display(l);
    }
  }	    
  Fl::event_clicks(0);
  if (docallbacks) do_callback();
  return 1;
}

int Fl_Browser_::deselect(int docallbacks) {
  if (type() == FL_MULTI_BROWSER) {
    int change = 0;
    for (void* p = item_first(); p; p = item_next(p))
      change |= select(p, 0, docallbacks);
    return change;
  } else {
    if (!selection_) return 0;
    item_select(selection_, 0);
    redraw_line(selection_);
    selection_ = 0;
    return 1;
  }
}

int Fl_Browser_::select_only(void* l, int docallbacks) {
  if (!l) return deselect(docallbacks);
  int change = 0;
  if (type() == FL_MULTI_BROWSER) {
    for (void* p = item_first(); p; p = item_next(p))
      if (p != l) change |= select(p, 0, docallbacks);
  }
  change |= select(l, 1, docallbacks);
  display(l);
  return change;
}

int Fl_Browser_::handle(int event) {

  // must do shortcuts first or the scrollbar will get them...
  if ((event == FL_SHORTCUT || event == FL_KEYBOARD)
      && type() >= FL_HOLD_BROWSER) {
    void* l1 = selection_;
    void* l = l1; if (!l) l = top_; if (!l) l = item_first();
    if (l) {
      if (type()==FL_HOLD_BROWSER) switch (Fl::event_key()) {
      case FL_Down:
	while ((l = item_next(l)))
	  if (item_height(l)>0) {select_only(l, 1); break;}
	return 1;
      case FL_Up:
	while ((l = item_prev(l))) if (item_height(l)>0) {
	  select_only(l, 1); break;}
	return 1;
      } else switch (Fl::event_key()) {
      case FL_Enter:
	select_only(l, 1);
	return 1;
      case ' ':
	selection_ = l;
	select(l, !item_selected(l), 1);
	return 1;
      case FL_Down:
	while ((l = item_next(l))) {
	  if (Fl::event_state(FL_SHIFT|FL_CTRL))
	    select(l, l1 ? item_selected(l1) : 1, 1);
	  if (item_height(l)>0) goto J1;
	}
	return 1;
      case FL_Up:
	while ((l = item_prev(l))) {
	  if (Fl::event_state(FL_SHIFT|FL_CTRL))
	    select(l, l1 ? item_selected(l1) : 1, 1);
	  if (item_height(l)>0) goto J1;
	}
	return 1;
      J1:
	if (selection_) redraw_line(selection_);
	selection_ = l; redraw_line(l);
	display(l);
	return 1;
      }
    }
  }

  if (Fl_Group::handle(event)) return 1;
  int X, Y, W, H; bbox(X, Y, W, H);
  int my;
  static char change;
  static char whichway;
  static int py;
  switch (event) {
  case FL_PUSH:
    redraw();
    if (!Fl::event_inside(X, Y, W, H)) return 0;
    if (type() == FL_SELECT_BROWSER) deselect();
    my = py = Fl::event_y();
    change = 0;
    if (type() == FL_NORMAL_BROWSER || !top_)
      ;
    else if (type() == FL_MULTI_BROWSER) {
      void* l = find_item(my);
      whichway = 1;
      if (Fl::event_state(FL_SHIFT|FL_CTRL)) { // toggle selection:
	if (l) {
	  whichway = !item_selected(l);
	  change = select(l, whichway, when() & FL_WHEN_CHANGED);
	}
      } else {
	change = select_only(l, when() & FL_WHEN_CHANGED);
      }
    } else {
      change = select_only(find_item(my), when() & FL_WHEN_CHANGED);
    }
    return 1;
  case FL_DRAG:
    // do the scrolling first:
    redraw();
    my = Fl::event_y();
    if (my < Y && my < py) {
      int p = real_position_+my-Y;
      if (p<0) p = 0;
      position(p);
    } else if (my > (Y+H) && my > py) {
      int p = real_position_+my-(Y+H);
      int h = full_height()-H; if (p > h) p = h;
      if (p<0) p = 0;
      position(p);
    }
    if (type() == FL_NORMAL_BROWSER || !top_)
      ;
    else if (type() == FL_MULTI_BROWSER) {
      void* l = find_item(my);
      void* t; void* b; // this will be the range to change
      if (my > py) { // go down
	t = selection_ ? item_next(selection_) : 0;
	b = l ? item_next(l) : 0;
      } else {	// go up
	t = l;
	b = selection_;
      }
      for (; t && t != b; t = item_next(t))
	change |= select(t, whichway, when() & FL_WHEN_CHANGED);
      if (l) selection_ = l;
    } else {
      void* l1 = selection_;
      void* l =
	(Fl::event_x()<x() || Fl::event_x()>x()+w()) ? selection_ :
	find_item(my);
      select_only(l, when() & FL_WHEN_CHANGED);
      change = (l != l1);
    }
    py = my;
    return 1;
  case FL_RELEASE:
    if (type() == FL_SELECT_BROWSER) {
      void* t = selection_; deselect(); selection_ = t;
    }
    if (change) {
      if (when() & FL_WHEN_RELEASE) do_callback();
      else if (!(when()&FL_WHEN_CHANGED)) set_changed();
    } else {
      if (when() & FL_WHEN_NOT_CHANGED) do_callback();
    }
    return 1;
  }

  return 0;
}

Fl_Browser_::Fl_Browser_(int x, int y, int w, int h, const char* l)
  : Fl_Group(x, y, w, h, l),
    scrollbar(0, 0, 0, 0, 0), // they will be resized by draw()
    hscrollbar(0, 0, 0, 0, 0)
{
  box(FL_NO_BOX);
  align(FL_ALIGN_BOTTOM);
  position_ = real_position_ = 0;
  hposition_ = real_hposition_ = 0;
  offset_ = 0;
  top_ = 0;
  when(FL_WHEN_RELEASE_ALWAYS);
  selection_ = 0;
  color(FL_WHITE);
  selection_color(FL_SELECTION_COLOR);
  scrollbar.callback(scrollbar_callback);
//scrollbar.align(FL_ALIGN_LEFT|FL_ALIGN_BOTTOM); // back compatability?
  hscrollbar.callback(hscrollbar_callback);
  hscrollbar.type(FL_HORIZONTAL);
  textfont_ = FL_HELVETICA;
  textsize_ = FL_NORMAL_SIZE;
  textcolor_ = FL_BLACK;
  has_scrollbar_ = BOTH;
  max_width = 0;
  max_width_item = 0;
  redraw1 = redraw2 = 0;
  end();
}

// Default versions of some of the virtual functions:

int Fl_Browser_::item_quick_height(void* l) const {
  return item_height(l);
}

int Fl_Browser_::incr_height() const {
  return item_quick_height(item_first());
}

int Fl_Browser_::full_height() const {
  int t = 0;
  for (void* p = item_first(); p; p = item_next(p))
    t += item_quick_height(p);
  return t;
}

int Fl_Browser_::full_width() const {
  return max_width;
}

void Fl_Browser_::item_select(void*, int) {}

int Fl_Browser_::item_selected(void* l) const {return l==selection_;}

//
// End of "$Id: Fl_Browser_.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_get_system_colors.cxx ---
//
// "$Id: Fl_get_system_colors.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// System color support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/math.h>

void Fl::background(uchar r, uchar g, uchar b) {
  // replace the gray ramp so that FL_GRAY is this color
  if (!r) r = 1; else if (r==255) r = 254;
  double powr = log(r/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  if (!g) g = 1; else if (g==255) g = 254;
  double powg = log(g/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  if (!b) b = 1; else if (b==255) b = 254;
  double powb = log(b/255.0)/log((FL_GRAY-FL_GRAY_RAMP)/(FL_NUM_GRAY-1.0));
  for (int i = 0; i < FL_NUM_GRAY; i++) {
    double gray = i/(FL_NUM_GRAY-1.0);
    Fl::set_color(fl_gray_ramp(i),
		  uchar(pow(gray,powr)*255+.5),
		  uchar(pow(gray,powg)*255+.5),
		  uchar(pow(gray,powb)*255+.5));
  }
}

void Fl::foreground(uchar r, uchar g, uchar b) {
  Fl::set_color(FL_BLACK,r,g,b);
}

void Fl::background2(uchar r, uchar g, uchar b) {
  Fl::set_color(FL_WHITE,r,g,b);
  Fl::set_color(FL_BLACK,get_color(contrast(FL_BLACK,FL_WHITE)));
}

// these are set by Fl::args() and override any system colors:
const char *fl_fg;
const char *fl_bg;
const char *fl_bg2;

#ifdef WIN32

#include <stdio.h>
// simulation of XParseColor:
int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b) {
  if (*p == '#') p++;
  int n = strlen(p);
  int m = n/3;
  const char *pattern = 0;
  switch(m) {
  case 1: pattern = "%1x%1x%1x"; break;
  case 2: pattern = "%2x%2x%2x"; break;
  case 3: pattern = "%3x%3x%3x"; break;
  case 4: pattern = "%4x%4x%4x"; break;
  default: return 0;
  }
  int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0;
  switch(m) {
  case 1: R *= 0x11; G *= 0x11; B *= 0x11; break;
  case 3: R >>= 4; G >>= 4; B >>= 4; break;
  case 4: R >>= 8; G >>= 8; B >>= 8; break;
  }
  r = R; g = G; b = B;
  return 1;
}

static void
getsyscolor(int what, const char* arg, void (*func)(uchar,uchar,uchar))
{
  if (arg) {
    uchar r,g,b;
    if (!fl_parse_color(arg, r,g,b))
      Fl::error("Unknown color: %s", arg);
    else
      func(r,g,b);
  } else {
    DWORD x = GetSysColor(what);
    func(uchar(x&255), uchar(x>>8), uchar(x>>16));
  }
}

void Fl::get_system_colors() {
  getsyscolor(COLOR_WINDOW,	fl_bg2,Fl::background2);
  getsyscolor(COLOR_WINDOWTEXT,	fl_fg, Fl::foreground);
  getsyscolor(COLOR_BTNFACE,	fl_bg, Fl::background);
}

#else

// For X we should do something. KDE and Gnome store these colors in
// some standard places, where?

static void
getsyscolor(const char *arg, void (*func)(uchar,uchar,uchar)) {
  if (arg) {
#ifdef NANO_X //tanghao
//	GR_COLOR x;
//      func(x.red>>8, x.green>>8, x.blue>>8);

#else
    XColor x;
    if (!XParseColor(fl_display, fl_colormap, arg, &x))
      Fl::error("Unknown color: %s", arg);
    else
      func(x.red>>8, x.green>>8, x.blue>>8);
#endif
  }

}

void Fl::get_system_colors()
{
  fl_open_display();
  getsyscolor(fl_bg2,Fl::background2);
  getsyscolor(fl_fg, Fl::foreground);
  getsyscolor(fl_bg, Fl::background);
}

#endif

//
// End of "$Id: Fl_get_system_colors.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_x.cxx ---
//
// "$Id: Fl_x.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// X specific code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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
[...2308 lines suppressed...]
void
Fl_Window::make_current ()
{
  static GC gc;			// the GC used by all X windows
  if (!gc)
    gc = XCreateGC (fl_display, i->xid, 0, 0);
  fl_window = i->xid;
  fl_gc = gc;
  current_ = this;
  fl_clip_region (0);
}

//NANOX
#endif
//WIN32
#endif

//
// End of "$Id: Fl_x.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".


--- NEW FILE: Fl_Menu_Window.cxx ---
//
// "$Id: Fl_Menu_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Menu window code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This is the window type used by Fl_Menu to make the pop-ups.
// It draws in the overlay planes if possible.

// Also here is the implementation of the mouse & keyboard grab,
// which are used so that clicks outside the program's windows
// can be used to dismiss the menus.

#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Menu_Window.H>

// WIN32 note: HAVE_OVERLAY is false
#if HAVE_OVERLAY
extern XVisualInfo *fl_find_overlay_visual();
extern XVisualInfo *fl_overlay_visual;
extern Colormap fl_overlay_colormap;
extern unsigned long fl_transparent_pixel;
static GC gc;			// the GC used by all X windows
extern uchar fl_overlay;	// changes how fl_color(x) works
#endif

#include <stdio.h>

void
Fl_Menu_Window::show()
{

#if HAVE_OVERLAY
    if (!shown() && overlay() && fl_find_overlay_visual()) {
	XInstallColormap(fl_display, fl_overlay_colormap);
	fl_background_pixel = int (fl_transparent_pixel);
	Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
	fl_background_pixel = -1;
    } else
#endif
#ifdef NANOX
	Fl_X::mw_parent = 0;
#endif
    Fl_Single_Window::show();
}

void
Fl_Menu_Window::flush()
{
#if HAVE_OVERLAY
    if (!fl_overlay_visual || !overlay()) {
	Fl_Single_Window::flush();
	return;
    }
    Fl_X *i = Fl_X::i(this);
    fl_window = i->xid;
    if (!gc)
	gc = XCreateGC(fl_display, i->xid, 0, 0);
    fl_gc = gc;
    fl_overlay = 1;
    fl_clip_region(i->region);
    i->region = 0;
    draw();
    fl_overlay = 0;
#else
    Fl_Single_Window::flush();
#endif
}

void
Fl_Menu_Window::erase()
{
#if HAVE_OVERLAY
    if (!gc || !shown())
	return;
//XSetForeground(fl_display, gc, 0);
//XFillRectangle(fl_display, fl_xid(this), gc, 0, 0, w(), h());
    XClearWindow(fl_display, fl_xid(this));
#endif
}

// Fix the colormap flashing on Maximum Impact Graphics by erasing the
// menu before unmapping it:
void
Fl_Menu_Window::hide()
{
    erase();
    Fl_Single_Window::hide();
}

Fl_Menu_Window::~Fl_Menu_Window()
{
    hide();
}

//
// End of "$Id: Fl_Menu_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_setext.cxx ---
//
// "$Id: filename_setext.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Filename extension routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Replace .ext with new extension
// If no . in name, append new extension
// If new extension is null, act like it is ""

#include <FL/filename.H>
#include <string.h>

char *filename_setext(char *buf, const char *ext) {
  char *q = (char *)filename_ext(buf);
  if (ext) strcpy(q,ext); else *q = 0;
  return(buf);
}

//
// End of "$Id: filename_setext.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu.cxx ---
//
// "$Id: Fl_Menu.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Menu code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Warning: this menu code is quite a mess!

// This file contains code for implementing Fl_Menu_Item, and for
// methods for bringing up popup menu hierarchies without using the
// Fl_Menu_ widget.

#include <FL/Fl.H>
#include <FL/Fl_Menu_Window.H>
#include <FL/Fl_Menu_.H>
#include <stdio.h>
#include <FL/fl_draw.H>

int
Fl_Menu_Item::size() const
{
    const Fl_Menu_Item *m = this;
    int nest = 0;
    for (;;) {
	if (!m->text) {
	    if (!nest)
		return (m - this + 1);
	    nest--;
	} else if (m->flags & FL_SUBMENU) {
	    nest++;
	}
	m++;
    }
}

const Fl_Menu_Item *
Fl_Menu_Item::next(int n) const
{
    if (n < 0)
	return 0;		// this is so selected==-1 returns NULL
    const Fl_Menu_Item *m = this;
    int nest = 0;
    while (n > 0) {
	if (!m->text) {
	    if (!nest)
		return m;
	    nest--;
	} else if (m->flags & FL_SUBMENU) {
	    nest++;
	}
	m++;
	if (!nest && m->visible())
	    n--;
    }
    return m;
}

// appearance of current menus are pulled from this parent widget:
static const Fl_Menu_ *button;

////////////////////////////////////////////////////////////////

// tiny window for title of menu:
class menutitle:public Fl_Menu_Window
{
    void draw();
  public:
    const Fl_Menu_Item *menu;
      menutitle(int X, int Y, int W, int H, const Fl_Menu_Item *);
};

// each vertical menu has one of these:
class menuwindow:public Fl_Menu_Window
{
    void draw();
    void drawentry(const Fl_Menu_Item *, int i, int erase);
  public:
      menutitle * title;
    int handle(int);
    int itemheight;		// zero == menubar
    int numitems;
    int selected;
    int drawn_selected;		// last redraw has this selected
    const Fl_Menu_Item *menu;
      menuwindow(const Fl_Menu_Item * m, int X, int Y, int W, int H,
		 const Fl_Menu_Item * picked, const Fl_Menu_Item * title,
		 int menubar = 0, int menubar_title = 0);
     ~menuwindow();
    void set_selected(int);
    int find_selected(int mx, int my);
    int titlex(int);
    void autoscroll(int);
    void position(int x, int y);
};

#define LEADING 4		// extra vertical leading

extern char fl_draw_shortcut;

// width of label, including effect of & characters:
int
Fl_Menu_Item::measure(int *hp, const Fl_Menu_ * m) const
{
    Fl_Label l;
    l.value = text;
    l.type = labeltype_;
    l.font =
	labelsize_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
    l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
    l.color = labelcolor_;
    fl_draw_shortcut = 1;
    int w = 0;
    int h = 0;
    l.measure(w, hp ? *hp : h);
    fl_draw_shortcut = 0;
    if (flags & (FL_MENU_TOGGLE | FL_MENU_RADIO))
	w += 14;
    return w;
}

void
Fl_Menu_Item::draw(int x, int y, int w, int h, const Fl_Menu_ * m,
		   int selected) const
{

    Fl_Label l;
    l.value = text;
    l.type = labeltype_;
    l.font =
	labelsize_ ? labelfont_ : uchar(m ? m->textfont() : FL_HELVETICA);
    l.size = labelsize_ ? labelsize_ : m ? m->textsize() : FL_NORMAL_SIZE;
    l.color = labelcolor_ ? labelcolor_ : m ? m->textcolor() : int (FL_BLACK);
    if (!active())
	l.color = inactive((Fl_Color) l.color);
    Fl_Color color = m ? m->color() : FL_GRAY;

    if (selected) {

	Fl_Color r = m ? m->selection_color() : FL_SELECTION_COLOR;
	Fl_Boxtype b = m && m->down_box()? m->down_box() : FL_FLAT_BOX;

	if (contrast(r, color) != r) {	// back compatability boxtypes
	    if (selected == 2) {	// menu title
		r = color;
		b = m ? m->box() : FL_UP_BOX;
	    } else {
		r = (Fl_Color) (FL_COLOR_CUBE - 1);	// white
		l.color = contrast((Fl_Color) labelcolor_, r);
	    }
	} else {
	    l.color = contrast((Fl_Color) labelcolor_, r);
	}

	if (selected == 2) {	// menu title
	    fl_draw_box(b, x, y, w, h, r);
	    x += 3;
	    w -= 8;
	} else {
	    //fl_draw_box(b, x+1, y-1, w-2, h+2, r);
	    fl_draw_box(b, x + 1, y - 1, w - 1, h + 3, r);
	}
    }


    if (flags & (FL_MENU_TOGGLE | FL_MENU_RADIO)) {

	int y1 = y + (h - 14) / 2;
	fl_color(FL_DARK3);
	if (flags & FL_MENU_RADIO) {
	    fl_line(x + 2, y1 + 7, x + 8, y1 + 1, x + 14, y1 + 7);
	    if (selected) {
		fl_color(color);
		fl_polygon(x + 3, y1 + 7, x + 8, y1 + 2, x + 13, y1 + 7,
			   x + 8, y1 + 12);
	    }
	    fl_color(FL_LIGHT3);
	    fl_line(x + 14, y1 + 7, x + 8, y1 + 13, x + 2, y1 + 7);
	    if (value()) {
		fl_color(FL_BLACK);
		fl_polygon(x + 4, y1 + 7, x + 8, y1 + 3, x + 12, y1 + 7,
			   x + 8, y1 + 11);
	    }
	} else {

	    fl_yxline(x + 3, y1 + 11, y1 + 2, x + 12);

	    if (selected) {
		fl_color(color);
		fl_rectf(x + 4, y1 + 3, 9, 9);
	    }

	    fl_color(FL_LIGHT3);
	    fl_xyline(x + 4, y1 + 12, x + 13, y1 + 3);

	    if (value()) {
		fl_color(FL_BLACK);
		fl_rectf(x + 5, y1 + 4, 7, 7);
	    }

	}
	x += 14;
	w -= 14;
    }

    if (!fl_draw_shortcut)
	fl_draw_shortcut = 1;

    l.draw(x + 3, y, w, h, FL_ALIGN_LEFT);
    fl_draw_shortcut = 0;

}

menutitle::menutitle(int X, int Y, int W, int H, const Fl_Menu_Item * L):
Fl_Menu_Window(X, Y, W, H, 0)
{
    end();
    set_modal();
    clear_border();
    menu = L;
    if (L->labelcolor_)
	clear_overlay();
}

menuwindow::menuwindow(const Fl_Menu_Item * m, int X, int Y, int Wp, int Hp,
		       const Fl_Menu_Item * picked, const Fl_Menu_Item * t,
		       int menubar, int menubar_title)
    :
Fl_Menu_Window(X, Y, Wp, Hp, 0)
{
    end();
    set_modal();
    clear_border();
    menu = m;
    drawn_selected = -1;
    box(button && button->box()? button->box() : FL_UP_BOX);
    color(button ? button->color() : FL_GRAY);
    selected = -1;
    {
	int i = 0;
	if (m)
	    for (const Fl_Menu_Item * m1 = m;; m1 = m1->next(), i++) {
		if (picked) {
		    if (m1 == picked) {
			selected = i;
			picked = 0;
		    } else if (m1 > picked) {
			selected = i - 1;
			picked = 0;
			Wp = Hp = 0;
		    }
		}
		if (!m1->text)
		    break;
	    }
	numitems = i;
    }

    if (menubar) {
	itemheight = 0;
	title = 0;
	return;
    }

    itemheight = 1;

    int hotKeysw = 0;
    int Wtitle = 0;
    int Htitle = 0;
    if (t)
	Wtitle = t->measure(&Htitle, button) + 12;
    int W = 0;
    if (m)
	for (; m->text; m = m->next()) {
	    int h;
	    int w1 = m->measure(&h, button);
	    if (h + LEADING > itemheight)
		itemheight = h + LEADING;
	    if (m->flags & (FL_SUBMENU | FL_SUBMENU_POINTER))
		w1 += 14;
	    if (w1 > W)
		W = w1;
	    if (m->shortcut_) {
		w1 = int (fl_width(fl_shortcut_label(m->shortcut_))) + 8;
		if (w1 > hotKeysw)
		    hotKeysw = w1;
	    }
	    if (m->labelcolor_)
		clear_overlay();
	}
    if (selected >= 0 && !Wp)
	X -= W / 2;
    int BW = Fl::box_dx(box());
    W += hotKeysw + 2 * BW + 7;
    if (Wp > W)
	W = Wp;
    if (Wtitle > W)
	W = Wtitle;

    if (!Wp) {
	if (X < 0)
	    X = 0;
	if (X > Fl::w() - W)
	    X = Fl::w() - W;
    }
    x(X);
    w(W);
    h((numitems ? itemheight * numitems - LEADING : 0) + 2 * BW + 5);
    if (selected >= 0)
	Y = Y + (Hp - itemheight) / 2 - selected * itemheight - BW + 1;
    else
	Y = Y + Hp;
    if (m)
	y(Y - 1);
    else {
	y(Y - 3);
	w(1);
	h(1);
    }

    if (t) {
	int ht = menubar_title ? button->h() - 6 : Htitle + 2 * BW + 3;
	title = new menutitle(X, Y - ht - 3, Wtitle, ht, t);
    } else
	title = 0;
}

menuwindow::~menuwindow()
{
    delete title;
}

void
menuwindow::position(int X, int Y)
{
    if (title) {
	title->position(X, title->y() + Y - y());
    }
    Fl_Menu_Window::position(X, Y);
    // x(X); y(Y); // don't wait for response from X
}

// scroll so item i is visible on screen
void
menuwindow::autoscroll(int i)
{
    int Y = y() + Fl::box_dx(box()) + 2 + i * itemheight;
    if (Y <= Fl::y())
	Y = Fl::y() - Y + 10;
    else {
	Y = Y + itemheight - Fl::h() - Fl::y();
	if (Y < 0)
	    return;
	Y = -Y - 10;
    }
    Fl_Menu_Window::position(x(), y() + Y);
    // y(y()+Y); // don't wait for response from X
}

////////////////////////////////////////////////////////////////

void
menuwindow::drawentry(const Fl_Menu_Item * m, int i, int erase)
{
    if (!m)
	return;			// this happens if -1 is selected item and redrawn

    int BW = Fl::box_dx(box());
    int x = BW;
    int W = this->w();
    int w = W - 2 * BW - 1;
    int y = BW + 2 + i * itemheight;
    int h = itemheight - LEADING;

    if (erase && i != selected) {
	fl_color(button ? button->color() : FL_GRAY);
	//    fl_rectf(x+1, y-1, w-2, h+2);
	fl_rectf(x + 1, y - 1, w - 1, h + 3);
    }

    m->draw(x, y, w, h, button, i == selected);

    // the shortcuts and arrows assumme fl_color() was left set by draw():
    if (m->submenu()) {
	int y1 = y + (h - 14) / 2;
	fl_polygon(x + w - 13, y1 + 2, x + w - 13, y1 + 2 + 10, x + w - 3,
		   y1 + 2 + 5);
    } else if (m->shortcut_) {
	Fl_Font f = button ? button->textfont() : FL_HELVETICA;
	fl_font(f, button ? button->textsize() : FL_NORMAL_SIZE);
	fl_draw(fl_shortcut_label(m->shortcut_), x, y, w - 3, h,
		FL_ALIGN_RIGHT);
    }

    if (m->flags & FL_MENU_DIVIDER) {
	fl_color(FL_DARK3);
	fl_xyline(BW - 1, y + h + 1, W - 2 * BW + 2);
	fl_color(FL_LIGHT3);
	fl_xyline(BW - 1, y + h + 2, W - 2 * BW + 2);
    }

}

void
menutitle::draw()
{
    menu->draw(0, 0, w(), h(), button, 2);
}

void
menuwindow::draw()
{

    if (damage() != FL_DAMAGE_CHILD) {	// complete redraw
	fl_draw_box(box(), 0, 0, w(), h(), color());
	if (menu) {
	    const Fl_Menu_Item *m;
	    int i;
	    for (m = menu, i = 0; m->text; i++, m = m->next())
		drawentry(m, i, 0);
	}
    } else {
	if (damage() & FL_DAMAGE_CHILD && selected != drawn_selected) {	// change selection
	    drawentry(menu->next(drawn_selected), drawn_selected, 1);
	    drawentry(menu->next(selected), selected, 1);
	}
    }
    drawn_selected = selected;
}

void
menuwindow::set_selected(int i)
{
    if (i != selected) {
	selected = i;
	damage(FL_DAMAGE_CHILD);
    }
}

////////////////////////////////////////////////////////////////

int
menuwindow::find_selected(int mx, int my)
{
    if (!menu || !menu->text)
	return -1;
    mx -= x();
    my -= y();
    if (my < 0 || my >= h())
	return -1;
    if (!itemheight) {		// menubar
	int x = 3;
	int i = 0;
	const Fl_Menu_Item *m = menu;
	for (;; m = m->next(), i++) {
	    if (!m->text)
		return -1;
	    x += m->measure(0, button) + 16;
	    if (x > mx)
		break;
	}
	return i;
    }
    if (mx < Fl::box_dx(box()) || mx >= w())
	return -1;
    int i = (my - Fl::box_dx(box()) - 1) / itemheight;
    if (i < 0 || i >= numitems)
	return -1;
    return i;
}

// return horizontal position for item i in a menubar:
int
menuwindow::titlex(int i)
{
    const Fl_Menu_Item *m;
    int x = 3;
    for (m = menu; i--; m = m->next())
	x += m->measure(0, button) + 16;
    return x;
}

// match shortcuts & label shortcuts, don't search submenus:
// returns menu item and index
const Fl_Menu_Item *
Fl_Menu_Item::find_shortcut(int *ip) const
{
    const Fl_Menu_Item *m1 = this;
    for (int ii = 0; m1 && m1->text; m1 = m1->next(1), ii++) {
	if (m1->activevisible() && (Fl::test_shortcut(m1->shortcut_)
				    || Fl_Widget::test_shortcut(m1->text))) {
	    if (ip)
		*ip = ii;
	    return m1;
	}
    }
    return 0;
}

////////////////////////////////////////////////////////////////
// Fl_Menu_Item::popup(...)

// Because Fl::grab() is done, all events go to one of the menu windows.
// But the handle method needs to look at all of them to find out
// what item the user is pointing at.  And it needs a whole lot
// of other state variables to determine what is going on with
// the currently displayed menus.
// So the main loop (handlemenu()) puts all the state in a structure
// and puts a pointer to it in a static location, so the handle()
// on menus can refer to it and alter it.  The handle() method
// changes variables in this state to indicate what item is
// picked, but does not actually alter the display, instead the
// main loop does that.  This is because the X mapping and unmapping
// of windows is slow, and we don't want to fall behind the events.

// values for menustate.state:
#define INITIAL_STATE 0		// no mouse up or down since popup() called
#define PUSH_STATE 1		// mouse has been pushed on a normal item
#define DONE_STATE 2		// exit the popup, the current item was picked
#define MENU_PUSH_STATE 3	// mouse has been pushed on a menu title

struct menustate
{
    const Fl_Menu_Item *current_item;	// what mouse is pointing at
    int menu_number;		// which menu it is in
    int item_number;		// which item in that menu, -1 if none
    menuwindow *p[20];		// pointers to menus
    int nummenus;
    int menubar;		// if true p[0] is a menubar
    int state;
};
static menustate *p;

static inline void
setitem(const Fl_Menu_Item * i, int m, int n)
{
    p->current_item = i;
    p->menu_number = m;
    p->item_number = n;
}

static void
setitem(int m, int n)
{
    menustate & p = *(::p);
    p.current_item = (n >= 0) ? p.p[m]->menu->next(n) : 0;
    p.menu_number = m;
    p.item_number = n;
}

static int
forward(int menu)
{				// go to next item in menu menu if possible
    menustate & p = *(::p);
    menuwindow & m = *(p.p[menu]);
    int item = (menu == p.menu_number) ? p.item_number : m.selected;
    while (++item < m.numitems) {
	const Fl_Menu_Item *m1 = m.menu->next(item);
	if (m1->activevisible()) {
	    setitem(m1, menu, item);
	    return 1;
	}
    }
    return 0;
}

static int
backward(int menu)
{				// previous item in menu menu if possible
    menustate & p = *(::p);
    menuwindow & m = *(p.p[menu]);
    int item = (menu == p.menu_number) ? p.item_number : m.selected;
    if (item < 0)
	item = m.numitems;
    while (--item >= 0) {
	const Fl_Menu_Item *m1 = m.menu->next(item);
	if (m1->activevisible()) {
	    setitem(m1, menu, item);
	    return 1;
	}
    }
    return 0;
}

int
menuwindow::handle(int e)
{
    menustate & p = *(::p);
    switch (e) {
    case FL_KEYBOARD:
	switch (Fl::event_key()) {
	case FL_Tab:
	    if (Fl::event_shift() & FL_SHIFT)
		goto BACKTAB;
	case ' ':
	    if (!forward(p.menu_number)) {
		p.item_number = -1;
		forward(p.menu_number);
	    }
	    return 1;
	case FL_BackSpace:
	case 0xFE20:		// backtab
	  BACKTAB:
	    if (!backward(p.menu_number)) {
		p.item_number = -1;
		backward(p.menu_number);
	    }
	    return 1;
	case FL_Up:
	    if (p.menubar && p.menu_number == 0);
	    else if (backward(p.menu_number));
	    else if (p.menubar && p.menu_number == 1)
		setitem(0, p.p[0]->selected);
	    return 1;
	case FL_Down:
	    if (p.menu_number || !p.menubar)
		forward(p.menu_number);
	    else if (p.menu_number < p.nummenus - 1)
		forward(p.menu_number + 1);
	    return 1;
	case FL_Right:
	    if (p.menubar
		&& (p.menu_number <= 0 || p.menu_number == 1
		    && p.nummenus == 2))
		forward(0);
	    else if (p.menu_number < p.nummenus - 1)
		forward(p.menu_number + 1);
	    return 1;
	case FL_Left:
	    if (p.menubar && p.menu_number <= 1)
		backward(0);
	    else if (p.menu_number > 0)
		setitem(p.menu_number - 1, p.p[p.menu_number - 1]->selected);
	    return 1;
	case FL_Enter:
	    p.state = DONE_STATE;
	    return 1;
	case FL_Escape:
	    setitem(0, -1, 0);
	    p.state = DONE_STATE;
	    return 1;
	}
	break;
    case FL_SHORTCUT:{
	    for (int menu = p.nummenus; menu--;) {
		menuwindow & mw = *(p.p[menu]);
		int item;
		const Fl_Menu_Item *m = mw.menu->find_shortcut(&item);
		if (m) {
		    setitem(m, menu, item);
		    if (!m->submenu())
			p.state = DONE_STATE;
		    return 1;
		}
	    }
	}
	break;
    case FL_PUSH:
	//case FL_MOVE:
    case FL_DRAG:{
	    int mx = Fl::event_x() + x();
	    int my = Fl::event_y() + y();
	    int item = 0;
	    int menu;
	    for (menu = p.nummenus - 1;; menu--) {
		item = p.p[menu]->find_selected(mx, my);
		if (item >= 0)
		    break;
		if (menu <= 0)
		    break;
	    }
	    setitem(menu, item);
	    if (e == FL_PUSH) {
		if (p.current_item && p.current_item->submenu()	// this is a menu title
		    && item != p.p[menu]->selected	// and it is not already on
		    && !p.current_item->callback_)	// and it does not have a callback
		    p.state = MENU_PUSH_STATE;
		else
		    p.state = PUSH_STATE;
	    }
	}
	return 1;
    case FL_RELEASE:
	// do nothing if they try to pick inactive items
	if (p.current_item && !p.current_item->activevisible())
	    return 1;
	// Mouse must either be held down/dragged some, or this must be
	// the second click (not the one that popped up the menu):
	if (!Fl::event_is_click() || p.state == PUSH_STATE || p.menubar && p.current_item && !p.current_item->submenu()	// button
	    ) {
#if 0				// makes the check/radio items leave the menu up
	    const Fl_Menu_Item *m = p.current_item;
	    if (m && button && (m->flags & (FL_MENU_TOGGLE | FL_MENU_RADIO))) {
		((Fl_Menu_ *) button)->picked(m);
		p.p[p.menu_number]->redraw();
	    } else
#endif
		p.state = DONE_STATE;
	}
	return 1;
    }
    return Fl_Window::handle(e);
}

const Fl_Menu_Item *
Fl_Menu_Item::pulldown(int X, int Y, int W, int H,
		       const Fl_Menu_Item * initial_item,
		       const Fl_Menu_ * pbutton,
		       const Fl_Menu_Item * t, int menubar) const
{
    Fl_Group::current(0);	// fix possible user error...

    button = pbutton;

    if (pbutton) {
	for (Fl_Window * w = pbutton->window(); w; w = w->window()) {
	    X += w->x();
	    Y += w->y();
	}
    } else {
	X += Fl::event_x_root() - Fl::event_x();
	Y += Fl::event_y_root() - Fl::event_y();
    }

    menuwindow mw(this, X, Y, W, H, initial_item, t, menubar);
    Fl::grab(mw);
    menustate p;
    ::p = &p;
    p.p[0] = &mw;
    p.nummenus = 1;
    p.menubar = menubar;
    p.state = INITIAL_STATE;

    menuwindow *fakemenu = 0;	// kludge for buttons in menubar

    // preselected item, pop up submenus if necessary:
    if (initial_item && mw.selected >= 0) {
	setitem(0, mw.selected);
	goto STARTUP;
    }

    p.current_item = 0;
    p.menu_number = 0;
    p.item_number = -1;
    if (menubar)
	mw.handle(FL_DRAG);	// find the initial menu
    initial_item = p.current_item;
    if (initial_item)
	goto STARTUP;

    // the main loop, runs until p.state goes to DONE_STATE:
    for (;;) {

	// make sure all the menus are shown:
	{
	    for (int k = menubar; k < p.nummenus; k++)
		if (!p.p[k]->shown()) {
		    if (p.p[k]->title)
			p.p[k]->title->show();
		    p.p[k]->show();
		}
	}

	// get events:
	{
	    const Fl_Menu_Item *oldi = p.current_item;
	    Fl::wait();
	    if (p.state == DONE_STATE)
		break;		// done.
	    if (p.current_item == oldi)
		continue;
	}
	// only do rest if item changes:

	delete fakemenu;
	fakemenu = 0;		// turn off "menubar button"

	if (!p.current_item) {	// pointing at nothing
	    // turn off selection in deepest menu, but don't erase other menus:
	    p.p[p.nummenus - 1]->set_selected(-1);
	    continue;
	}

	delete fakemenu;
	fakemenu = 0;
	initial_item = 0;	// stop the startup code
	p.p[p.menu_number]->autoscroll(p.item_number);

      STARTUP:
	menuwindow & cw = *p.p[p.menu_number];
	const Fl_Menu_Item *m = p.current_item;
	if (!m->activevisible()) {	// pointing at inactive item
	    cw.set_selected(-1);
	    initial_item = 0;	// turn off startup code
	    continue;
	}
	cw.set_selected(p.item_number);

	if (m == initial_item)
	    initial_item = 0;	// stop the startup code if item found
	if (m->submenu()) {
	    const Fl_Menu_Item *title = m;
	    const Fl_Menu_Item *menutable;
	    if (m->flags & FL_SUBMENU)
		menutable = m + 1;
	    else
		menutable = (Fl_Menu_Item *) (m)->user_data_;
	    // figure out where new menu goes:
	    int nX, nY;
	    if (!p.menu_number && p.menubar) {	// menu off a menubar:
		nX = cw.x() + cw.titlex(p.item_number);
		nY = cw.y() + cw.h();
		initial_item = 0;
	    } else {
		nX = cw.x() + cw.w();
		nY = cw.y() + 1 + p.item_number * cw.itemheight;
		title = 0;
	    }
	    if (initial_item) {	// bring up submenu containing initial item:
		menuwindow *n =
		    new menuwindow(menutable, X, Y, W, H, initial_item,
				   title);
		p.p[p.nummenus++] = n;
		// move all earlier menus to line up with this new one:
		if (n->selected >= 0) {
		    int dy = n->y() - nY;
		    int dx = n->x() - nX;
		    for (int menu = 0; menu <= p.menu_number; menu++) {
			menuwindow *t = p.p[menu];
			int nx = t->x() + dx;
			if (nx < 0) {
			    nx = 0;
			    dx = -t->x();
			}
			int ny = t->y() + dy + 1;
			if (ny < 0) {
			    ny = 0;
			    dy = -t->y() - 1;
			}
			t->position(nx, ny);
		    }
		    setitem(p.nummenus - 1, n->selected);
		    goto STARTUP;
		}
	    } else if (p.nummenus > p.menu_number + 1 &&
		       p.p[p.menu_number + 1]->menu == menutable) {
		// the menu is already up:
		while (p.nummenus > p.menu_number + 2)
		    delete p.p[--p.nummenus];
		p.p[p.nummenus - 1]->set_selected(-1);
	    } else {
		// delete all the old menus and create new one:
		while (p.nummenus > p.menu_number + 1)
		    delete p.p[--p.nummenus];
		p.p[p.nummenus++] = new menuwindow(menutable, nX, nY,
						   title ? 1 : 0, 0, 0, title,
						   0, menubar);
	    }
	} else {		// !m->submenu():
	    while (p.nummenus > p.menu_number + 1)
		delete p.p[--p.nummenus];
	    if (!p.menu_number && p.menubar) {
		// kludge so "menubar buttons" turn "on" by using menu title:
		fakemenu = new menuwindow(0,
					  cw.x() + cw.titlex(p.item_number),
					  cw.y() + cw.h(), 0, 0, 0, m, 0, 1);
		fakemenu->title->show();
	    }
	}
    }
    const Fl_Menu_Item *m = p.current_item;
    delete fakemenu;
    while (p.nummenus > 1)
	delete p.p[--p.nummenus];
    mw.hide();
    Fl::release();
    return m;
}

const Fl_Menu_Item *
Fl_Menu_Item::popup(int X, int Y,
		    const char *title,
		    const Fl_Menu_Item * picked,
		    const Fl_Menu_ * button) const
{
    static Fl_Menu_Item dummy;	// static so it is all zeros
    dummy.text = title;
    return pulldown(X, Y, 0, 0, picked, button, title ? &dummy : 0);
}

const Fl_Menu_Item *
Fl_Menu_Item::test_shortcut() const
{
    const Fl_Menu_Item *m = this;
    const Fl_Menu_Item *ret = 0;
    if (m)
	for (; m->text; m = m->next()) {
	    if (m->activevisible()) {
		// return immediately any match of an item in top level menu:
		if (Fl::test_shortcut(m->shortcut_))
		    return m;
		// if (Fl_Widget::test_shortcut(m->text)) return m;
		// only return matches from lower menu if nothing found in top menu:
		if (!ret && m->submenu()) {
		    const Fl_Menu_Item *s =
			(m->flags & FL_SUBMENU) ? m +
			1 : (const Fl_Menu_Item *) m->user_data_;
		    ret = s->test_shortcut();
		}
	    }
	}
    return ret;
}

//
// End of "$Id: Fl_Menu.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_boxtype.cxx ---
//
// "$Id: fl_boxtype.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Box drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Box drawing code for the common box types and the table of
// boxtypes.  Other box types are in seperate files so they are not
// linked in if not used.

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include <config.h>

////////////////////////////////////////////////////////////////

static uchar active_ramp[24] = {
  FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3,
  FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7,
  FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11,
  FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15,
  FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19,
  FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23};
static uchar inactive_ramp[24] = {
  43, 43, 44, 44,
  44, 45, 45, 46,
  46, 46, 47, 47,
  48, 48, 48, 49,
  49, 49, 50, 50,
  51, 51, 52, 52};
static int draw_it_active = 1;
uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}

void fl_frame(const char* s, int x, int y, int w, int h) {
  uchar *g = fl_gray_ramp();
  if (h > 0 && w > 0) for (;*s;) {
	 // draw top line:
    fl_color(g[*s++]);
    fl_xyline(x, y, x+w-1);
    y++; if (--h <= 0) break;
    // draw left line:
    fl_color(g[*s++]);
    fl_yxline(x, y+h-1, y);
    x++; if (--w <= 0) break;
    // draw bottom line:
    fl_color(g[*s++]);
    fl_xyline(x, y+h-1, x+w-1);
    if (--h <= 0) break;
    // draw right line:
    fl_color(g[*s++]);
    fl_yxline(x+w-1, y+h-1, y);
    if (--w <= 0) break;
  }
}

void fl_frame2(const char* s, int x, int y, int w, int h) {
  uchar *g = fl_gray_ramp();
  if (h > 0 && w > 0) for (;*s;) {
    // draw bottom line:
    fl_color(g[*s++]);
    fl_xyline(x, y+h-1, x+w-1);
    if (--h <= 0) break;
    // draw right line:
    fl_color(g[*s++]);
    fl_yxline(x+w-1, y+h-1, y);
    if (--w <= 0) break;
    // draw top line:
    fl_color(g[*s++]);
    fl_xyline(x, y, x+w-1);
    y++; if (--h <= 0) break;
    // draw left line:
    fl_color(g[*s++]);
    fl_yxline(x, y+h-1, y);
    x++; if (--w <= 0) break;
  }
}


void fl_pda_no_box(int, int, int, int, Fl_Color) {}

void fl_thin_down_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
  fl_color(FL_BLACK);
  fl_rect(x, y, w, h);
#else
  fl_frame2("WWHH",x,y,w,h);
#endif
}

void fl_thin_down_box(int x, int y, int w, int h, Fl_Color c) {
  fl_thin_down_frame(x,y,w,h,c);
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
}

void fl_thin_up_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
	fl_color(FL_BLACK);
	fl_rect(x, y, w, h);
#else
	fl_frame2("HHWW",x,y,w,h);
#endif
}

void fl_thin_up_box(int x, int y, int w, int h, Fl_Color c) {
  fl_thin_up_frame(x,y,w,h,c);
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
}

void fl_up_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
  fl_color(FL_BLACK);
  fl_rect(x, y, w, h);
#else
#if BORDER_WIDTH == 1
  fl_frame2("HHWW",x,y,w,h);
#else
#if BORDER_WIDTH == 2
  fl_frame2("AAUWMMTT",x,y,w,h);
#else
  fl_frame("AAAAWUJJUTNN",x,y,w,h);
#endif
#endif
#endif
}
	

#define D1 BORDER_WIDTH
#define D2 (BORDER_WIDTH+BORDER_WIDTH)

void fl_up_box(int x, int y, int w, int h, Fl_Color c) {
  fl_up_frame(x,y,w,h,c);
#ifdef PDA
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
#else  
  fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2);
#endif
}

void fl_down_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
  fl_color(FL_BLACK);
  fl_rect(x, y, w, h);
#else
#if BORDER_WIDTH == 1
  fl_frame2("WWHH",x,y,w,h);
#else
#if BORDER_WIDTH == 2
  fl_frame2("UWMMPPAA",x,y,w,h);
#else
  fl_frame("NNTUJJUWAAAA",x,y,w,h);
#endif
#endif
#endif
}

		  
void fl_down_box(int x, int y, int w, int h, Fl_Color c) {
  fl_down_frame(x,y,w,h,c);
#ifdef PDA
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
#else
  fl_color(c); fl_rectf(x+D1, y+D1, w-D2, h-D2);
#endif
}

void fl_engraved_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
	fl_color(FL_BLACK);
	fl_rect(x, y, w, h);
#else
  fl_frame("HHWWWWHH",x,y,w,h);
#endif
}

void fl_engraved_box(int x, int y, int w, int h, Fl_Color c) {
  fl_engraved_frame(x,y,w,h,c);
#ifdef PDA
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
#else
  fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
#endif
}

void fl_embossed_frame(int x, int y, int w, int h, Fl_Color) {
#ifdef PDA
	fl_color(FL_BLACK);
	fl_rect(x, y, w, h);
#else
	fl_frame("WWHHHHWW",x,y,w,h);
#endif
}

void fl_embossed_box(int x, int y, int w, int h, Fl_Color c) {
  fl_embossed_frame(x,y,w,h,c);
#ifdef PDA
  fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
#else
  fl_color(c); fl_rectf(x+2, y+2, w-4, h-4);
#endif
}

void fl_rectbound(int x, int y, int w, int h, Fl_Color bgcolor) {
  fl_color(FL_BLACK); 
  fl_rect(x, y, w, h);
  fl_color(bgcolor); fl_rectf(x+1, y+1, w-2, h-2);
}
#define fl_border_box fl_rectbound

void fl_rectf(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c);
  fl_rectf(x, y, w, h);
}

void fl_border_frame(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c);
  fl_rect(x, y, w, h);
}

#ifdef PDA
void fl_no_box(int, int, int, int, Fl_Color) {}

void fl_bottom_box(int x, int y, int w, int h, Fl_Color c)
{
  y = y + h - 3;
	fl_color(FL_BLACK); fl_rect(x, y, w, 1);
	fl_color(c); fl_rectf(x+1, y+1, w-2, h-2);
}

void fl_pda_box(int x, int y, int w, int h, Fl_Color c)
{ 
  fl_color(FL_BLACK); fl_rect(x, y, w, h);
  fl_color(FL_LIGHT1); fl_rectf(x+1, y+1, w-2, h-2);
}

void fl_black_box(int x, int y, int w, int h, Fl_Color c)
{
 	fl_color(FL_BLACK);
	fl_rectf(x+1, y+1, w-2, h-2 );
}

void fl_white_box(int x, int y, int w, int h, Fl_Color c)
{
   fl_color(FL_BLACK); fl_rect(x, y, w, h);
	fl_color(FL_WHITE);
	fl_rectf(x+1, y+1, w-2, h-2 );
}
#endif
////////////////////////////////////////////////////////////////

static struct {
  Fl_Box_Draw_F *f;
  uchar dx, dy, dw, dh;
} fl_box_table[] = {
// must match list in Enumerations.H!!!
#ifdef PDA  
  {fl_no_box,		0,0,0,0},
#endif		
  {fl_rectf,		0,0,0,0}, // FL_FLAT_BOX
  {fl_up_box,		D1,D1,D2,D2},
  {fl_down_box,		D1,D1,D2,D2},
  {fl_up_frame,		D1,D1,D2,D2},
  {fl_down_frame,	D1,D1,D2,D2},
  {fl_thin_up_box,	1,1,2,2},
  {fl_thin_down_box,	1,1,2,2},
  {fl_thin_up_frame,	1,1,2,2},
  {fl_thin_down_frame,	1,1,2,2},
  {fl_engraved_box,	2,2,4,4},
  {fl_embossed_box,	2,2,4,4},
  {fl_engraved_frame,	2,2,4,4},
  {fl_embossed_frame,	2,2,4,4},
  {fl_border_box,	1,1,2,2},
  {fl_border_box,	1,1,2,2}, // _FL_SHADOW_BOX,
  {fl_border_frame,	1,1,2,2},
  {fl_border_frame,	1,1,2,2}, // _FL_SHADOW_FRAME,
  {fl_border_box,	1,1,2,2}, // _FL_ROUNDED_BOX,
  {fl_border_box,	1,1,2,2}, // _FL_RSHADOW_BOX,
  {fl_border_frame,	1,1,2,2}, // _FL_ROUNDED_FRAME
  {fl_rectf,		0,0,0,0}, // _FL_RFLAT_BOX,
  {fl_up_box,		3,3,6,6}, // _FL_ROUND_UP_BOX
  {fl_down_box,		3,3,6,6}, // _FL_ROUND_DOWN_BOX,
  {fl_up_box,		0,0,0,0}, // _FL_DIAMOND_UP_BOX
  {fl_down_box,		0,0,0,0}, // _FL_DIAMOND_DOWN_BOX
  {fl_border_box,	1,1,2,2}, // _FL_OVAL_BOX,
  {fl_border_box,	1,1,2,2}, // _FL_OVAL_SHADOW_BOX,
  {fl_border_frame,	1,1,2,2}, // _FL_OVAL_FRAME
  {fl_rectf,		0,0,0,0}, // _FL_OVAL_FLAT_BOX,
  {fl_up_box,		3,3,6,6}, // FL_FREE_BOX+0
  {fl_down_box,		3,3,6,6}, // FL_FREE_BOX+1
  {fl_up_box,		3,3,6,6}, // FL_FREE_BOX+2
  {fl_down_box,		3,3,6,6}, // FL_FREE_BOX+3
  {fl_up_box,		3,3,6,6}, // FL_FREE_BOX+4
  {fl_down_box,		3,3,6,6}, // FL_FREE_BOX+5
  {fl_up_box,		3,3,6,6}, // FL_FREE_BOX+6
  {fl_down_box,		3,3,6,6}, // FL_FREE_BOX+7
#ifdef PDA
  {fl_pda_box,			0,0,0,0},
  {fl_black_box,		0,0,0,0},
  {fl_white_box,		0,0,0,0},
  {fl_pda_no_box, 	0,0,0,0},
	{fl_bottom_box, 	0,0,0,0},
#endif
};


#ifdef PDA
int Fl::box_dx(Fl_Boxtype t) {return 0;}
int Fl::box_dy(Fl_Boxtype t) {return 0;}
int Fl::box_dw(Fl_Boxtype t) {return 0;}
int Fl::box_dh(Fl_Boxtype t) {return 0;}
#else
int Fl::box_dx(Fl_Boxtype t) {return fl_box_table[t].dx;}
int Fl::box_dy(Fl_Boxtype t) {return fl_box_table[t].dy;}
int Fl::box_dw(Fl_Boxtype t) {return fl_box_table[t].dw;}
int Fl::box_dh(Fl_Boxtype t) {return fl_box_table[t].dh;}
#endif
void fl_internal_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f) {fl_box_table[t].f=f;}

void Fl::set_boxtype(Fl_Boxtype t, Fl_Box_Draw_F* f,
		      uchar a, uchar b, uchar c, uchar d) {
  fl_box_table[t].f=f;
  fl_box_table[t].dx = a;
  fl_box_table[t].dy = b;
  fl_box_table[t].dw = c;
  fl_box_table[t].dh = d;
}

void Fl::set_boxtype(Fl_Boxtype t, Fl_Boxtype f) {
  fl_box_table[t] = fl_box_table[f];
}

void fl_draw_box(Fl_Boxtype t, int x, int y, int w, int h, Fl_Color c) {
  if (t) fl_box_table[t].f(x,y,w,h,c);
}

//extern Fl_Widget *fl_boxcheat; // hack set by Fl_Window.C

void Fl_Widget::draw_box() const {
  int t = box_;
  if (!t) return;
//   if (this == fl_boxcheat) {
//     fl_boxcheat = 0;
//     if (t == FL_FLAT_BOX) return;
//     t += 2; // convert box to frame
//   }
  draw_box((Fl_Boxtype)t, x_, y_, w_, h_, (Fl_Color)color_);
}

void Fl_Widget::draw_box(Fl_Boxtype b, Fl_Color c) const {
  draw_box(b, x_, y_, w_, h_, c);
}

void Fl_Widget::draw_box(Fl_Boxtype b, int x, int y, int w, int h, Fl_Color c)
const {
  draw_it_active = active_r();
  fl_box_table[b].f(x, y, w, h, c);
  draw_it_active = 1;
}

//
// End of "$Id: fl_boxtype.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Multi_Label.cxx ---
//
// "$Id: Fl_Multi_Label.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Multi-label widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Allows two labels to be used on a widget (by having one of them
// be one of these it allows an infinte number!)

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Multi_Label.H>

static void multi_labeltype(
    const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
{
  Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
  Fl_Label local = *o;
  local.value = b->labela;
  local.type = b->typea;
  int W = w; int H = h; local.measure(W, H);
  local.draw(x,y,w,h,a);
  if (a & FL_ALIGN_BOTTOM) h -= H;
  else if (a & FL_ALIGN_TOP) {y += H; h -= H;}
  else if (a & FL_ALIGN_RIGHT) w -= W;
  else if (a & FL_ALIGN_LEFT) {x += W; w -= W;}
  else {int d = (h+H)/2; y += d; h -= d;}
  local.value = b->labelb;
  local.type = b->typeb;
  local.draw(x,y,w,h,a);
}

// measurement is only correct for left-to-right appending...
static void multi_measure(const Fl_Label* o, int& w, int& h) {
  Fl_Multi_Label* b = (Fl_Multi_Label*)(o->value);
  Fl_Label local = *o;
  local.value = b->labela;
  local.type = b->typea;
  local.measure(w,h);
  local.value = b->labelb;
  local.type = b->typeb;
  int W = 0; int H = 0; local.measure(W,H);
  w += W; if (H>h) h = H;
}

void Fl_Multi_Label::label(Fl_Widget* o) {
  Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
  o->label(_FL_MULTI_LABEL, (const char*)this);
}

void Fl_Multi_Label::label(Fl_Menu_Item* o) {
  Fl::set_labeltype(_FL_MULTI_LABEL, multi_labeltype, multi_measure);
  o->label(_FL_MULTI_LABEL, (const char*)this);
}

//
// End of "$Id: Fl_Multi_Label.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_shadow_box.cxx ---
//
// "$Id: fl_shadow_box.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Shadow box drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/fl_draw.H>

#define BW 3

static void fl_shadow_frame(int x, int y, int w, int h, Fl_Color c) {
  fl_color(FL_DARK3);
  fl_rectf(x+BW, y+h,  w, BW);
  fl_rectf(x+w,  y+BW, BW,  h);
  fl_color(c);
  fl_rect(x,y,w,h);
}

static void fl_shadow_box(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c);
  fl_rectf(x+1,y+1,w-2,h-2);
  fl_shadow_frame(x,y,w,h,FL_GRAY0);
}

extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
Fl_Boxtype define_FL_SHADOW_BOX() {
  fl_internal_boxtype(_FL_SHADOW_FRAME, fl_shadow_frame);
  fl_internal_boxtype(_FL_SHADOW_BOX, fl_shadow_box);
  return _FL_SHADOW_BOX;
}

//
// End of "$Id: fl_shadow_box.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_overlay.cxx ---
//
// "$Id: fl_overlay.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Overlay support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Extremely limited "overlay" support.  You can use this to drag out
// a rectangle in response to mouse events.  It is your responsibility
// to erase the overlay before drawing anything that might intersect
// it.

#include <FL/x.H>
#include <FL/fl_draw.H>

static int px,py,pw,ph;

static void draw_current_rect() {
#ifdef WIN32
  int old = SetROP2(fl_gc, R2_NOT);
  fl_rect(px, py, pw, ph);
  SetROP2(fl_gc, old);
#else
#ifdef NANO_X //tanghao
        GR_GC_ID temp_gc = GrCopyGC(fl_gc);
        GrSetGCMode(temp_gc,GR_MODE_XOR);
	GrSetGCForeground(temp_gc,0xffffff);
	GrRect(fl_window,temp_gc,px,py,pw,ph);
	GrDestroyGC(temp_gc);
#else
  XSetFunction(fl_display, fl_gc, GXxor);
  XSetForeground(fl_display, fl_gc, 0xffffffff);
  XDrawRectangle(fl_display, fl_window, fl_gc, px, py, pw, ph);
  XSetFunction(fl_display, fl_gc, GXcopy);
#endif 
#endif
}

void fl_overlay_clear() {
  if (pw > 0) {draw_current_rect(); pw = 0;}
}

void fl_overlay_rect(int x, int y, int w, int h) {
  if (w < 0) {x += w; w = -w;} else if (!w) w = 1;
  if (h < 0) {y += h; h = -h;} else if (!h) h = 1;
  if (pw > 0) {
    if (x==px && y==py && w==pw && h==ph) return;
    draw_current_rect();
  }
  px = x; py = y; pw = w; ph = h;
  draw_current_rect();
}

//
// End of "$Id: fl_overlay.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_compatability.cxx ---
//
// "$Id: forms_compatability.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms compatibility functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Forms library compatability functions.
// Many more functions are defined as inlines in forms.h!

#include <FL/forms.H>
#include <stdlib.h>

char fl_flip = 2;
void fl_end_form() {
  while (Fl_Group::current()) Fl_Group::current()->forms_end();
}
void Fl_Group::forms_end() {
  // set the dimensions of a group to surround contents
  if (children() && !w()) {
    Fl_Widget*const* a = array();
    Fl_Widget* o = *a++;
    int rx = o->x();
    int ry = o->y();
    int rw = rx+o->w();
    int rh = ry+o->h();
    for (int i=children_-1; i--;) {
      o = *a++;
      if (o->x() < rx) rx = o->x();
      if (o->y() < ry) ry = o->y();
      if (o->x()+o->w() > rw) rw = o->x()+o->w();
      if (o->y()+o->h() > rh) rh = o->y()+o->h();
    }
    x(rx);
    y(ry);
    w(rw-rx);
    h(rh-ry);
  }
  // flip all the children's coordinate systems:
  if (fl_flip) {
    Fl_Widget* o = (type()>=FL_WINDOW) ? this : window();
    int Y = o->h();
    Fl_Widget*const* a = array();
    for (int i=children(); i--;) {
      Fl_Widget* o = *a++;
      int newy = Y-o->y()-o->h();
      o->y(newy);
    }
  }
  end();
}

static int initargc;
static char **initargv;

void fl_initialize(int *argc, char **argv, const char *, FL_CMD_OPT *, int) {
  initargc = *argc;
  initargv = new char*[*argc+1];
  int i,j;
  for (i=0; i<=*argc; i++) initargv[i] = argv[i];
  for (i=j=1; i<*argc; ) {
    if (Fl::arg(*argc,argv,i));
    else argv[j++] = argv[i++];
  }
  argv[j] = 0;
  *argc = j;
  if (fl_flip==2) fl_flip = 0;
}

char fl_modal_next; // set by fl_freeze_forms()

void fl_show_form(Fl_Window *f,int place,int b,const char *n) {

  Fl::enable_symbols();

  f->label(n);
  if (!b) f->clear_border();
  if (fl_modal_next || b==FL_TRANSIENT) {f->set_modal(); fl_modal_next = 0;}

  if (place & FL_PLACE_MOUSE) f->hotspot(f);

  if (place & FL_PLACE_CENTER)
    f->position((Fl::w()-f->w())/2, (Fl::h()-f->h())/2);

  if (place & FL_PLACE_FULLSCREEN)
    f->fullscreen();

  if (place & (FL_PLACE_POSITION | FL_PLACE_GEOMETRY))
    f->position(
      (f->x() < 0) ? Fl::w()-f->w()+f->x()-1 : f->x(),
      (f->y() < 0) ? Fl::h()-f->h()+f->y()-1 : f->y());

// if (place & FL_PLACE_ASPECT) {
// this is not yet implemented
// it can be done by setting size_range().

  if (place == FL_PLACE_FREE || place == FL_PLACE_SIZE)
    f->free_position();

  if (place == FL_PLACE_FREE || place & FL_FREE_SIZE)
    if (!f->resizable()) f->resizable(f);

  if (initargc) {f->show(initargc,initargv); initargc = 0;}
  else f->show();
}

Fl_Widget *fl_do_forms(void) {
  Fl_Widget *obj;
  while (!(obj = Fl::readqueue())) if (!Fl::wait()) exit(0);
  return obj;
}

Fl_Widget *fl_check_forms() {
  Fl::check();
  return Fl::readqueue();
}

void fl_set_graphics_mode(int /*r*/,int /*d*/) {}

void Fl_FormsText::draw() {
  draw_box();
  align(align()|FL_ALIGN_INSIDE); // questionable method of compatability
  draw_label();
}

// Create a forms button by selecting correct fltk subclass:

#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Repeat_Button.H>

Fl_Button *fl_add_button(uchar t,int x,int y,int w,int h,const char *l) {
  Fl_Button *b;
  switch (t) {
  case FL_RETURN_BUTTON:
  case FL_HIDDEN_RET_BUTTON:
    b = new Fl_Return_Button(x,y,w,h,l);
    break;
  case FL_TOUCH_BUTTON:
    b = new Fl_Repeat_Button(x,y,w,h,l);
    break;
  default:
    b = new Fl_Button(x,y,w,h,l);
  }
  switch (t) {
  case FL_TOGGLE_BUTTON:
  case FL_RADIO_BUTTON:
    b->type(t);
    break;
  case FL_HIDDEN_BUTTON:
  case FL_HIDDEN_RET_BUTTON:
    b->type(FL_HIDDEN_BUTTON);
    break;
  case FL_INOUT_BUTTON:
    b->when(FL_WHEN_CHANGED);
    break;
  }
  return b;
}

void fl_show_message(const char *q1,const char *q2,const char *q3) {
  fl_message("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"");
}

void fl_show_alert(const char *q1,const char *q2,const char *q3,int) {
  fl_alert("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"");
}

int fl_show_question(const char *q1,const char *q2,const char *q3) {
  return fl_ask("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"");
}

int fl_show_choice(
  const char *q1,
  const char *q2,
  const char *q3,
  int, // number of buttons, ignored
  const char *b0,
  const char *b1,
  const char *b2) {
  return fl_choice("%s\n%s\n%s", q1?q1:"", q2?q2:"", q3?q3:"", b0,b1,b2)+1;
}

char *fl_show_simple_input(const char *str1, const char *defstr) {
  const char *r = fl_input(str1, defstr);
  return (char *)(r ? r : defstr);
}

//
// End of "$Id: forms_compatability.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu_Bar.cxx ---
//
// "$Id: Fl_Menu_Bar.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Menu bar widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Menu_Bar.H>

void Fl_Menu_Bar::draw() {
  //  draw_box();
  if (!menu() || !menu()->text) return;
  const Fl_Menu_Item* m;
  int X = x()+6;
  for (m=menu(); m->text; m = m->next()) {
    m->draw(X, y(), 0, h(), this);
    X += m->measure(0,this) + 16;
  }
}

int Fl_Menu_Bar::handle(int event) {
  const Fl_Menu_Item* v;
  if (menu() && menu()->text) switch (event) {
  case FL_ENTER:
  case FL_LEAVE:
    return 1;
  case FL_PUSH:
    v = 0;
  J1:
    v = menu()->pulldown(x(), y(), w(), h(), v, this, 0, 1);
    picked(v);
    return 1;
  case FL_SHORTCUT:
    v = menu()->test_shortcut();
    if (v) {picked(v); return 1;}
    if (visible_r() && (v = menu()->find_shortcut())) goto J1;
    return 0;
  }
  return 0;
}

//
// End of "$Id: Fl_Menu_Bar.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu_global.cxx ---
//
// "$Id: Fl_Menu_global.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Global menu shortcut code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Make all the shortcuts in this menu global.
// Currently only one menu at a time and you cannot destruct the menu,
// is this sufficient?

#include <FL/Fl.H>
#include <FL/Fl_Menu_.H>

static Fl_Menu_* the_widget;

static int handler(int e) {
  if (e != FL_SHORTCUT || Fl::modal()) return 0;
  return the_widget->handle(e);
}

void Fl_Menu_::global() {
  if (!the_widget) Fl::add_handler(handler);
  the_widget = this;
}

//
// End of "$Id: Fl_Menu_global.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_isdir.cxx ---
//
// "$Id: filename_isdir.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Directory detection routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Used by fl_file_chooser

#include <config.h>
#include <FL/filename.H>
#include <sys/stat.h>

int filename_isdir(const char* n) {
  struct stat s;
  return !stat(n, &s) && (s.st_mode&0170000)==0040000;
}

//
// End of "$Id: filename_isdir.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_rect.cxx ---
//
// "$Id: fl_rect.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// These routines from fl_draw.H are used by the standard boxtypes
// and thus are always linked into an fltk program.
// Also all fl_clip routines, since they are always linked in so
// that minimal update works.

#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>
#include <FL/x.H>

void fl_rect(int x, int y, int w, int h) {
  if (w<=0 || h<=0) return;
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x+w-1, y);
  LineTo(fl_gc, x+w-1, y+h-1);
  LineTo(fl_gc, x, y+h-1);
  LineTo(fl_gc, x, y);
#else
#ifdef NANO_X
  GrRect(fl_window, fl_gc, x, y, w, h);	// Nano-X draws w and h unlike X
#else
  XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
#endif
#endif
}

void fl_rectf(int x, int y, int w, int h) {
  if (w<=0 || h<=0) return;
#ifdef WIN32
  RECT rect;
  rect.left = x; rect.top = y;  
  rect.right = x + w; rect.bottom = y + h;
  FillRect(fl_gc, &rect, fl_brush());
#else
#ifdef NANO_X
  if (w && h) GrFillRect(fl_window,fl_gc,x,y,w,h);
#else
  if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
#endif
#endif
}

void fl_xyline(int x, int y, int x1) {
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
#else
#ifdef NANO_X
  GrLine(fl_window,fl_gc,x,y,x1,y);
#else
  XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
#endif
#endif
}

void fl_xyline(int x, int y, int x1, int y2) {
#ifdef WIN32
  if (y2 < y) y2--;
  else y2++;
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y);
  LineTo(fl_gc, x1, y2);
#else
#ifdef NANO_X
	GR_POINT p[3];
	p[0].x = x;  p[0].y = p[1].y = y;
	p[1].x = p[2].x = x1; p[2].y = y2;
	GrPoly(fl_window,fl_gc,3,p);
#else
  XPoint p[3];
  p[0].x = x;  p[0].y = p[1].y = y;
  p[1].x = p[2].x = x1; p[2].y = y2;
  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
#endif
#endif
}

void fl_xyline(int x, int y, int x1, int y2, int x3) {
#ifdef WIN32
  if(x3 < x1) x3--;
  else x3++;
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y);
  LineTo(fl_gc, x1, y2);
  LineTo(fl_gc, x3, y2);
#else
#ifdef NANO_X
	GR_POINT p[4];
	p[0].x = x;  p[0].y = p[1].y = y;
	p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
	p[3].x = x3;
	GrPoly(fl_window,fl_gc,4,p);
#else
  XPoint p[4];
  p[0].x = x;  p[0].y = p[1].y = y;
  p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
  p[3].x = x3;
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
#endif
#endif
}

void fl_yxline(int x, int y, int y1) {
#ifdef WIN32
  if (y1 < y) y1--;
  else y1++;
  MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
#else
#ifdef NANO_X
  GrLine(fl_window,fl_gc,x,y,x,y1);
#else
  XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
#endif
#endif
}

void fl_yxline(int x, int y, int y1, int x2) {
#ifdef WIN32
  if (x2 > x) x2++;
  else x2--;
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x, y1);
  LineTo(fl_gc, x2, y1);
#else
#ifdef NANO_X
	GR_POINT p[3];
	p[0].x = p[1].x = x;  p[0].y = y;
	p[1].y = p[2].y = y1; p[2].x = x2;
	GrPoly(fl_window,fl_gc,3,p);
#else
  XPoint p[3];
  p[0].x = p[1].x = x;  p[0].y = y;
  p[1].y = p[2].y = y1; p[2].x = x2;
  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
#endif
#endif
}

void fl_yxline(int x, int y, int y1, int x2, int y3) {
#ifdef WIN32
  if(y3<y1) y3--;
  else y3++;
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x, y1);
  LineTo(fl_gc, x2, y1);
  LineTo(fl_gc, x2, y3);
#else
#ifdef NANO_X
	GR_POINT p[4];
	p[0].x = p[1].x = x;  p[0].y = y;
	p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
	p[3].y = y3;
	GrPoly(fl_window,fl_gc,4,p);
#else
  XPoint p[4];
  p[0].x = p[1].x = x;  p[0].y = y;
  p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
  p[3].y = y3;
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
#endif
#endif
}

void fl_line(int x, int y, int x1, int y1) {
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y1);
  // Draw the last point *again* because the GDI line drawing
  // functions will not draw the last point ("it's a feature!"...)
  SetPixel(fl_gc, x1, y1, fl_RGB());
#else
#ifdef NANO_X
  GrLine(fl_window,fl_gc,x,y,x1,y1);
#else
  XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
#endif
#endif
}

void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y1);
  LineTo(fl_gc, x2, y2);
  // Draw the last point *again* because the GDI line drawing
  // functions will not draw the last point ("it's a feature!"...)
  SetPixel(fl_gc, x2, y2, fl_RGB());
#else
#ifdef NANO_X
	GR_POINT p[3];
	p[0].x = x;  p[0].y = y;
	p[1].x = x1; p[1].y = y1;
	p[2].x = x2; p[2].y = y2;
	GrPoly(fl_window,fl_gc,3,p);
#else
  XPoint p[3];
  p[0].x = x;  p[0].y = y;
  p[1].x = x1; p[1].y = y1;
  p[2].x = x2; p[2].y = y2;
  XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
#endif
#endif
}

void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y1);
  LineTo(fl_gc, x2, y2);
  LineTo(fl_gc, x, y);
#else
#ifdef NANO_X
	GR_POINT p[4];
	p[0].x = x;  p[0].y = y;
	p[1].x = x1; p[1].y = y1;
	p[2].x = x2; p[2].y = y2;
	p[3].x = x;  p[3].y = y;
	GrPoly(fl_window,fl_gc,4,p);
#else
  XPoint p[4];
  p[0].x = x;  p[0].y = y;
  p[1].x = x1; p[1].y = y1;
  p[2].x = x2; p[2].y = y2;
  p[3].x = x;  p[3].y = y;
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
#endif
#endif
}

void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
#ifdef WIN32
  MoveToEx(fl_gc, x, y, 0L); 
  LineTo(fl_gc, x1, y1);
  LineTo(fl_gc, x2, y2);
  LineTo(fl_gc, x3, y3);
  LineTo(fl_gc, x, y);
#else
#ifdef NANO_X
	GR_POINT p[5];
	p[0].x = x;  p[0].y = y;
	p[1].x = x1; p[1].y = y1;
	p[2].x = x2; p[2].y = y2;
	p[3].x = x3; p[3].y = y3;
	p[4].x = x;  p[4].y = y;
	GrPoly(fl_window,fl_gc,5,p);
#else
  XPoint p[5];
  p[0].x = x;  p[0].y = y;
  p[1].x = x1; p[1].y = y1;
  p[2].x = x2; p[2].y = y2;
  p[3].x = x3; p[3].y = y3;
  p[4].x = x;  p[4].y = y;
  XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
#endif
#endif
}

void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
#ifdef NANO_X
	GR_POINT p[4];
#else
  XPoint p[4];
#endif
  p[0].x = x;  p[0].y = y;
  p[1].x = x1; p[1].y = y1;
  p[2].x = x2; p[2].y = y2;
#ifdef WIN32
  SelectObject(fl_gc, fl_brush());
  Polygon(fl_gc, p, 3);
#else
  p[3].x = x;  p[3].y = y;
#ifdef NANO_X
  GrFillPoly(fl_window,fl_gc,4,p);
#else
  XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0);
  XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
#endif
#endif
}

void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
#ifdef NANO_X
	GR_POINT p[5];
#else
  XPoint p[5];
#endif
  p[0].x = x;  p[0].y = y;
  p[1].x = x1; p[1].y = y1;
  p[2].x = x2; p[2].y = y2;
  p[3].x = x3; p[3].y = y3;
#ifdef WIN32
  SelectObject(fl_gc, fl_brush());
  Polygon(fl_gc, p, 4);
#else
  p[4].x = x;  p[4].y = y;
#ifdef NANO_X
  GrFillPoly(fl_window,fl_gc,5,p);
#else
  XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0);
  XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
#endif
#endif
}

void fl_point(int x, int y) {
#ifdef WIN32
  SetPixel(fl_gc, x, y, fl_RGB());
#else
#ifdef NANO_X
	GrPoint(fl_window,fl_gc,x,y);
#else
  XDrawPoint(fl_display, fl_window, fl_gc, x, y);
#endif
#endif
}

////////////////////////////////////////////////////////////////

#define STACK_SIZE 10
#define STACK_MAX (STACK_SIZE - 1)
static Region rstack[STACK_SIZE];
static int rstackptr=0;
int fl_clip_state_number=0; // used by gl_begin.C to update GL clip

#ifndef WIN32
// Missing X call: (is this the fastest way to init a 1-rectangle region?)
// MSWindows equivalent exists, implemented inline in win32.H
Region XRectangleRegion(int x, int y, int w, int h) {
#ifdef NANO_X
  GR_RECT R;
  R.x = x; R.y = y; R.width = w; R.height = h;
  GR_REGION_ID r = GrNewRegion();
  GrUnionRectWithRegion(r, &R);
  return r;
#else
  XRectangle R;
  R.x = x; R.y = y; R.width = w; R.height = h;
  Region r = XCreateRegion();
  XUnionRectWithRegion(&R, r, r);
  return r;
#endif
}
#endif

// undo any clobbering of clip done by your program:
void fl_restore_clip() {
  fl_clip_state_number++;
  Region r = rstack[rstackptr];
#ifdef WIN32
  SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared
#else
#ifdef NANO_X
  GrSetGCRegion(fl_gc, r); // if r is 0, clip is cleared
#else
  if (r) XSetRegion(fl_display, fl_gc, r);
  else XSetClipMask(fl_display, fl_gc, 0);
#endif
#endif
}

// Replace the top of the clip stack:
void fl_clip_region(Region r) {
  Region oldr = rstack[rstackptr];
#ifdef NANO_X
  if (oldr) GrDestroyRegion(oldr);
#else
  if (oldr) XDestroyRegion(oldr);
#endif
  rstack[rstackptr] = r;
  fl_restore_clip();
}

// Intersect & push a new clip rectangle:
void fl_clip(int x, int y, int w, int h) {
  Region r;
  if (w > 0 && h > 0) {
    r = XRectangleRegion(x,y,w,h);
    Region current = rstack[rstackptr];
    if (current) {
#ifndef WIN32
#ifdef NANO_X
      Region temp = GrNewRegion();
      GrIntersectRegion(temp, current, r);
      GrDestroyRegion(r);
#else
      Region temp = XCreateRegion();
      XIntersectRegion(current, r, temp);
      XDestroyRegion(r);
#endif
      r = temp;
#else
      CombineRgn(r,r,current,RGN_AND);
#endif
    }
  } else { // make empty clip region:
#ifndef WIN32
#ifdef NANO_X
    r = GrNewRegion();
#else
    r = XCreateRegion();
#endif
#else
    r = CreateRectRgn(0,0,0,0);
#endif
  }
  if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
  fl_restore_clip();
}

// make there be no clip (used by fl_begin_offscreen() only!)
void fl_push_no_clip() {
  if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
  fl_restore_clip();
}

// pop back to previous clip:
void fl_pop_clip() {

  if (rstackptr > 0) {
    Region oldr = rstack[rstackptr--];
#ifdef NANO_X	
    if (oldr) GrDestroyRegion(oldr);
#else
    if (oldr) XDestroyRegion(oldr);
#endif

  }
  fl_restore_clip();
}

// does this rectangle intersect current clip?
int fl_not_clipped(int x, int y, int w, int h) {

  Region r = rstack[rstackptr];
#ifndef WIN32
#ifdef NANO_X
  return r ? GrRectInRegion(r, x, y, w, h) : 1;
#else
  return r ? XRectInRegion(r, x, y, w, h) : 1;
#endif
#else
  if (!r) return 1;
  RECT rect;
  rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
  return RectInRegion(r,&rect);
#endif

}

// return rectangle surrounding intersection of this rectangle and clip:
int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
  X = x; Y = y; W = w; H = h;
  Region r = rstack[rstackptr];
  if (!r) return 0;
#ifndef WIN32
#ifdef NANO_X
 	{
	switch (GrRectInRegion(r, x, y, w, h)) {
	case MWRECT_OUT: // completely outside
		W = H = 0;
		return 2;
	case MWRECT_ALLIN: // completely inside
		return 0;
	default: // partial:
		break;
	}
  	Region rr = XRectangleRegion(x,y,w,h);
  	Region temp = GrNewRegion();
	GrIntersectRegion(temp, r, rr);
	GR_RECT rect;
	GrGetRegionBox(temp, &rect);
	X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
	GrDestroyRegion(temp);
	GrDestroyRegion(rr);
	return 1;
	}
#else	
  switch (XRectInRegion(r, x, y, w, h)) {
  case 0: // completely outside
    W = H = 0;
    return 2;
  case 1: // completely inside:
    return 0;
  default: // partial:
    break;
  }
  Region rr = XRectangleRegion(x,y,w,h);
  Region temp = XCreateRegion();
  XIntersectRegion(r, rr, temp);
  XRectangle rect;
  XClipBox(temp, &rect);
  X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
  XDestroyRegion(temp);
  XDestroyRegion(rr);
  return 1;
#endif
#else
// The win32 API makes no distinction between partial and complete
// intersection, so we have to check for partial intersection ourselves.
// However, given that the regions may be composite, we have to do
// some voodoo stuff...
  Region rr = XRectangleRegion(x,y,w,h);
  Region temp = CreateRectRgn(0,0,0,0);
  int ret;
  if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
    W = H = 0;
    ret = 2;
  } else if (EqualRgn(temp, rr)) { // complete
    ret = 0;
  } else {	// parital intersection
    RECT rect;
    GetRgnBox(temp, &rect);
    X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
    ret = 1;
  }
  DeleteObject(temp);
  DeleteObject(rr);
  return ret;
#endif
}

//
// End of "$Id: fl_rect.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Adjuster.cxx ---
//
// "$Id: Fl_Adjuster.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Adjuster widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//


#include <FL/Fl.H>
#include <FL/Fl_Adjuster.H>
#include <FL/Fl_Bitmap.H>
#include <FL/fl_draw.H>

#include "fastarrow.h"
static Fl_Bitmap fastarrow(fastarrow_bits, fastarrow_width, fastarrow_height);
#include "mediumarrow.h"
static Fl_Bitmap mediumarrow(mediumarrow_bits, mediumarrow_width, mediumarrow_height);
#include "slowarrow.h"
static Fl_Bitmap slowarrow(slowarrow_bits, slowarrow_width, slowarrow_height);

// changing the value does not change the appearance:
void Fl_Adjuster::value_damage() {}

void Fl_Adjuster::draw() {
  int dx, dy, W, H;
  if (w()>=h()) {
    dx = W = w()/3;
    dy = 0; H = h();
  } else {
    dx = 0; W = w();
    dy = H = h()/3;
  }
  draw_box(drag==1?FL_DOWN_BOX:box(), x(),  y()+2*dy, W, H, color());
  draw_box(drag==2?FL_DOWN_BOX:box(), x()+dx, y()+dy, W, H, color());
  draw_box(drag==3?FL_DOWN_BOX:box(), x()+2*dx,  y(), W, H, color());
  if (active_r())
    fl_color(selection_color());
  else
    fl_color(inactive(selection_color()));
  fastarrow.draw(x()+(W-fastarrow_width)/2,
		 y()+2*dy+(H-fastarrow_height)/2, W, H);
  mediumarrow.draw(x()+dx+(W-mediumarrow_width)/2,
		   y()+dy+(H-mediumarrow_height)/2, W, H);
  slowarrow.draw(x()+2*dx+(W-slowarrow_width)/2,
		 y()+(H-slowarrow_width)/2, W, H);
}

int Fl_Adjuster::handle(int event) {
  double v;
  int delta;
  int mx = Fl::event_x();
  switch (event) {
  case FL_PUSH:
    ix = mx;
    if (w()>=h())
      drag = 3*(mx-x())/w() + 1;
    else
      drag = 3-3*(Fl::event_y()-y()-1)/h();
    handle_push();
    redraw();
    return 1;
  case FL_DRAG:
    if (w() >= h()) {
      delta = x()+(drag-1)*w()/3;	// left edge of button
      if (mx < delta)
	delta = mx-delta;
      else if (mx > (delta+w()/3)) // right edge of button
	delta = mx-delta-w()/3;
      else
	delta = 0;
    } else {
      if (mx < x())
	delta = mx-x();
      else if (mx > (x()+w()))
	delta = mx-x()-w();
      else
	delta = 0;
    }
    switch (drag) {
    case 3: v = increment(previous_value(), delta); break;
    case 2: v = increment(previous_value(), delta*10); break;
    default:v = increment(previous_value(), delta*100); break;
    }
    handle_drag(soft() ? softclamp(v) : clamp(v));
    return 1;
  case FL_RELEASE:
    if (Fl::event_is_click()) { // detect click but no drag
      if (Fl::event_state()&0xF0000) delta = -10;
      else delta = 10;
      switch (drag) {
      case 3: v = increment(previous_value(), delta); break;
      case 2: v = increment(previous_value(), delta*10); break;
      default:v = increment(previous_value(), delta*100); break;
      }
      handle_drag(soft() ? softclamp(v) : clamp(v));
    }
    drag = 0;
    redraw();
    handle_release();
    return 1;
  }
  return 0;
}

Fl_Adjuster::Fl_Adjuster(int x, int y, int w, int h, const char* l)
  : Fl_Valuator(x, y, w, h, l) {
  box(FL_UP_BOX);
  step(1, 10000);
  selection_color(FL_BLACK);
  drag = 0;
  soft_ = 1;
}

//
// End of "$Id: Fl_Adjuster.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_bitmap.cxx ---
//
// "$Id: forms_bitmap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms compatible bitmap function for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/forms.H>

Fl_FormsBitmap::Fl_FormsBitmap(
  Fl_Boxtype t, int x, int y, int w, int h, const char* l)
: Fl_Widget(x, y, w, h, l) {
  box(t);
  b = 0;
  color(FL_BLACK);
  align(FL_ALIGN_BOTTOM);
}

void Fl_FormsBitmap::set(int W, int H, const uchar *bits) {
  delete b;
  bitmap(new Fl_Bitmap(bits, W, H));
}

void Fl_FormsBitmap::draw() {
  draw_box(box(), selection_color());
  if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
  draw_label();
}

//
// End of "$Id: forms_bitmap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Output.cxx ---
//
// "$Id: Fl_Output.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Output widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This subclass of Fl_Input_ does not allow user to edit the output.
// Used to display output.

#include <FL/Fl.H>
#include <FL/Fl_Output.H>
#include <FL/fl_draw.H>

void Fl_Output::draw() {
  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
  if (damage() & FL_DAMAGE_ALL) draw_box(b, color());
  Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
		      w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
}

int Fl_Output::handle(int event) {
  if (event == FL_FOCUS) return 0;
  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
  return Fl_Input_::handletext(event,
	x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
	w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
}

//
// End of "$Id: Fl_Output.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_draw_pixmap.cxx ---
//
// "$Id: fl_draw_pixmap.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implemented without using the xpm library (which I can't use because
// it interferes with the color cube used by fl_draw_image).
// Current implementation is cheap and slow, and works best on a full-color
// display.  Transparency is not handled, and colors are dithered to
// the color cube.  Color index is achieved by adding the id
// characters together!  Also mallocs a lot of temporary memory!
// Notice that there is no pixmap file interface.  This is on purpose,
// as I want to discourage programs that require support files to work.
// All data needed by a program ui should be compiled in!!!

#include <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <ctype.h>
#include <stdio.h>
#include <string.h>

static int ncolors, chars_per_pixel;

int fl_measure_pixmap(/*const*/char * const *data, int &w, int &h) {
  int i = sscanf(data[0],"%d %d %d %d",&w,&h,&ncolors,&chars_per_pixel);
  if (i<4 || w<=0 || h<=0 ||
      chars_per_pixel!=1 && chars_per_pixel!=2) return w=0;
  return 1;
}

#ifdef U64

// The callback from fl_draw_image to get a row of data passes this:
struct pixmap_data {
  int w, h;
  const uchar*const* data;
  union {
    U64 colors[256];
    U64* byte1[256];
  };
};

// callback for 1 byte per pixel:
static void cb1(void*v, int x, int y, int w, uchar* buf) {
  pixmap_data& d = *(pixmap_data*)v;
  const uchar* p = d.data[y]+x;
  U64* q = (U64*)buf;
  for (int X=(w+1)/2; X--; p += 2) {
#if WORDS_BIGENDIAN
    *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]];
#else
    *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]];
#endif
  }
}

// callback for 2 bytes per pixel:
static void cb2(void*v, int x, int y, int w, uchar* buf) {
  pixmap_data& d = *(pixmap_data*)v;
  const uchar* p = d.data[y]+2*x;
  U64* q = (U64*)buf;
  for (int X=(w+1)/2; X--;) {
    U64* colors = d.byte1[*p++];
    int index = *p++;
    U64* colors1 = d.byte1[*p++];
    int index1 = *p++;
#if WORDS_BIGENDIAN
    *q++ = (colors[index]<<32) | colors1[index1];
#else
    *q++ = (colors1[index1]<<32) | colors[index];
#endif
  }
}

#else

// The callback from fl_draw_image to get a row of data passes this:
struct pixmap_data {
  int w, h;
  const uchar*const* data;
  union {
    U32 colors[256];
    U32* byte1[256];
  };
};

// callback for 1 byte per pixel:
static void cb1(void*v, int x, int y, int w, uchar* buf) {
  pixmap_data& d = *(pixmap_data*)v;
  const uchar* p = d.data[y]+x;
  U32* q = (U32*)buf;
  for (int X=w; X--;) *q++ = d.colors[*p++];
}

// callback for 2 bytes per pixel:
static void cb2(void*v, int x, int y, int w, uchar* buf) {
  pixmap_data& d = *(pixmap_data*)v;
  const uchar* p = d.data[y]+2*x;
  U32* q = (U32*)buf;
  for (int X=w; X--;) {
    U32* colors = d.byte1[*p++];
    *q++ = colors[*p++];
  }
}

#endif

#ifdef WIN32
// this is in Fl_arg.C:
extern int fl_parse_color(const char*, uchar&, uchar&, uchar&);
#endif

#ifdef NANO_X

int fl_parse_color(const char* p, uchar& r, uchar& g, uchar& b)
{
  if (*p == '#') p++;
  int n = strlen(p);
  int m = n/3;
  const char *pattern = 0;
  switch(m) {
  case 1: pattern = "%1x%1x%1x"; break;
  case 2: pattern = "%2x%2x%2x"; break;
  case 3: pattern = "%3x%3x%3x"; break;
  case 4: pattern = "%4x%4x%4x"; break;
  default: return 0;
  }
  int R,G,B; if (sscanf(p,pattern,&R,&G,&B) != 3) return 0;
  switch(m) {
  case 1: R *= 0x11; G *= 0x11; B *= 0x11; break;
  case 3: R >>= 4; G >>= 4; B >>= 4; break;
  case 4: R >>= 8; G >>= 8; B >>= 8; break;
  }
  r = R; g = G; b = B;
  return 1;
}

#endif

uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here

int fl_draw_pixmap(/*const*/char*const* di, int x, int y, Fl_Color bg) {
  pixmap_data d;
  if (!fl_measure_pixmap(di, d.w, d.h)) return 0;
  const uchar*const* data = (const uchar*const*)(di+1);
  int transparent_index = -1;

  if (ncolors < 0) {	// fltk (non standard) compressed colormap
    ncolors = -ncolors;
    const uchar *p = *data++;
    // if first color is ' ' it is transparent (put it later to make
    // it not be transparent):
    if (*p == ' ') {
      uchar* c = (uchar*)&d.colors[' '];
#ifdef U64
      *(U64*)c = 0;
#if WORDS_BIGENDIAN
      c += 4;
#endif
#endif
      transparent_index = ' ';
      Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
      p += 4;
      ncolors--;
    }
    // read all the rest of the colors:
    for (int i=0; i < ncolors; i++) {
      uchar* c = (uchar*)&d.colors[*p++];
#ifdef U64
      *(U64*)c = 0;
#if WORDS_BIGENDIAN
      c += 4;
#endif
#endif
      *c++ = *p++;
      *c++ = *p++;
      *c++ = *p++;
      *c = 0;
    }
  } else {	// normal XPM colormap with names
    if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1));
    for (int i=0; i<ncolors; i++) {
      const uchar *p = *data++;
      // the first 1 or 2 characters are the color index:
      int index = *p++;
      uchar* c;
      if (chars_per_pixel>1) {
#ifdef U64
	U64* colors = d.byte1[index];
	if (!colors) colors = d.byte1[index] = new U64[256];
#else
	U32* colors = d.byte1[index];
	if (!colors) colors = d.byte1[index] = new U32[256];
#endif
	c = (uchar*)&colors[*p];
	index = (index<<8)+*p++;
      } else {
	c = (uchar *)&d.colors[index];
      }
      // look for "c word", or last word if none:
      const uchar *previous_word = p;
      for (;;) {
	while (*p && isspace(*p)) p++; uchar what = *p++;
	while (*p && !isspace(*p)) p++;
	while (*p && isspace(*p)) p++;
	if (!*p) {p = previous_word; break;}
	if (what == 'c') break;
	previous_word = p;
	while (*p && !isspace(*p)) p++;
      }
#ifdef U64
      *(U64*)c = 0;
#if WORDS_BIGENDIAN
      c += 4;
#endif
#endif
#ifdef WIN32
      if (fl_parse_color((const char*)p, c[0], c[1], c[2])) {;
#else
#ifndef NANO_X //tanghao
      XColor x;
      if (XParseColor(fl_display, fl_colormap, (const char*)p, &x)) {
	c[0] = x.red>>8; c[1] = x.green>>8; c[2] = x.blue>>8;
#else
      if (fl_parse_color((const char*)p, c[0], c[1], c[2])) {;
#endif //tanghao
#endif
      } else { // assumme "None" or "#transparent" for any errors
	// this should be transparent...
	Fl::get_color(bg, c[0], c[1], c[2]);
	transparent_index = index;
      }
    }
  }
  d.data = data;

  // build the mask bitmap used by Fl_Pixmap:
  if (fl_mask_bitmap && transparent_index >= 0) {
    int W = (d.w+7)/8;
    uchar* bitmap = new uchar[W * d.h];
    *fl_mask_bitmap = bitmap;
    for (int y = 0; y < d.h; y++) {
      const uchar* p = data[y];
      if (chars_per_pixel <= 1) {
	for (int x = 0; x < W; x++) {
	  int b = (*p++ != transparent_index);
	  if (*p++ != transparent_index) b |= 2;
	  if (*p++ != transparent_index) b |= 4;
	  if (*p++ != transparent_index) b |= 8;
	  if (*p++ != transparent_index) b |= 16;
	  if (*p++ != transparent_index) b |= 32;
	  if (*p++ != transparent_index) b |= 64;
	  if (*p++ != transparent_index) b |= 128;
	  *bitmap++ = b;
	}
      } else {
	for (int x = 0; x < W; x++) {
	  int b = 0;
	  for (int i = 0; i < 8; i++) {
	    int index = *p++;
	    index = (index<<8) | (*p++);
	    if (index != transparent_index) b |= (1<<i);
	  }
	  *bitmap++ = b;
	}
      }
    }
  }

  fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
  if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete d.byte1[i];
  return 1;
}

//
// End of "$Id: fl_draw_pixmap.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Round_Button.cxx ---
//
// "$Id: Fl_Round_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Round button for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// A subclass of Fl_Button that always draws as a round circle.  This
// circle is smaller than the widget size and can be surrounded by
// another box type, for compatability with Forms.

#include <FL/Fl.H>
#include <FL/Fl_Round_Button.H>

Fl_Round_Button::Fl_Round_Button(int x,int y,int w,int h, const char *l)
: Fl_Light_Button(x,y,w,h,l) {
  box(FL_NO_BOX);
  down_box(FL_ROUND_DOWN_BOX);
  selection_color(FL_RED);
}

//
// End of "$Id: Fl_Round_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: scandir.c ---
/* Copyright (C) 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
This file is part of the GNU C Library.

The GNU C 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.

The GNU C 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.  */

#ifdef WIN32
#include "scandir_win32.c"
#else

#include <config.h>

#if HAVE_SCANDIR
#else

#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <errno.h>

#if HAVE_DIRENT_H
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
# if HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# if HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif

int
scandir (const char *dir, struct dirent ***namelist,
	 int (*select)(struct dirent *),
	 int (*compar)(struct dirent **, struct dirent **))
{
  DIR *dp = opendir (dir);
  struct dirent **v = NULL;
  size_t vsize = 0, i;
  struct dirent *d;
  int save;

  if (dp == NULL)
    return -1;

  save = errno;
  errno = 0;

  i = 0;
  while ((d = readdir (dp)) != NULL)
    if (select == NULL || (*select) (d))
      {
      size_t dsize;

      if (i == vsize)
        {
          struct dirent **newv;
          if (vsize == 0)
            vsize = 10;
          else
            vsize *= 2;
          newv = (struct dirent **) realloc (v, vsize * sizeof (*v));
          if (newv == NULL)
            {
            lose:
              errno = ENOMEM;
              break;
            }
          v = newv;
        }

#define _D_EXACT_NAMLEN(d) (strlen ((d)->d_name))
#define _D_ALLOC_NAMLEN(d) (sizeof (d)->d_name > 1 ? sizeof (d)->d_name : \
                              _D_EXACT_NAMLEN (d) + 1)

      dsize = &d->d_name[_D_ALLOC_NAMLEN (d)] - (char *) d;
      v[i] = (struct dirent *) malloc (dsize);
      if (v[i] == NULL)
        goto lose;

      memcpy (v[i++], d, dsize);
      }

  if (errno != 0)
    {
      save = errno;
      (void) closedir (dp);
      while (i > 0)
      free (v[--i]);
      free (v);
      errno = save;
      return -1;
    }

  (void) closedir (dp);
  errno = save;

  /* Sort the list if we have a comparison function to sort with.  */
  if (compar) qsort (v, i, sizeof (*v), (int (*)(const void *, const void *))compar);
  *namelist = v;
  return i;
}

int alphasort (struct dirent **a, struct dirent **b) {
  return strcmp ((*a)->d_name, (*b)->d_name);
}

#endif
#endif

--- NEW FILE: fl_symbols.cxx ---
//
// "$Id: fl_symbols.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Symbol drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// These are small graphics drawn by the normal label-drawing
// code when the string starts with an '@' sign.

// Adapted from original code written by:

// Written by Mark Overmars
// Version 2.1 a
// Date: Oct  2, 1992

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <string.h>

typedef struct {
  const char *name;
  void (*drawit)(Fl_Color);
  char scalable;
  char notempty;
} SYMBOL;

#define MAXSYMBOL       211
   /* Maximal number of symbols in table. Only half of them are
      used. Should be prime. */

static SYMBOL symbols[MAXSYMBOL];      /* The symbols */
static int symbnumb = -1;              /* Their number */

static int find(const char *name) {
// returns hash entry if it exists, or first empty slot:
  int pos = name[0] ? (
    name[1] ? (
      name[2] ? 71*name[0]+31*name[1]+name[2] : 31*name[0]+name[1]
    ) :
      name[0]
  ) : 0;
  pos %= MAXSYMBOL;
  int hh2 = name[0] ? (
    (name[1]) ? 51*name[0]+3*name[1] : 3*name[0]
    ) : 1;
  hh2 %= MAXSYMBOL; if (!hh2) hh2 = 1;
  for (;;) {
    if (!symbols[pos].notempty) return pos;
    if (!strcmp(symbols[pos].name,name)) return pos;
    pos = (pos + hh2) % MAXSYMBOL;
  }
}

static void fl_init_symbols(void);

/**************** The routines seen by the user *************************/

int fl_add_symbol(const char *name, void (*drawit)(Fl_Color), int scalable)
/* Adds a symbol to the system. Returns whether correct. */
{
  fl_init_symbols();
  int pos;
  if (symbnumb > MAXSYMBOL / 2) return 0;	// table is full
  pos = find(name);
  symbols[pos].name = name;
  symbols[pos].drawit = drawit;
  symbols[pos].notempty = 1;
  symbols[pos].scalable = scalable;
  symbnumb++;
  return 1;
}

int fl_return_arrow(int x,int y,int w,int h);

// provided for back compatability:
int fl_draw_symbol(const char *label,int x,int y,int w,int h,Fl_Color col) {
  const char *p = label;
  if (*p++ != '@') return 0;
  fl_init_symbols();
  int equalscale = 0;
  if (*p == '#') {equalscale = 1; p++;}
  if (*p == '-' && p[1]>='1' && p[1]<='9') {
    int n = p[1]-'0';
    x += n; y += n; w -= 2*n; h -= 2*n;
    p += 2;
  } else if (*p == '+' && p[1]>='1' && p[1]<='9') {
    int n = p[1]-'0';
    x -= n; y -= n; w += 2*n; h += 2*n;
    p += 2;
  }
  if (w < 10) {x -= (10-w)/2; w = 10;}
  if (h < 10) {y -= (10-h)/2; h = 10;}
  w = (w-1)|1; h = (h-1)|1;
  int rotangle;
  switch (*p++) {
  case '0':
    rotangle = 1000*(p[1]-'0') + 100*(p[2]-'0') + 10*(p[3]-'0');
    p += 4;
    break;
  case '1': rotangle = 2250; break;
  case '2': rotangle = 2700; break;
  case '3': rotangle = 3150; break;
  case '4': rotangle = 1800; break;
  case '5':
  case '6': rotangle = 0; break;
  case '7': rotangle = 1350; break;
  case '8': rotangle =  900; break;
  case '9': rotangle =  450; break;
  default: rotangle = 0; p--; break;
  }
  int pos = find(p);
  if (!symbols[pos].notempty) return 0;
  if (symbols[pos].scalable == 3) { // kludge to detect return arrow
    fl_return_arrow(x,y,w,h);
    return 1;
  }
  fl_push_matrix();
  fl_translate(x+w/2,y+h/2);
  if (symbols[pos].scalable) {
    if (equalscale) {if (w<h) h = w; else w = h;}
    fl_scale(0.5*w, 0.5*h);
    fl_rotate(rotangle/10.0);
  }
  (symbols[pos].drawit)(col);
  fl_pop_matrix();
  return 1;
}

/******************** THE DEFAULT SYMBOLS ****************************/

/* Some help stuff */

#define BP fl_begin_polygon()
#define EP fl_end_polygon()
#define BL fl_begin_line()
#define EL fl_end_line()
#define BC fl_begin_loop()
#define EC fl_end_loop()
#define vv(x,y) fl_vertex(x,y)

//for the outline color
static void set_outline_color(Fl_Color c) {
  fl_color(fl_color_average(c, FL_BLACK, .5));
}

static void rectangle(double x,double y,double x2,double y2,Fl_Color col) {
  fl_color(col);
  BP; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EP;
  set_outline_color(col);
  BC; vv(x,y); vv(x2,y); vv(x2,y2); vv(x,y2); EC;
}

/* The drawing routines */

static void draw_arrow1(Fl_Color col)
{
  fl_color(col);
  BP; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,-0.4); EP;
  BP; vv(0.0,0.8); vv(0.8,0.0); vv(0.0,-0.8); vv(0.0,-0.4); vv(0.0,0.4); EP;
  set_outline_color(col);
  BC; vv(-0.8,-0.4); vv(-0.8,0.4); vv(0.0,0.4); vv(0.0,0.8); vv(0.8,0.0);
      vv(0.0,-0.8); vv(0.0,-0.4); EC;
}

static void draw_arrow1bar(Fl_Color col)
{
  draw_arrow1(col);
  rectangle(.6,-.8,.9,.8,col);
}

static void draw_arrow2(Fl_Color col)
{
  fl_color(col);
  BP; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EP;
  set_outline_color(col);
  BC; vv(-0.3,0.8); vv(0.50,0.0); vv(-0.3,-0.8); EC;
}

static void draw_arrow3(Fl_Color col)
{
  fl_color(col);
  BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
  BP; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EP;
  set_outline_color(col);
  BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
  BC; vv(-0.7,0.8); vv(0.1,0.0); vv(-0.7,-0.8); EC;
}

static void draw_arrowbar(Fl_Color col)
{
  fl_color(col);
  BP; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EP;
  BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
  set_outline_color(col);
  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
  BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
}

static void draw_arrowbox(Fl_Color col)
{
  fl_color(col);
  BP; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EP;
  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
  set_outline_color(col);
  BC; vv(0.2,0.8); vv(0.6,0.8); vv(0.6,-0.8); vv(0.2,-0.8); EC;
  BC; vv(-0.6,0.8); vv(0.2,0.0); vv(-0.6,-0.8); EC;
}

static void draw_bararrow(Fl_Color col)
{
  fl_color(col);
  BP; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EP;
  BP; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EP;
  set_outline_color(col);
  BC; vv(0.1,0.8); vv(0.9,0.0); vv(0.1,-0.8); EC;
  BC; vv(-0.5,0.8); vv(-0.1,0.8); vv(-0.1,-0.8); vv(-0.5,-0.8); EC;
}

static void draw_doublebar(Fl_Color col) { 
  rectangle(-0.6,-0.8,-.1,.8,col);
  rectangle(.1,-0.8,.6,.8,col); 
}

static void draw_arrow01(Fl_Color col)
  { fl_rotate(180); draw_arrow1(col); }

static void draw_arrow02(Fl_Color col)
  { fl_rotate(180); draw_arrow2(col); }

static void draw_arrow03(Fl_Color col)
  { fl_rotate(180); draw_arrow3(col); }

static void draw_0arrowbar(Fl_Color col)
  { fl_rotate(180); draw_arrowbar(col); }

static void draw_0arrowbox(Fl_Color col)
  { fl_rotate(180); draw_arrowbox(col); }

static void draw_0bararrow(Fl_Color col)
  { fl_rotate(180); draw_bararrow(col); }

static void draw_doublearrow(Fl_Color col)
{
  fl_color(col);
  BP; vv(-0.35,-0.4); vv(-0.35,0.4); vv(0.35,0.4); vv(0.35,-0.4); EP;
  BP; vv(0.15,0.8); vv(0.95,0.0); vv(0.15,-0.8); EP;
  BP; vv(-0.15,0.8); vv(-0.95,0.0); vv(-0.15,-0.8); EP;
  set_outline_color(col);
  BC; vv(-0.15,0.4); vv(0.15,0.4); vv(0.15,0.8); vv(0.95,0.0);
      vv(0.15,-0.8); vv(0.15,-0.4); vv(-0.15,-0.4); vv(-0.15,-0.8);
      vv(-0.95,0.0); vv(-0.15,0.8); EC;
}

static void draw_arrow(Fl_Color col)
{
  fl_color(col);
  BP; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EP;
  BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
  set_outline_color(col);
  BL; vv(-1.0,0.0); vv(0.65,0.0); EL;
  BC; vv(0.65,0.1); vv(1.0,0.0); vv(0.65,-0.1); EC;
}

static void draw_square(Fl_Color col)
  { rectangle(-1,-1,1,1,col); }

static void draw_circle(Fl_Color col) {
  fl_color(col); BP; fl_circle(0,0,1); EP;
  set_outline_color(col);
  BC; fl_circle(0,0,1); EC;
}

static void draw_line(Fl_Color col)
  { fl_color(col); BL; vv(-1.0,0.0); vv(1.0,0.0); EL; }

static void draw_plus(Fl_Color col)
{
  fl_color(col);
  BP; vv(-0.9,-0.15); vv(-0.9,0.15); vv(0.9,0.15); vv(0.9,-0.15); EP;
  BP; vv(-0.15,-0.9); vv(-0.15,0.9); vv(0.15,0.9); vv(0.15,-0.9); EP;
  set_outline_color(col);
  BC;
  vv(-0.9,-0.15); vv(-0.9,0.15); vv(-0.15,0.15); vv(-0.15,0.9);
  vv(0.15,0.9); vv(0.15,0.15); vv(0.9,0.15); vv(0.9,-0.15);
  vv(0.15,-0.15); vv(0.15,-0.9); vv(-0.15,-0.9); vv(-0.15,-0.15);
  EC;
}

static void draw_uparrow(Fl_Color) {
  fl_color(FL_LIGHT3);
  BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
  fl_color(FL_DARK3);
  BL; vv(-.8,.8); vv(.8, 0); EL;
}

static void draw_downarrow(Fl_Color) {
  fl_color(FL_DARK3);
  BL; vv(-.8,.8); vv(-.8,-.8); vv(.8,0); EL;
  fl_color(FL_LIGHT3);
  BL; vv(-.8,.8); vv(.8, 0); EL;
}

static void draw_menu(Fl_Color col)
{
  rectangle(-0.65, 0.85, 0.65, -0.25, col);
  rectangle(-0.65, -0.6, 0.65, -1.0, col);
}

static void fl_init_symbols(void) {
  static char beenhere;
  if (beenhere) return;
  beenhere = 1;
  symbnumb = 0;

  fl_add_symbol("",		draw_arrow1,		1);
  fl_add_symbol("->",		draw_arrow1,		1);
  fl_add_symbol(">",		draw_arrow2,		1);
  fl_add_symbol(">>",		draw_arrow3,		1);
  fl_add_symbol(">|",		draw_arrowbar,		1);
  fl_add_symbol(">[]",		draw_arrowbox,		1);
  fl_add_symbol("|>",		draw_bararrow,		1);
  fl_add_symbol("<-",		draw_arrow01,		1);
  fl_add_symbol("<",		draw_arrow02,		1);
  fl_add_symbol("<<",		draw_arrow03,		1);
  fl_add_symbol("|<",		draw_0arrowbar,		1);
  fl_add_symbol("[]<",		draw_0arrowbox,		1);
  fl_add_symbol("<|",		draw_0bararrow,		1);
  fl_add_symbol("<->",		draw_doublearrow,	1);
  fl_add_symbol("-->",		draw_arrow,		1);
  fl_add_symbol("+",		draw_plus,		1);
  fl_add_symbol("->|",		draw_arrow1bar,		1);
  fl_add_symbol("arrow",	draw_arrow,		1);
  fl_add_symbol("returnarrow",	0,			3);
  fl_add_symbol("square",	draw_square,		1);
  fl_add_symbol("circle",	draw_circle,		1);
  fl_add_symbol("line",		draw_line,		1);
  fl_add_symbol("plus",		draw_plus,		1);
  fl_add_symbol("menu",		draw_menu,		1);
  fl_add_symbol("UpArrow",	draw_uparrow,		1);
  fl_add_symbol("DnArrow",	draw_downarrow,		1);
  fl_add_symbol("||",		draw_doublebar,		1);
}

////////////////////////////////////////////////////////////////

#include <FL/Fl_Widget.H>

// this is the labeltype function:
extern void fl_normal_label(const Fl_Label*, int, int, int, int, Fl_Align);
static void fl_symbol_label(
    const Fl_Label* o, int x, int y, int w, int h, Fl_Align align)
{
  if (!fl_draw_symbol(o->value, x, y, w, h, (Fl_Color)o->color))
    fl_normal_label(o, x, y, w, h, align);
}

Fl_Labeltype define_FL_SYMBOL_LABEL() {
  Fl::set_labeltype(_FL_SYMBOL_LABEL, fl_symbol_label, 0);
  return _FL_SYMBOL_LABEL;
}

void Fl::enable_symbols() {
  Fl::set_labeltype(FL_NORMAL_LABEL, fl_symbol_label, 0);
}

//
// End of "$Id: fl_symbols.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_expand.cxx ---
//
// "$Id: filename_expand.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Filename expansion routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

/* expand a file name by substuting environment variables and
   home directories.  Returns true if any changes were made.
   to & from may be the same buffer.
*/

#include <FL/filename.H>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#else
# include <unistd.h>
# include <pwd.h>
#endif

#if defined(WIN32) || defined(__EMX__)
static inline int isdirsep(char c) {return c=='/' || c=='\\';}
#else
#define isdirsep(c) ((c)=='/')
#endif

int filename_expand(char *to,const char *from) {

  char temp[FL_PATH_MAX];
  strcpy(temp,from);
  const char *start = temp;
  const char *end = temp+strlen(temp);

  int ret = 0;

  for (char *a=temp; a<end; ) {	// for each slash component
    char *e; for (e=a; e<end && !isdirsep(*e); e++); // find next slash
    const char *value = 0; // this will point at substitute value
    switch (*a) {
    case '~':	// a home directory name
      if (e <= a+1) {	// current user's directory
	value = getenv("HOME");
#ifndef WIN32
      } else {	// another user's directory
	struct passwd *pwd;
	char t = *e; *(char *)e = 0; 
        pwd = getpwnam(a+1); 
        *(char *)e = t;
	    if (pwd) value = pwd->pw_dir;
#endif
      }
      break;
    case '$':		/* an environment variable */
      {char t = *e; *(char *)e = 0; value = getenv(a+1); *(char *)e = t;}
      break;
    }
    if (value) {
      // substitutions that start with slash delete everything before them:
      if (isdirsep(value[0])) start = a;
#if defined(WIN32) || defined(__EMX__)
      // also if it starts with "A:"
      if (value[0] && value[1]==':') start = a;
#endif
      int t = strlen(value); if (isdirsep(value[t-1])) t--;
      memmove(a+t, e, end+1-e);
      end = a+t+(end-e);
      memcpy(a, value, t);
      ret++;
    } else {
      a = e+1;
#if defined(WIN32) || defined(__EMX__)
      if (*e == '\\') {*e = '/'; ret++;} // ha ha!
#endif
    }
  }
  strcpy(to,start);
  return ret;
}

//
// End of "$Id: filename_expand.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_cutpaste.cxx ---
//
// "$Id: Fl_cutpaste.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Cut/paste code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implementation of cut and paste.

// This is seperated from Fl.C mostly to test Fl::add_handler().
// But this will save a small amount of code size in a program that
// has no text editing fields or other things that call cut or paste.

#ifdef WIN32
#include "Fl_cutpaste_win32.cxx"
#else

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <string.h>

static char *selection_buffer;
static int selection_length;
static int selection_buffer_length;
static char beenhere;

extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()

static int selection_xevent_handler(int) {

  switch (fl_xevent->type) {
#ifndef NANO_X  //tanghao
  case SelectionNotify: {
    if (!fl_selection_requestor) return 0;
    static char *pastebuffer;
    if (pastebuffer) {XFree(pastebuffer); pastebuffer = 0;}
    if (fl_xevent->xselection.property != 0) {
      Atom a; int f; unsigned long n,b;
      if (!XGetWindowProperty(fl_display,
			      fl_xevent->xselection.requestor,
			      fl_xevent->xselection.property,
			      0,100000,1,0,&a,&f,&n,&b,
			      (unsigned char**)&pastebuffer)) {
	Fl::e_text = pastebuffer;
	Fl::e_length = int(n);
	fl_selection_requestor->handle(FL_PASTE);
      }
    }}
    return 1;

  case SelectionClear:
    Fl::selection_owner(0);
    return 1;

  case SelectionRequest: {
    XSelectionEvent e;
    e.type = SelectionNotify;
    e.display = fl_display;
    e.requestor = fl_xevent->xselectionrequest.requestor;
    e.selection = fl_xevent->xselectionrequest.selection;
    e.target = fl_xevent->xselectionrequest.target;
    e.time = fl_xevent->xselectionrequest.time;
    if (fl_xevent->xselectionrequest.target != XA_STRING || !selection_length) {
      e.property = 0;
    } else {
      e.property = fl_xevent->xselectionrequest.property;
    }
    if (e.property) {
      XChangeProperty(fl_display, e.requestor, e.property,
		      XA_STRING, 8, 0, (unsigned char *)selection_buffer,
		      selection_length);
    }
    XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
    return 1;

  default:
    return 0;
#endif //tanghao
  }
}

////////////////////////////////////////////////////////////////

// Call this when a "paste" operation happens:
void Fl::paste(Fl_Widget &receiver) {
  if (selection_owner()) {
    // We already have it, do it quickly without window server.
    // Notice that the text is clobbered if set_selection is
    // called in response to FL_PASTE!
    Fl::e_text = selection_buffer;
    Fl::e_length = selection_length;
    receiver.handle(FL_PASTE);
    return;
  }
  // otherwise get the window server to return it:
  fl_selection_requestor = &receiver;
#ifndef NANO_X //tanghao
  XConvertSelection(fl_display, XA_PRIMARY, XA_STRING, XA_PRIMARY,
		    fl_xid(Fl::first_window()), fl_event_time);
#endif
  if (!beenhere) {
    Fl::add_handler(selection_xevent_handler);
    beenhere = 1;
  }
}

////////////////////////////////////////////////////////////////

// call this when you create a selection:
void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
  if (!stuff || len<0) return;
  if (len+1 > selection_buffer_length) {
    delete[] selection_buffer;
    selection_buffer = new char[len+100];
    selection_buffer_length = len+100;
  }
  memcpy(selection_buffer, stuff, len);
  selection_buffer[len] = 0; // needed for direct paste
  selection_length = len;
  selection_owner(&owner);
  static Window selxid; // window X thinks selection belongs to
#ifdef NANO_X
  if (!selxid) selxid =
		GrNewWindow(GR_ROOT_WINDOW_ID,0,0,1,1,0,0,0);
			//(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y,
			//GR_SIZE width, GR_SIZE height, GR_SIZE bordersize,
			//GR_COLOR background, GR_COLOR bordercolor);
#else
  if (!selxid) selxid =
		 XCreateSimpleWindow(fl_display, 
				     RootWindow(fl_display, fl_screen),
				     0,0,1,1,0,0,0);
  XSetSelectionOwner(fl_display, XA_PRIMARY, selxid, fl_event_time);
#endif
  if (!beenhere) {
    Fl::add_handler(selection_xevent_handler);
    beenhere = 1;
  }
}

#endif

//
// End of "$Id: Fl_cutpaste.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Dial.cxx ---
//
// "$Id: Fl_Dial.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Circular dial widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Dial.H>
#include <FL/fl_draw.H>
#include <stdlib.h>
#include <FL/math.h>

// All angles are measured with 0 to the right and counter-clockwise

void Fl_Dial::draw(int x, int y, int w, int h) {
  if (damage()&FL_DAMAGE_ALL) draw_box(box(), x, y, w, h, color());
  x += Fl::box_dx(box());
  y += Fl::box_dy(box());
  w -= Fl::box_dw(box());
  h -= Fl::box_dh(box());
  double angle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
  if (type() == FL_FILL_DIAL) {
    // foo: draw this nicely in certain round box types
    int foo = (box() > _FL_ROUND_UP_BOX && Fl::box_dx(box()));
    if (foo) {x--; y--; w+=2; h+=2;}
    fl_color(color());
    fl_pie(x, y, w-1, h-1, 270-a1, angle > a1 ? 360+270-angle : 270-360-angle);
    fl_color(selection_color());
    fl_pie(x, y, w-1, h-1, 270-angle, 270-a1);
    if (foo) {
      fl_color(FL_BLACK);
      fl_arc(x, y, w, h, 0, 360);
    }
    return;
  }
  if (!(damage()&FL_DAMAGE_ALL)) {
    fl_color(color());
    fl_pie(x+1, y+1, w-2, h-2, 0, 360);
  }
  fl_push_matrix();
  fl_translate(x+w/2-.5, y+h/2-.5);
  fl_scale(w-1, h-1);
  fl_rotate(45-angle);
  fl_color(selection_color());
  if (type()) { // FL_LINE_DIAL
    fl_begin_polygon();
    fl_vertex(0.0,   0.0);
    fl_vertex(-0.04, 0.0);
    fl_vertex(-0.25, 0.25);
    fl_vertex(0.0,   0.04);
    fl_end_polygon();
    fl_color(FL_BLACK);
    fl_begin_loop();
    fl_vertex(0.0,   0.0);
    fl_vertex(-0.04, 0.0);
    fl_vertex(-0.25, 0.25);
    fl_vertex(0.0,   0.04);
    fl_end_loop();
  } else {
    fl_begin_polygon(); fl_circle(-0.20, 0.20, 0.07); fl_end_polygon();
    fl_color(FL_BLACK);
    fl_begin_loop(); fl_circle(-0.20, 0.20, 0.07); fl_end_loop();
  }
  fl_pop_matrix();
}

void Fl_Dial::draw() {
  draw(x(), y(), w(), h());
  draw_label();
}

int Fl_Dial::handle(int event, int x, int y, int w, int h) {
  switch (event) {
  case FL_PUSH:
    handle_push();
  case FL_DRAG: {
    int mx = Fl::event_x()-x-w/2;
    int my = Fl::event_y()-y-h/2;
    if (!mx && !my) return 1;
    double angle = 270-atan2((float)-my, (float)mx)*180/M_PI;
    double oldangle = (a2-a1)*(value()-minimum())/(maximum()-minimum()) + a1;
    while (angle < oldangle-180) angle += 360;
    while (angle > oldangle+180) angle -= 360;
    double val;
    if ((a1<a2) ? (angle <= a1) : (angle >= a1)) {
      val = minimum();
    } else if ((a1<a2) ? (angle >= a2) : (angle <= a2)) {
      val = maximum();
    } else {
      val = minimum() + (maximum()-minimum())*(angle-a1)/(a2-a1);
    }
    handle_drag(clamp(round(val)));
  } return 1;
  case FL_RELEASE:
    handle_release();
    return 1;
  default:
    return 0;
  }
}

int Fl_Dial::handle(int e) {
  return handle(e, x(), y(), w(), h());
}

Fl_Dial::Fl_Dial(int x, int y, int w, int h, const char* l)
  : Fl_Valuator(x, y, w, h, l) {
  box(FL_OVAL_BOX);
  selection_color(FL_INACTIVE_COLOR); // was 37
  a1 = 45;
  a2 = 315;
}

//
// End of "$Id: Fl_Dial.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_scroll_area.cxx ---
//
// "$Id: fl_scroll_area.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Scrolling routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Drawing function to move the contents of a rectangle.  This is passed
// a "callback" which is called to draw rectangular areas that are moved
// into the drawing area.

#include <FL/x.H>

// scroll a rectangle and redraw the newly exposed portions:
void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
	       void (*draw_area)(void*, int,int,int,int), void* data)
{
  if (!dx && !dy) return;
  if (dx <= -W || dx >= W || dy <= -H || dy >= H) {
    // no intersection of old an new scroll
    draw_area(data,X,Y,W,H);
    return;
  }
  int src_x, src_w, dest_x, clip_x, clip_w;
  if (dx > 0) {
    src_x = X;
    dest_x = X+dx;
    src_w = W-dx;
    clip_x = X;
    clip_w = dx;
  } else {
    src_x = X-dx;
    dest_x = X;
    src_w = W+dx;
    clip_x = X+src_w;
    clip_w = W-src_w;
  }
  int src_y, src_h, dest_y, clip_y, clip_h;
  if (dy > 0) {
    src_y = Y;
    dest_y = Y+dy;
    src_h = H-dy;
    clip_y = Y;
    clip_h = dy;
  } else {
    src_y = Y-dy;
    dest_y = Y;
    src_h = H+dy;
    clip_y = Y+src_h;
    clip_h = H-src_h;
  }
#ifdef WIN32
  BitBlt(fl_gc, dest_x, dest_y, src_w, src_h, fl_gc, src_x, src_y,SRCCOPY);
  // NYI: need to redraw areas that the source of BitBlt was bad due to
  // overlapped windows, probably similar to X version:
#else
#ifdef NANO_X //tanghao
  GrCopyArea(fl_window,fl_gc,dest_x,dest_y,src_w,src_h,fl_window,src_x,src_y,MWROP_SRCCOPY);
#else
  XCopyArea(fl_display, fl_window, fl_window, fl_gc,
	    src_x, src_y, src_w, src_h, dest_x, dest_y);
#endif //tanghao
  // we have to sync the display and get the GraphicsExpose events! (sigh)
  for (;;) {
#ifdef NANO_X // Century Software
    draw_area(data, dest_x, dest_y, src_w, src_h);
    break;
#else
    XEvent e; XWindowEvent(fl_display, fl_window, ExposureMask, &e);
    if (e.type == NoExpose) break;
    // otherwise assumme it is a GraphicsExpose event:
    draw_area(data, e.xexpose.x, e.xexpose.y,
	      e.xexpose.width, e.xexpose.height);
    if (!e.xgraphicsexpose.count) break;
#endif //tanghao
  }
#endif
  if (dx) draw_area(data, clip_x, dest_y, clip_w, src_h);
  if (dy) draw_area(data, X, clip_y, W, clip_h);
}

//
// End of "$Id: fl_scroll_area.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu_.cxx ---
//
// "$Id: Fl_Menu_.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Common menu code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This is a base class for all items that have a menu:
//	Fl_Menu_Bar, Fl_Menu_Button, Fl_Choice
// This provides storage for a menu item, functions to add/modify/delete
// items, and a call for when the user picks a menu item.

// More code in Fl_Menu_add.C

#include <FL/Fl.H>
#include <FL/Fl_Menu_.H>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int Fl_Menu_::value(const Fl_Menu_Item* m) {
  clear_changed();
  if (value_ != m) {value_ = m; return 1;}
  return 0;
}

// When user picks a menu item, call this.  It will do the callback.
// Unfortunatly this also casts away const for the checkboxes, but this
// was necessary so non-checkbox menus can really be declared const...
const Fl_Menu_Item* Fl_Menu_::picked(const Fl_Menu_Item* v) {
  if (v) {
    if (v->radio()) {
      if (!v->value()) { // they are turning on a radio item
	set_changed();
	((Fl_Menu_Item*)v)->setonly();
      }
      redraw();
    } else if (v->flags & FL_MENU_TOGGLE) {
      set_changed();
      ((Fl_Menu_Item*)v)->flags ^= FL_MENU_VALUE;
      redraw();
    } else if (v != value_) { // normal item
      set_changed();
    }
    value_ = v;
    if (when()&(FL_WHEN_CHANGED|FL_WHEN_RELEASE)) {
      if (changed() || when()&FL_WHEN_NOT_CHANGED) {
	clear_changed();
	if (value_ && value_->callback_) value_->do_callback((Fl_Widget*)this);
	else do_callback();
      }
    }
  }
  return v;
}

// turn on one of a set of radio buttons
void Fl_Menu_Item::setonly() {
  flags |= FL_MENU_RADIO | FL_MENU_VALUE;
  Fl_Menu_Item* j;
  for (j = this; ; ) {	// go down
    if (j->flags & FL_MENU_DIVIDER) break; // stop on divider lines
    j++;
    if (!j->text || !j->radio()) break; // stop after group
    j->clear();
  }
  for (j = this-1; ; j--) { // go up
    if (!j->text || (j->flags&FL_MENU_DIVIDER) || !j->radio()) break;
    j->clear();
  }
}

Fl_Menu_::Fl_Menu_(int X,int Y,int W,int H,const char* l)
: Fl_Widget(X,Y,W,H,l) {
  set_flag(SHORTCUT_LABEL);
  box(FL_UP_BOX);
  when(FL_WHEN_RELEASE_ALWAYS);
  value_ = menu_ = 0;
  alloc = 0;
  selection_color(FL_SELECTION_COLOR);
  textfont(FL_HELVETICA);
  textsize(FL_NORMAL_SIZE);
  textcolor(FL_BLACK);
  down_box(FL_NO_BOX);
}

int Fl_Menu_::size() const {
  if (!menu_) return 0;
  return menu_->size();
}

void Fl_Menu_::menu(const Fl_Menu_Item* m) {
  clear();
  value_ = menu_ = (Fl_Menu_Item*)m;
}

#if 1
// this version is ok with new Fl_Menu_add code with fl_menu_array_owner:

void Fl_Menu_::copy(const Fl_Menu_Item* m, void* user_data) {
  int n = m->size();
  Fl_Menu_Item* newMenu = new Fl_Menu_Item[n];
  memcpy(newMenu, m, n*sizeof(Fl_Menu_Item));
  menu(newMenu);
  alloc = 1; // make destructor free array, but not strings
  // for convienence, provide way to change all the user data pointers:
  if (user_data) for (; n--;) {
    if (newMenu->callback_) newMenu->user_data_ = user_data;
    newMenu++;
  }
}

#else
// This is Guillaume Nodet's fixed version for the older Fl_Menu_add
// that enlarged the array at powers of 2:

void Fl_Menu_::copy(const Fl_Menu_Item* m, void* user_data) {
  int i, s = m->size(), n=s;
  for (i=0; n; n>>=1, i++);
  n = 1 << i;
  Fl_Menu_Item* newMenu = new Fl_Menu_Item[n];
  memcpy(newMenu, m, s*sizeof(Fl_Menu_Item));
  memset(newMenu+s, 0, (n-s)*sizeof(Fl_Menu_Item));
  menu(newMenu);
  alloc = 1; // make destructor free it
  // for convienence, provide way to change all the user data pointers:
  if (user_data) for (; s--;) {
    if (newMenu->callback_) newMenu->user_data_ = user_data;
    newMenu++;
  }
}
#endif

Fl_Menu_::~Fl_Menu_() {
  clear();
}

// Fl_Menu::add() uses this to indicate the owner of the dynamically-
// expanding array.  We must not free this array:
Fl_Menu_* fl_menu_array_owner = 0;

void Fl_Menu_::clear() {
  if (alloc) {
    if (alloc>1) for (int i = size(); i--;)
      if (menu_[i].text) free((void*)menu_[i].text);
    if (this == fl_menu_array_owner)
      fl_menu_array_owner = 0;
    else
      delete[] menu_;
    menu_ = 0;
    value_ = 0;
    alloc = 0;
  }
}

//
// End of "$Id: Fl_Menu_.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_set_gray.cxx ---
//
// "$Id: fl_set_gray.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Background (gray) color routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// -fg, -bg, and -bg2 switches

#include <FL/Fl.H>

void Fl::background(uchar r, uchar g, uchar b) {
  // replace the gray ramp so that color 47 is this color
  int i;
  for (i = 32; i <= 47; i++) {
    int m = (i-32)*255/23;
    Fl::set_color((Fl_Color)i,r*m/166,g*m/166,b*m/166);
  }
  for (; i < 56; i++) {
    int m = 255-(i-32)*255/23;
    Fl::set_color((Fl_Color)i,255-(255-r)*m/89,255-(255-g)*m/89,255-(255-b)*m/89);
  }
}

static void set_others() {
  uchar r,g,b; Fl::get_color(FL_BLACK,r,g,b);
  uchar r1,g1,b1; Fl::get_color(FL_WHITE,r1,g1,b1);
  Fl::set_color(FL_INACTIVE_COLOR,(2*r+r1)/3, (2*g+g1)/3, (2*b+b1)/3);
  Fl::set_color(FL_SELECTION_COLOR,(2*r1+r)/3, (2*g1+g)/3, (2*b1+b)/3);
}

void Fl::foreground(uchar r, uchar g, uchar b) {
  Fl::set_color(FL_BLACK,r,g,b);
  set_others();
}

void Fl::background2(uchar r, uchar g, uchar b) {
  Fl::set_color(FL_WHITE,r,g,b);
  set_others();
}

//
// End of "$Id: fl_set_gray.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_pixmap.cxx ---
//
// "$Id: forms_pixmap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms pixmap drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/forms.H>

Fl_FormsPixmap::Fl_FormsPixmap(
  Fl_Boxtype t, int x, int y, int w, int h, const char* l)
: Fl_Widget(x, y, w, h, l) {
  box(t);
  b = 0;
  color(FL_BLACK);
  align(FL_ALIGN_BOTTOM);
}

void Fl_FormsPixmap::set(char*const* bits) {
  delete b;
  b = new Fl_Pixmap(bits);
}

void Fl_FormsPixmap::draw() {
  draw_box(box(), selection_color());
  if (b) {fl_color(color()); b->draw(x(), y(), w(), h());}
  draw_label();
}

//
// End of "$Id: forms_pixmap.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Box.cxx ---
//
// "$Id: Fl_Box.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Box widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl_Widget.H>
#include <FL/Fl_Box.H>

// MRS - shouldn't we inline this?

void Fl_Box::draw() {
  draw_box();
  draw_label();
}

//
// End of "$Id: Fl_Box.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: fastarrow.h ---
#define fastarrow_width 16
#define fastarrow_height 16
static unsigned char fastarrow_bits[] = {
   0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03,
   0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff,
   0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00};

--- NEW FILE: makedepend ---

--- NEW FILE: Fl_Scrollbar.cxx ---
//
// "$Id: Fl_Scrollbar.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Scroll bar widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Scrollbar.H>
#include <FL/fl_draw.H>
#include <math.h>

#define INITIALREPEAT .5
#define REPEAT .05

void Fl_Scrollbar::increment_cb() {
  int i;
  int W = horizontal() ? w() : h();
  int S = int(slider_size()*W+.5);

  switch (pushed_) {
  case 1: i = -linesize_; break;
  default:i =  linesize_; break;
  case 3: i = -int(S * (maximum() - minimum()) / W); break;
  case 4: i =  int(S * (maximum() - minimum()) / W); break;
  }
  if (maximum() < minimum() && pushed_ < 3) i = -i;
  handle_drag(clamp(value() + i));
}

void Fl_Scrollbar::timeout_cb(void* v) {
  Fl_Scrollbar* s = (Fl_Scrollbar*)v;
  s->increment_cb();
  //Fl::add_timeout(REPEAT, timeout_cb, s);
}

int Fl_Scrollbar::handle(int event) {
  // area of scrollbar:
  int area;
  int X=x(); int Y=y(); int W=w(); int H=h();
  int SX = X; int SY = Y; int SW = W; int SH = H;

  // adjust slider area to be inside the arrow buttons:
  if (horizontal()) {
    if (W >= 3*H) {X += H; W -= 2*H;}
  } else {
    if (H >= 3*W) {Y += W; H -= 2*W;}
  }

  // which widget part is highlighted?
  int mx = Fl::event_x();
  int my = Fl::event_y();
  if (!Fl::event_inside(SX, SY, SW, SH)) area = 0;
  else if (horizontal()) {
    if (mx < X) area = 1;
    else if (mx >= X+W) area = 2;
    else {
      int sliderx;
      int S = int(slider_size()*W+.5);
      double val = (value()-minimum())/(maximum()-minimum());
		if (val >= 1.0) sliderx = W-S;
      else if (val <= 0.0) sliderx = 0;
      else sliderx = int(val*(W-S)+.5);

      if (mx < X+sliderx) area = 3;
      else if (mx >= X+sliderx+S) area = 4;
      else area = 5;
    }
  } else {
    if (mx < X || mx >= X+W) area = 0;
    else if (my < Y) area = 1;
    else if (my >= Y+H) area = 2;
    else {
      int slidery;
      int S = int(slider_size()*H+.5);
      double val = (value()-minimum())/(maximum()-minimum());
      if (val >= 1.0) slidery = H-S;
      else if (val <= 0.0) slidery = 0;
      else slidery = int(val*(H-S)+.5);

      if (my < Y+slidery) area = 3;
      else if (my >= Y+slidery+S) area = 4;
      else area = 5;
    }
  }
  switch (event) {
  case FL_ENTER:
  case FL_LEAVE:
    return 1;
  case FL_RELEASE:
    damage(FL_DAMAGE_EXPOSE);
    if (pushed_) {
      //Fl::remove_timeout(timeout_cb, this);
      pushed_ = 0;
    }
    handle_release();
    return 1;
  case FL_PUSH:
    if (pushed_) return 1;
	 if (area != 5) pushed_ = area;
    if (pushed_) {
      handle_push();
      //Fl::add_timeout(INITIALREPEAT, timeout_cb, this);
      increment_cb();
      damage(FL_DAMAGE_EXPOSE);
      return 1;
    }
    return Fl_Slider::handle(event, X,Y,W,H);
  case FL_DRAG:
    if (pushed_) return 1;
    return Fl_Slider::handle(event, X,Y,W,H);
  case FL_SHORTCUT: {
    int v = value();
    int ls = maximum()>=minimum() ? linesize_ : -linesize_;
    if (horizontal()) {
      switch (Fl::event_key()) {
      case FL_Left:
	v -= ls;
	break;
      case FL_Right:
	v += ls;
	break;
      default:
	return 0;
      }
    } else { // vertical
      switch (Fl::event_key()) {
      case FL_Up:
	v -= ls;
	break;
      case FL_Down:
	v += ls;
	break;
      case FL_Page_Up:
	if (slider_size() >= 1.0) return 0;
	v -= int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
	v += ls;
	break;
      case FL_Page_Down:
	if (slider_size() >= 1.0) return 0;
	v += int((maximum()-minimum())*slider_size()/(1.0-slider_size()));
	v -= ls;
	break;
      case FL_Home:
	v = int(minimum());
	break;
      case FL_End:
	v = int(maximum());
	break;
      default:
	return 0;
      }
    }
    v = int(clamp(v));
    if (v != value()) {
      Fl_Slider::value(v);
      value_damage();
      do_callback();
    }
    return 1;}
  }
  return 0;
}

void Fl_Scrollbar::draw() {
#ifdef PDA 
  box(FL_BORDER_BOX);
  Fl_Color col = selection_color();
#endif  
  int X = x()+Fl::box_dx(box());
  int Y = y()+Fl::box_dy(box());
  int W = w()-Fl::box_dw(box());
  int H = h()-Fl::box_dh(box());
  if (damage()&FL_DAMAGE_ALL); draw_box();
  if (horizontal()) {
#ifdef PDA
	 // the slider button
    if (W < 3*H) {Fl_Slider::draw(X-1,Y,W+2,H); return;}
	 Fl_Slider::draw(X+H-1,Y,W-2*H+2,H);
      // draw the boxes for the buttons
    if (damage()) {
		draw_box((pushed_ == 1) ? FL_BLACK_BOX : FL_BORDER_BOX,
	       X, Y, H, H, col);
		draw_box((pushed_ == 2) ? FL_BLACK_BOX : FL_BORDER_BOX,
	       X+W-H, Y, H, H, col);
#else
	 // the slider button
    if (W < 3*H) {Fl_Slider::draw(X,Y,W,H); return;}
	 Fl_Slider::draw(X+H,Y,W-2*H,H);
      // draw the boxes for the buttons
    if (damage()) {
      draw_box((pushed_ == 2) ? down(slider()) : slider(),
		  X+W-H, Y, H, H, selection_color());
      draw_box((pushed_ == 1) ? down(slider()) : slider(),
		  X, Y, H, H, selection_color());
#endif
      if (active_r())
        fl_color(labelcolor());
      else
        fl_color(inactive(labelcolor()));
      int w1 = (H-1)|1; // use odd sizes only
      int Y1 = Y+w1/2;
      int W1 = w1/3;
      int X1 = X+w1/2+W1/2;
		//or arrows on buttons
#ifdef PDA
		if ( pushed_ == 1 )
			fl_color(FL_WHITE);
		else 
			fl_color(FL_BLACK);
		fl_polygon(X1-W1, Y1, X1, Y1-W1, X1, Y1+W1);
      X1 = X+W-(X1-X)-1;
#else
		fl_polygon(X1-W1, Y1, X1, Y1-W1, X1, Y1+W1);
      X1 = X+W-(X1-X)-1;
#endif
#ifdef PDA
		if ( pushed_ == 2)
			fl_color(FL_WHITE);
		else
			fl_color(FL_BLACK);
      fl_polygon(X1+W1, Y1, X1, Y1+W1, X1, Y1-W1);
#else
      fl_polygon(X1+W1, Y1, X1, Y1+W1, X1, Y1-W1);
#endif    
	 }
  } else { // vertical
#ifdef PDA
    if (H < 3*W) {Fl_Slider::draw(X,Y-1,W,H+2); return;}
    Fl_Slider::draw(X,Y+W-1,W,H-2*W+2);
    if (damage()) {
      draw_box((pushed_ == 1) ? FL_BLACK_BOX : FL_BORDER_BOX,
	       X, Y, W, W, col);
      draw_box((pushed_ == 2) ? FL_BLACK_BOX : FL_BORDER_BOX,
	       X, Y+H-W, W, W, col);
#else      
    if (H < 3*W) {Fl_Slider::draw(X,Y,W,H); return;}
    Fl_Slider::draw(X,Y+W,W,H-2*W);
    if (damage()) {
		draw_box((pushed_ == 1) ? down(slider()) : slider(),
	       X, Y, W, W, selection_color());
      draw_box((pushed_ == 2) ? down(slider()) : slider(),
	       X, Y+H-W, W, W, selection_color());
#endif
		if (active_r())
        fl_color(labelcolor());
      else
        fl_color(labelcolor() | 8);
      int w1 = (W-1)|1; // use odd sizes only
      int X1 = X+w1/2;
      int W1 = w1/3;
      int Y1 = Y+w1/2+W1/2;
		// draw the arrow on the buttons
#ifdef PDA
		if ( pushed_ == 1 )
			fl_color(FL_WHITE);
		else 
			fl_color(FL_BLACK);
#endif
      fl_polygon(X1, Y1-W1, X1+W1, Y1, X1-W1, Y1);
      Y1 = Y+H-(Y1-Y)-1;
#ifdef PDA
		if ( pushed_ == 2 )
			fl_color(FL_WHITE);
		else
			fl_color(FL_BLACK);
#endif
      fl_polygon(X1, Y1+W1, X1-W1, Y1, X1+W1, Y1);
    }
  }
}

Fl_Scrollbar::Fl_Scrollbar(int X, int Y, int W, int H, const char* L)
  : Fl_Slider(X, Y, W, H, L)
{
  box(FL_FLAT_BOX);
  // set the color for the underbar here
#ifdef PDA
  color(FL_WHITE);
#else
  color(FL_DARK2);
#endif
  slider(FL_UP_BOX);
  linesize_ = 16;
  pushed_ = 0;
  step(1);
}

//
// End of "$Id: Fl_Scrollbar.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Double_Window.cxx ---
//
// "$Id: Fl_Double_Window.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Double-buffered window code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#include <FL/x.H>
#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>

// On systems that support double buffering "naturally" the base
// Fl_Window class will probably do double-buffer and this subclass
// does nothing.
#ifndef NANO_X //tanghao

#if USE_XDBE
#include <X11/extensions/Xdbe.h>

static int use_xdbe;

static int can_xdbe() {
  static int tried;
  if (!tried) {
    tried = 1;
    int event_base, error_base;
    if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
    Drawable root = RootWindow(fl_display,fl_screen);
    int numscreens = 1;
    XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
    if (!a) return 0;
    for (int j = 0; j < a->count; j++)
      if (a->visinfo[j].visual == fl_visual->visualid
	  /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;}
    XdbeFreeVisualInfo(a);
  }
  return use_xdbe;
}
#endif
#endif //tanghao

void Fl_Double_Window::show() {
#ifndef WIN32
  if (!shown()) { // don't set the background pixel
    fl_open_display();
    Fl_X::make_xid(this);
    return;
  }
#endif
  Fl_Window::show();
}

#ifdef WIN32

// Code used to switch output to an off-screen window.  See macros in
// win32.H which save the old state in local variables.

HDC fl_makeDC(HBITMAP bitmap) {
  HDC new_gc = CreateCompatibleDC(fl_gc);
  SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
  SetBkMode(new_gc, TRANSPARENT);
#if USE_COLORMAP
  if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
#endif
  SelectObject(new_gc, bitmap);
  return new_gc;
}

void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
  HDC new_gc = CreateCompatibleDC(fl_gc);
  SelectObject(new_gc, bitmap);
  BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
  DeleteDC(new_gc);
}

extern void fl_restore_clip();

#endif

// Fl_Overlay_Window relies on flush(1) copying the back buffer to the
// front everywhere, even if damage() == 0, thus erasing the overlay,
// and leaving the clip region set to the entire window.

void Fl_Double_Window::flush() {flush(0);}

void Fl_Double_Window::flush(int eraseoverlay) {
  make_current(); // make sure fl_gc is non-zero
  Fl_X *i = Fl_X::i(this);
  if (!i->other_xid) {
#ifndef NANO_X
#if USE_XDBE
    if (can_xdbe()) i->other_xid =
      XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeUndefined);
    else
#endif
#endif
      i->other_xid = fl_create_offscreen(w(), h());
    clear_damage(FL_DAMAGE_ALL);
  }
#ifndef NANO_X
#if USE_XDBE
  if (use_xdbe) {
    // if this is true, copy rather than swap so back buffer is preserved:
    int copy = (i->region || eraseoverlay);
    if (i->backbuffer_bad) { // make sure we do a complete redraw...
      if (i->region) {XDestroyRegion(i->region); i->region = 0;}
      clear_damage(FL_DAMAGE_ALL);
    }
    if (damage()) {
      fl_clip_region(i->region); i->region = 0;
      fl_window = i->other_xid;
      draw();
      fl_window = i->xid;
    }
    if (!copy) {
      XdbeSwapInfo s;
      s.swap_window = fl_xid(this);
      s.swap_action = XdbeUndefined;
      XdbeSwapBuffers(fl_display, &s, 1);
      i->backbuffer_bad = 1;
      return;
    }
    // otherwise just use normal copy from back to front:
    i->backbuffer_bad = 0; // which won't destroy the back buffer...
  } else
#endif
#endif
  if (damage() & ~FL_DAMAGE_EXPOSE) {
    fl_clip_region(i->region); i->region = 0;
#ifdef WIN32
    HDC _sgc = fl_gc;
    fl_gc = fl_makeDC(i->other_xid);
    fl_restore_clip(); // duplicate region into new gc
    draw();
    DeleteDC(fl_gc);
    fl_gc = _sgc;
#else // X:
    fl_window = i->other_xid;
    draw();
    fl_clip_region(0); // NANO_X
    fl_window = i->xid;
#endif
  }
  if (eraseoverlay) fl_clip_region(0);
  // on Irix (at least) it is faster to reduce the area copied to
  // the current clip region:
  int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H);
  fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
}

void Fl_Double_Window::resize(int X,int Y,int W,int H) {
  int ow = w();
  int oh = h();
  Fl_Window::resize(X,Y,W,H);
#ifndef NANO_X //tanghao
#if USE_XDBE
  if (use_xdbe) return;
#endif
#endif //tanghao
  Fl_X* i = Fl_X::i(this);
  if (i && i->other_xid && (ow != w() || oh != h())) {
    fl_delete_offscreen(i->other_xid);
    i->other_xid = 0;
  }
}

void Fl_Double_Window::hide() {
  Fl_X* i = Fl_X::i(this);
  if (i && i->other_xid) {
#ifndef NANO_X
#if USE_XDBE
    if (!use_xdbe)
#endif
#endif
      fl_delete_offscreen(i->other_xid);
  }
  Fl_Window::hide();
}

Fl_Double_Window::~Fl_Double_Window() {
  hide();
}

//
// End of "$Id: Fl_Double_Window.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Pack.cxx ---
//
// "$Id: Fl_Pack.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Packing widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Based on code by Curtis Edwards
// Group that compresses all it's children together and resizes to surround
// them on each redraw (only if box() is zero)
// Bugs: ?

#include <FL/Fl.H>
#include <FL/Fl_Pack.H>
#include <FL/fl_draw.H>

Fl_Pack::Fl_Pack(int x,int y,int w ,int h,const char *l)
: Fl_Group(x, y, w, h, l) {
  resizable(0);
  spacing_ = 0;
  // type(VERTICAL); // already set like this
}

void Fl_Pack::draw() {
  int tx = x()+Fl::box_dx(box());
  int ty = y()+Fl::box_dy(box());
  int tw = w()-Fl::box_dw(box());
  int th = h()-Fl::box_dh(box());
  int current_position = horizontal() ? tx : ty;
  int maximum_position = current_position;
  uchar d = damage();
  Fl_Widget*const* a = array();
  for (int i = children(); i--;) {
    Fl_Widget* o = *a++;
    if (o->visible()) {
      int X,Y,W,H;
      if (horizontal()) {
        X = current_position;
        W = o->w();
        Y = ty;
        H = th;
      } else {
        X = tx;
        W = tw;
        Y = current_position;
        H = o->h();
      }
      if (spacing_ && current_position>maximum_position &&
  	  (X != o->x() || Y != o->y() || d&FL_DAMAGE_ALL)) {
        fl_color(color());
        if (horizontal())
	  fl_rectf(maximum_position, ty, spacing_, th);
        else
	  fl_rectf(tx, maximum_position, tw, spacing_);
      }
      if (X != o->x() || Y != o->y() || W != o->w() || H != o->h()) {
        o->resize(X,Y,W,H);
        o->clear_damage(FL_DAMAGE_ALL);
      }
      if (d&FL_DAMAGE_ALL) draw_child(*o); else update_child(*o);
      // child's draw() can change it's size, so use new size:
      current_position += (horizontal() ? o->w() : o->h());
      if (current_position > maximum_position)
        maximum_position = current_position;
      current_position += spacing_;
    }
  }

  if (horizontal()) {
    if (maximum_position < tx+tw) {
      fl_color(color());
      fl_rectf(maximum_position, ty, tx+tw-maximum_position, th);
    }
    tw = maximum_position-tx;
  } else {
    if (maximum_position < ty+th) {
      fl_color(color());
      fl_rectf(tx, maximum_position, tw, ty+th-maximum_position);
    }
    th = maximum_position-ty;
  }

  tw += Fl::box_dw(box()); if (tw <= 0) tw = 1;
  th += Fl::box_dh(box()); if (th <= 0) th = 1;
  if (tw != w() || th != h()) {Fl_Widget::resize(x(),y(),tw,th); d = FL_DAMAGE_ALL;}
  if (d&FL_DAMAGE_ALL) draw_box();
}

//
// End of "$Id: Fl_Pack.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Slider.cxx ---
//
// "$Id: Fl_Slider.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Slider widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <stdio.h>
#include <FL/Fl.H>
#include <FL/Fl_Slider.H>
#include <FL/fl_draw.H>
#include <math.h>

void
Fl_Slider::_Fl_Slider()
{
    slider_size_ = 0;
    slider_ = 0;		// FL_UP_BOX;
}

Fl_Slider::Fl_Slider(int x, int y, int w, int h, const char *l)
    :
Fl_Valuator(x, y, w, h, l)
{
    box(FL_DOWN_BOX);
    _Fl_Slider();
}

Fl_Slider::Fl_Slider(uchar t, int x, int y, int w, int h, const char *l)
    :
Fl_Valuator(x, y, w, h, l)
{
    type(t);
    box(t == FL_HOR_NICE_SLIDER || t == FL_VERT_NICE_SLIDER ?
	FL_FLAT_BOX : FL_DOWN_BOX);
    _Fl_Slider();
}

void
Fl_Slider::slider_size(double v)
{
    if (v < 0)
	v = 0;
    if (v > 1)
	v = 1;
    if (slider_size_ != float (v)) {
	slider_size_ = float (v);
	damage(FL_DAMAGE_EXPOSE);
    }
}

void
Fl_Slider::bounds(double a, double b)
{
    if (minimum() != a || maximum() != b) {
	Fl_Valuator::bounds(a, b);
	damage(FL_DAMAGE_EXPOSE);
    }
}

void
Fl_Slider::slider_ver_lines(int x, int y, int w, int h, int W, Fl_Color c)
{
    int cx = x + w / 2;
    int cy = y + h / 2;

    fl_color(FL_BLACK);
    if (type() != FL_HORIZONTAL) {
	draw_box(FL_BORDER_BOX, x, y, w, h, c);
    } else {
	if (w > 0 && h > 0) {
#ifndef PDA
	    if (w < 17) {
		w = 17;
		slider_size(double (w) / double (W));
		slider_size_min_ = slider_size();
	    }
#else
	    slider_size_min_ = slider_size();
#endif
	    draw_box(FL_BORDER_BOX, x, y, w, h, c);
	    fl_color(FL_BLACK);
	    cx = x + w / 2;
	    fl_line(cx, cy - h / 2 + 4, cx, cy + h / 2 - 4);
	    fl_line(cx - 3, cy - h / 2 + 4, cx - 3, cy + h / 2 - 4);
	    fl_line(cx + 3, cy - h / 2 + 4, cx + 3, cy + h / 2 - 4);
	}
    }
}

void
Fl_Slider::slider_hor_lines(int x, int y, int w, int h, int W, Fl_Color c)
{
    int cx = x + w / 2;
    int cy = y + h / 2;

    fl_color(FL_BLACK);
    if (type() != FL_VERTICAL) {
	draw_box(FL_BORDER_BOX, x, y, w, h, c);
    } else {
	if (w > 0 && h > 0) {
#ifndef PDA
	    if (h < 17) {
		h = 17;
		slider_size(double (h) / double (W));
		slider_size_min_ = slider_size();
	    }
#else
	    slider_size_min_ = slider_size();
#endif

	    draw_box(FL_BORDER_BOX, x, y, w, h, c);
	    fl_color(FL_BLACK);
	    cy = y + h / 2;
	    fl_line(cx + w / 2 - 4, cy, cx - w / 2 + 4, cy);
	    fl_line(cx + w / 2 - 4, cy - 3, cx - w / 2 + 4, cy - 3);
	    fl_line(cx + w / 2 - 4, cy + 3, cx - w / 2 + 4, cy + 3);
	}
    }
}

int
Fl_Slider::scrollvalue(int p, int w, int t, int l)
{
//      p = position, first line displayed
//      w = window, number of lines displayed
//      t = top, number of first line
//      l = length, total number of lines
    step(1, 1);
    if (p + w > t + l)
	l = p + w - t;
    slider_size(w >= l ? 1.0 : double (w) / double (l));
#ifdef PDA
    if (slider_size() < slider_size_min_) {
	slider_size(slider_size_min_);
    }
#endif
    bounds(t, l - w + t);
    return value(p);
}

// All slider interaction is done as though the slider ranges from
// zero to one, and the left (bottom) edge of the slider is at the
// given position.  Since when the slider is all the way to the
// right (top) the left (bottom) edge is not all the way over, a
// position on the widget itself covers a wider range than 0-1,
// actually it ranges from 0 to 1/(1-size).

void
Fl_Slider::draw_bg(int x, int y, int w, int h)
{
    if (!(damage() & FL_DAMAGE_ALL)) {	// not a complete redraw
	draw_box();
    }
    Fl_Color black = active_r()? FL_BLACK : FL_INACTIVE_COLOR;
    if (type() == FL_VERT_NICE_SLIDER) {
	draw_box(FL_THIN_DOWN_BOX, x + w / 2 - 2, y, 4, h, black);
    } else if (type() == FL_HOR_NICE_SLIDER) {
	draw_box(FL_THIN_DOWN_BOX, x, y + h / 2 - 2, w, 4, black);
    }
}

void
Fl_Slider::draw(int x, int y, int w, int h)
{
    double val;

    if (minimum() == maximum())
	val = 0.5;
    else {
	val = (value() - minimum()) / (maximum() - minimum());
	if (val > 1.0)
	    val = 1.0;
	else if (val < 0.0)
	    val = 0.0;
    }

    int W = (horizontal()? w : h);
    int X, S;
    if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) {
	S = int (val * W + .5);

	if (minimum() > maximum()) {
	    S = W - S;
	    X = W - S;
	} else
	    X = 0;
    } else {
	S = int (slider_size_ * W + .5);
	int T = (horizontal()? h : w) / 2 + 1;

	if (type() == FL_VERT_NICE_SLIDER || type() == FL_HOR_NICE_SLIDER)
	    T += 4;
	if (S < T)
	    S = T;
	X = int (val * (W - S) + .5);

    }
    int xsl, ysl, wsl, hsl;
    if (horizontal()) {
	xsl = x + X;
	wsl = S;
	ysl = y;
	hsl = h;
    } else {
	ysl = y + X;
	hsl = S;
	xsl = x;
	wsl = w;
    }

    if (damage() & FL_DAMAGE_ALL) {	// complete redraw
	draw_bg(x, y, w, h);
    } else {			// partial redraw, clip off new position of slider
	if (X > 0) {
	    if (horizontal())
		fl_clip(x, ysl, X, hsl);
	    else
		fl_clip(xsl, y, wsl, X);
	    draw_bg(x, y, w, h);
	    fl_pop_clip();
	}
	if (X + S < W) {
	    if (horizontal())
		fl_clip(xsl + wsl, ysl, x + w - xsl - wsl, hsl);
	    else
		fl_clip(xsl, ysl + hsl, wsl, y + h - ysl - hsl);
	    draw_bg(x, y, w, h);
	    fl_pop_clip();
	}
    }
    Fl_Boxtype box1 = slider();
    if (!box1) {
	box1 = (Fl_Boxtype) (box() & -2);
	if (!box1)
	    box1 = FL_UP_BOX;
    }
    if (type() == FL_VERT_NICE_SLIDER) {
	draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
	int d = (hsl - 4) / 2;
	draw_box(FL_THIN_DOWN_BOX, xsl + 2, ysl + d, wsl - 4, hsl - 2 * d,
		 selection_color());
    } else if (type() == FL_HOR_NICE_SLIDER) {
	draw_box(box1, xsl, ysl, wsl, hsl, FL_GRAY);
	int d = (wsl - 4) / 2;
	draw_box(FL_THIN_DOWN_BOX, xsl + d, ysl + 2, wsl - 2 * d, hsl - 4,
		 selection_color());
    } else {			// draw the slider box
#ifdef PDA
	Fl_Color col = selection_color();
	if (horizontal()) {
	    slider_ver_lines(xsl, ysl, wsl, hsl, W, col);
	} else {
	    slider_hor_lines(xsl, ysl, wsl, hsl, W, col);
	}
#else
	if (wsl > 0 && hsl > 0)
	    draw_box(box1, xsl, ysl, wsl, hsl, selection_color());
#endif
    }
    draw_label(xsl, ysl, wsl, hsl);
}

void
Fl_Slider::draw()
{
    if (damage() & FL_DAMAGE_ALL)
	draw_box();
    draw(x() + Fl::box_dx(box()),
	 y() + Fl::box_dy(box()),
	 w() - Fl::box_dw(box()), h() - Fl::box_dh(box()));
}

int
Fl_Slider::handle(int event, int x, int y, int w, int h)
{
    switch (event) {
    case FL_PUSH:
	if (!Fl::event_inside(x, y, w, h))
	    return 0;
	handle_push();
    case FL_DRAG:{
	    int W = (horizontal()? w : h);
	    //int H = (horizontal() ? h : w);
	    int mx = (horizontal()? Fl::event_x() - x : Fl::event_y() - y);
	    int S = int (slider_size_ * W + .5);
	    int X;
	    static int offcenter;
	    if (type() == FL_HOR_FILL_SLIDER || type() == FL_VERT_FILL_SLIDER) {
		double val = (value() - minimum()) / (maximum() - minimum());

		if (val >= 1.0)
		    X = W;
		else if (val <= 0.0)
		    X = 0;
		else
		    X = int (val * W + .5);

		if (event == FL_PUSH) {
		    offcenter = mx - X;
		    if (offcenter < -S / 2)
			offcenter = 0;
		    else if (offcenter > S / 2)
			offcenter = 0;
		    else
			return 1;
		}
		S = 0;
	    } else {
		double val = (value() - minimum()) / (maximum() - minimum());

		if (val >= 1.0)
		    X = W - S;
		else if (val <= 0.0)
		    X = 0;
		else
		    X = int (val * (W - S) + .5);

		if (event == FL_PUSH) {
		    offcenter = mx - X;
		    if (offcenter < 0)
			offcenter = 0;
		    else if (offcenter > S)
			offcenter = S;
		    else
			return 1;
		}
	    }
	    X = mx - offcenter;
	    double v;
	  TRY_AGAIN:
	    if (X < 0) {
		X = 0;
		offcenter = mx;
		if (offcenter < 0)
		    offcenter = 0;
	    } else if (X > (W - S)) {
		X = W - S;
		offcenter = mx - X;
		if (offcenter > S)
		    offcenter = S;
	    }
	    v = round(X * (maximum() - minimum()) / (W - S) + minimum());
	    // make sure a click outside the sliderbar moves it:
	    if (event == FL_PUSH && v == value()) {
		offcenter = S / 2;
		event = FL_DRAG;
		goto TRY_AGAIN;
	    }
	    handle_drag(clamp(v));
	}
	return 1;
    case FL_RELEASE:
	handle_release();
	return 1;
    default:
	return 0;
    }
}

int
Fl_Slider::handle(int event)
{
    return handle(event,
		  x() + Fl::box_dx(box()),
		  y() + Fl::box_dy(box()),
		  w() - Fl::box_dw(box()), h() - Fl::box_dh(box()));
}

//
// End of "$Id: Fl_Slider.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_file_chooser.cxx ---
//
// "$Id: fl_file_chooser.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// File chooser widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#include <FL/fl_file_chooser.H>

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Browser_.H>
#include <FL/Fl_Input.H>
#include <FL/fl_draw.H>
#include <FL/filename.H>

#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>

static void default_callback(const char*) {}
static void (*current_callback)(const char*) = default_callback;
void fl_file_chooser_callback(void (*cb)(const char*)) {
  current_callback = cb ? cb : default_callback;
}

// "File Chooser Browser" widget:
class FCB : public Fl_Browser_ {
  void* item_first() const ;
  void* item_next(void*) const ;
  void* item_prev(void*) const ;
  int item_height(const dirent*, int) const ;
  int item_height(void*) const ;
  int item_width(const dirent*) const ;
  int item_width(void*) const ;
  int item_quick_height(void*) const ;
  int incr_height() const ;
  void item_draw(void*, int, int, int, int) const ;
  int checkdir(const dirent*, char*) const ;
  void draw();
  void clear_prev();
public:
  char listed[FL_PATH_MAX];// current dir & starname
  int dirend;		// points after last / before starname
  int nameend;		// length to trailing '*' or '\0'
  const char* pattern;	// default pattern
  dirent** list;	// the file names
  dirent** last;	// pointer after end of list
  const char* message;	// message if no file names
  char preved[FL_PATH_MAX];// directory listed in prev
  dirent** prev;	// cached list of another directory
  dirent** prev_last;	// end of that list
  int prev_count;
  FCB(int x, int y, int w, int h) : Fl_Browser_(x, y, w, h, 0) {
    type(FL_HOLD_BROWSER);
    listed[0] = 0;
    dirend = nameend = 1;
    pattern = 0;
    list = prev = 0;
    message = 0;
  }
  // ~FCB nyi
  void clear();
  void set(const char*);
  int get(char*);
};

// "File Chooser Window" widget:
class FCW : public Fl_Window {
public:
  int handle(int);
  Fl_Input input;
  Fl_Button* ok_button;
  Fl_Button* cancel_button;
  Fl_Button* normal_button;
  FCB browser;
  FCW();
};

/* Files are marked as being directories by replacing the trailing null
   with a '/' if it is a directory, a '\001' if it is *not* a directory.
   An item has height (and is thus selectable) if it is either a directory
   or if it matches the pattern.  Quick-height assummes all unknown files
   are directories, and thus saves the time needed to do a stat().
*/

// return pointer to last character:
static const char* end_of_name(const dirent* d) {
#if HAVE_DIRENT_H
  const char* e;
  for (e = d->d_name; ;e++) switch (*e) {
  case 0: case 1: case '/': return e;
  }
#else
  // warning: clobbers byte after end of name
  return d->d_name + d->d_namelen;
#endif
}

// return true if item is directory, when given pointer to last character:
int FCB::checkdir(const dirent* d, char* e) const {
  if (*e == 1) return 0;
  if (*e == '/') return 1;
  char buf[FL_PATH_MAX];
  memcpy(buf, listed, dirend);
  memcpy(buf+dirend, d->d_name, e-d->d_name);
  *(buf+dirend+(e-d->d_name)) = 0;
  if (filename_isdir(buf)) {
    *e = '/'; return 1;
  } else {
    *e = 1; return 0;
  }
}

void* FCB::item_first() const {return list;}

void* FCB::item_next(void* p) const {
  if ((dirent**)p+1 >= last) return 0;
  return (dirent**)p+1;
}

void* FCB::item_prev(void* p) const {
  if ((dirent**)p <= list) return 0;
  return ((dirent**)p)-1;
}

static int ido_matching(const dirent* p, const char* e, const char* n) {
  // replace / or 1 at end with 0 and do match, then put back.  yukko
  int save = *e; *(char*)e = 0;
  int r = filename_match(p->d_name, n);
  *(char*)e = save;
  return(r);
}

int FCB::incr_height() const {return textsize()+2;}

int FCB::item_height(const dirent* p, int slow) const {
  const char* e = end_of_name(p);
  if (listed[dirend]) {
//  if (p->d_name[0]=='.' && listed[dirend]!='.') return 0;
    if (listed[nameend-1]=='/') {
      if (slow ? !checkdir(p, (char*)e) : *e==1) return 0;
      ((char*)listed)[nameend-1] = 0;
      int r = ido_matching(p, e, listed+dirend);
      ((char*)listed)[nameend-1] = '/';
      if (!r) return 0;
    } else {
      if (!ido_matching(p, e, listed+dirend)) return 0;
    }
  } else {
    if (p->d_name[0]=='.') return 0;
    if (pattern && (slow ? !checkdir(p, (char*)e) : *e==1) &&
	!ido_matching(p, e, pattern)) return 0;
  }
  return textsize()+2;
}

int FCB::item_height(void* x) const {
  return item_height(*(const dirent**)x, 1);
}

int FCB::item_quick_height(void* x) const {
  return item_height(*(const dirent**)x, 0);
}

void FCB::item_draw(void* v, int x, int y, int, int h) const {
  const dirent* p = *(const dirent**)v;
  const char* e = end_of_name(p);
  if (checkdir(p, (char*)e)) e++;
  if (v == selection()) fl_color(contrast(textcolor(), selection_color()));
  else fl_color(textcolor());
  fl_font(textfont(), textsize());
  fl_draw(p->d_name, e-p->d_name, x+4, y+h-3);
}

int FCB::item_width(const dirent* p) const {
  const char* e = end_of_name(p); if (*e == '/') e++;
  fl_font(textfont(), textsize());
  return (int)fl_width(p->d_name, e-p->d_name)+4;
}

int FCB::item_width(void* x) const {
  return item_width(*(const dirent**)x);
}

// "get" the current value by copying the name of the selected file
// or if none are selected, by copying as many common letters as
// possible of the matched file list:
int FCB::get(char* buf) {
  dirent** q = (dirent**)selection(); // the file to copy from
  int n = 0;	// number of letters
  if (q) {	// a file is selected
    const char* e = end_of_name(*q);
    n = e - (*q)->d_name;
    if (*e == '/') n++;
  } else {	// do filename completion
    for (q = list; q < last && !item_height(*q, 0); q++);
    if (q < last) {
      const char* e = end_of_name(*q);
      n = e - (*q)->d_name;
      if (*e == '/') n++;
      for (dirent** r = q+1; n && r < last; r++) {
	if (!item_height(*r, 0)) continue;
	int i;
	for (i=0; i<n && (*q)->d_name[i]==(*r)->d_name[i]; i++);
	n = i;
      }
    }
  }
  if (n) {
    memcpy(buf, listed, dirend);
    memcpy(buf+dirend, (*q)->d_name, n);
    buf[dirend+n]=0;
  }
  return n;
}

// "set" the current value by changing the directory being listed and
// changing the highlighted item, if possible:
void FCB::set(const char* buf) {

  int bufdirend;
  int ispattern = 0;
  const char* c = buf;
  for (bufdirend=0; *c;) switch(*c++) {
  case '?': case '[': case '*': case '{': ispattern = 1; goto BREAK;
#if defined(WIN32) || defined(__EMX__)
  case '\\':
#endif
  case '/': bufdirend=c-buf; break;
  }
#if defined(WIN32) || defined(__EMX__)
  if ((!bufdirend) && isalpha(buf[0]) && (buf[1]==':')) bufdirend = 2;
#endif
 BREAK:
  int bufend = strlen(buf);
  if (bufend<=bufdirend) ispattern = 1;

  // if directory is different, change list to xxx/ :
  if (bufdirend != dirend || strncmp(buf, listed, bufdirend)) {
    if (prev &&
	preved[bufdirend]==0 && !strncmp(buf, preved, bufdirend)) {
      strcpy(preved, listed); preved[dirend] = 0;
      dirent** t;
      t = prev; prev = list; list = t;
      t = prev_last; prev_last = last; last = t;
      strcpy(listed, buf);
      dirend = nameend = bufdirend;
      message = 0;
    } else {
      if (list) {
	clear_prev();
	strcpy(preved, listed); preved[dirend]=0;
	prev = list;
	prev_last = last;
      }
      list = last = 0;
      message = "reading..."; redraw(); Fl::flush(); redraw();
      strcpy(listed, buf);
      dirend = nameend = bufdirend;
      listed[dirend] = listed[dirend+1] = 0;
      int n = filename_list(dirend ? listed : ".", &list);
      if (n < 0) {
	if (errno==ENOENT) message = "No such directory";
	else message = strerror(errno);
	n = 0; list = 0;
      } else message = 0;
      last = list+n;
    }
    if (list && last <= list+2) message = "Empty directory";
    new_list();
  }

  dirent** q = 0; // will point to future selection
  int any = 0; // true if any names shown

  // do we match one item in the previous list?
  if (!ispattern && bufend >= nameend) {
    for (q = list; ; q++) {
      if (q >= last) {q = 0; break;}
      if (item_height(*q, 0)==0) continue;
      any = 1;
      const char* a = (*q)->d_name;
      const char* b = buf+bufdirend;
#ifdef WIN32
      while (*b && tolower(*a)==tolower(*b)) {a++; b++;}
#else
      while (*b && *a==*b) {a++; b++;}
#endif
      if (!*b && (*a==0 || /* *a=='/' ||*/ *a==1)) break;
    }
  }

  // no, change the list pattern to the new text + a star:
  if (!q) {
    strcpy(listed+dirend, buf+bufdirend);
    nameend = bufend;
    if (!ispattern) {listed[nameend]='*'; listed[nameend+1]=0;}
    any = 0;
    // search again for an exact match:
    for (q = list; ; q++) {
      if (q >= last) {q = 0; break;}
      if (item_height(*q, 0)==0) continue;
      any = 1;
      const char* a = (*q)->d_name;
      const char* b = buf+bufdirend;
#ifdef WIN32
      while (*b && tolower(*a)==tolower(*b)) {a++; b++;}
#else
      while (*b && *a==*b) {a++; b++;}
#endif
      if (!*b && (*a==0 || /* *a=='/' ||*/ *a==1)) break;
    }
    new_list();
  }

  if (any) message = 0;
  else if (!message) message = "No matching files";
  select_only(q);
  if (q) current_callback(buf);
}

void FCB::draw() {
  if (!message) {
    Fl_Browser_::draw();
    if (full_height() > 0) return;
    message = "No matching files";
  }
  Fl_Boxtype b = box(); if (!b) b = FL_DOWN_BOX;
  draw_box(b,color());
  fl_color(FL_INACTIVE_COLOR);
  fl_font(textfont(), textsize());
  fl_draw(message, x()+7, y()+3, w(), h()-3, FL_ALIGN_TOP_LEFT);
  // insure scrollbars are redrawn if error message goes away:
  scrollbar.redraw();
  hscrollbar.redraw();
}

void FCB::clear_prev() {
  if (prev) {
    for (dirent**p=prev_last-1; p>=prev; p--) free((void*)*p);
    free((void*)prev);
    prev = prev_last = 0;
  }
}

void FCB::clear() {
  if (list) {
    for (dirent**p=last-1; p>=list; p--) free((void*)*p);
    free((void*)list);
    list = last = 0;
  }
  clear_prev();
  listed[0] = 0; dirend = 1;
}

////////////////////////////////////////////////////////////////

static void fcb_cb(Fl_Widget*, void* v) {
  FCW* w = (FCW*)v;
  char buf[FL_PATH_MAX];
  if (w->browser.get(buf)) {
    w->input.value(buf);
    w->input.position(10000);
//  w->input.position(10000, w->browser.dirend);
    if (Fl::event_button()==1) {
      if (Fl::event_clicks()) w->ok_button->do_callback();
      else w->browser.set(buf);
    } else {
      current_callback(buf);
    }
  }
}

static void tab_cb(Fl_Widget*, void* v) {
  FCW* w = (FCW*)v;
  char buf[FL_PATH_MAX];
  if (w->browser.get(buf)) {
    w->input.value(buf);
    w->input.position(10000);
    w->browser.set(buf);
  }
}

#if defined(WIN32) || defined(__EMX__)
// ':' needs very special handling!
static inline int isdirsep(char c) {return c=='/' || c=='\\';}
#else
#define isdirsep(c) ((c)=='/')
#endif

static void input_cb(Fl_Widget*, void* v) {
  FCW* w = (FCW*)v;
  const char* buf = w->input.value();
  char localbuf[FL_PATH_MAX];
  if (buf[0] && isdirsep(buf[w->input.size()-1])
      && filename_expand(localbuf, buf)) {
    buf = localbuf;
    w->input.value(localbuf);
    w->input.position(10000);
  }
  w->browser.set(buf);
}

static void up_cb(Fl_Widget*, void* v) { // the .. button
  FCW* w = (FCW*)v;
  char* p;
  char* newname;
  char buf[FL_PATH_MAX];
  p = w->browser.listed+w->browser.dirend-1; // point right before last '/'
  if (p < w->browser.listed)
    newname = "../"; // go up from current directory
  else {
    for (; p>w->browser.listed; p--) if (isdirsep(*(p-1))) break;
    if (isdirsep(*p) || *p=='.' &&
	(isdirsep(p[1]) || p[1]=='.' && isdirsep(p[2]))) {
      p = w->browser.listed+w->browser.dirend;
      memcpy(buf, w->browser.listed, p-w->browser.listed);
      strcpy(buf+(p-w->browser.listed), "../");
    } else {
      memcpy(buf, w->browser.listed, p-w->browser.listed);
      buf[p-w->browser.listed] = 0;
    }
    newname = buf;
  }
  w->input.value(newname);
  w->input.position(10000);
  w->browser.set(newname);
}

static void dir_cb(Fl_Widget* obj, void* v) { // directory buttons
  FCW* w = (FCW*)v;
  const char* p = obj->label(); if (*p=='&') p++;
  char buf[FL_PATH_MAX];
  char* q; for (q=buf; *p && *p!=' '; *q++ = *p++); *q = 0;
  filename_expand(buf, buf);
  w->input.value(buf);
  w->input.position(10000);
  w->browser.set(buf);
}

static void working_cb(Fl_Widget*, void* v) { // directory buttons
  FCW*w = (FCW*)v;
  char buf[FL_PATH_MAX];
  filename_absolute(buf, "");
  w->input.value(buf);
  w->input.position(10000);
  w->browser.set(buf);
}

static void files_cb(Fl_Widget* obj, void* v) { // file pattern buttons
  FCW* w = (FCW*)v;
  char buf[FL_PATH_MAX];
  strcpy(buf, w->input.value());
  char* q = buf+w->browser.dirend;
  if (obj != w->normal_button) {	// tack on first word of label
    const char* p = obj->label(); if (*p=='&') p++;
    for (; *p && *p!=' '; *q++ = *p++);
  }
  *q = 0;
  w->input.value(buf);
  w->input.position(10000, w->browser.dirend);
  w->browser.set(buf);
}

/*----------------------- The Main Routine ----------------------*/
#define HEIGHT_BOX	(4*WIDTH_SPC+HEIGHT_BUT+HEIGHT_INPUT+HEIGHT_BROWSER)
#define HEIGHT_BUT	25
#define HEIGHT_INPUT	30
#define HEIGHT_BROWSER	(9*HEIGHT_BUT+2) // must be > buttons*HEIGHT_BUT
#define WIDTH_BOX	(3*WIDTH_SPC+WIDTH_BUT+WIDTH_BROWSER)
#define WIDTH_BROWSER	350
#define WIDTH_BUT	125
#define WIDTH_OK	70
#define WIDTH_SPC	5

int FCW::handle(int event) {
  if (Fl_Window::handle(event)) return 1;
  if (event==FL_KEYBOARD && Fl::event_key()==FL_Tab) {
    tab_cb(this, this);
    return 1;
  }
  return 0;
}

// set this to make extra directory-jumping button:
const char* fl_file_chooser_button;
extern const char* fl_ok;
extern const char* fl_cancel;

FCW::FCW() : Fl_Window(WIDTH_BOX, HEIGHT_BOX),
	input(WIDTH_SPC, HEIGHT_BOX-HEIGHT_BUT-2*WIDTH_SPC-HEIGHT_INPUT,
	      WIDTH_BOX-2*WIDTH_SPC, HEIGHT_INPUT, 0),
	browser(2*WIDTH_SPC+WIDTH_BUT, WIDTH_SPC,
		WIDTH_BROWSER, HEIGHT_BROWSER)
{
  int but_y = WIDTH_SPC;
  input.callback(input_cb, this);
  input.when(FL_WHEN_CHANGED);
  //  add(browser);
  browser.callback(fcb_cb, this);

  begin();
  Fl_Widget* obj;
  obj = ok_button = new Fl_Return_Button(
    WIDTH_BOX-2*(WIDTH_SPC+WIDTH_OK), HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT,
    WIDTH_OK, HEIGHT_BUT, fl_ok);
  obj = cancel_button = new Fl_Button(
    WIDTH_BOX-WIDTH_SPC-WIDTH_OK, HEIGHT_BOX-WIDTH_SPC-HEIGHT_BUT,
    WIDTH_OK, HEIGHT_BUT, fl_cancel);
  cancel_button->shortcut("^[");

  obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "&Up one directory");
  obj->callback(up_cb, this);
  but_y += HEIGHT_BUT;

  obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&~/ Home");
  obj->callback(dir_cb, this);
  but_y += HEIGHT_BUT;

  obj = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&/ Root");
  obj->callback(dir_cb, this);
  but_y += HEIGHT_BUT;

  obj=new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "&Current dir");
  obj->callback(working_cb, this);
  but_y += HEIGHT_BUT;

  if (fl_file_chooser_button) {
    obj=new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT,fl_file_chooser_button);
    obj->callback(dir_cb, this);
    but_y += HEIGHT_BUT;
  }

  normal_button = new Fl_Button(WIDTH_SPC, but_y, WIDTH_BUT, HEIGHT_BUT, "");
  normal_button->callback(files_cb, this);
  but_y += HEIGHT_BUT;

  obj = new Fl_Button(WIDTH_SPC,but_y, WIDTH_BUT, HEIGHT_BUT, "* &All files");
  obj->callback(files_cb, this);
  but_y += HEIGHT_BUT;

  obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, ". &Hidden files");
  obj->callback(files_cb, this);
  but_y += HEIGHT_BUT;

  obj = new Fl_Button(WIDTH_SPC,but_y,WIDTH_BUT,HEIGHT_BUT, "*/ &Directories");
  obj->callback(files_cb, this);
  but_y += HEIGHT_BUT;

  resizable(new Fl_Box(browser.x(), but_y,
		       cancel_button->x()-browser.x(),
		       browser.y()+browser.h()-but_y));
  // add(input); // put last for better draw() speed
  end();
  set_modal();
}

char* fl_file_chooser(const char* message, const char* pat, const char* fname)
{
  static FCW* f; if (!f) f = new FCW();
  f->ok_button->label(fl_ok);
  f->cancel_button->label(fl_cancel);

  if (pat && !*pat) pat = 0;
  if (fname && *fname) {
    f->input.value(fname);
  } else if (f->browser.pattern != pat && (!pat || !f->browser.pattern ||
					   strcmp(pat,f->browser.pattern))) {
    // if pattern is different, remove name but leave old directory:
    const char* p = f->input.value();
    const char* q = filename_name(p);
    f->input.value(p, q-p);
  }
  f->browser.pattern = pat;
  f->normal_button->label(pat ? pat : "visible files");
  f->browser.set(f->input.value());
  f->input.position(10000, f->browser.dirend);

  f->label(message);
  f->hotspot(f);
  f->show();
  int ok = 0;
  for (;;) {
    Fl::wait();
    Fl_Widget* o = Fl::readqueue();
    if (o == f->ok_button) {ok = 1; break;}
    else if (o == f->cancel_button || o == f) break;
  }
  f->hide();
  f->browser.clear();

  if (!ok) return 0;
  const char* r = f->input.value();
  const char* p;
  for (p=r+f->browser.dirend; *p; p++)
    if (*p=='*' || *p=='?' || *p=='[' || *p=='{') return 0;
  return (char*)r;
}

//
// End of "$Id: fl_file_chooser.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Pixmap.cxx ---
//
// "$Id: Fl_Pixmap.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Draws X pixmap data, keeping it stashed in a server pixmap so it
// redraws fast.

// See fl_draw_pixmap.C for code used to get the actual data into pixmap.
// Implemented without using the xpm library (which I can't use because
// it interferes with the color cube used by fl_draw_image).

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Pixmap.H>

#include <stdio.h>

extern uchar **fl_mask_bitmap; // used by fl_draw_pixmap.C to store mask
void fl_restore_clip(); // in fl_rect.C

void Fl_Pixmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
  // ignore empty or bad pixmap data:
  if (w<0) {
    fl_measure_pixmap(data, w, h);
    if (WP==-1) { WP = w; HP = h; }
  }
  if (!w) return;
  // account for current clip region (faster on Irix):
  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
  cx += X-XP; cy += Y-YP;
  // clip the box down to the size of image, quit if empty:
  if (cx < 0) {W += cx; X -= cx; cx = 0;}
  if (cx+W > w) W = w-cx;
  if (W <= 0) return;
  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
  if (cy+H > h) H = h-cy;
  if (H <= 0) return;
  if (!id) {
    id = (ulong)fl_create_offscreen(w, h);
    fl_begin_offscreen((Fl_Offscreen)id);
    uchar *bitmap = 0;
    fl_mask_bitmap = &bitmap;
    fl_draw_pixmap(data, 0, 0, FL_BLACK);
    fl_mask_bitmap = 0;
    if (bitmap) {
#ifdef WIN32 // Matt: mask done
      // this won't work ehen the user changes display mode during run or
      // has two screens with differnet depths
      static uchar hiNibble[16] =
      { 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
	0x10, 0x90, 0x50, 0xd0, 0x20, 0xb0, 0x70, 0xf0 };
      static uchar loNibble[16] =
      { 0x00, 0x08, 0x04, 0x0c, 0x02, 0x0a, 0x06, 0x0e,
	0x01, 0x09, 0x05, 0x0d, 0x02, 0x0b, 0x07, 0x0f };
      int np  = GetDeviceCaps(fl_gc, PLANES);	//: was always one on sample machines
      int bpp = GetDeviceCaps(fl_gc, BITSPIXEL);//: 1,4,8,16,24,32 and more odd stuff?
      int Bpr = (bpp*w+7)/8;			//: bytes per row
      int pad = Bpr&1, w1 = (w+7)/8, shr = ((w-1)&7)+1;
      if (bpp==4) shr = (shr+1)/2;
      uchar *newarray = new uchar[(Bpr+pad)*h], *dst = newarray, *src = bitmap;
      for (int i=0; i<h; i++) {
	//: this is slooow, but we do it only once per pixmap
	for (int j=w1; j>0; j--) {
	  uchar b = *src++;
	  if (bpp==1) {
	    *dst++ = ( hiNibble[b&15] ) | ( loNibble[(b>>4)&15] );
	  } else if (bpp==4) {
	    for (int k=(j==1)?shr:4; k>0; k--) {
	      *dst++ = "\377\360\017\000"[b&3];
	      b = b >> 2;
	    }
	  } else {
	    for (int k=(j==1)?shr:8; k>0; k--) {
	      if (b&1) {
		*dst++=0;
		if (bpp>8) *dst++=0;
		if (bpp>16) *dst++=0;
		if (bpp>24) *dst++=0;
	      } else {
		*dst++=0xff;
		if (bpp>8) *dst++=0xff;
		if (bpp>16) *dst++=0xff;
		if (bpp>24) *dst++=0xff;
	      }
	      b = b >> 1;
	    }
	  }
	}
	dst += pad;
      }
      mask = (ulong)CreateBitmap(w, h, np, bpp, newarray);
      delete[] newarray;
#else
#ifdef NANO_X //tanghao
#if 1
      mask = GrNewRegion();

      int h = H;
      int w = (W+7)/8;

      GR_RECT rect;
      rect.width  = 1;
      rect.height = 1;

      uchar * p = bitmap;

      for ( int cy = 0; cy < h; ++cy )
      {
        rect.x = 0;
        rect.y = cy;
	for ( int cx = 0; cx < w; ++cx )
	{
          if ((*p &   1)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &   2)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &   4)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &   8)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &  16)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &  32)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p &  64)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          if ((*p & 128)) { GrUnionRectWithRegion(mask,&rect); } ++rect.x;
          ++p;
	}
      }
#endif
#else
      mask = XCreateBitmapFromData(fl_display, fl_window,
				(const char*)bitmap, (w+7)&-8, h);
#endif //tanghao
#endif
      delete[] bitmap;
    }
    fl_end_offscreen();
  }
#ifdef WIN32
  if (mask) {
    HDC new_gc = CreateCompatibleDC(fl_gc);
    SelectObject(new_gc, (void*)mask);
    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCAND);
    SelectObject(new_gc, (void*)id);
    BitBlt(fl_gc, X, Y, W, H, new_gc, cx, cy, SRCPAINT);
    DeleteDC(new_gc);
  } else {
    fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
  }
#else
#ifndef NANO_X //tanghao
  if (mask) {
    // I can't figure out how to combine a mask with existing region,
    // so cut the image down to a clipped rectangle:
    int nx, ny; fl_clip_box(X,Y,W,H,nx,ny,W,H);
    cx += nx-X; X = nx;
    cy += ny-Y; Y = ny;
    // make X use the bitmap as a mask:
    XSetClipMask(fl_display, fl_gc, mask);
    int ox = X-cx; if (ox < 0) ox += w;
    int oy = Y-cy; if (oy < 0) oy += h;
    XSetClipOrigin(fl_display, fl_gc, X-cx, Y-cy);
  }
#else
  GR_GC_ID oldgc;
#define DOIT 1
  if (mask && DOIT) 
  {
    oldgc = fl_gc;
    fl_gc = GrNewGC();
    GrSetGCRegion(fl_gc,mask);
    GrOffsetRegion(mask,X,Y);
  }
#endif //tanghao
  fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
#ifndef NANO_X //tanghao
  if (mask) {
    // put the old clip region back
    XSetClipOrigin(fl_display, fl_gc, 0, 0);
    fl_restore_clip();
  }
#else
  if (mask && DOIT)
  {
    GrOffsetRegion(mask,-X,-Y);
    GrDestroyGC(fl_gc);
    fl_gc = oldgc;
  }
#endif //tanghao
#endif
}

Fl_Pixmap::~Fl_Pixmap() {
  if (id) fl_delete_offscreen((Fl_Offscreen)id);
#ifndef NANO_X
  if (mask) fl_delete_offscreen((Fl_Offscreen)mask);
#else
  if (mask) GrDestroyRegion(mask);
#endif
}

static void pixmap_labeltype(
														 const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
{
  Fl_Pixmap* b = (Fl_Pixmap*)(o->value);
  if (b->w<0) fl_measure_pixmap(b->data, b->w, b->h);
  int cx;
  if (a & FL_ALIGN_LEFT) cx = 0;
  else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
  else cx = (b->w-w)/2;
  int cy;
  if (a & FL_ALIGN_TOP) cy = 0;
  else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
  else cy = (b->h-h)/2;
  b->draw(x,y,w,h,cx,cy);
}

static void pixmap_measure(const Fl_Label* o, int& w, int& h) {
  Fl_Pixmap* b = (Fl_Pixmap*)(o->value);
  if (b->w<0) fl_measure_pixmap(b->data, b->w, b->h);
  w = b->w;
  h = b->h;
}

void Fl_Pixmap::label(Fl_Widget* o) {
  Fl::set_labeltype(_FL_PIXMAP_LABEL, pixmap_labeltype, pixmap_measure);
  o->label(_FL_PIXMAP_LABEL, (const char*)this);
}

void Fl_Pixmap::label(Fl_Menu_Item* o) {
  Fl::set_labeltype(_FL_PIXMAP_LABEL, pixmap_labeltype, pixmap_measure);
  o->label(_FL_PIXMAP_LABEL, (const char*)this);
}

//
// End of "$Id: Fl_Pixmap.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_get_key_win32.cxx ---
//
// "$Id: Fl_get_key_win32.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// WIN32 keyboard state routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Return the current state of a key.  Keys are named by fltk symbols,
// which are actually X keysyms.  So this has to translate to MSWindows
// VK_x symbols.

#include <FL/Fl.H>
#include <FL/win32.H>

// convert an Fltk (X) keysym to a MSWindows VK symbol:
// See also the inverse converter in Fl_win32.C
// This table is in numeric order by Fltk symbol order for binary search:

static const struct {unsigned short vk, fltk;} vktab[] = {
  {VK_SPACE,	' '},
  {'1',		'!'},
  {0xde,	'\"'},
  {'3',		'#'},
  {'4',		'$'},
  {'5',		'%'},
  {'7',		'&'},
  {0xde,	'\''},
  {'9',		'('},
  {'0',		')'},
  {'8',		'*'},
  {0xbb,	'+'},
  {0xbc,	','},
  {0xbd,	'-'},
  {0xbe,	'.'},
  {0xbf,	'/'},
  {0xba,	':'},
  {0xba,	';'},
  {0xbc,	'<'},
  {0xbb,	'='},
  {0xbe,	'>'},
  {0xbf,	'?'},
  {'2',		'@'},
  {0xdb,	'['},
  {0xdc,	'\\'},
  {0xdd,	']'},
  {'6',		'^'},
  {0xbd,	'_'},
  {0xc0,	'`'},
  {0xdb,	'{'},
  {0xdc,	'|'},
  {0xdd,	'}'},
  {0xc0,	'~'},
  {VK_BACK,	FL_BackSpace},
  {VK_TAB,	FL_Tab},
  {VK_CLEAR,	0xff0b/*XK_Clear*/},
  {VK_RETURN,	FL_Enter},
  {VK_PAUSE,	FL_Pause},
  {VK_SCROLL,	FL_Scroll_Lock},
  {VK_ESCAPE,	FL_Escape},
  {VK_HOME,	FL_Home},
  {VK_LEFT,	FL_Left},
  {VK_UP,	FL_Up},
  {VK_RIGHT,	FL_Right},
  {VK_DOWN,	FL_Down},
  {VK_PRIOR,	FL_Page_Up},
  {VK_NEXT,	FL_Page_Down},
  {VK_END,	FL_End},
  {VK_SNAPSHOT,	FL_Print},
  {VK_INSERT,	FL_Insert},
  {VK_APPS,	FL_Menu},
  {VK_NUMLOCK,	FL_Num_Lock},
//{VK_???,	FL_KP_Enter},
  {VK_MULTIPLY,	FL_KP+'*'},
  {VK_ADD,	FL_KP+'+'},
  {VK_SUBTRACT,	FL_KP+'-'},
  {VK_DECIMAL,	FL_KP+'.'},
  {VK_DIVIDE,	FL_KP+'/'},
  {VK_LSHIFT,	FL_Shift_L},
  {VK_RSHIFT,	FL_Shift_R},
  {VK_LCONTROL,	FL_Control_L},
  {VK_RCONTROL,	FL_Control_R},
  {VK_CAPITAL,	FL_Caps_Lock},
  {VK_LWIN,	FL_Meta_L},
  {VK_RWIN,	FL_Meta_R},
  {VK_LMENU,	FL_Alt_L},
  {VK_RMENU,	FL_Alt_R},
  {VK_DELETE,	FL_Delete}
};

static int fltk2ms(int fltk) {
  if (fltk >= '0' && fltk <= '9') return fltk;
  if (fltk >= 'A' && fltk <= 'Z') return fltk;
  if (fltk >= 'a' && fltk <= 'z') return fltk-('a'-'A');
  if (fltk > FL_F && fltk <= FL_F+16) return fltk-(FL_F-(VK_F1-1));
  if (fltk >= FL_KP+'0' && fltk<=FL_KP+'9') return fltk-(FL_KP+'0'-VK_NUMPAD0);
  int a = 0;
  int b = sizeof(vktab)/sizeof(*vktab);
  while (a < b) {
    int c = (a+b)/2;
    if (vktab[c].fltk == fltk) return vktab[c].vk;
    if (vktab[c].fltk < fltk) a = c+1; else b = c;
  }
  return 0;
}

int Fl::event_key(int k) {
  return GetKeyState(fltk2ms(k))&~1;
}

int Fl::get_key(int k) {
  uchar foo[256];
  GetKeyboardState(foo);
  return foo[fltk2ms(k)]&~1;
}

//
// End of "$Id: Fl_get_key_win32.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Image.cxx ---
//
// "$Id: Fl_Image.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Image drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Image.H>

void Fl_Image::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
  // account for current clip region (faster on Irix):
  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
  cx += X-XP; cy += Y-YP;
  // clip the box down to the size of image, quit if empty:
  if (cx < 0) {W += cx; X -= cx; cx = 0;}
  if (cx+W > w) W = w-cx;
  if (W <= 0) return;
  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
  if (cy+H > h) H = h-cy;
  if (H <= 0) return;
  if (!id) {
    id = (ulong)fl_create_offscreen(w, h);
    fl_begin_offscreen((Fl_Offscreen)id);
    fl_draw_image(array, 0, 0, w, h, d, ld);
    fl_end_offscreen();
  }
  fl_copy_offscreen(X, Y, W, H, (Fl_Offscreen)id, cx, cy);
}

Fl_Image::~Fl_Image() {
  if (id) fl_delete_offscreen((Fl_Offscreen)id);
}

static void image_labeltype(
    const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
{
  Fl_Image* b = (Fl_Image*)(o->value);
  int cx;
  if (a & FL_ALIGN_LEFT) cx = 0;
  else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
  else cx = (b->w-w)/2;
  int cy;
  if (a & FL_ALIGN_TOP) cy = 0;
  else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
  else cy = (b->h-h)/2;
  b->draw(x,y,w,h,cx,cy);
}

static void image_measure(const Fl_Label* o, int& w, int& h) {
  Fl_Image* b = (Fl_Image*)(o->value);
  w = b->w;
  h = b->h;
}

void Fl_Image::label(Fl_Widget* o) {
  Fl::set_labeltype(_FL_IMAGE_LABEL, image_labeltype, image_measure);
  o->label(_FL_IMAGE_LABEL, (const char*)this);
}

void Fl_Image::label(Fl_Menu_Item* o) {
  Fl::set_labeltype(_FL_IMAGE_LABEL, image_labeltype, image_measure);
  o->label(_FL_IMAGE_LABEL, (const char*)this);
}

//
// End of "$Id: Fl_Image.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_get_key.cxx ---
//
// "$Id: Fl_get_key.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Keyboard state routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//


#ifdef WIN32
#include "Fl_get_key_win32.cxx"
#else

// Return the current state of a key.  This is the X version.  I identify
// keys (mostly) by the X keysym.  So this turns the keysym into a keycode
// and looks it up in the X key bit vector, which Fl_x.C keeps track of.

#include <FL/Fl.H>
#include <FL/x.H>

extern char fl_key_vector[32]; // in Fl_x.C

int Fl::event_key(int k) {
  if (k > FL_Button && k <= FL_Button+8)
    return Fl::event_state(8<<(k-FL_Button));
  int i;
#ifdef __sgi

  // get some missing PC keyboard keys:
  if (k == FL_Meta_L) i = 147;
  else if (k == FL_Meta_R) i = 148;
  else if (k == FL_Menu) i = 149;
  else
#endif
#ifdef NANO_X //tanghao
#else
    i = XKeysymToKeycode(fl_display, k);
#endif //tanghao
  return fl_key_vector[i/8] & (1 << (i%8));
}

int Fl::get_key(int k) {
  fl_open_display();
#ifndef NANO_X
  XQueryKeymap(fl_display, fl_key_vector);
#endif
  return event_key(k);
}

#endif

//
// End of "$Id: Fl_get_key.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: numericsort.c ---
/*
 * "$Id: numericsort.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
 *
 * Numeric sorting routine for the Fast Light Tool Kit (FLTK).
 *
 * Copyright 1998-1999 by Bill Spitzak and others.
 *
 * 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 at easysw.com".
 */

/* My own scandir sorting function, useful for the film industry where
   we have many files with numbers in their names: */

#include <config.h>
#include <ctype.h>
#include <stdlib.h>
#include <sys/types.h>

#ifdef WIN32
#include <FL/filename.H>
#else
#if HAVE_DIRENT_H
# include <dirent.h>
#else
# define dirent direct
# if HAVE_SYS_NDIR_H
#  include <sys/ndir.h>
# endif
# if HAVE_SYS_DIR_H
#  include <sys/dir.h>
# endif
# if HAVE_NDIR_H
#  include <ndir.h>
# endif
#endif
#endif

#ifdef __cplusplus
extern "C"
#endif
int numericsort(struct dirent **A, struct dirent **B) {
  const char* a = (*A)->d_name;
  const char* b = (*B)->d_name;
  int ret = 0;
  for (;;) {
    if (isdigit((unsigned)*a) && isdigit((unsigned)*b)) {
      int diff,magdiff;
      while (*a == '0') a++;
      while (*b == '0') b++;
      while (isdigit((unsigned)*a) && *a == *b) {a++; b++;}
      diff = (isdigit((unsigned)*a) && isdigit((unsigned)*b)) ? *a - *b : 0;
      magdiff = 0;
      while (isdigit((unsigned)*a)) {magdiff++; a++;}
      while (isdigit((unsigned)*b)) {magdiff--; b++;}
      if (magdiff) {ret = magdiff; break;} /* compare # of significant digits*/
      if (diff) {ret = diff; break;}	/* compare first non-zero digit */
    } else {
#if 1
      if ((ret = tolower((unsigned)*a)-tolower((unsigned)*b))) break; /* compare case-insensitve */
#else
      if ((ret = *a-*b)) break;	/* compare case-sensitive */
#endif
      if (!*a) break;
      a++; b++;
    }
  }
  if (!ret) return 0;
  else return (ret < 0) ? -1 : 1;
}

/*
 * End of "$Id: numericsort.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
 */

--- NEW FILE: filename_ext.cxx ---
//
// "$Id: filename_ext.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Filename extension routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// returns pointer to the last '.' or to the null if none:

#include <FL/filename.H>

const char *filename_ext(const char *buf) {
  const char *q = 0;
  const char *p = buf;
  for (p=buf; *p; p++) {
    if (*p == '/') q = 0;
#if defined(WIN32) || defined(__EMX__)
    else if (*p == '\\') q = 0;
#endif
    else if (*p == '.') q = p;
  }
  return q ? q : p;
}

//
// End of "$Id: filename_ext.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: dump_compose.c ---
/* write out the documentation for the compose key */

/* copy the string from Fl_Input.C */
static const char* const compose_pairs =
"  ! @ # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'DDss"
"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'ddy:";

#include <stdio.h>

int main() {
  int x,y;
  for (x = 0; x<16; x++) {
    for (y = 0; y<6; y++) {
      const char *p = compose_pairs + (16*y+x)*2;
      if (p[1] == ' ')
	printf("<td><code>%c&nbsp</code>&nbsp&nbsp&nbsp%c\n",
	       p[0],(p-compose_pairs)/2+0xA0);
      else
	printf("<td><code>%c%c</code>&nbsp&nbsp&nbsp%c\n",
	       p[0],p[1],(p-compose_pairs)/2+0xA0);
    }
    printf("<tr>");
  }
  return 0;
}

--- NEW FILE: Fl_Window.cxx ---
//
// "$Id: Fl_Window.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Window widget class for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// The Fl_Window is a window in the fltk library.
// This is the system-independent portions.  The huge amount of 
// crap you need to do to communicate with X is in Fl_x.C, the
// equivalent (but totally different) crap for MSWindows is in Fl_win32.C

#include <FL/Fl.H>
#include <FL/Fl_Window.H>

void Fl_Window::_Fl_Window() {
  type(FL_WINDOW);
  box(FL_FLAT_BOX);
  labeltype(FL_NO_LABEL);
  wm_props = 0;
  i = 0;
  xclass_ = 0;
  icon_ = 0;
  iconlabel_ = 0;
  resizable(0);
  size_range_set = 0;
  callback((Fl_Callback*)default_callback);
}

Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
: Fl_Group(X, Y, W, H, l) {
  _Fl_Window();
  set_flag(FL_FORCE_POSITION);
}

Fl_Window::Fl_Window(int W, int H, const char *l)
// fix common user error of a missing end() with current(0):
  : Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
  _Fl_Window();
  clear_visible();
}

Fl_Window *Fl_Widget::window() const {
  for (Fl_Widget *o = parent(); o; o = o->parent())
    if (o->type() >= FL_WINDOW) return (Fl_Window*)o;
  return 0;
}

int Fl_Window::x_root() const {
  Fl_Window *p = window();
  if (p) return p->x_root() + x();
  return x();
}

int Fl_Window::y_root() const {
  Fl_Window *p = window();
  if (p) return p->y_root() + y();
  return y();
}

void Fl_Window::draw() {
  int savex = x(); x(0);
  int savey = y(); y(0);
  Fl_Group::draw();
  y(savey);
  x(savex);
}

#include <stdio.h>
void Fl_Window::resize_notify(int X,int Y,int W,int H)
{
  if ( (X == x()) && (Y == y()) ) {
    size(W, H);
  }
}

void Fl_Window::label(const char *name) {label(name, iconlabel());}

void Fl_Window::iconlabel(const char *iname) {label(label(), iname);}

// the Fl::atclose pointer is provided for back compatability.  You
// can now just change the callback for the window instead.

void Fl::default_atclose(Fl_Window* window, void* v) {
  window->hide();
  Fl_Widget::default_callback(window, v); // put on Fl::read_queue()
}

void (*Fl::atclose)(Fl_Window*, void*) = default_atclose;

void Fl_Window::default_callback(Fl_Window* window, void* v) {
  Fl::atclose(window, v);
}

//
// End of "$Id: Fl_Window.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_arci.cxx ---
//
// "$Id: fl_arci.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Arc (integer) drawing functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// "integer" circle drawing functions.  These draw the limited
// circle types provided by X and NT graphics.  The advantage of
// these is that small ones draw quite nicely (probably due to stored
// hand-drawn bitmaps of small circles!) and may be implemented by
// hardware and thus are fast.

// Probably should add fl_chord.

// 3/10/98: created

#include <FL/fl_draw.H>
#include <FL/x.H>
//#include <stdio.H> //tanghao
#ifdef WIN32
#include <FL/math.h>
#endif

void fl_arc(int x,int y,int w,int h,double a1,double a2) {
  if (w <= 0 || h <= 0) return;
#ifdef WIN32
  int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
  int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
  int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
  int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
  Arc(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); 
#else

#ifdef NANO_X 

  --w;  --h;

  GrArcAngle(fl_window, fl_gc, x + w/2, y + h/2, w/2, h/2, 
	     int(a1 * 64), int(a2 * 64), MWARC);

  ++w;  ++h;

#ifdef oldold //tanghao
  GrEllipse(fl_window,fl_gc,x+(w-1)/2,y+(h-1)/2,(w-1)/2,(h-1)/2);
  //llx+w/2,lly+h/2,w/2,h/2);
  //printf("not support ARC now,in Nano_X\n");
#endif

#else
  XDrawArc(fl_display, fl_window, fl_gc, x,y,w-1,h-1, int(a1*64),int((a2-a1)*64));
#endif //tanghao
#endif
}


void fl_pie(int x,int y,int w,int h,double a1,double a2) {
  if (w <= 0 || h <= 0) return;
  if (a1 == a2) return;

#ifdef WIN32
  int xa = x+w/2+int(w*cos(a1/180.0*M_PI));
  int ya = y+h/2-int(h*sin(a1/180.0*M_PI));
  int xb = x+w/2+int(w*cos(a2/180.0*M_PI));
  int yb = y+h/2-int(h*sin(a2/180.0*M_PI));
  SelectObject(fl_gc, fl_brush());
  Pie(fl_gc, x, y, x+w, y+h, xa, ya, xb, yb); 
#else
#ifdef NANO_X 
 
  --w;  --h;

  GrArcAngle(fl_window, fl_gc, x + w/2, y + h/2, w/2, h/2, 
	     int(a1 * 64), int(a2 * 64), MWPIE);
  
  ++w;  ++h;

#ifdef oldold //tanghao
  GrFillEllipse(fl_window,fl_gc,x+w/2,y+h/2,w/2,h/2);
  //  printf("not support fillARC now,in Nano_X\n");
#endif

#else
  XFillArc(fl_display, fl_window, fl_gc, x,y,w,h, int(a1*64),int((a2-a1)*64));
#endif //tanghao
#endif
}

//
// End of "$Id: fl_arci.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_vertex.cxx ---
//
// "$Id: fl_vertex.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Portable drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Portable drawing code for drawing arbitrary shapes with
// simple 2D transformations.  See also fl_arc.C

#include <FL/fl_draw.H>
#include <FL/x.H>
#include <FL/math.h>
#include <stdlib.h>

struct matrix {double a, b, c, d, x, y;};

static matrix m = {1, 0, 0, 1, 0, 0};

static matrix stack[10];
static int sptr = 0;

void fl_push_matrix() {stack[sptr++] = m;}

void fl_pop_matrix() {m = stack[--sptr];}

void fl_mult_matrix(double a, double b, double c, double d, double x, double y) {

  matrix o;
  o.a = a*m.a + b*m.c;
  o.b = a*m.b + b*m.d;
  o.c = c*m.a + d*m.c;
  o.d = c*m.b + d*m.d;
  o.x = x*m.a + y*m.c + m.x;
  o.y = x*m.b + y*m.d + m.y;
  m = o;
}

void fl_scale(double x,double y) {fl_mult_matrix(x,0,0,y,0,0);}

void fl_scale(double x) {fl_mult_matrix(x,0,0,x,0,0);}

void fl_translate(double x,double y) {fl_mult_matrix(1,0,0,1,x,y);}

void fl_rotate(double d) {
  if (d) {
    double s, c;
    if (d == 0) {s = 0; c = 1;}
    else if (d == 90) {s = 1; c = 0;}
    else if (d == 180) {s = 0; c = -1;}
    else if (d == 270 || d == -90) {s = -1; c = 0;}
    else {s = sin(d*M_PI/180); c = cos(d*M_PI/180);}
    fl_mult_matrix(c,-s,s,c,0,0);
  }
}
#ifdef NANO_X
static GR_POINT *p = (GR_POINT *)0;
#else
static XPoint *p = (XPoint *)0;
#endif
// typedef what the x,y fields in a point are:
#ifdef WIN32
typedef int COORD_T;
#else
typedef short COORD_T;
#endif

static int p_size;
static int n;
static int what;
enum {LINE, LOOP, POLYGON, POINT_};

void fl_begin_points() {n = 0; what = POINT_;}

void fl_begin_line() {n = 0; what = LINE;}

void fl_begin_loop() {n = 0; what = LOOP;}

void fl_begin_polygon() {n = 0; what = POLYGON;}

double fl_transform_x(double x, double y) {return x*m.a + y*m.c + m.x;}

double fl_transform_y(double x, double y) {return x*m.b + y*m.d + m.y;}

double fl_transform_dx(double x, double y) {return x*m.a + y*m.c;}

double fl_transform_dy(double x, double y) {return x*m.b + y*m.d;}

static void fl_transformed_vertex(COORD_T x, COORD_T y) {
  if (!n || x != p[n-1].x || y != p[n-1].y) {
    if (n >= p_size) {
      p_size = p ? 2*p_size : 16;
#ifdef NANO_X
		p = (GR_POINT *)realloc((void*)p, p_size*sizeof(*p));
#else
      p = (XPoint *)realloc((void*)p, p_size*sizeof(*p));
#endif
    }
    p[n].x = x;
    p[n].y = y;
    n++;
  }
}

void fl_transformed_vertex(double xf, double yf) {
  fl_transformed_vertex(COORD_T(xf+.5), COORD_T(yf+.5));
}

void fl_vertex(double x,double y) {
  fl_transformed_vertex(x*m.a + y*m.c + m.x, x*m.b + y*m.d + m.y);
}

void fl_end_points() {
#ifdef WIN32
  for (int i=0; i<n; i++) SetPixel(fl_gc, p[i].x, p[i].y, fl_RGB());
#else
#ifdef NANO_X
  if (n>1) GrPoly(fl_window,fl_gc, n, p);
			//(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count,
			//GR_POINT *pointtable);
#else
  if (n>1) XDrawPoints(fl_display, fl_window, fl_gc, p, n, 0);
#endif //tanghao
#endif
}

void fl_end_line() {
#ifdef WIN32
  if (n>1) Polyline(fl_gc, p, n);
#else
#ifdef NANO_X
  if (n>1) GrPoly(fl_window,fl_gc,n,p);
				//(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count,
				//GR_POINT *pointtable);
#else
  if (n>1) XDrawLines(fl_display, fl_window, fl_gc, p, n, 0);
#endif //tanghao
#endif
}

static void fixloop() {  // remove equal points from closed path
  while (n>2 && p[n-1].x == p[0].x && p[n-1].y == p[0].y) n--;
}

void fl_end_loop() {
  fixloop();
  if (n>2) fl_transformed_vertex((COORD_T)p[0].x, (COORD_T)p[0].y);
  fl_end_line();
}

void fl_end_polygon() {
  fixloop();
#ifdef WIN32
  if (n>2) {
    SelectObject(fl_gc, fl_brush());
    Polygon(fl_gc, p, n);
  }
#else
#ifdef NANO_X
  if (n>2) GrFillPoly(fl_window,fl_gc,n,p);
			//(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count,
			//GR_POINT *pointtable);
#else
  if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, Convex, 0);
#endif
#endif
}

static int gap;
#ifdef WIN32
static int counts[20];
static int numcount;
#endif

void fl_begin_complex_polygon() {
  fl_begin_polygon();
  gap = 0;
#ifdef WIN32
  numcount = 0;
#endif
}

void fl_gap() {
  while (n>gap+2 && p[n-1].x == p[gap].x && p[n-1].y == p[gap].y) n--;
  if (n > gap+2) {
    fl_transformed_vertex((COORD_T)p[gap].x, (COORD_T)p[gap].y);
#ifdef WIN32
    counts[numcount++] = n-gap;
#endif
    gap = n;
  } else {
    n = gap;
  }
}

void fl_end_complex_polygon() {
  fl_gap();
#ifdef WIN32
  if (n>2) {
    SelectObject(fl_gc, fl_brush());
    PolyPolygon(fl_gc, p, counts, numcount);
  }
#else
#ifdef NANO_X
  if (n>2) GrFillPoly(fl_window,fl_gc,n,p);
			//(GR_DRAW_ID id, GR_GC_ID gc, GR_COUNT count,
			//GR_POINT *pointtable);
#else
  if (n>2) XFillPolygon(fl_display, fl_window, fl_gc, p, n, 0, 0);
#endif //tanghao
#endif
}

// shortcut the closed circles so they use XDrawArc:
// warning: these do not draw rotated ellipses correctly!
// See fl_arc.c for portable version.

void fl_circle(double x, double y,double r) {
  double xt = fl_transform_x(x,y);
  double yt = fl_transform_y(x,y);
  double rx = r * (m.c ? sqrt(m.a*m.a+m.c*m.c) : fabs(m.a));
  double ry = r * (m.b ? sqrt(m.b*m.b+m.d*m.d) : fabs(m.d));
  int llx = int(xt-rx+.5);
  int w = int(xt+rx+.5)-llx;
  int lly = int(yt-ry+.5);
  int h = int(yt+ry+.5)-lly;
#ifdef WIN32
  if (what==POLYGON) {
    SelectObject(fl_gc, fl_brush());
    Pie(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); 
  } else
    Arc(fl_gc, llx, lly, llx+w, lly+h, 0,0, 0,0); 
#else
#ifdef NANO_X //tanghao
  if (what == POLYGON)
    GrFillEllipse(fl_window,fl_gc,llx+w/2,lly+h/2,w/2,h/2);
  else
    GrEllipse(fl_window,fl_gc,llx+w/2,lly+h/2,w/2,h/2);
			//(GR_DRAW_ID id, GR_GC_ID gc, GR_COORD x, GR_COORD y,
			//GR_SIZE rx, GR_SIZE ry);
#else
  (what == POLYGON ? XFillArc : XDrawArc)
    (fl_display, fl_window, fl_gc, llx, lly, w, h, 0, 360*64);
#endif //tanghao
#endif
}

//
// End of "$Id: fl_vertex.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_arc.cxx ---
//
// "$Id: fl_arc.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Arc functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Utility for drawing arcs and circles.  They are added to
// the current fl_begin/fl_vertex/fl_end path.
// Incremental math implementation:

#include <FL/fl_draw.H>
#include <FL/math.h>

void fl_arc(double x, double y, double r, double start, double end) {

  // draw start point accurately:
  double A = start*(M_PI/180);
  double X = r*cos(A);
  double Y = -r*sin(A);
  fl_vertex(x+X,y+Y);

  // number of segments per radian:
  int n; {
    double x1 = fl_transform_dx(r,0);
    double y1 = fl_transform_dy(r,0);
    double r1 = x1*x1+y1*y1;
    x1 = fl_transform_dx(0,r);
    y1 = fl_transform_dy(0,r);
    double r2 = x1*x1+y1*y1;
    if (r2 < r1) r1 = r2;
    n = int(sqrt(r1)*.841471);
    if (n < 2) n = 2;
  }
  double epsilon = 1.0/n;
  double E = end*(M_PI/180);
  int i = int((E-A)*n);
  if (i < 0) {i = -i; epsilon = -epsilon;}
  double epsilon2 = epsilon/2;
  for (; i>1; i--) {
    X += epsilon*Y;
    Y -= epsilon2*X;
    fl_vertex(x+X,y+Y);
    Y -= epsilon2*X;
  }

  // draw the end point accurately:
  fl_vertex(x+r*cos(E), y-r*sin(E));
}

#if 0 // portable version.  X-specific one in fl_vertex.C
void fl_circle(double x,double y,double r) {
  _fl_arc(x, y, r, r, 0, 360);
}
#endif

//
// End of "$Id: fl_arc.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_own_colormap.cxx ---
//
// "$Id: Fl_own_colormap.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Private colormap support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Using the default system colormap can be a bad idea on PseudoColor
// visuals, since typically every application uses the default colormap and
// you can run out of colormap entries easily.
//
// The solution is to always create a new colormap on PseudoColor displays
// and copy the first 16 colors from the default colormap so that we won't
// get huge color changes when switching windows.

#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>

#ifdef WIN32
// There is probably something relevant to do on MSWindows 8-bit displays
// but I don't know what it is

void Fl::own_colormap() {}

#else
// X version

void Fl::own_colormap() {
  fl_open_display();
#ifndef NANO_X
#if USE_COLORMAP
  switch (fl_visual->c_class) {
  case GrayScale :
  case PseudoColor :
  case DirectColor :
    break;
  default:
    return; // don't do anything for non-colormapped visuals
  }
  int i;
  XColor colors[16];
  // Get the first 16 colors from the default colormap...
  for (i = 0; i < 16; i ++) colors[i].pixel = i;
  XQueryColors(fl_display, fl_colormap, colors, 16);
  // Create a new colormap...
  fl_colormap = XCreateColormap(fl_display,
				RootWindow(fl_display,fl_screen),
				fl_visual->visual, AllocNone);
  // Copy those first 16 colors to our own colormap:
  for (i = 0; i < 16; i ++)
    XAllocColor(fl_display, fl_colormap, colors + i);
#endif
#endif//tanghao
}

#endif

//
// End of "$Id: Fl_own_colormap.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Scroll.cxx ---
//
// "$Id: Fl_Scroll.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Scroll widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Scroll.H>
#include <FL/fl_draw.H>

#include <iostream.h>

// Insure the scrollbars are the last children:
void Fl_Scroll::fix_scrollbar_order() {
  Fl_Widget*const* a = array();
  if (a[children()-1] != &scrollbar) {
    Fl_Widget** a = (Fl_Widget**)array();
    int i,j; for (i = j = 0; j < children(); j++)
      if (a[j] != &hscrollbar && a[j] != &scrollbar) a[i++] = a[j];
    a[i++] = &hscrollbar;
    a[i++] = &scrollbar;
  }
}

void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) {
  fl_clip(X,Y,W,H);
  Fl_Scroll* s = (Fl_Scroll*)v;
  // erase background if there is a boxtype:
  if (s->box() && !(s->damage()&FL_DAMAGE_ALL)) {
    fl_color(s->color());
    fl_rectf(X,Y,W,H);
  }
  Fl_Widget*const* a = s->array();
  int R = X; int B = Y; // track bottom & right edge of all children
  for (int i=s->children()-2; i--;) {
    Fl_Widget& o = **a++;
    s->draw_child(o);
    s->draw_outside_label(o);
    if (o.x()+o.w() > R) R = o.x()+o.w();
    if (o.y()+o.h() > B) B = o.y()+o.h();
  }
  // fill any area to right & bottom of widgets:
  if (R < X+W && B > Y) {
    fl_color(s->color());
    fl_rectf(R,Y,X+W-R,B-Y);
  }
  if (B < Y+H) {
    fl_color(s->color());
    fl_rectf(X,B,W,Y+H-B);
  }
  fl_pop_clip();
}

void Fl_Scroll::bbox(int& X, int& Y, int& W, int& H) {
  X = x()+Fl::box_dx(box());
  Y = y()+Fl::box_dy(box());
  W = w()-Fl::box_dw(box());
  H = h()-Fl::box_dh(box());
  if (scrollbar.visible()) {
    W -= scrollbar.w();
    if (scrollbar.align() & FL_ALIGN_LEFT) X += scrollbar.w();
  }
  if (hscrollbar.visible()) {
    H -= hscrollbar.h();
    if (scrollbar.align() & FL_ALIGN_TOP) Y += hscrollbar.h();
  }
}

void Fl_Scroll::draw() {
  fix_scrollbar_order();
  int X,Y,W,H; bbox(X,Y,W,H);

  uchar d = damage();
#ifdef PDA
  X=X+1;
  W=W-2;
  H=H-1;	
#endif
	if (d & FL_DAMAGE_ALL) { // full redraw
#ifdef PDA
    draw_box(box(),x(),y()-1,w(),h()+1,color());
#else
    draw_box(box(),x(),y(),w(),h(),color());
#endif
    draw_clip(this, X, Y, W, H);
  } else {
    if (d & FL_DAMAGE_SCROLL) { // scroll the contents:
      fl_scroll(X, Y, W, H, oldx-xposition_, oldy-yposition_, draw_clip, this);
    }
    if (d & FL_DAMAGE_CHILD) { // draw damaged children
      fl_clip(X, Y, W, H);
      Fl_Widget*const* a = array();
      for (int i=children()-2; i--;) update_child(**a++);
      fl_pop_clip();
    }
  }

  // accumulate bounding box of children:
  int l = X; int r = X; int t = Y; int b = Y;
  Fl_Widget*const* a = array();
  for (int i=children()-2; i--;) {
    Fl_Object* o = *a++;
    if (o->x() < l) l = o->x();
    if (o->y() < t) t = o->y();
    if (o->x()+o->w() > r) r = o->x()+o->w();
    if (o->y()+o->h() > b) b = o->y()+o->h();
  }

  // turn the scrollbars on and off as necessary:
  for (int z = 0; z<2; z++) {
    if ((type()&VERTICAL) && (type()&ALWAYS_ON || t < Y || b > Y+H)) {
      if (!scrollbar.visible()) {
	scrollbar.set_visible();
	W -= scrollbar.w();
	d = FL_DAMAGE_ALL;
      }
    } else {
      if (scrollbar.visible()) {
	scrollbar.clear_visible();
	draw_clip(this,
		  scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
		  Y, scrollbar.w(), H);
	W += scrollbar.w();
	d = FL_DAMAGE_ALL;
      }
    }
    if ((type()&HORIZONTAL) && (type()&ALWAYS_ON || l < X || r > X+W)) {
      if (!hscrollbar.visible()) {
	hscrollbar.set_visible();
	H -= hscrollbar.h();
	d = FL_DAMAGE_ALL;
      }
    } else {
      if (hscrollbar.visible()) {
	hscrollbar.clear_visible();
	draw_clip(this, X,
		  scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
		  W, hscrollbar.h());
	H += hscrollbar.h();
	d = FL_DAMAGE_ALL;
      }
    }
  }
#ifdef PDA
  
#if 1  
  int __Y = Y - 1;
  int __H = H + 2;
  int __X = X; 
  int __W = W;

  scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? __X-scrollbar.w()  : __X+__W,
		   __Y, scrollbar.w(), __H);
  
  hscrollbar.resize(__X,
		    scrollbar.align()&FL_ALIGN_TOP ? __Y-hscrollbar.h() : __Y+__H,
		    __W, hscrollbar.h());
  
#else	
	  scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w()  : X+W,
	  Y, scrollbar.w(), H);
	  
	  hscrollbar.resize(X,
	  scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
	  W, hscrollbar.h());
	  #endif
#else
  scrollbar.resize(scrollbar.align()&FL_ALIGN_LEFT ? X-scrollbar.w() : X+W,
		   Y, scrollbar.w(), H);
  
  hscrollbar.resize(X,
		    scrollbar.align()&FL_ALIGN_TOP ? Y-hscrollbar.h() : Y+H,
		    W, hscrollbar.h());
#endif
  scrollbar.value(oldy = yposition_ = (Y-t), H, 0, b-t);

  hscrollbar.value(oldx = xposition_ = (X-l), W, 0, r-l);

  // draw the scrollbars:
  if (d & FL_DAMAGE_ALL) {
    draw_child(scrollbar);
    draw_child(hscrollbar);
    if (scrollbar.visible() && hscrollbar.visible()) {
      // fill in the little box in the corner
      fl_color(color());
      fl_rectf(scrollbar.x(), hscrollbar.y(), scrollbar.w(), hscrollbar.h());
    }
  } else {
    update_child(scrollbar);
    update_child(hscrollbar);
  }
}

void Fl_Scroll::resize(int X, int Y, int W, int H) {
  fix_scrollbar_order();
  // move all the children:
  Fl_Widget*const* a = array();
  for (int i=children()-2; i--;) {
    Fl_Object* o = *a++;
    o->position(o->x()+X-x(), o->y()+Y-y());
  }
  Fl_Widget::resize(X,Y,W,H);
}

void Fl_Scroll::position(int X, int Y) {
  int dx = xposition_-X;
  int dy = yposition_-Y;

  if (!dx && !dy) return;
  xposition_ = X;
  yposition_ = Y;
  Fl_Widget*const* a = array();
  for (int i=children(); i--;) {
    Fl_Widget* o = *a++;
    if (o == &hscrollbar || o == &scrollbar) continue;
    o->position(o->x()+dx, o->y()+dy);
  }
  damage(FL_DAMAGE_SCROLL);
}

void Fl_Scroll::hscrollbar_cb(Fl_Widget* o, void*) {
  Fl_Scroll* s = (Fl_Scroll*)(o->parent());
  s->position(int(((Fl_Scrollbar*)o)->value()), s->yposition());
}

void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) {
  Fl_Scroll* s = (Fl_Scroll*)(o->parent());
  s->position(s->xposition(), int(((Fl_Scrollbar*)o)->value()));
}

#define SLIDER_WIDTH 17

Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L)
  : Fl_Group(X,Y,W,H,L), 
    scrollbar(X+W-SLIDER_WIDTH,Y,SLIDER_WIDTH,H-SLIDER_WIDTH),
    hscrollbar(X,Y+H-SLIDER_WIDTH,W-SLIDER_WIDTH,SLIDER_WIDTH) {
  type(BOTH);
  xposition_ = 0;
  yposition_ = 0;
  hscrollbar.type(FL_HORIZONTAL);
  hscrollbar.callback(hscrollbar_cb);
  scrollbar.callback(scrollbar_cb);
}

int Fl_Scroll::handle(int event) {
  fix_scrollbar_order();
  return Fl_Group::handle(event);
}

//
// End of "$Id: Fl_Scroll.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_font.cxx ---
//
// "$Id: fl_font.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $"
//
// Font selection code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 GNULibrary 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 at easysw.com".
//

// Select fonts from the fltk font table.

#ifdef WIN32
#include "fl_font_win32.cxx"
#else

#include <config.h>
#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include "Fl_Font.H"

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#ifdef NANO_X

/* Define a class here for the font cache */

#define WIDTH_CACHE_SIZE 20

typedef struct
{
    GR_FONT_ID fontid;
    GR_FONT_INFO fi;
    int age;
    unsigned char widths[256];
}
width_cache_struct;

class font_cache
{
  private:
    width_cache_struct * cache[WIDTH_CACHE_SIZE];

  public:
    width_cache_struct * check_cache(GR_FONT_ID curfont)
    {
	/* For the moment, we index the cache with the font ID */
	int n;

	for (n = 0; n < WIDTH_CACHE_SIZE; n++)
	{
	    if (cache[n]) {
		if (cache[n]->fontid == curfont) {
		    cache[n]->age = 0;
		    return (cache[n]);
		}

		cache[n]->age++;
	    }
	}

	return ((width_cache_struct *) 0);
    }

    void add_cache(GR_FONT_ID curfont, unsigned char *widths,
		   GR_FONT_INFO * fi)
    {
	int n;
	int oldest = -1;


	for (n = 0; n < WIDTH_CACHE_SIZE; n++) {
	    if (!cache[n]) {
		cache[n] =
		    (width_cache_struct *) malloc(sizeof(width_cache_struct));

		if (!cache[n])
		    return;

		cache[n]->fontid = curfont;
		cache[n]->age = 0;

		bcopy(widths, cache[n]->widths, 256);
		memcpy(&cache[n]->fi, fi, sizeof(GR_FONT_INFO));
		return;
	    } else {
		if (oldest != -1) {
		    if (cache[n]->age > cache[oldest]->age)
			oldest = n;
		} else
		    oldest = n;
	    }
	}

	if (oldest == -1)
	    return;

	bzero(cache[oldest], sizeof(width_cache_struct));

	cache[oldest]->fontid = curfont;
	cache[oldest]->age = 0;

	bcopy(widths, cache[oldest]->widths, 256);

	return;
    }

    font_cache() {
	int n;

	for (n = 0; n < WIDTH_CACHE_SIZE; n++)
	    cache[n] = (width_cache_struct *) 0;
    }

    ~font_cache() {
	int n;

	for (n = 0; n < WIDTH_CACHE_SIZE; n++)
	    if (cache[n])
		free(cache[n]);
    }
};

font_cache width_cache;

#endif

// size is not used unless we're nano-X and then it size defaults to 16
// if TTF we'll resize it later

Fl_FontSize::Fl_FontSize(const char *name, int size)
{
#ifdef NANO_X
    isTTF = false;
    next = 0;			// it can't be in a list yet

    font = GrCreateFont((GR_CHAR *) name, size, NULL);

    // need to determine whether the font is TrueType
    // GrGetFontInfo() needs a way to indicate that
    // so this is a bit of a hack; are all TTF fonts in .ttf files?
    if (font) {
	if (strstr(name, ".ttf")) {
	    minsize = size;
	    maxsize = size;	// TTF fonts always scale
	    isTTF = true;
	} else {
	    minsize = size;
	    maxsize = size;	// not true type always scale
	}
    } else {
	Fl::warning("bad font: %s, using a builtin", name);
//      font = GrCreateFont("HZKFONT", 16, NULL);
	font = GrCreateFont((GR_CHAR *) "fonts/simfang.ttf", 16, NULL);
	if (!font)
	    font = GrCreateFont((GR_CHAR *) GR_FONT_GUI_VAR, 0, NULL);
    }

#else
    font = XLoadQueryFont(fl_display, name);
    if (!font) {
	Fl::warning("bad font: %s", name);
	font = XLoadQueryFont(fl_display, "fixed");	// if fixed fails we crash
    }
#endif
#if HAVE_GL
    listbase = 0;
#endif
}

Fl_FontSize *fl_fontsize;

#ifdef NANOX
// attempts to resize the font in microwindows
void
Fl_FontSize::Resize(int size)
{
    GrSetFontSize(font, size);
}
#endif

Fl_FontSize::~Fl_FontSize()
{
#if HAVE_GL
// Delete list created by gl_draw().  This is not done by this code
// as it will link in GL unnecessarily.  There should be some kind
// of "free" routine pointer, or a subclass?
// if (listbase) {
//  int base = font->min_char_or_byte2;
//  int size = font->max_char_or_byte2-base+1;
//  int base = 0; int size = 256;
//  glDeleteLists(listbase+base,size);
// }
#endif
    if (this == fl_fontsize)
	fl_fontsize = 0;
#ifdef NANO_X
    if (font)
	GrDestroyFont(font);
#else
    XFreeFont(fl_display, font);
#endif
}

////////////////////////////////////////////////////////////////
#ifdef NANO_X

/* JHC - Major hack! */

#ifdef PDA

static Fl_Fontdesc built_in_table[] = {
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_SYSTEM_FIXED},
    {GR_FONT_SYSTEM_FIXED},
    {GR_FONT_SYSTEM_FIXED},
    {GR_FONT_SYSTEM_FIXED},
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_GUI_VAR},
    {GR_FONT_OEM_FIXED},
    {GR_FONT_SYSTEM_FIXED},
    {GR_FONT_SYSTEM_FIXED},
    {"pda3x6.fnt"}
};

#else

// WARNING: if you add to this table, you must redefine FL_FREE_FONT
// in Enumerations.H & recompile!!
static Fl_Fontdesc built_in_table[] = {

    {"/usr/local/microwin/fonts/arial.ttf"},
    {"/usr/local/microwin/fonts/arialb.ttf"},
    {"/usr/local/microwin/fonts/ariali.ttf"},
    {"/usr/local/microwin/fonts/arialz.ttf"},
    {"/usr/local/microwin/fonts/cour.ttf"},
    {"/usr/local/microwin/fonts/courb.ttf"},
    {"/usr/local/microwin/fonts/couri.ttf"},
    {"/usr/local/microwin/fonts/courz.ttf"},
    {"/usr/local/microwin/fonts/times.ttf"},
    {"/usr/local/microwin/fonts/timesb.ttf"},
    {"/usr/local/microwin/fonts/timesi.ttf"},
    {"/usr/local/microwin/fonts/timesz.ttf"},
    {"/usr/local/microwin/fonts/impact.ttf"},
    {"/usr/local/microwin/fonts/comic.ttf"},
    {"/usr/local/microwin/fonts/comicbd.ttf"},
    {"Terminal"}

    /*
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"},
       {"HZKFONT"}
     */

};
#endif /* PDA */

#else
// WARNING: if you add to this table, you must redefine FL_FREE_FONT
// in Enumerations.H & recompile!!
static Fl_Fontdesc built_in_table[] = {
    {"-*-helvetica-medium-r-normal--*"},
    {"-*-helvetica-bold-r-normal--*"},
    {"-*-helvetica-medium-o-normal--*"},
    {"-*-helvetica-bold-o-normal--*"},
    {"-*-courier-medium-r-normal--*"},
    {"-*-courier-bold-r-normal--*"},
    {"-*-courier-medium-o-normal--*"},
    {"-*-courier-bold-o-normal--*"},
    {"-*-times-medium-r-normal--*"},
    {"-*-times-bold-r-normal--*"},
    {"-*-times-medium-i-normal--*"},
    {"-*-times-bold-i-normal--*"},
    {"-*-symbol-*"},
    {"-*-lucidatypewriter-medium-r-normal-sans-*"},
    {"-*-lucidatypewriter-bold-r-normal-sans-*"},
    {"-*-*zapf dingbats-*"}
};
#endif

Fl_Fontdesc *fl_fonts = built_in_table;

#define MAXSIZE 32767

// return dash number N, or pointer to ending null if none:
const char *
fl_font_word(const char *p, int n)
{
    while (*p) {
	if (*p == '-') {
	    if (!--n)
		break;
	}
	p++;
    }
    return p;
}

// return a pointer to a number we think is "point size":
char *
fl_find_fontsize(char *name)
{
    char *c = name;
    // for standard x font names, try after 7th dash:
    if (*c == '-') {
	c = (char *) fl_font_word(c, 7);
	if (*c++ && isdigit(*c))
	    return c;
	return 0;		// malformed x font name?
    }
    char *r = 0;
    // find last set of digits:
    for (c++; *c; c++)
	if (isdigit(*c) && !isdigit(*(c - 1)))
	    r = c;
    return r;
}

const char *fl_encoding = "iso8859-1";

// return true if this matches fl_encoding:
int
fl_correct_encoding(const char *name)
{
    if (*name != '-')
	return 0;
    const char *c = fl_font_word(name, 13);
    return (*c++ && !strcmp(c, fl_encoding));
}

#ifdef NANO_X

// font choosers - if the fonts change in built_in_table, 
// these and the enum in Fl/Enumerations.H will have to change

inline bool
IsBold(int fnum)
{
    switch (fnum) {
    case FL_HELVETICA_BOLD:
    case FL_HELVETICA_BOLD_ITALIC:
    case FL_COURIER_BOLD:
    case FL_COURIER_BOLD_ITALIC:
	return true;
    default:
	return false;
    }
}
inline bool
IsItalic(int fnum)
{
    switch (fnum) {
    case FL_HELVETICA_ITALIC:
    case FL_HELVETICA_BOLD_ITALIC:
    case FL_COURIER_ITALIC:
    case FL_COURIER_BOLD_ITALIC:
	return true;
    default:
	return false;
    }
}
#endif // NANO-X

#ifdef NANO_X

static Fl_FontSize *
find(int fnum, int size)
{
    Fl_Fontdesc *s = fl_fonts + fnum;
    if (!s->name)
	s = fl_fonts;		// use font 0 if still undefined
    Fl_FontSize *f;
    for (f = s->first; f; f = f->next) {
	if (f->minsize <= size && f->maxsize >= size) {
	    return f;
	}
    }

    fl_open_display();

    // time to create one
    if (!s->first) {
	s->first = new Fl_FontSize(s->name, size);
	return s->first;
    }


    for (f = s->first; f->next; f = f->next);
    f->next = new Fl_FontSize(s->name, size);



    return f;

}

#else
// locate or create an Fl_FontSize for a given Fl_Fontdesc and size:
static Fl_FontSize *
find(int fnum, int size)
{

    Fl_Fontdesc *s = fl_fonts + fnum;
    if (!s->name)
	s = fl_fonts;		// use font 0 if still undefined
    Fl_FontSize *f;
    for (f = s->first; f; f = f->next) {
	if (f->minsize <= size && f->maxsize >= size
#ifdef NANOX
	    && !f->isTTF
#endif
	    ) {
	    return f;
	}
    }

    fl_open_display();

#ifdef NANO_X
    // time to create one
    if (!s->first) {
	s->first = new Fl_FontSize(s->name, size);
    }
    // if this is TTF there will only be a first, so resize it
    if (s->first && s->first->isTTF) {
	s->first->Resize(size);
	return s->first;
    }
#endif

    if (!s->xlist) {
#ifndef NANO_X			//tanghao
	s->xlist = XListFonts(fl_display, s->name, 100, &(s->n));
#endif //tanghao
	if (!s->xlist) {	// use fixed if no matching font...
#ifdef NANO_X
//      s->first = new Fl_FontSize("HZKFONT");
	    s->first = new Fl_FontSize(GR_FONT_GUI_VAR);	//"/Setup/microwin/src/fonts/simfang.ttf"););//"simfang.ttf");
#else
	    s->first = new Fl_FontSize("fixed");
#endif
	    s->first->minsize = size;
	    s->first->maxsize = size;
	    return s->first;
	}
    }
    // search for largest <= font size:
    char *name = s->xlist[0];
    int ptsize = 0;		// best one found so far
    int matchedlength = 32767;
    char namebuffer[1024];	// holds scalable font name
    int found_encoding = 0;
    int m = s->n;
    if (m < 0)
	m = -m;
    for (int n = 0; n < m; n++) {

	char *thisname = s->xlist[n];
	if (fl_correct_encoding(thisname)) {
	    if (!found_encoding)
		ptsize = 0;	// force it to choose this
	    found_encoding = 1;
	} else {
	    if (found_encoding)
		continue;
	}
	char *c = fl_find_fontsize(thisname);
	int thissize = c ? atoi(c) : MAXSIZE;
	int thislength = strlen(thisname);
	if (thissize == size && thislength < matchedlength) {
	    // exact match, use it:
	    name = thisname;
	    ptsize = size;
	    matchedlength = thislength;
	} else if (!thissize && ptsize != size) {

	    // whoa!  A scalable font!  Use unless exact match found:
	    int l = c - thisname;
	    memcpy(namebuffer, thisname, l);
#if 1				// this works if you don't want stdio
	    if (size >= 100)
		namebuffer[l++] = size / 100 + '0';
	    if (size >= 10)
		namebuffer[l++] = (size / 10) % 10 + '0';
	    namebuffer[l++] = (size % 10) + '0';
#else
	    //for some reason, sprintf fails to return the right value under Solaris.
	    l += sprintf(namebuffer + l, "%d", size);
#endif
	    while (*c == '0')
		c++;
	    strcpy(namebuffer + l, c);
	    name = namebuffer;
	    ptsize = size;
	} else if (!ptsize ||	// no fonts yet
		   thissize < ptsize && ptsize > size ||	// current font too big
		   thissize > ptsize && thissize <= size	// current too small
	    ) {
	    name = thisname;
	    ptsize = thissize;
	    matchedlength = thislength;
	}
    }

    if (ptsize != size) {	// see if we already found this unscalable font:
	for (f = s->first; f; f = f->next) {
	    if (f->minsize <= ptsize && f->maxsize >= ptsize) {
		if (f->minsize > size)
		    f->minsize = size;
		if (f->maxsize < size)
		    f->maxsize = size;
		return f;
	    }
	}
    }
    // okay, we definately have some name, make the font:
    f = new Fl_FontSize(name);
    if (ptsize < size) {
	f->minsize = ptsize;
	f->maxsize = size;
    } else {
	f->minsize = size;
	f->maxsize = ptsize;
    }
    f->next = s->first;
    s->first = f;
    return f;
}
#endif

////////////////////////////////////////////////////////////////
// Public interface:

int fl_font_;
int fl_size_;
#ifdef NANO_X
GR_FONT_ID fl_xfont;
#else
XFontStruct *fl_xfont;
#endif
static GC font_gc;

void
fl_font(int fnum, int size)
{
    if (fnum == fl_font_ && size == fl_size_)
	return;
    fl_font_ = fnum;
    fl_size_ = size;
    Fl_FontSize *f = find(fnum, size);
    if (f != fl_fontsize) {
	fl_fontsize = f;
	fl_xfont = f->font;
	font_gc = 0;
    }
}

int
fl_height()
{
#ifdef NANO_X
    GR_FONT_INFO fi;
    width_cache_struct *wc = width_cache.check_cache(fl_xfont);

    if (!wc) {
	GrGetFontInfo(fl_xfont, &fi);
	width_cache.add_cache(fl_xfont, fi.widths, &fi);
	return fi.height;
    } else {
	return wc->fi.height;
    }
#else
    return (fl_xfont->ascent + fl_xfont->descent);
#endif
}

int
fl_descent()
{
#ifdef NANO_X
    GR_FONT_INFO fi;
    width_cache_struct *wc = width_cache.check_cache(fl_xfont);

    if (!wc) {
	GrGetFontInfo(fl_xfont, &fi);
	width_cache.add_cache(fl_xfont, fi.widths, &fi);
	return fi.height - fi.baseline;
    } else {
	return wc->fi.height - wc->fi.baseline;
    }
#else
    return fl_xfont->descent;
#endif
}

/* JHC 0928/00 - We must implement caching for the   */
/* NanoX functions, because of speed issues with the */
/* TrueType fonts */

double
fl_width(const char *c)
{
#ifdef NANO_X
    GR_FONT_INFO fi;
    double res = 0.0;

    width_cache_struct *wc = width_cache.check_cache(fl_xfont);
    unsigned char *fwidths;

    if (!wc) {
	GrGetFontInfo(fl_xfont, &fi);
	width_cache.add_cache(fl_xfont, fi.widths, &fi);

	fwidths = fi.widths;
    } else {
	fwidths = wc->widths;
    }

    while (*c) {
	res += fwidths[*c];
	c++;
    }

    return res;

#else
    XCharStruct *p = fl_xfont->per_char;
    if (!p)
	return strlen(c) * fl_xfont->min_bounds.width;
    int a = fl_xfont->min_char_or_byte2;
    int b = fl_xfont->max_char_or_byte2 - a;
    int w = 0;
    while (*c) {
	int x = *(uchar *) c++ - a;
	if (x >= 0 && x <= b)
	    w += p[x].width;
	else
	    w += fl_xfont->min_bounds.width;
    }
    return w;
#endif //tanghao
}

double
fl_width(const char *c, int n)
{
#ifdef NANO_X
    double w = 0;
    GR_FONT_INFO fi;
    width_cache_struct *wc = width_cache.check_cache(fl_xfont);
    unsigned char *fwidths;

    if (!wc) {
	GrGetFontInfo(fl_xfont, &fi);
	width_cache.add_cache(fl_xfont, fi.widths, &fi);

	fwidths = fi.widths;
    } else {
	fwidths = wc->widths;
    }

    for (int i = 0; i < n; i++) {
	w += (double) (fwidths[*(c + i)]);
    }
    return w;

#else
    XCharStruct *p = fl_xfont->per_char;
    if (!p)
	return n * fl_xfont->min_bounds.width;
    int a = fl_xfont->min_char_or_byte2;
    int b = fl_xfont->max_char_or_byte2 - a;
    int w = 0;
    while (n--) {
	int x = *(uchar *) c++ - a;
	if (x >= 0 && x <= b)
	    w += p[x].width;
	else
	    w += fl_xfont->min_bounds.width;
    }
    return w;
#endif //tanghao
}

double
fl_width(uchar c)
{
#ifdef NANO_X
    GR_FONT_INFO fi;
    width_cache_struct *wc = width_cache.check_cache(fl_xfont);
    unsigned char *fwidths;

    if (!wc) {
	GrGetFontInfo(fl_xfont, &fi);
	width_cache.add_cache(fl_xfont, fi.widths, &fi);

	fwidths = fi.widths;
    } else {
	fwidths = wc->widths;
    }

    return fwidths[c];

#else
    XCharStruct *p = fl_xfont->per_char;
    if (p) {
	int a = fl_xfont->min_char_or_byte2;
	int b = fl_xfont->max_char_or_byte2 - a;
	int x = c - a;
	if (x >= 0 && x <= b)
	    return p[x].width;
    }
    return fl_xfont->min_bounds.width;
#endif //tanghao
}

void
fl_draw(const char *str, int n, int x, int y)
{
    if (font_gc != fl_gc) {
	if (!fl_xfont) {
	    fl_font(FL_HELVETICA, 14);
	}

	font_gc = fl_gc;
#if NANO_X
	GrSetGCFont(fl_gc, fl_xfont);
#else
	XSetFont(fl_display, fl_gc, fl_xfont->fid);
#endif
    }
#if NANO_X
    //FIXME hack becasue nano-X will not draw a true type font
    // correctly without first setting its background!!!
    GR_GC_INFO info;

    GrGetGCInfo(fl_gc, &info);
    if (info.background == MWRGB(255, 255, 255))
	GrSetGCBackground(fl_gc, MWRGB(255, 0, 0));
    else
	GrSetGCBackground(fl_gc, MWRGB(255, 255, 255));
    GrSetGCUseBackground(fl_gc, GR_FALSE);
    GrText(fl_window, fl_gc, x, y, (GR_CHAR *) str, n, GR_TFASCII);
#else
    XDrawString(fl_display, fl_window, fl_gc, x, y, str, n);
#endif
}

void
fl_draw(const char *str, int x, int y)
{
    fl_draw(str, strlen(str), x, y);
}

#endif

//
// End of "$Id: fl_font.cxx,v 1.1 2006-10-03 11:25:13 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_rounded_box.cxx ---
//
// "$Id: fl_rounded_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Rounded box drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/fl_draw.H>

#define RN	5
#define RS	15
#define BW	3

static double offset[RN] = { 0.0, 0.07612, 0.29289, 0.61732, 1.0};

static void rbox(int fill, int x, int y, int w, int h) {
  int i;
  int rsx ,rsy, rs;
  rsx = w*2/5; rsy = h*2/5;
  if (rsx > rsy) rs = rsy; else  rs = rsx;
  if (rs > RS) rs = RS;
  rsx = rs; rsy = rs;

  if (fill) fl_begin_polygon(); else fl_begin_loop();
  for (i=0; i<RN; i++)
    fl_vertex(x + offset[RN-i-1]*rsx, y + offset[i] * rsy);
  for (i=0; i<RN; i++)
    fl_vertex(x + offset[i]*rsx, y + h-1 - offset[RN-i-1] * rsy);
  for (i=0; i<RN; i++)
    fl_vertex(x + w-1 - offset[RN-i-1]*rsx, y + h-1 - offset[i] * rsy);
  for (i=0; i<RN; i++)
    fl_vertex(x + w-1 - offset[i]*rsx, y + offset[RN-i-1] * rsy);
  if (fill) fl_end_polygon(); else fl_end_loop();
}

static void fl_rflat_box(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c); rbox(1, x, y, w, h); rbox(0, x, y, w, h);
}

static void fl_rounded_frame(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c); rbox(0, x, y, w, h);
}

static void fl_rounded_box(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c); rbox(1, x, y, w, h);
  fl_color(FL_BLACK); rbox(0, x, y, w, h);
}

static void fl_rshadow_box(int x, int y, int w, int h, Fl_Color c) {
  // draw shadow:
  fl_color(FL_DARK3);
  rbox(1, x+BW, y+BW, w, h);
  rbox(0, x+BW, y+BW, w, h);
  // draw the box:
  fl_rounded_box(x, y, w, h, c);
}

extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);

Fl_Boxtype define_FL_ROUNDED_BOX() {
  fl_internal_boxtype(_FL_ROUNDED_FRAME, fl_rounded_frame);
  fl_internal_boxtype(_FL_ROUNDED_BOX, fl_rounded_box);
  return _FL_ROUNDED_BOX;
}

Fl_Boxtype define_FL_RFLAT_BOX() {
  fl_internal_boxtype(_FL_RFLAT_BOX, fl_rflat_box);
  return _FL_RFLAT_BOX;
}

Fl_Boxtype define_FL_RSHADOW_BOX() {
  fl_internal_boxtype(_FL_RSHADOW_BOX, fl_rshadow_box);
  return _FL_RSHADOW_BOX;
}

//
// End of "$Id: fl_rounded_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: Makefile ---
#
# "$Id: Makefile,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
#
# Library makefile for the Fast Light Tool Kit (FLTK).
#
# Copyright 1998 by Bill Spitzak and others.
#
# 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 at easysw.com".
#

CPPFILES = \
	Fl.cxx \
	Fl_Adjuster.cxx \
	Fl_Animator.cxx \
	Fl_Bitmap.cxx \
	Fl_Browser.cxx \
	Fl_Browser_.cxx \
	Fl_Browser_load.cxx \
	Fl_Box.cxx \
	Fl_Button.cxx \
	Fl_Chart.cxx \
	Fl_Check_Button.cxx \
	Fl_Choice.cxx \
	Fl_Clock.cxx \
	Fl_Color_Chooser.cxx \
	Fl_Counter.cxx \
	Fl_Dial.cxx \
	Fl_Double_Window.cxx \
	Fl_Gl_Choice.cxx \
	Fl_Gl_Overlay.cxx \
	Fl_Gl_Window.cxx \
	Fl_Group.cxx \
	Fl_Image.cxx \
	Fl_Input.cxx \
	Fl_Input_.cxx \
	Fl_Light_Button.cxx \
	Fl_Menu.cxx \
	Fl_Menu_.cxx \
	Fl_Menu_Bar.cxx \
	Fl_Menu_Button.cxx \
	Fl_Menu_Window.cxx \
	Fl_Menu_add.cxx \
	Fl_Menu_global.cxx \
	Fl_Multi_Label.cxx \
	Fl_Output.cxx \
	Fl_Overlay_Window.cxx \
	Fl_Pack.cxx \
	Fl_Pixmap.cxx \
	Fl_Positioner.cxx \
	Fl_Repeat_Button.cxx \
	Fl_Return_Button.cxx \
	Fl_Roller.cxx \
	Fl_Round_Button.cxx \
	Fl_Scroll.cxx \
	Fl_Scrollbar.cxx \
	Fl_Single_Window.cxx \
	Fl_Slider.cxx \
	Fl_Tabs.cxx \
	Fl_Tile.cxx \
	Fl_Valuator.cxx \
	Fl_Value_Input.cxx \
	Fl_Value_Output.cxx \
	Fl_Value_Slider.cxx \
	Fl_Widget.cxx \
	Fl_Window.cxx \
	Fl_Window_fullscreen.cxx \
	Fl_Window_hotspot.cxx \
	Fl_Window_iconize.cxx \
	Fl_abort.cxx \
	Fl_add_idle.cxx \
	Fl_arg.cxx \
	Fl_cutpaste.cxx \
	Fl_display.cxx \
	Fl_get_key.cxx \
	Fl_get_system_colors.cxx \
	Fl_grab.cxx \
	Fl_own_colormap.cxx \
	Fl_visual.cxx \
	Fl_x.cxx \
	filename_absolute.cxx \
	filename_expand.cxx \
	filename_ext.cxx \
	filename_isdir.cxx \
	filename_list.cxx \
	filename_match.cxx \
	filename_setext.cxx \
	fl_arc.cxx \
	fl_arci.cxx \
	fl_ask.cxx \
	fl_boxtype.cxx \
	fl_color.cxx \
	fl_cursor.cxx \
	fl_curve.cxx \
	fl_diamond_box.cxx \
	fl_draw.cxx \
	fl_draw_image.cxx \
	fl_draw_pixmap.cxx \
	fl_engraved_label.cxx \
	fl_file_chooser.cxx \
	fl_font.cxx \
	fl_labeltype.cxx \
	fl_oval_box.cxx \
	fl_overlay.cxx \
	fl_overlay_visual.cxx \
	fl_rect.cxx \
	fl_round_box.cxx \
	fl_rounded_box.cxx \
	fl_set_font.cxx \
	fl_set_fonts.cxx \
	fl_scroll_area.cxx \
	fl_shadow_box.cxx \
	fl_shortcut.cxx \
	fl_show_colormap.cxx \
	fl_symbols.cxx \
	fl_vertex.cxx \
	forms_compatability.cxx \
	forms_bitmap.cxx \
	forms_free.cxx \
	forms_fselect.cxx \
	forms_pixmap.cxx \
	forms_timer.cxx \
	gl_draw.cxx \
	gl_start.cxx \
	glut_compatability.cxx \
	glut_font.cxx

CFILES = fl_call_main.c scandir.c numericsort.c vsnprintf.c

CLEAN =

################################################################

include ../makeinclude

LIBRARY = ../lib/$(LIBNAME)

OBJECTS = $(CPPFILES:.cxx=.o) $(CFILES:.c=.o)

all:	$(LIBRARY) $(DSONAME)

#$(LIBRARY): $(OBJECTS)
#	@echo $(LIBCOMMAND) $@ ...
#	@$(LIBCOMMAND) $@ $(OBJECTS)
#	@$(RANLIB) $@

#libfltk.so.1 libfltk.sl.1: $(OBJECTS)
#	@echo $(DSOCOMMAND) $@ ...
#	@$(DSOCOMMAND) $@ $(OBJECTS)
#	$@

# by tanghao ,for NanoX
$(LIBRARY): $(OBJECTS)
	@echo $(LIBCOMMAND) $@ ...
	@$(LIBCOMMAND) $@ $(OBJECTS)
	@$(RANLIB) $@

libfltk.so.1 libfltk.sl.1: $(OBJECTS)
	@echo $(DSOCOMMAND) $@ ...
	@$(DSOCOMMAND) $@ $(OBJECTS)
	@(if [ -f $(DSONAME) ]; then \
		cd ../lib; \
		ln -sf ../src/$(DSONAME) $(DSONAME); \
		BASELIB=`echo $(DSONAME) | cut -f1 -d'.'`; \
		ln -sf ../src/$(DSONAME) $$BASELIB.so; \
	fi)
#\
#	-lnano-X -lmwengine -lmwdrivers -lmwfonts -lnwidget

.SUFFIXES:	.cxx .h .o

.cxx.o :
	$(CXX) -I.. $(CXXFLAGS) -c $<
.c.o :
	$(CC) -I.. $(CFLAGS) -c -o $@ $<

clean :
	-@ rm -f *.o *.do $(DSONAME) $(LIBRARY) $(CLEAN) core *~ ../include/*~ makedepend cmap
	@touch makedepend

depend:
	$(MAKEDEPEND) -I.. $(CXXFLAGS) $(CPPFILES) $(CFILES) > makedepend
include makedepend

################################################################

install: $(LIBRARY) $(DSONAME)
	@echo "Installing libraries..."
	@-mkdir -p $(libdir)
	@rm -f $(libdir)/$(LIBNAME)
	@-cp $(LIBRARY) $(libdir)
	@-chmod 644 $(libdir)/$(LIBNAME)
	@if test "$(DSONAME)" = libfltk.so.1; then\
		rm -f $(libdir)/libfltk.so*;\
		cp libfltk.so.1 $(libdir); \
		chmod 755 $(libdir)/libfltk.so.1; \
		ln -s $(libdir)/libfltk.so.1 $(libdir)/libfltk.so;\
	fi
	@if test "$(DSONAME)" = libfltk.sl.1; then\
		rm -f $(libdir)/libfltk.sl*;\
		cp libfltk.sl.1 $(libdir); \
		chmod 755 $(libdir)/libfltk.sl.1; \
		ln -s $(libdir)/libfltk.sl.1 $(libdir)/libfltk.sl;\
	fi
	@echo "Installing include files..."
	@-mkdir -p $(includedir)
	@rm -rf $(includedir)/FL $(includedir)/Fl
	@-cp -r ../FL $(includedir)
	@-chmod 755 $(includedir)/FL
	@-chmod 644 $(includedir)/FL/*
	@for file in $(includedir)/FL/*.H; do\
		newfile="`basename $$file H`h";\
		ln -s $$file $(includedir)/FL/$$newfile;\
	done
	@-ln -s FL $(includedir)/Fl

#
# End of "$Id: Makefile,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
#

--- NEW FILE: gl_start.cxx ---
//
// "$Id: gl_start.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
//
// OpenGL context routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// You MUST use gl_visual() to select the default visual before doing
// show() of any windows.  Mesa will crash if you try to use a visual
// not returned by glxChooseVisual.

// This does not work with Fl_Double_Window's!  It will try to draw
// into the front buffer.  Depending on the system this will either
// crash or do nothing (when pixmaps are being used as back buffer
// and GL is being done by hardware), work correctly (when GL is done
// with software, such as Mesa), or draw into the front buffer and
// be erased when the buffers are swapped (when double buffer hardware
// is being used)

#include <config.h>
#if HAVE_GL

#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
#include <FL/fl_draw.H>

#include "Fl_Gl_Choice.H"

extern GLXContext fl_first_context; // in Fl_Gl_Choice.C
extern int fl_clip_state_number; // in fl_rect.C

static GLXContext context;
static int clip_state_number=-1;
static int pw, ph;

#ifdef WIN32
static int default_mode;
#endif

Region XRectangleRegion(int x, int y, int w, int h); // in fl_rect.C

void gl_start() {
#ifdef WIN32
  HDC hdc = fl_private_dc(Fl_Window::current(), default_mode,0);
#endif
  if (!context) {
#ifdef WIN32
    context = wglCreateContext(hdc);
    if (!fl_first_context) fl_first_context = context;
    else wglShareLists(fl_first_context, context);
#else
    context = glXCreateContext(fl_display, fl_visual, fl_first_context, 1);
    if (!context) Fl::fatal("OpenGL does not support this visual");
    if (!fl_first_context) fl_first_context = context;
#endif
  }
  fl_set_gl_context(Fl_Window::current(), context);
#ifndef WIN32
  glXWaitX();
#endif
  if (pw != Fl_Window::current()->w() || ph != Fl_Window::current()->h()) {
    pw = Fl_Window::current()->w();
    ph = Fl_Window::current()->h();
    glLoadIdentity();
    glViewport(0, 0, pw, ph);
    glOrtho(0, pw, 0, ph, -1, 1);
    glDrawBuffer(GL_FRONT);
  }
  if (clip_state_number != fl_clip_state_number) {
    clip_state_number = fl_clip_state_number;
    int x, y, w, h;
    if (fl_clip_box(0, 0, Fl_Window::current()->w(), Fl_Window::current()->h(),
		    x, y, w, h)) {
      fl_clip_region(XRectangleRegion(x,y,w,h));
      glScissor(x, Fl_Window::current()->h()-(y+h), w, h);
      glEnable(GL_SCISSOR_TEST);
    } else {
      glDisable(GL_SCISSOR_TEST);
    }
  }
}

void gl_finish() {
#ifdef WIN32
  glFlush();
#else
  glXWaitGL();
#endif
}

int Fl::gl_visual(int mode, int *alist) {
#ifdef WIN32
  default_mode = mode;
#else
  Fl_Gl_Choice *c = Fl_Gl_Choice::find(mode,alist);
  if (!c) return 0;
  fl_visual = c->vis;
  fl_colormap = c->colormap;
#endif
  return 1;
}

#endif

//
// End of "$Id: gl_start.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
//

--- NEW FILE: ns_mask.xbm ---
#define ns_mask_width 16
#define ns_mask_height 16
#define ns_mask_x_hot 8
#define ns_mask_y_hot 8
static unsigned char ns_mask_bits[] = {
   0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
   0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
   0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01};

--- NEW FILE: Fl_Animator.cxx ---
#include <FL/Fl.H>
#include <FL/Fl_Animator.H>

void Fl_Animator::run_animation(void *data)
{
  Fl_Animator *ani = (Fl_Animator *) data;

  ani->_curframe++;
  
  if (ani->_curframe == ani->_fcount)
    ani->_curframe = 0;
  
  ani->redraw();
  
  if (ani->_playing)
    Fl::add_timeout(ani->_interval, run_animation, data);
}
 
void Fl_Animator::draw_frame()
{
  int swidth = _curframe * _fwidth;

  _image->draw(_xpos, _ypos, 
	       _fwidth, _fheight,
	       swidth, 0);
}


Fl_Animator::Fl_Animator(char * const *image, int X, int Y,
			 int fcount, int fwidth, int fheight, 
			 int interval, const char *label = 0)
  : Fl_Widget(X,Y,fwidth,fheight,label)
  
{
  int x, y;
  
  _image = new Fl_Pixmap(image);

  _xpos = X;
  _ypos = Y;

  _fcount = fcount;
  _fwidth = fwidth;
  _fheight = fheight;
  
  _interval = ((double) interval / 1000);

  _curframe = 0;
  
  _playing = false;
}

void Fl_Animator::draw() 
{
  /* Draw the current frame */
  if (_image) draw_frame();
}

Fl_Animator::~Fl_Animator()
{
  delete(_image);
}

void Fl_Animator::start_animation()
{
  if (_playing == true)
    return;

  _playing = true;
  Fl::add_timeout(_interval, run_animation, (void *) this);
}

void Fl_Animator::stop_animation()
{
  if (_playing == false)
    return;

  _playing = false;
  Fl::remove_timeout(run_animation, (void *) this);
}

--- NEW FILE: Fl_grab.cxx ---
//
// "$Id: Fl_grab.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Grab/release code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>

////////////////////////////////////////////////////////////////
// "Grab" is done while menu systems are up.  This has several effects:
// Events are all sent to the "grab window", which does not even
// have to be displayed (and in the case of Fl_Menu.C it isn't).
// The system is also told to "grab" events and send them to this app.
// This also modifies how Fl_Window::show() works, on X it turns on
// override_redirect, it does similar things on WIN32.

extern void fl_fix_focus(); // in Fl.cxx

#ifdef WIN32
// We have to keep track of whether we have captured the mouse, since
// MSWindows shows little respect for this... Grep for fl_capture to
// see where and how this is used.
extern HWND fl_capture;
#endif

void Fl::grab(Fl_Window* w) {
  if (w) {
    if (!grab_) {
#ifdef WIN32
      SetActiveWindow(fl_capture = fl_xid(first_window()));
      SetCapture(fl_capture);
#else
#ifndef NANO_X //tanghao
      XGrabPointer(fl_display,
		   fl_xid(first_window()),
		   1,
		   ButtonPressMask|ButtonReleaseMask|
		   ButtonMotionMask|PointerMotionMask,
		   GrabModeAsync,
		   GrabModeAsync, 
		   None,
		   0,
		   fl_event_time);
      XGrabKeyboard(fl_display,
		    fl_xid(first_window()),
		    1,
		    GrabModeAsync,
		    GrabModeAsync, 
		    fl_event_time);
#endif //tanghao
#endif
    }
    grab_ = w;
  } else {
    if (grab_) {
#ifdef WIN32
      fl_capture = 0;
      ReleaseCapture();
#else
#ifndef NANO_X
      XUngrabKeyboard(fl_display, fl_event_time);
      XUngrabPointer(fl_display, fl_event_time);
      // this flush is done in case the picked menu item goes into
      // an infinite loop, so we don't leave the X server locked up:
      XFlush(fl_display);
#endif

#endif
      grab_ = 0;
      fl_fix_focus();
    }
  }
}

//
// End of "$Id: Fl_grab.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_round_box.cxx ---
//
// "$Id: fl_round_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Round box drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Box drawing code for an obscure box type.
// These box types are in seperate files so they are not linked
// in if not used.

#include <FL/Fl.H>
#include <FL/fl_draw.H>

// A compiler from a certain very large software company will not compile
// the function pointer assignment due to the name conflict with fl_arc.
// This function is to fix that:
void fl_arc_i(int x,int y,int w,int h,double a1,double a2) {
  fl_arc(x,y,w,h,a1,a2);
}

enum {UPPER_LEFT, LOWER_RIGHT, CLOSED, FILL};

static void draw(int which, int x,int y,int w,int h, int inset, uchar color)
{
  if (inset*2 >= w) inset = (w-1)/2;
  if (inset*2 >= h) inset = (h-1)/2;
  x += inset;
  y += inset;
  w -= 2*inset;
  h -= 2*inset;
  int d = w <= h ? w : h;
  if (d <= 1) return;
  fl_color((Fl_Color)color);
  void (*f)(int,int,int,int,double,double);
  f = (which==FILL) ? fl_pie : fl_arc_i;
  if (which >= CLOSED) {
    f(x+w-d, y, d, d, w<=h ? 0 : -90, w<=h ? 180 : 90);
    f(x, y+h-d, d, d, w<=h ? 180 : 90, w<=h ? 360 : 270);
  } else if (which == UPPER_LEFT) {
    f(x+w-d, y, d, d, 45, w<=h ? 180 : 90);
    f(x, y+h-d, d, d, w<=h ? 180 : 90, 225);
  } else { // LOWER_RIGHT
    f(x, y+h-d, d, d, 225, w<=h ? 360 : 270);
    f(x+w-d, y, d, d, w<=h ? 360 : 270, 360+45);
  }
  if (which == FILL) {
    if (w < h)
      fl_rectf(x, y+d/2, w, h-(d&-2));
    else if (w > h)
      fl_rectf(x+d/2, y, w-(d&-2), h);
  } else {
    if (w < h) {
      if (which != UPPER_LEFT) fl_yxline(x+w-1, y+d/2, y+h-d/2);
      if (which != LOWER_RIGHT) fl_yxline(x, y+d/2, y+h-d/2);
    } else if (w > h) {
      if (which != UPPER_LEFT) fl_xyline(x+d/2, y+h-1, x+w-d/2);
      if (which != LOWER_RIGHT) fl_xyline(x+d/2, y, x+w-d/2);
    }
  }
}

extern uchar* fl_gray_ramp();

static void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) {
#ifdef PDA
  draw(FILL,	     x,   y, w,   h, 4, bgcolor);
  draw(UPPER_LEFT,  x,   y, w,   h, 0, FL_BLACK);
  draw(LOWER_RIGHT, x,   y, w,   h, 0, FL_BLACK);
  if ( h % 2 == 0 && w % 2 == 0 ) {
     fl_xyline(x,y+h/2-1,x,y+h/2-1);
  	  fl_xyline(x+w-2,y+h/2-1,x+w-2,y+h/2-1);
  }
  else {
     fl_xyline(x,y+h/2,x,y+h/2);
     fl_xyline(x+w-1,y+h/2,x+w-1,y+h/2);
  }
#else		  
  uchar *g = fl_gray_ramp();
  draw(FILL,	    x,   y, w,   h, 2, bgcolor);
  draw(UPPER_LEFT,  x+1, y, w-2, h, 0, g['N']);
  draw(UPPER_LEFT,  x+1, y, w-2, h, 1, g['H']);
  draw(UPPER_LEFT,  x,   y, w,   h, 0, g['N']);
  draw(UPPER_LEFT,  x,   y, w,   h, 1, g['H']);
  draw(LOWER_RIGHT, x,   y, w,   h, 0, g['S']);
  draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['U']);
  draw(LOWER_RIGHT, x,   y, w,   h, 1, g['U']);
  draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['W']);
  draw(CLOSED,	    x,   y, w,   h, 2, g['A']);
#endif
}

static void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) {
#ifdef PDA
  draw(FILL,	     x,  y, w,   h, 2, bgcolor);
  draw(UPPER_LEFT,  x,  y, w,   h, 0, FL_BLACK);
  draw(LOWER_RIGHT, x,  y, w,   h, 0, FL_BLACK);
  if ( h % 2 == 0 && w % 2 == 0 ) {
     fl_xyline(x,y+h/2-1,x,y+h/2-1);
  	  fl_xyline(x+w-2,y+h/2-1,x+w-2,y+h/2-1);
  }
  else {
     fl_xyline(x,y+h/2,x,y+h/2);
  	  fl_xyline(x+w-1,y+h/2,x+w-1,y+h/2);
  }
#else  
  uchar *g = fl_gray_ramp();
  draw(FILL,	    x,   y, w,   h, 2, bgcolor);
  draw(LOWER_RIGHT, x+1, y, w-2, h, 0, g['H']);
  draw(LOWER_RIGHT, x+1, y, w-2, h, 1, g['N']);
  draw(LOWER_RIGHT, x,   y, w,   h, 1, g['H']);
  draw(LOWER_RIGHT, x,   y, w,   h, 2, g['N']);
  draw(UPPER_LEFT,  x,   y, w,   h, 2, g['U']);
  draw(UPPER_LEFT,  x+1, y, w-2, h, 1, g['S']);
  draw(UPPER_LEFT,  x,   y, w,   h, 1, g['W']);
  draw(UPPER_LEFT,  x+1, y, w-2, h, 0, g['U']);
  draw(CLOSED,	    x,   y, w,   h, 0, g['A']);
#endif
}

extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
Fl_Boxtype define_FL_ROUND_UP_BOX() {
  fl_internal_boxtype(_FL_ROUND_DOWN_BOX, fl_round_down_box);
  fl_internal_boxtype(_FL_ROUND_UP_BOX, fl_round_up_box);
  return _FL_ROUND_UP_BOX;
}

//
// End of "$Id: fl_round_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_color.cxx ---
//
// "$Id: fl_color.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Color functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implementation of fl_color(i), fl_color(r,g,b).

#ifdef WIN32
#include "fl_color_win32.cxx"
#else

// Also code to look at the X visual and figure out the best way to turn
// a color into a pixel value.

// SGI compiler seems to have problems with unsigned char arguments
// being used to index arrays.  So I always copy them to an integer
// before use.

#include "Fl_XColor.H"
#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/fl_draw.H>

////////////////////////////////////////////////////////////////
// figure_out_visual() calculates masks & shifts for generating
// pixels in true-color visuals:

uchar fl_redmask, fl_greenmask, fl_bluemask;
int fl_redshift, fl_greenshift, fl_blueshift, fl_extrashift;
static uchar beenhere;

static void
figure_out_visual()
{
    beenhere = 1;
#ifndef NANO_X			//tanghao
    if (!fl_visual->red_mask || !fl_visual->green_mask
	|| !fl_visual->blue_mask) {
#if USE_COLORMAP
	fl_redmask = 0;
	return;
#else
	Fl::fatal("Requires true color visual");
#endif
    }
#endif //tanghao

    // get the bit masks into a more useful form:
    int i, j;
#ifndef NANO_X			//tanghao
    int m;
    for (i = 0, m = 1; m; i++, m <<= 1)
	if (fl_visual->red_mask & m)
	    break;
    for (j = i; m; j++, m <<= 1)
	if (!(fl_visual->red_mask & m))
	    break;
#else

    j = 64;
    i = 8;

#endif //tanghao
    fl_redshift = j - 8;
    fl_redmask = (j - i >= 8) ? 0xFF : 0xFF - (255 >> (j - i));

#ifndef NANO_X			//tanghao

    for (i = 0, m = 1; m; i++, m <<= 1)
	if (fl_visual->green_mask & m)
	    break;
    for (j = i; m; j++, m <<= 1)
	if (!(fl_visual->green_mask & m))
	    break;
#endif //tanghao

    fl_greenshift = j - 8;
    fl_greenmask = (j - i >= 8) ? 0xFF : 0xFF - (255 >> (j - i));

#ifndef NANO_X			//tanghao
    for (i = 0, m = 1; m; i++, m <<= 1)
	if (fl_visual->blue_mask & m)
	    break;
    for (j = i; m; j++, m <<= 1)
	if (!(fl_visual->blue_mask & m))
	    break;
#endif //tanghao

    fl_blueshift = j - 8;
    fl_bluemask = (j - i >= 8) ? 0xFF : 0xFF - (255 >> (j - i));

    i = fl_redshift;
    if (fl_greenshift < i)
	i = fl_greenshift;
    if (fl_blueshift < i)
	i = fl_blueshift;
    if (i < 0) {
	fl_extrashift = -i;
	fl_redshift -= i;
	fl_greenshift -= i;
	fl_blueshift -= i;
    } else
	fl_extrashift = 0;

}

////////////////////////////////////////////////////////////////
// Get an rgb color.  This is easy for a truecolor visual.  For
// colormapped it picks the closest color out of the fltk colormap
// but be warned that this results in *two* approximations: one
// to the fltk colormap, and another to whatever colors X allocates.

ulong
fl_xpixel(uchar r, uchar g, uchar b)
{
    if (!beenhere)
	figure_out_visual();
#if USE_COLORMAP
    if (!fl_redmask) {
	Fl_Color i;
	if (r == g && r == b) {	// get it out of gray ramp
	    i = fl_gray_ramp(r * FL_NUM_GRAY / 256);
	} else {		// get it out of color cube:
	    i = fl_color_cube(r * FL_NUM_RED / 256, g * FL_NUM_GREEN / 256,
			      b * FL_NUM_BLUE / 256);
	}
	return fl_xpixel(i);
    }
#endif
#ifdef NANO_X
    return GR_RGB(r, g, b);
#else
    return
	(((r & fl_redmask) << fl_redshift) +
	 ((g & fl_greenmask) << fl_greenshift) +
	 ((b & fl_bluemask) << fl_blueshift)
	) >> fl_extrashift;
#endif
}

void
fl_color(uchar r, uchar g, uchar b)
{
#ifdef NANO_X			//tanghao
    GrSetGCForeground(fl_gc, fl_xpixel(r, g, b));	//(GR_GC_ID gc, GR_COLOR foreground);
    GrSetGCBackground(fl_gc, GR_RGB(200, 200, 200));
#else
    XSetForeground(fl_display, fl_gc, fl_xpixel(r, g, b));
#endif //tanghao
}

////////////////////////////////////////////////////////////////
// Get a color out of the the fltk colormap.  Again for truecolor
// visuals this is easy.  For colormap this actually tries to allocate
// an X color, and does a least-squares match to find the closest
// color if X cannot allocate that color.

static unsigned fl_cmap[256] = {
#include "fl_cmap.h"		// this is a file produced by "cmap.C":
};

#if HAVE_OVERLAY
Fl_XColor fl_xmap[2][256];
uchar fl_overlay;
Colormap fl_overlay_colormap;
XVisualInfo *fl_overlay_visual;
ulong fl_transparent_pixel;
#else
Fl_XColor fl_xmap[1][256];
#endif

// calculate what color is actually on the screen for a mask:
static inline uchar
realcolor(uchar color, uchar mask)
{
#if 1
    // accurate version if the display has linear gamma, but fl_draw_image
    // works better with the simpler version on most screens...
    uchar m = mask;
    uchar result = color & m;
    for (;;) {
	while (m & mask) {
	    m >>= 1;
	    color >>= 1;
	}
	if (!m)
	    break;
	mask = m;
	result |= color & m;
    }
    return result;
#else
    return (color & mask) | (~mask) & (mask >> 1);
#endif
}

ulong
fl_xpixel(Fl_Color i)
{

#if HAVE_OVERLAY
    Fl_XColor & xmap = fl_xmap[fl_overlay][i];
#else
    Fl_XColor & xmap = fl_xmap[0][i];
#endif
    if (xmap.mapped)
	return xmap.pixel;

    if (!beenhere)
	figure_out_visual();
    uchar r, g, b;
    {
	unsigned c = fl_cmap[i];
	r = uchar(c >> 24);
	g = uchar(c >> 16);
	b = uchar(c >> 8);
    }

#if USE_COLORMAP
    Colormap colormap;
#if HAVE_OVERLAY
    if (fl_overlay) {
	colormap = fl_overlay_colormap;
	goto J1;
    }
#endif
    if (!fl_redmask) {
	colormap = fl_colormap;
#if HAVE_OVERLAY
      J1:
	static XColor *ac[2];
	XColor *&allcolors = ac[fl_overlay];
	static int nc[2];
	int &numcolors = nc[fl_overlay];
#else

#ifdef NANO_X
	//static GR_COLOR *allcolors;
	static int numcolors;
#else
	static XColor *allcolors;
	static int numcolors;
#endif
#endif

	// I don't try to allocate colors with XAllocColor once it fails
	// with any color.  It is possible that it will work, since a color
	// may have been freed, but some servers are extremely slow and this
	// avoids one round trip:
	if (!numcolors) {	// don't try after a failure
#ifdef NANO_X
	    GR_COLOR xcol;
	    xcol = GR_RGB(r, g, b);
	    xmap.mapped = 1;
	    xmap.r = r >> 8;
	    xmap.g = g >> 8;
	    xmap.b = b >> 8;
	    return xcol;
#else
	    XColor xcol;
	    xcol.red = r << 8;
	    xcol.green = g << 8;
	    xcol.blue = b << 8;
	    if (XAllocColor(fl_display, colormap, &xcol)) {
		xmap.mapped = 1;
		xmap.r = xcol.red >> 8;
		xmap.g = xcol.green >> 8;
		xmap.b = xcol.blue >> 8;
		return xmap.pixel = xcol.pixel;
#endif
	    }
#ifndef NANO_X
	    // I only read the colormap once.  Again this is due to the slowness
	    // of round-trips to the X server, even though other programs may alter
	    // the colormap after this and make decisions here wrong.
#if HAVE_OVERLAY
	    if (fl_overlay)
		numcolors = fl_overlay_visual->colormap_size;
	    else
#endif

		numcolors = fl_visual->colormap_size;
	    if (!allcolors)
		allcolors = new XColor[numcolors];
	    for (int p = numcolors; p--;)
		allcolors[p].pixel = p;
	    XQueryColors(fl_display, colormap, allcolors, numcolors);
	}
	// find least-squares match:
	int mindist = 0x7FFFFFFF;
	unsigned int bestmatch = 0;
	for (unsigned int n = numcolors; n--;) {
#if HAVE_OVERLAY
	    if (fl_overlay && n == fl_transparent_pixel)
		continue;
#endif
	    XColor & a = allcolors[n];
	    int d, t;
	    t = int (r) - int (a.red >> 8);
	    d = t * t;
	    t = int (g) - int (a.green >> 8);
	    d += t * t;
	    t = int (b) - int (a.blue >> 8);
	    d += t * t;
	    if (d <= mindist) {
		bestmatch = n;
		mindist = d;
	    }
	}
	XColor & p = allcolors[bestmatch];

	// It appears to "work" to not call this XAllocColor, which will
	// avoid another round-trip to the server.  But then X does not
	// know that this program "owns" this value, and can (and will)
	// change it when the program that did allocate it exits:
	if (XAllocColor(fl_display, colormap, &p)) {
	    xmap.mapped = 1;
	    xmap.pixel = p.pixel;
	} else {
	    // However, if that XAllocColor fails, I have to give up and
	    // assumme the pixel is ok for the duration of the program.  This
	    // is due to bugs (?) in the Solaris X and some X terminals
	    // where XAllocColor *always* fails when the colormap is full,
	    // even if we ask for a color already in it...
	    xmap.mapped = 2;	// 2 prevents XFreeColor from being called
	    xmap.pixel = bestmatch;
	}
	xmap.r = p.red >> 8;
	xmap.g = p.green >> 8;
	xmap.b = p.blue >> 8;
	return xmap.pixel;
#endif //tanghao

    }
#endif
    // return color for a truecolor visual:
    xmap.mapped = 2;		// 2 prevents XFreeColor from being called
    xmap.r = realcolor(r, fl_redmask);
    xmap.g = realcolor(g, fl_greenmask);
    xmap.b = realcolor(b, fl_bluemask);
    return xmap.pixel = fl_xpixel(r, g, b);

}

Fl_Color fl_color_;
#include <stdio.h>
void
fl_color(Fl_Color i)
{
    fl_color_ = i;
#ifdef NANO_X
    //GR_COLOR c = fl_xpixel(i);
    GrSetGCForeground(fl_gc, fl_xpixel(i));	//(GR_GC_ID gc, GR_COLOR foreground);
    GrSetGCBackground(fl_gc, GR_RGB(255, 255, 255));
#else
    XSetForeground(fl_display, fl_gc, fl_xpixel(i));
#endif //tanghao
}

void
Fl::free_color(Fl_Color i, int overlay)
{
#if HAVE_OVERLAY
#else
    if (overlay)
	return;
#endif
    if (fl_xmap[overlay][i].mapped) {
#if USE_COLORMAP
#if HAVE_OVERLAY
	Colormap colormap = overlay ? fl_overlay_colormap : fl_colormap;
#else
#ifndef NANO_X
	Colormap colormap = fl_colormap;
#endif
#endif
#ifndef NANO_X
	if (fl_xmap[overlay][i].mapped == 1)
	    XFreeColors(fl_display, colormap, &(fl_xmap[overlay][i].pixel), 1,
			0);
#endif //tanghao
#endif
	fl_xmap[overlay][i].mapped = 0;
    }
}

void
Fl::set_color(Fl_Color i, unsigned c)
{
    if (fl_cmap[i] != c) {
	free_color(i, 0);
#if HAVE_OVERLAY
	free_color(i, 1);
#endif
	fl_cmap[i] = c;
    }
}

#endif // end of X-specific code

unsigned
Fl::get_color(Fl_Color i)
{
    return fl_cmap[i];
}

void
Fl::set_color(Fl_Color i, uchar red, uchar green, uchar blue)
{
    Fl::set_color(i,
		  ((unsigned) red << 24) + ((unsigned) green << 16) +
		  ((unsigned) blue << 8));
}

void
Fl::get_color(Fl_Color i, uchar & red, uchar & green, uchar & blue)
{
    unsigned c = fl_cmap[i];
    red = uchar(c >> 24);
    green = uchar(c >> 16);
    blue = uchar(c >> 8);
}

Fl_Color
fl_color_average(Fl_Color color1, Fl_Color color2, float weight)
{
    Fl_Color avg;
    unsigned rgb1 = fl_cmap[color1];
    unsigned rgb2 = fl_cmap[color2];
    uchar r, g, b;

    r = (uchar) (((uchar) (rgb1 >> 24)) * weight +
		 ((uchar) (rgb2 >> 24)) * (1 - weight));
    g = (uchar) (((uchar) (rgb1 >> 16)) * weight +
		 ((uchar) (rgb2 >> 16)) * (1 - weight));
    b = (uchar) (((uchar) (rgb1 >> 8)) * weight +
		 ((uchar) (rgb2 >> 8)) * (1 - weight));

    if (r == g && r == b) {	// get it out of gray ramp
	avg = fl_gray_ramp(r * FL_NUM_GRAY / 256);
    } else {			// get it out of color cube:
	avg =
	    fl_color_cube(r * FL_NUM_RED / 256, g * FL_NUM_GREEN / 256,
			  b * FL_NUM_BLUE / 256);
    }

    return avg;
}

Fl_Color
inactive(Fl_Color c)
{
    return fl_color_average(c, FL_GRAY, .33f);
}

Fl_Color
contrast(Fl_Color fg, Fl_Color bg)
{
    int c1 = int (fl_cmap[fg]);
    int c2 = int (fl_cmap[bg]);

    if ((c1 ^ c2) & 0x80800000)
	return fg;
    else if (c2 & 0x80800000)
	return FL_GRAY_RAMP;	// black from gray ramp
    else
	return (Fl_Color) (FL_COLOR_CUBE - 1);	// white from gray ramp
}

//
// End of "$Id: fl_color.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Input.cxx ---
//
// "$Id: Fl_Input.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Input widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This is the "user interface", it decodes user actions into what to
// do to the text.  See also Fl_Input_.C, where the text is actually
// manipulated (and some ui, in particular the mouse, is done...).
// In theory you can replace this code with another subclass to change
// the keybindings.

#include <FL/Fl.H>
#include <FL/Fl_Input.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <ctype.h>

void Fl_Input::draw() {
  if (type() == FL_HIDDEN_INPUT) return;
  Fl_Boxtype b = box();
  if (damage() & FL_DAMAGE_ALL) {
    draw_box(b, color());
  }
#ifdef PDA
	if (b == FL_BOTTOM_BOX) 
		Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b)+3,
		      w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b)-6);
	else
#endif
		Fl_Input_::drawtext(x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
		      w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
}

// kludge so shift causes selection to extend:
int Fl_Input::shift_position(int p) {
  return position(p, Fl::event_state(FL_SHIFT) ? mark() : p);
}
int Fl_Input::shift_up_down_position(int p) {
  return up_down_position(p, Fl::event_state(FL_SHIFT));
}

////////////////////////////////////////////////////////////////
// Fltk "compose"
//
// This is a demonstration of a IMHO "correct" interface to compose
// character sequences.  It does not have a "dead key" effect: the
// user has feedback at all times, and sees exactly the symbol they
// will get if they stop typing at that point.  Notice that I totally
// ignore the horrid XIM extension!
//
// You only need to keep track of your normal text buffer and a
// single integer "state".  Call fl_compose() for each character
// keystroke.  The return value is the new "state" that must be passed
// the next time you call fl_compose().  It also returns the number of
// characters to delete to the left, a buffer of new characters, and
// the number of characters in that buffer.  Obey these editing
// instructions.  Reset the state to zero if the user types any
// function keys or clicks the mouse.
//
// Fl_Input does not call fl_compose unless you hit the "compose" key
// first.  It may be interesting and useful to always call it, though...

// Although this simple code is only for ISO-8859-1 character
// encodings, I think the interface can be expanded to UTF-8 (encoded
// Unicode) someday.

// This string lists a pair for each possible foreign letter in ISO-8859-1
// starting at code 0xa0 (nbsp).  If the second character is a space then
// only the first character needs to by typed:
static const char* const compose_pairs =
"  ! % # $ y=| & : c a <<~ - r _ * +-2 3 ' u p . , 1 o >>141234? "
"A`A'A^A~A:A*AEC,E`E'E^E:I`I'I^I:D-N~O`O'O^O~O:x O/U`U'U^U:Y'THss"
"a`a'a^a~a:a*aec,e`e'e^e:i`i'i^i:d-n~o`o'o^o~o:-:o/u`u'u^u:y'thy:";

int fl_compose(int state, char c, int& del, char* buffer, int& ins) {
  del = 0; ins = 1; buffer[0] = c;

  if (c == '"') c = ':';

  if (!state) {	// first character
    if (c == ' ') {buffer[0]=char(0xA0);return 0x100;} // space turns into nbsp
    // see if it is either character of any pair:
    state = 0;
    for (const char *p = compose_pairs; *p; p += 2) 
      if (p[0] == c || p[1] == c) {
	if (p[1] == ' ') buffer[0] = (p-compose_pairs)/2+0xA0;
	state = c;
      }
    return state;

  } else if (state == 0x100) { // third character
    return 0;

  } else { // second character
    char c1 = char(state); // first character
    // now search for the pair in either order:
    for (const char *p = compose_pairs; *p; p += 2) {
      if (p[0] == c && p[1] == c1 || p[1] == c && p[0] == c1) {
	buffer[0] = (p-compose_pairs)/2+0xA0;
	ins = del = 1;
	return 0x100;
      }
    }
    return 0;
  }
}

////////////////////////////////////////////////////////////////

#define CTRL_MODE  0x2
#define SHIFT_MODE 0x1
#define ALT_MODE   0x4

static int compose; // compose state (# of characters so far + 1)
static unsigned char modifier_state = 0;

static uchar shift_map[128] = {
    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
    0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
    0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,    
    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
    0x28,0x29,0x2A,0x2B,0x3C,0x5F,0x3E,0x3F,
    0x29,0x21,0x40,0x23,0x24,0x25,0x5E,0x26, /* 0 1 2 3 4 5 6 7 */
    0x2A,0x28,0x3A,0x3A,0x3C,0x2B,0x3E,0x3F, /* 8 9 : ; < = > ? */
    0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47, /* @ A B C D E F G */
    0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, /* H I J K L M N O */
    0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, /* P Q R S T U V W */
    0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x5E,0x5F, /* X Y Z [ \ ] ^ _ */
    0x7E,0x41,0x42,0x43,0x44,0x45,0x46,0x47, /* ` a b c d e f g */
    0x48,0x49,0x4A,0x4B,0x4C,0x4D,0x4E,0x4F, /* h i j k l m n o */
    0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57, /* p q r s t u v w */
    0x58,0x59,0x5A,0x7B,0x7C,0x7D,0x7E,0x7F  /* x y z { | } ~   */
};

// If you define this symbol as zero you will get the peculiar fltk
// behavior where moving off the end of an input field will move the
// cursor into the next field:
// define it as 1 to prevent cursor movement from going to next field:
#define NORMAL_INPUT_MOVE 0

#define ctrl(x) (x^0x40)

/* TODOTODO:  Keypad handling (It just ignores it right now) */

int Fl_Input::handle_key() {
  int i;

  int pcompose = compose; compose = 0;
  unsigned char key;
  unsigned char tbuf[20];

  /* printf("KEY = %d\n", (unsigned char) Fl::event_text()[0]); */

  /* Ok, so we have to map the shift key somehow...   */
  /* This is a slow and not elegant kudge.  Fix it    */

  if ((Fl::event_state(FL_SHIFT) || (modifier_state & SHIFT_MODE) == SHIFT_MODE) ||
      (Fl::event_state(FL_CAPS_LOCK)))
    {
      for(i = 0; i < Fl::event_length(); i++)
	{
	  unsigned char nkey;

	  if ((nkey = Fl::event_text()[i]) <= 128)
	    tbuf[i] = shift_map[nkey];
	  else
	    tbuf[i] = nkey;
	}

      modifier_state &= ~SHIFT_MODE;
    }
  else
    {
      for(i = 0; i < Fl::event_length(); i++)
	tbuf[i] = Fl::event_text()[i];    }

  key = tbuf[0];

  if (pcompose && Fl::event_length()) {
    char buf[20]; int ins; int del;

    /* JHC 09/20/00 - Check for shift mode here */

    compose = fl_compose(pcompose-1, key, del, buf, ins);
    if (compose) {
      replace(position(), del ? position()-del : mark(), buf, ins);
      compose++; // store value+1 so 1 can initialize compose state
      return 1;
    } else {
      if (pcompose==1)	// compose also acts as quote-next:
	return replace(position(),mark(),(char *) tbuf,Fl::event_length());
    }
  }

  if (Fl::event_state(FL_ALT|FL_META)) { // reserved for shortcuts
    compose = pcompose;
    return 0;
  }

  switch (Fl::event_key()) {
  case FL_Left:
    key = ctrl('B'); break;
  case FL_Right:
    key = ctrl('F'); break;
  case FL_Up:
    key = ctrl('P'); break;
  case FL_Down:
    key = ctrl('N'); break;
  case FL_Delete:
    key = ctrl('D'); break;
  case FL_Home:
    key = ctrl('A'); break;
  case FL_End:
    key = ctrl('E'); break;
  case FL_BackSpace:
    if (mark() != position()) cut();
    else cut(-1);
    return 1;
  case FL_Enter:
  case FL_KP_Enter:
    if (when() & FL_WHEN_ENTER_KEY) {
      position(size(), 0);
      maybe_do_callback();
      return 1;
    } else if (type() == FL_MULTILINE_INPUT)
      return replace(position(), mark(), "\n", 1);
    else 
      return 0;	// reserved for shortcuts
  case FL_Tab:
    if (Fl::event_state(FL_CTRL) || type()!=FL_MULTILINE_INPUT) return 0;
    break;
  case FL_Escape:
    return 0;	// reserved for shortcuts (Forms cleared field)

  case FL_Caps_Lock:
    return(1);

  case FL_Shift_L:
  case FL_Shift_R:
    modifier_state |= SHIFT_MODE;
    return(1);

  case FL_Control_L:
  case FL_Control_R:
    modifier_state |= CTRL_MODE;
    return(1);

  case FL_Alt_L:
  case FL_Alt_R:
    return(1);

  default:
    if (Fl::event_key() & 0xFF00)
      return(0);
  }

  if (Fl::event_state(FL_CTRL) || (modifier_state & CTRL_MODE) == CTRL_MODE)
    {
      /* For the moment, we will translate the key to uppercase */
      /* because thats what the stuff below wants.              */
      
      key = ctrl(shift_map[key]);

      /* Further ctrl-<key> presses are handled by the event state */
      modifier_state &= ~CTRL_MODE;
    }

  switch(key) {
  case 0:	// key did not translate to any text
    compose = pcompose; // allow user to hit shift keys after ^Q
    return 0;
  case ctrl('A'):
    if (type() == FL_MULTILINE_INPUT)
      for (i=position(); i && index(i-1)!='\n'; i--) ;
    else
      i = 0;
    return shift_position(i) + NORMAL_INPUT_MOVE;
  case ctrl('B'):
    return shift_position(position()-1) + NORMAL_INPUT_MOVE;
  case ctrl('C'): // copy
    return copy();
  case ctrl('D'):
    if (mark() != position()) return cut();
    else return cut(1);
  case ctrl('E'):
    if (type() == FL_MULTILINE_INPUT)
      for (i=position(); index(i) && index(i)!='\n'; i++) ;
    else
      i = size();
    return shift_position(i) + NORMAL_INPUT_MOVE;
  case ctrl('F'):
    return shift_position(position()+1) + NORMAL_INPUT_MOVE;
  case ctrl('K'):
    if (position()>=size()) return 0;
    if (type() == FL_MULTILINE_INPUT) {
      if (index(position()) == '\n')
	i = position() + 1;
      else 
	for (i=position()+1; index(i) && index(i) != '\n'; i++);
    } else
      i = size();
    cut(position(), i);
    return copy_cuts();
  case ctrl('N'):
    if (type()!=FL_MULTILINE_INPUT) return 0;
    for (i=position(); index(i)!='\n'; i++)
      if (!index(i)) return NORMAL_INPUT_MOVE;
    shift_up_down_position(i+1);
    return 1;
  case ctrl('P'):
    if (type()!=FL_MULTILINE_INPUT) return 0;
    for (i = position(); i > 0 && index(i-1) != '\n'; i--) ;
    if (!i) return NORMAL_INPUT_MOVE;
    shift_up_down_position(i-1);
    return 1;
  case ctrl('Q'):
    compose = 1;
    return 1;
  case ctrl('U'):
    return cut(0, size());
  case ctrl('V'):
  case ctrl('Y'):
    Fl::paste(*this);
    return 1;
  case ctrl('X'):
  case ctrl('W'):
    copy();
    return cut();
  case ctrl('Z'):
  case ctrl('_'):
    return undo();
  }

  // skip all illegal characters
  // this could be improved to make sure characters are inserted at
  // legal positions...
  if (type() == FL_FLOAT_INPUT) {
    if (!strchr("0123456789.eE+-", key)) return 0;
  } else if (type() == FL_INT_INPUT) {
    if (!position() && (key == '+' || key == '-'));
    else if (key >= '0' && key <= '9');
    // we allow 0xabc style hex numbers to be typed:
    else if (position()==1 && index(0)=='0' && (key == 'x' || key == 'X'));
    else if (position()>1 && index(0)=='0' && (index(1)=='x'||index(1)=='X')
           && (key>='A'&& key<='F' || key>='a'&& key<='f'));
    else return 0;
  }

  return replace(position(), mark(), (char *) tbuf, Fl::event_length());
}

int Fl_Input::handle(int event) {

  switch (event) {

  case FL_FOCUS:
    switch (Fl::event_key()) {
    case FL_Right:
      position(0);
      break;
    case FL_Left:
      position(size());
      break;
    case FL_Down:
      up_down_position(0);
      break;
    case FL_Up:
      up_down_position(size());
      break;
    case FL_Tab:
    case 0xfe20: // XK_ISO_Left_Tab
      position(size(),0);
      break;
    }
    break;

  case FL_UNFOCUS:
    compose = 0;
    break;

  case FL_KEYBOARD:
    return handle_key();

  case FL_PUSH:
    if (Fl::focus() != this) {
      Fl::focus(this);
      handle(FL_FOCUS);
      // Windoze-style: select everything on first click:
      if (type() != FL_MULTILINE_INPUT) {
        position(0, size()); // select everything
        return 1;
      }
    }
    compose = 0;
    break;

  case FL_RELEASE:
    if (Fl::event_button() == 2) {
      Fl::event_is_click(0); // stop double click from picking a word
      Fl::paste(*this);
    } else if (!Fl::event_is_click()) {
      // copy drag-selected text to the clipboard.
      //copy();
    }

    return 1;

  }
  Fl_Boxtype b = box();
  return Fl_Input_::handletext(event,
	x()+Fl::box_dx(b)+3, y()+Fl::box_dy(b),
	w()-Fl::box_dw(b)-6, h()-Fl::box_dh(b));
}

Fl_Input::Fl_Input(int x, int y, int w, int h, const char *l)
: Fl_Input_(x, y, w, h, l) {
}

//
// End of "$Id: Fl_Input.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Gl_Choice.H ---
//
// "$Id: Fl_Gl_Choice.H,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// OpenGL definitions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Internal interface to set up OpenGL.
//
// A "Fl_Gl_Choice" is used to cache results of calling the
// OpenGL code for system-specific information needed to
// implement a "mode".
// For X this is a visual, and this must be called *before*
// the X window is created.
// For win32 this can be delayed to a more convienent time,
// as it only returns information for modifying a device
// context.
// This is used by Fl_Gl_Window, gl_start(), and gl_visual()

#ifndef Fl_Gl_Choice_H
#define Fl_Gl_Choice_H

#ifdef WIN32
# include <windows.h>
# include <FL/gl.h>
# define GLXContext HGLRC
# define GLX_BUFFER_SIZE      1
# define GLX_RGBA	      2
# define GLX_GREEN_SIZE	      3
# define GLX_ALPHA_SIZE	      4
# define GLX_ACCUM_GREEN_SIZE 5
# define GLX_ACCUM_ALPHA_SIZE 6
# define GLX_DOUBLEBUFFER     7
# define GLX_DEPTH_SIZE	      8
# define GLX_STENCIL_SIZE     9
#else
# include <GL/glx.h>
#endif

// one of these structures is returned:
class Fl_Gl_Choice {
  int mode;
  const int *alist;
  Fl_Gl_Choice *next;
public:
#ifdef WIN32
  PIXELFORMATDESCRIPTOR pfd;
#else
  XVisualInfo *vis;	// the visual to use
  Colormap colormap;	// a colormap to use
#endif
  uchar r,d,o;		// rgb mode, double buffered, overlay flags
  // Return one of these structures for a given gl mode.
  // The second argument is a glX attribute list, and is used if mode is
  // zero.  This is not supported on Win32:
  static Fl_Gl_Choice *find(int mode, const int *);
};

extern GLXContext fl_first_context; // used to make all contexts share
extern GLXContext fl_current_context;

class Fl_Window;

#ifdef WIN32
// This must be called before fl_set_gl_context works:
HDC fl_private_dc(Fl_Window*, int, Fl_Gl_Choice **gp);
#endif

void fl_set_gl_context(Fl_Window*, GLXContext);
void fl_no_gl_context();

#endif

//
// End of "$Id: Fl_Gl_Choice.H,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Button.cxx ---
//
// "$Id: Fl_Button.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Group.H>
#include <stdio.h>

// There are a lot of subclasses, named Fl_*_Button.  Some of
// them are implemented by setting the type() value and testing it
// here.  This includes Fl_Radio_Button and Fl_Toggle_Button

int Fl_Button::value(int v) {
  v = v ? 1 : 0;
  oldval = v;
  clear_changed();
  if (value_ != v) {value_ = v; redraw(); return 1;}
  else return 0;
}

void Fl_Button::setonly() { // set this radio button on, turn others off
  value(1);
  Fl_Group* g = (Fl_Group*)parent();
  Fl_Widget*const* a = g->array();
  for (int i = g->children(); i--;) {
    Fl_Widget* o = *a++;
    if (o != this && o->type()==FL_RADIO_BUTTON) ((Fl_Button*)o)->value(0);
  }
}

void Fl_Button::draw() {
  if (type() == FL_HIDDEN_BUTTON) return;
  Fl_Color col = value() ? selection_color() : color();

#ifdef PDA
  if( value_ ) {
 	Fl_Color old_label_clr = labelcolor();
			
	  labelcolor(contrast(color(), labelcolor()));

	  draw_box(down(box()),selection_color());
	  draw_label();
	  labelcolor(old_label_clr);

  } else  {
    draw_box(box(), col);
    draw_label();
  }
#else
  draw_box(value() ? (down_box()?down_box():down(box())) : box(), col);
  draw_label();
#endif

}
int Fl_Button::handle(int event) {
  int newval;
  switch (event) {
  case FL_ENTER:
  case FL_LEAVE:
//  if ((value_?selection_color():color())==FL_GRAY) redraw();
    return 1;
  case FL_PUSH:
  case FL_DRAG:
    if (Fl::event_inside(this)) {
      if (type() == FL_RADIO_BUTTON) newval = 1;
      else newval = !oldval;
    } else
      newval = oldval;
    if (newval != value_) {
	   value_ = newval;
		redraw();
      if (when() & FL_WHEN_CHANGED) do_callback();
    }
    return 1;
  case FL_RELEASE:
    if (value_ == oldval) return 1;
    if (type() == FL_RADIO_BUTTON)
      setonly();
    else if (type() == FL_TOGGLE_BUTTON)
      oldval = value_;
    else {
      value(oldval);
      if (when() & FL_WHEN_CHANGED) do_callback();
    }
	 redraw();
    if (when() & FL_WHEN_RELEASE) do_callback(); else set_changed();
	 return 1;
  case FL_SHORTCUT:
    if (!(shortcut() ?
	  Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
	  if (type() == FL_RADIO_BUTTON && !value_) {
      setonly();
      if (when() & FL_WHEN_CHANGED) do_callback();
    } else if (type() == FL_TOGGLE_BUTTON) {
      value(!value());
      if (when() & FL_WHEN_CHANGED) do_callback();
    }
    if (when() & FL_WHEN_RELEASE) do_callback(); else set_changed();
    return 1;
  default:
    return 0;
  }
}

Fl_Button::Fl_Button(int x,int y,int w,int h, const char *l)
: Fl_Widget(x,y,w,h,l) {
  box(FL_UP_BOX);
  down_box(FL_NO_BOX);
  value_ = oldval = 0;
  shortcut_ = 0;
  set_flag(SHORTCUT_LABEL);
}

//
// End of "$Id: Fl_Button.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: glut_font.cxx ---
//
// "$Id: glut_font.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
//
// GLUT bitmap font routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// (sort of) emulation of Glut's bitmap drawing functions, using FL's
// font stuff.  Not all the fonts match!

#include <config.h>
#if HAVE_GL

#include <FL/glut.H>
#include <FL/gl.h>

Glut_Bitmap_Font glutBitmap9By15 = {FL_SCREEN, 15};
Glut_Bitmap_Font glutBitmap8By13 = {FL_SCREEN, 13};
Glut_Bitmap_Font glutBitmapTimesRoman10 = {FL_TIMES, 10};
Glut_Bitmap_Font glutBitmapTimesRoman24 = {FL_TIMES, 24};
Glut_Bitmap_Font glutBitmapHelvetica10 = {FL_HELVETICA, 10};
Glut_Bitmap_Font glutBitmapHelvetica12 = {FL_HELVETICA, 12};
Glut_Bitmap_Font glutBitmapHelvetica18 = {FL_HELVETICA, 18};

void glutBitmapCharacter(void *font, int character) {
  gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
  char a[1]; a[0] = character;
  gl_draw(a,1);
}

int glutBitmapWidth(int font, int character) {
  gl_font(((Glut_Bitmap_Font *)font)->font,((Glut_Bitmap_Font *)font)->size);
  return int(gl_width(character)+.5);
}

#endif

//
// End of "$Id: glut_font.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_set_font.cxx ---
//
// "$Id: fl_set_font.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Font utilities for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Add a font to the internal table.
// Also see fl_set_fonts.C which adds all possible fonts.

#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>
#include "Fl_Font.H"
#include <stdlib.h>
#include <string.h>

static int table_size;

void Fl::set_font(Fl_Font fnum, const char* name) {
  if (fnum >= table_size) {
    int i = table_size;
    if (!i) {	// don't realloc the built-in table
      table_size = 2*FL_FREE_FONT;
      i = FL_FREE_FONT;
      Fl_Fontdesc* t = (Fl_Fontdesc*)malloc(table_size*sizeof(Fl_Fontdesc));
      memcpy(t, fl_fonts, FL_FREE_FONT*sizeof(Fl_Fontdesc));
      fl_fonts = t;
    } else {
      table_size = 2*table_size;
      fl_fonts=(Fl_Fontdesc*)realloc(fl_fonts, table_size*sizeof(Fl_Fontdesc));
    }
    for (; i < table_size; i++) fl_fonts[i].name = 0;
  }
  Fl_Fontdesc* s = fl_fonts+fnum;
  if (s->name) {
    if (!strcmp(s->name, name)) {s->name = name; return;}
#ifndef WIN32
#ifndef NANO_X //tanghao
    if (s->xlist && s->n >= 0) XFreeFontNames(s->xlist);
#endif 
#endif
    for (Fl_FontSize* f = s->first; f;) {
      Fl_FontSize* n = f->next; delete f; f = n;
    }
    s->first = 0;
  }
  s->name = name;
#ifndef WIN32
  s->xlist = 0;
#endif
  s->first = 0;
}

const char* Fl::get_font(Fl_Font fnum) {return fl_fonts[fnum].name;}

//
// End of "$Id: fl_set_font.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_cutpaste_win32.cxx ---
//
// "$Id: Fl_cutpaste_win32.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// WIN32 cut/paste for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implementation of cut and paste.

// This is seperated from Fl.C mostly to test Fl::add_handler().
// But this will save a small amount of code size in a program that
// has no text editing fields or other things that call cut or paste.

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Widget.H>
#include <string.h>
#include <stdio.h>

static char *selection_buffer;
static int selection_length;
static int selection_buffer_length;
static char beenhere;

extern Fl_Widget *fl_selection_requestor; // widget doing request_paste()

static int selection_xevent_handler(int) {

  switch (fl_msg.message) {

  case WM_DESTROYCLIPBOARD: {
      Fl_Window *w = Fl::first_window();
      while (w != (Fl_Window *)0)
        if (fl_msg.hwnd == fl_xid(w)) break;
        else w = Fl::next_window(w);

      if (w == (Fl_Window *)0) {
        Fl::selection_owner(0);
        Fl::flush(); // get the redraw to happen
      }
      return 1;
    }

  case WM_RENDERALLFORMATS:
    if (!OpenClipboard(fl_xid(Fl::first_window()))) return 0;
    EmptyClipboard();
    // fall through...
  case WM_RENDERFORMAT: {
    HANDLE h = GlobalAlloc(GHND, selection_length+1);
    if (h) {
      LPSTR p = (LPSTR)GlobalLock(h);
      memcpy(p, selection_buffer, selection_length);
      p[selection_length] = 0;
      GlobalUnlock(h);
      SetClipboardData(CF_TEXT, h);
    }
    if (fl_msg.message == WM_RENDERALLFORMATS)
      CloseClipboard();
    return 1;}

  default:
    return 0;
  }
}

////////////////////////////////////////////////////////////////

// call this when you create a selection:
void Fl::selection(Fl_Widget &owner, const char *stuff, int len) {
  if (!stuff || len<0) return;
  if (len+1 > selection_buffer_length) {
    delete[] selection_buffer;
    selection_buffer = new char[len+100];
    selection_buffer_length = len+100;
  }
  memcpy(selection_buffer, stuff, len);
  selection_buffer[len] = 0; // needed for direct paste
  selection_length = len;
  if (OpenClipboard(fl_xid(Fl::first_window()))) {
    EmptyClipboard();
    SetClipboardData(CF_TEXT, NULL);
    CloseClipboard();
    if (!beenhere) {
      Fl::add_handler(selection_xevent_handler);
      beenhere = 1;
    }
  }
  selection_owner(&owner);
}

////////////////////////////////////////////////////////////////

// Call this when a "paste" operation happens:
void Fl::paste(Fl_Widget &receiver) {
  if (selection_owner()) {
    // We already have it, do it quickly without window server.
    // Notice that the text is clobbered if set_selection is
    // called in response to FL_PASTE!
    Fl::e_text = selection_buffer;
    Fl::e_length = selection_length;
    receiver.handle(FL_PASTE);
  } else {
    if (!OpenClipboard(fl_xid(Fl::first_window()))) return;
    HANDLE h = GetClipboardData(CF_TEXT);
    if (h) {
      Fl::e_text = (LPSTR)GlobalLock(h);
      LPSTR a,b;
      a = b = Fl::e_text;
      while (*a) { // strip the CRLF pairs ($%$#@^)
	if (*a == '\r' && a[1] == '\n') a++;
	else *b++ = *a++;
      }
      *b = 0;
      Fl::e_length = b - Fl::e_text;
      receiver.handle(FL_PASTE);
      GlobalUnlock(h);
    }
    CloseClipboard();
  }
}

//
// End of "$Id: Fl_cutpaste_win32.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_timer.cxx ---
//
// "$Id: forms_timer.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms timer object for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Emulate the Forms Timer object
// You don't want to use this if you just want a timeout, call
// Fl::add_timeout directly!

#include <FL/Fl.H>
#include <FL/Fl_Timer.H>
#include <FL/fl_draw.H>
#ifdef WIN32
# include <sys/types.h> 
# include <sys/timeb.h>
#else
# include <sys/time.h>
#endif
#include <stdio.h>

#define FL_TIMER_BLINKRATE	0.2

void fl_gettime(long* sec, long* usec) {
#ifdef WIN32
  struct timeb tp;
  ftime(&tp);
  *sec = tp.time;
  *usec = tp.millitm * 1000;
#else
  struct timeval tp;
  struct timezone tzp;
  gettimeofday(&tp, &tzp);
  *sec = tp.tv_sec;
  *usec = tp.tv_usec;
#endif
}

void Fl_Timer::draw() {
  int tt;
  Fl_Color col;
  char str[32];
  if (!on || delay>0.0)
    col = color();
  else if ((int) (delay / FL_TIMER_BLINKRATE) % 2)
    col = color();
  else
    col = selection_color();
  draw_box(box(), col);
  if (type() == FL_VALUE_TIMER && delay>0.0) {
    double d = direction_ ? total-delay : delay;
    if (d < 60.0)
      sprintf(str, "%.1f", d);
    else {
      tt = (int) ((d+0.05) / 60.0);
      sprintf(str, "%d:%04.1f", tt, d - 60.0 * tt);
    }
    fl_font(labelfont(), labelsize());
    fl_color(labelcolor());
    fl_draw(str, x(), y(), w(), h(), FL_ALIGN_CENTER);
  } else
    draw_label();
}

void Fl_Timer::stepcb(void* v) {
  ((Fl_Timer*)v)->step();
}

void Fl_Timer::step() {
  if (!on) return;
  double lastdelay = delay;
  long sec, usec; fl_gettime(&sec, &usec);
  delay -= (double) (sec - lastsec) + (double) (usec - lastusec) / 1000000.0;
  lastsec = sec; lastusec = usec;
  if (lastdelay > 0.0 && delay <= 0.0) {
    if (type() == FL_HIDDEN_TIMER) {
      on = 0;
      delay = 0;
    } else {
      redraw();
      Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
    }
    do_callback();
  } else {
    if (type() == FL_VALUE_TIMER) redraw();
    Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
  }
}

int Fl_Timer::handle(int event) {
  if (event == FL_RELEASE && delay <= 0) value(0.0);
  return 0;
}

Fl_Timer::~Fl_Timer() {
  Fl::remove_timeout(stepcb, this);
}

Fl_Timer::Fl_Timer(uchar t, int x, int y, int w, int h, const char* l)
: Fl_Widget(x, y, w, h, l) {
  box(FL_DOWN_BOX);
  selection_color(FL_RED);
  delay = 0;
  on = 0;
  direction_ = 0;
  type(t);
  if (t == FL_HIDDEN_TIMER) clear_visible();
  if (t == FL_VALUE_TIMER) align(FL_ALIGN_LEFT);
}

void Fl_Timer::value(double d) {
  delay = total = d;
  on = (d > 0.0);
  fl_gettime(&(lastsec), &(lastusec));
  if (type() != FL_HIDDEN_TIMER) redraw();
  Fl::remove_timeout(stepcb, this);
  if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
}

void Fl_Timer::suspended(char d) {
  if (!d) {
    if (on) return;
    on = (delay > 0.0);
    fl_gettime(&(lastsec), &(lastusec));
    if (on) Fl::add_timeout(FL_TIMER_BLINKRATE, stepcb, this);
  } else {
    if (!on) return;
    on = 0;
    Fl::remove_timeout(stepcb, this);
  }
}

//
// End of "$Id: forms_timer.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu_add.cxx ---
//
// "$Id: Fl_Menu_add.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Menu utilities for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Methods to alter the menu in an Fl_Menu_ widget.

// These are for Forms emulation and for dynamically changing the
// menus.  They are in this source file so they are not linked in if
// not used, which is what will happen if the the program only uses
// constant menu tables.

// Not at all guaranteed to be Forms compatable, especially with any
// string with a % sign in it!

#include <FL/Fl_Menu_.H>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

// If the array is this, we will double-reallocate as necessary:
static Fl_Menu_Item* local_array = 0;
static int local_array_alloc = 0; // number allocated
static int local_array_size = 0; // == size(local_array)
extern Fl_Menu_* fl_menu_array_owner; // in Fl_Menu_.cxx

// For historical reasons there are matching methods that work on a
// user-allocated array of Fl_Menu_Item.  These methods are quite
// depreciated and should not be used.  These old methods use the
// above pointers to detect if the array belongs to an Fl_Menu_
// widget, and if so it reallocates as necessary.

// Insert a single Fl_Menu_Item into an array of size at offset n,
// if this is local_array it will be reallocated if needed.
static Fl_Menu_Item* insert(
  Fl_Menu_Item* array, int size,
  int n,
  const char *text,
  int flags
) {
  if (array == local_array && size >= local_array_alloc) {
    local_array_alloc = 2*size;
    Fl_Menu_Item* newarray = new Fl_Menu_Item[local_array_alloc];
    memmove(newarray, array, size*sizeof(Fl_Menu_Item));
    delete[] local_array;
    local_array = array = newarray;
  }
  // move all the later items:
  memmove(array+n+1, array+n, sizeof(Fl_Menu_Item)*(size-n));
  // create the new item:
  Fl_Menu_Item* m = array+n;
  m->text = text ? strdup(text) : 0;
  m->shortcut_ = 0;
  m->callback_ = 0;
  m->user_data_ = 0;
  m->flags = flags;
  m->labeltype_ = m->labelfont_ = m->labelsize_ = m->labelcolor_ = 0;
  return array;
}

// Add an item.  The text is split at '|' characters to automatically
// produce submenus (actually a totally unnecessary feature as you can
// now add submenu titles directly by setting SUBMENU in the flags):
int Fl_Menu_Item::add(
  const char *text,
  int shortcut,
  Fl_Callback *cb,	
  void *data,
  int flags
) {
  Fl_Menu_Item *array = this;
  Fl_Menu_Item *m = this;
  const char *p;
  char *q;
  char buf[1024];

  int size = array==local_array ? local_array_size : array->size();
  int flags1 = 0;
  char* item;
  for (;;) {    /* do all the supermenus: */

    /* fill in the buf with name, changing \x to x: */
    q = buf;
    for (p=text; *p && *p != '/'; *q++ = *p++) if (*p=='\\') p++;
    *q = 0;

    item = buf;
    if (*item == '_') {item++; flags1 = FL_MENU_DIVIDER;}
    if (*p != '/') break; /* not a menu title */
    text = p+1;	/* point at item title */

    /* find a matching menu title: */
    for (; m->text; m = m->next())
      if (m->flags&FL_SUBMENU && !strcmp(item, m->text)) break;

    if (!m->text) { /* create a new menu */
      int n = m-array;
      array = insert(array, size, n, item, FL_SUBMENU|flags1);
      size++;
      array = insert(array, size, n+1, 0, 0);
      size++;
      m = array+n;
    }
    m++;	/* go into the submenu */
    flags1 = 0;
  }

  /* find a matching menu item: */
  for (; m->text; m = m->next())
    if (!strcmp(m->text,item)) break;

  if (!m->text) {	/* add a new menu item */
    int n = m-array;
    array = insert(array, size, n, item, flags|flags1);
    size++;
    if (flags & FL_SUBMENU) { // add submenu delimiter
      array = insert(array, size, n+1, 0, 0);
      size++;
    }
    m = array+n;
  }

  /* fill it in */
  m->shortcut_ = shortcut;
  m->callback_ = cb;
  m->user_data_ = data;
  m->flags = flags|flags1;

  if (array == local_array) local_array_size = size;
  return m-array;
}

int Fl_Menu_::add(const char *t, int s, Fl_Callback *c,void *v,int f) {
  // make this widget own the local array:
  if (this != fl_menu_array_owner) {
    if (fl_menu_array_owner) {
      Fl_Menu_* o = fl_menu_array_owner;
      // the previous owner get's its own correctly-sized array:
      int value_offset = o->value_-local_array;
      int n = local_array_size;
      Fl_Menu_Item* newMenu = o->menu_ = new Fl_Menu_Item[n];
      memcpy(newMenu, local_array, n*sizeof(Fl_Menu_Item));
      if (o->value_) o->value_ = newMenu+value_offset;
    }
    if (menu_) {
      // this already has a menu array, use it as the local one:
      delete[] local_array;
      if (!alloc) copy(menu_); // duplicate a user-provided static array
      // add to the menu's current array:
      local_array_alloc = local_array_size = size();
      local_array = menu_;
    } else {
      // start with a blank array:
      alloc = 2; // indicates that the strings can be freed
      if (local_array) {
	menu_ = local_array;
      } else {
	local_array_alloc = 15;
	local_array = menu_ = new Fl_Menu_Item[local_array_alloc];
      }
      menu_[0].text = 0;
      local_array_size = 1;
    }
    fl_menu_array_owner = this;
  }
  int r = menu_->add(t,s,c,v,f);
  // if it rellocated array we must fix the pointer:
  int value_offset = value_-menu_;
  menu_ = local_array; // in case it reallocated it
  if (value_) value_ = menu_+value_offset;
  return r;
}

// This is a Forms (and SGI GL library) compatable add function, it
// adds many menu items, with '|' seperating the menu items, and tab
// seperating the menu item names from an optional shortcut string.
int Fl_Menu_::add(const char *str) {
  char buf[128];
  int r = 0;
  while (*str) {
    int shortcut = 0;
    char *c;
    for (c = buf; *str && *str != '|'; str++) {
      if (*str == '\t') {*c++ = 0; shortcut = fl_old_shortcut(str);}
      else *c++ = *str;
    }
    *c = 0;
    r = add(buf, shortcut, 0, 0, 0);
    if (*str) str++;
  }
  return r;
}

void Fl_Menu_::replace(int i, const char *str) {
  if (i<0 || i>=size()) return;
  if (!alloc) copy(menu_);
  if (alloc > 1) {
    free((void *)menu_[i].text);
    str = strdup(str);
  }
  menu_[i].text = str;
}

void Fl_Menu_::remove(int i) {
  int n = size();
  if (i<0 || i>=n) return;
  if (!alloc) copy(menu_);
  if (alloc > 1) free((void *)menu_[i].text);
  memmove(&menu_[i],&menu_[i+1],(n-i)*sizeof(Fl_Menu_Item));
}

//
// End of "$Id: Fl_Menu_add.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Tabs.cxx ---
//
// "$Id: Fl_Tabs.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Tab widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This is the "file card tabs" interface to allow you to put lots and lots
// of buttons and switches in a panel, as popularized by many toolkits.

// Each child widget is a card, and it's label() is printed on the card tab.
// Clicking the tab makes that card visible.

#include <FL/Fl.H>
#include <FL/Fl_Tabs.H>
#include <FL/fl_draw.H>

#define BORDER 10
#define TABSLOPE 8

// return the left edges of each tab (plus a fake left edge for a tab
// past the right-hand one).  These position are actually of the left
// edge of the slope.  They are either seperated by the correct distance
// or by TABSLOPE or by zero.
// Return value is the index of the selected item.

int Fl_Tabs::tab_positions(int* p, int* w) {
  int selected = -1;
  Fl_Widget*const* a = array();
  int i;
  p[0] = 0;
  for (i=0; i<children(); i++) {
    Fl_Widget* o = *a++;
    if (o->visible()) selected = i;
    if (o->label()) {
      int wt = 0; int ht = 0; o->measure_label(wt,ht);
      w[i] = wt+TABSLOPE;
      if (2*TABSLOPE > w[i]) w[i] = 2*TABSLOPE;
    } else 
      w[i] = 2*TABSLOPE;
    p[i+1] = p[i]+w[i];
  }
  int r = this->w()-TABSLOPE-1;
  if (p[i] <= r) return selected;
  // uh oh, they are too big:
  // pack them against right edge:
  p[i] = r;
  for (i = children(); i--;) {
    int l = r-w[i];
    if (p[i+1]-TABSLOPE < l) l = p[i+1]-TABSLOPE;
    if (p[i] <= l) break;
    p[i] = l;
    r -= TABSLOPE;
  }
  // pack them against left edge and truncate width if they still don't fit:
  for (i = 0; i<children(); i++) {
    if (p[i] >= i*TABSLOPE) break;
    p[i] = i*TABSLOPE;
    int W = this->w()-1-TABSLOPE*(children()-i) - p[i];
    if (w[i] > W) w[i] = W;
  }
  // adjust edges according to visiblity:
  for (i = children(); i > selected; i--) {
    p[i] = p[i-1]+w[i-1];
  }
  return selected;
}

// return space needed for tabs.  Negative to put them on the bottom:
int Fl_Tabs::tab_height() {
  int H = h();
  int H2 = y();
  Fl_Widget*const* a = array();
  for (int i=children(); i--;) {
    Fl_Widget* o = *a++;
    if (o->y() < y()+H) H = o->y()-y();
    if (o->y()+o->h() > H2) H2 = o->y()+o->h();
  }
  H2 = y()+h()-H2;
  if (H2 > H) {
    H = H2-Fl::box_dy(box());
    return (H <= 0) ? 0 : -H;
  } else {
    H = H-Fl::box_dy(box());
    return (H <= 0) ? 0 : H;
  }
}

// this is used by fluid to pick tabs:
Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
  int H = tab_height();
  if (H < 0) {
    if (event_y > y()+h() || event_y < y()+h()+H) return 0;
  } else {
    if (event_y > y()+H || event_y < y()) return 0;
  }
  if (event_x < x()) return 0;
  int p[128], w[128];
  int selected = tab_positions(p, w);
  int d = (event_y-(H>=0?y():y()+h()))*TABSLOPE/H;
  for (int i=0; i<children(); i++) {
    if (event_x < x()+p[i+1]+(i<selected ? TABSLOPE-d : d)) return child(i);
  }
  return 0;
}

int Fl_Tabs::handle(int event) {

  Fl_Widget *o;

  switch (event) {

  case FL_PUSH: {
    int H = tab_height();
    if (H >= 0) {
      if (Fl::event_y() > y()+H) goto DEFAULT;
    } else {
      if (Fl::event_y() < y()+h()+H) goto DEFAULT;
    }}
  case FL_DRAG:
  case FL_RELEASE:
    o = which(Fl::event_x(), Fl::event_y());
    if (event == FL_RELEASE) {push(0); if (o && value(o)) do_callback();}
    else push(o);
    return 1;

  default:
  DEFAULT:
    return Fl_Group::handle(event);

  }
}

int Fl_Tabs::push(Fl_Widget *o) {
  if (push_ == o) return 0;
  if (push_ && !push_->visible() || o && !o->visible())
    damage(FL_DAMAGE_EXPOSE);
  push_ = o;
  return 1;
}

// The value() is the first visible child (or the last child if none
// are visible) and this also hides any other children.
// This allows the tabs to be deleted, moved to other groups, and
// show()/hide() called without it screwing up.
Fl_Widget* Fl_Tabs::value() {
  Fl_Widget* v = 0;
  Fl_Widget*const* a = array();
  for (int i=children(); i--;) {
    Fl_Widget* o = *a++;
    if (v) o->hide();
    else if (o->visible()) v = o;
    else if (!i) {o->show(); v = o;}
  }
  return v;
}

// Setting the value hides all other children, and makes this one
// visible, iff it is really a child:
int Fl_Tabs::value(Fl_Widget *newvalue) {
  Fl_Widget*const* a = array();
  for (int i=children(); i--;) {
    Fl_Widget* o = *a++;
    if (o == newvalue) {
      if (o->visible()) return 0; // no change
      o->show();
    } else {
      o->hide();
    }
  }
  return 1;
}

enum {LEFT, RIGHT, SELECTED};

void Fl_Tabs::draw() {
  Fl_Widget *v = value();
  int H = tab_height();
  if (damage() & FL_DAMAGE_ALL) { // redraw the entire thing:
    fl_clip(x(), y()+(H>=0?H:0), w(), h()-(H>=0?H:-H));
    draw_box(box(), x(), y(), w(), h(), v ? v->color() : color());
    fl_pop_clip();
    if (v) draw_child(*v);
  } else { // redraw the child
    if (v) update_child(*v);
  }
  if (damage() & (FL_DAMAGE_EXPOSE|FL_DAMAGE_ALL)) {
    int p[128]; int w[128];
    int selected = tab_positions(p,w);
    int i;
    Fl_Widget*const* a = array();
    for (i=0; i<selected; i++)
      draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], LEFT);
    for (i=children()-1; i > selected; i--)
      draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], RIGHT);
    if (v) {
      i = selected;
      draw_tab(x()+p[i], x()+p[i+1], w[i], H, a[i], SELECTED);
    } else {
      // draw the edge when no selection:
      fl_color(H >= 0 ? FL_LIGHT3 : FL_DARK3);
      fl_xyline(x(), H >= 0 ? y()+H : y()+h()+H, x()+this->w());
    }
  }
}

void Fl_Tabs::draw_tab(int x1, int x2, int W, int H, Fl_Widget* o, int what) {
  if (x2 < x1+W) {
    if (what == LEFT) {
      if (x1+W < x2+TABSLOPE) x2 = x1+W;
      else x2 += TABSLOPE;
    } else {
      if (x1+W < x2+TABSLOPE) x1 = x2-W;
      else x1 -= TABSLOPE;
    }
  }
  int sel = (what == SELECTED);
  fl_color(o->color());
  if (H >= 0) {
    fl_polygon(x1, y()+H+sel, x1+TABSLOPE, y(), x2, y(),
	       x2+TABSLOPE, y()+H+sel);
    fl_color(!sel && o==push_ ? FL_DARK3 : FL_LIGHT3);
#ifdef PDA
	 fl_color(FL_BLACK);
#endif
	 fl_line(x1, y()+H, x1+TABSLOPE, y(), x2, y());
    if (sel) {
      if (x1>x()) fl_xyline(x(), y()+H, x1);
      if (x2+TABSLOPE < x()+w()-1) fl_xyline(x2+TABSLOPE, y()+H, x()+w()-1);
    }

    fl_color(!sel && o==push_ ? FL_LIGHT3 : FL_DARK3);
#ifdef PDA
	 fl_color(FL_BLACK);
#endif
	 fl_line(x2, y(), x2+TABSLOPE, y()+H);
  } else {
    fl_polygon(x1, y()+h()+H-sel, x1+TABSLOPE, y()+h(), x2, y()+h(),
	       x2+TABSLOPE, y()+h()+H-sel);
    fl_color(!sel && o==push_ ? FL_LIGHT3 : FL_DARK3);
#ifdef PDA
	 fl_color(FL_BLACK);
#endif
    fl_line(x1+TABSLOPE, y()+h()-1, x2, y()+h()-1, x2+TABSLOPE, y()+h()+H);
    if (sel) {
      if (x1>x()) fl_xyline(x(), y()+h()+H, x1);
      if (x2+TABSLOPE < x()+w()-1) fl_xyline(x2+TABSLOPE, y()+h()+H,x()+w()-1);
    }
    fl_color(!sel && o==push_ ? FL_DARK3 : FL_LIGHT3);
#ifdef PDA
	 fl_color(FL_BLACK);
#endif
    fl_line(x1, y()+h()+H, x1+TABSLOPE, y()+h()-1);
  }
  if (W > TABSLOPE)
    o->draw_label(what==LEFT ? x1+TABSLOPE : x2-W+TABSLOPE,
		  y()+(H<0?h()+H-3:0), W-TABSLOPE,
		  (H<0?-H:H)+3, FL_ALIGN_CENTER);
}

Fl_Tabs::Fl_Tabs(int X,int Y,int W, int H, const char *l) :
  Fl_Group(X,Y,W,H,l)
{
  box(FL_THIN_UP_BOX);
  push_ = 0;
}

//
// End of "$Id: Fl_Tabs.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_curve.cxx ---
//
// "$Id: fl_curve.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Bezier curve functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Utility for drawing Bezier curves, adding the points to
// the current fl_begin/fl_vertex/fl_end path.
// Incremental math implementation:
// I very much doubt this is optimal!  From Foley/vanDam page 511.
// If anybody has a better algorithim, please send it!

#include <FL/fl_draw.H>
#include <math.h>

void fl_curve(double X0, double Y0,
	      double X1, double Y1,
	      double X2, double Y2,
	      double X3, double Y3) {
  double x = fl_transform_x(X0,Y0);
  double y = fl_transform_y(X0,Y0);
  double x1 = fl_transform_x(X1,Y1);
  double y1 = fl_transform_y(X1,Y1);
  double x2 = fl_transform_x(X2,Y2);
  double y2 = fl_transform_y(X2,Y2);
  double x3 = fl_transform_x(X3,Y3);
  double y3 = fl_transform_y(X3,Y3);

  int n; { // find smaller size of bounding box
    double lx = x; if (x1<lx) lx=x1; if (x2<lx) lx=x2; if (x3<lx) lx=x3;
    double rx = x; if (x1>rx) rx=x1; if (x2>rx) rx=x2; if (x3>rx) rx=x3;
    double ly = y; if (y1<ly) ly=y1; if (y2<ly) ly=y2; if (y3<ly) ly=y3;
    double ry = y; if (y1>ry) ry=y1; if (y2>ry) ry=y2; if (y3>ry) ry=y3;
    // calculate number of pieces to cut curve into:
    n = int((rx-lx+ry-ly)/8); if (n < 3) n = 3;
  }
  double e = 1.0/n;

  // calculate the coefficients of 3rd order equation:
  double xa = (x3-3*x2+3*x1-x);
  double xb = 3*(x2-2*x1+x);
  double xc = 3*(x1-x);
  // calculate the forward differences:
  double dx1 = ((xa*e+xb)*e+xc)*e;
  double dx3 = 6*xa*e*e*e;
  double dx2 = dx3 + 2*xb*e*e;

  // calculate the coefficients of 3rd order equation:
  double ya = (y3-3*y2+3*y1-y);
  double yb = 3*(y2-2*y1+y);
  double yc = 3*(y1-y);
  // calculate the forward differences:
  double dy1 = ((ya*e+yb)*e+yc)*e;
  double dy3 = 6*ya*e*e*e;
  double dy2 = dy3 + 2*yb*e*e;

  // draw point 0:
  fl_transformed_vertex(x,y);

  // draw points 1 .. n-2:
  for (int m=2; m<n; m++) {
    x += dx1;
    dx1 += dx2;
    dx2 += dx3;
    y += dy1;
    dy1 += dy2;
    dy2 += dy3;
    fl_transformed_vertex(x,y);
  }

  // draw point n-1:
  fl_transformed_vertex(x+dx1, y+dy1);

  // draw point n:
  fl_transformed_vertex(x3,y3);
}

//
// End of "$Id: fl_curve.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Bitmap.cxx ---
//
// "$Id: Fl_Bitmap.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Bitmap drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Bitmap.H>

void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
  // account for current clip region (faster on Irix):
  int X,Y,W,H; fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
  cx += X-XP; cy += Y-YP;
  // clip the box down to the size of image, quit if empty:
  if (cx < 0) {W += cx; X -= cx; cx = 0;}
  if ((cx+W) > w) W = w-cx;
  if (W <= 0) return;
  if (cy < 0) {H += cy; Y -= cy; cy = 0;}
  if ((cy+H) > h) H = h-cy;
  if (H <= 0) return;
#ifdef WIN32
  if (!id) {
    // we need to pad the lines out to words & swap the bits
    // in each byte.
    int w1 = (w+7)/8;
    int w2 = ((w+15)/16)*2;
    uchar* newarray = new uchar[w2*h];
    const uchar* src = array;
    uchar* dest = newarray;
    static uchar reverse[16] =	/* Bit reversal lookup table */
  		{ 0x00, 0x88, 0x44, 0xcc, 0x22, 0xaa, 0x66, 0xee,
		  0x11, 0x99, 0x55, 0xdd, 0x33, 0xbb, 0x77, 0xff };
    for (int y=0; y < h; y++) {
      for (int n = 0; n < w1; n++, src++)
	*dest++ = (reverse[*src & 0x0f] & 0xf0) |
	          (reverse[(*src >> 4) & 0x0f] & 0x0f);
      dest += w2-w1;
    }
    id = (ulong)CreateBitmap(w, h, 1, 1, newarray);
    array = newarray; // keep the pointer so I can free it later
  }
  HDC tempdc = CreateCompatibleDC(fl_gc);
  SelectObject(tempdc, (HGDIOBJ)id);
  SelectObject(fl_gc, fl_brush());
  // secret bitblt code found in old MSWindows reference manual:
  BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
  DeleteDC(tempdc);
#else
#if defined(NANO_X)
#if 1
  // basically as contributed by Vladimir Cotfas <unix_router at yahoo.com>
  // tweaked asthetically by SDR
  if (!id) // decode the bitmap into memory
  {
    int k = 0;
    int w1 = (w+7)/8;
    int w2 = ((w+15)/16)*2;

    uchar * new_array = new uchar [ w2 * h ];

    static uchar reverse_table [ 16 ] = // bit reversal lookup table
    {
      0x00, 0x88, 0x44, 0xCC, 0x22, 0xAA, 0x66, 0xEE,
      0x11, 0x99, 0x55, 0xDD, 0x33, 0xBB, 0x77, 0xFF
    };

    if (w < 8)
    {
      for ( int y = 0; y < h; ++y )
      {
        char p = array[y];
        new_array[k] = 0;
        new_array[k+1] =
          (reverse_table[ p    &0x0F] & 0xF0) |
          (reverse_table[(p>>4)&0x0F] & 0x0F);
        k += 2;
      }
    }
    else
    {
      uchar * dest = new_array;
      for ( int y = 0; y < h; ++y )
      {
        for ( int n = 0; n < w1; ++n, ++k )
	{
          uchar p = array[k + ((n % 2) ? -1 : 1)];
          *dest++ = 
            (reverse_table[ p    &0x0F] & 0xF0) |
	    (reverse_table[(p>>4)&0x0F] & 0x0F);
	}
        dest += w2-w1;
      }
    }
    id = (ulong)new_array;
  }
  {
    // if you don't set this the first time the bitmap is drawn in test/bitmap.cxx the background color is wrong (WHITE): all subsequent draws are correct -- why?
    GrSetGCUseBackground(fl_gc,false);
  }
  GrBitmap(fl_window,fl_gc,X,Y,W,H,(GR_BITMAP*)id);
#endif
#else
  if (!id) id = XCreateBitmapFromData(fl_display, fl_window,
				      (const char*)array, (w+7)&-8, h);
  XSetStipple(fl_display, fl_gc, id);
  int ox = X-cx; if (ox < 0) ox += w;
  int oy = Y-cy; if (oy < 0) oy += h;
  XSetTSOrigin(fl_display, fl_gc, ox, oy);
  XSetFillStyle(fl_display, fl_gc, FillStippled);
  XFillRectangle(fl_display, fl_window, fl_gc, X, Y, W, H);
  XSetFillStyle(fl_display, fl_gc, FillSolid);
#endif
#endif
}

Fl_Bitmap::~Fl_Bitmap() {
#ifdef WIN32
  if (id) {
    DeleteObject((HGDIOBJ)id);
    delete[] (uchar*)array;
  }
#else
#if defined(NANO_X)
  if (id) delete [] ((uchar*)id);
#else
  if (id) fl_delete_offscreen((Fl_Offscreen)id);
#endif
#endif
}

static void bitmap_labeltype(
    const Fl_Label* o, int x, int y, int w, int h, Fl_Align a)
{
  Fl_Bitmap* b = (Fl_Bitmap*)(o->value);
  int cx;
  if (a & FL_ALIGN_LEFT) cx = 0;
  else if (a & FL_ALIGN_RIGHT) cx = b->w-w;
  else cx = (b->w-w)/2;
  int cy;
  if (a & FL_ALIGN_TOP) cy = 0;
  else if (a & FL_ALIGN_BOTTOM) cy = b->h-h;
  else cy = (b->h-h)/2;
  fl_color((Fl_Color)o->color);
  b->draw(x,y,w,h,cx,cy);
}

static void bitmap_measure(const Fl_Label* o, int& w, int& h) {
  Fl_Bitmap* b = (Fl_Bitmap*)(o->value);
  w = b->w;
  h = b->h;
}

void Fl_Bitmap::label(Fl_Widget* o) {
  Fl::set_labeltype(_FL_BITMAP_LABEL, bitmap_labeltype, bitmap_measure);
  o->label(_FL_BITMAP_LABEL, (const char*)this);
}

void Fl_Bitmap::label(Fl_Menu_Item* o) {
  Fl::set_labeltype(_FL_BITMAP_LABEL, bitmap_labeltype, bitmap_measure);
  o->label(_FL_BITMAP_LABEL, (const char*)this);
}

//
// End of "$Id: Fl_Bitmap.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_overlay_visual.cxx ---
//
// "$Id: fl_overlay_visual.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// X overlay support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Return an overlay visual, if any.  Also allocate a colormap and
// record the depth for fl_color() to use.
// Another disgusting X interface, based on code extracted and
// purified with great difficulty from XLayerUtil.C:

#include <config.h>
#if HAVE_OVERLAY
#include <FL/Fl.H>
#include <FL/x.H>

// SERVER_OVERLAY_VISUALS property element:
struct OverlayInfo {
  long overlay_visual;
  long transparent_type;
  long value;
  long layer;
};

extern Colormap fl_overlay_colormap;
extern XVisualInfo* fl_overlay_visual;
extern ulong fl_transparent_pixel;

XVisualInfo *fl_find_overlay_visual() {
  static char beenhere;
  if (beenhere) return fl_overlay_visual;
  beenhere = 1;

  fl_open_display();
  Atom overlayVisualsAtom =
    XInternAtom(fl_display,"SERVER_OVERLAY_VISUALS",1);
  if (!overlayVisualsAtom) return 0;
  OverlayInfo *overlayInfo;
  ulong sizeData, bytesLeft;
  Atom actualType;
  int actualFormat;
  if (XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
			 overlayVisualsAtom, 0L, 10000L, False,
			 overlayVisualsAtom, &actualType, &actualFormat,
			 &sizeData, &bytesLeft,
			 (unsigned char **) &overlayInfo)) return 0;

  if (actualType == overlayVisualsAtom && actualFormat == 32) {
    int n = int(sizeData/4);
    XVisualInfo* v = 0;
    // find the greatest depth that has a transparent pixel:
    for (int i = 0; i < n; i++) {
      if (overlayInfo[i].transparent_type != 1) continue;
      if (overlayInfo[i].layer <= 0) continue;
      XVisualInfo templt;
      templt.visualid = overlayInfo[i].overlay_visual;
      int num;
      XVisualInfo *v1=XGetVisualInfo(fl_display, VisualIDMask, &templt, &num);
      if (v1->screen == fl_screen && 
	  !v1->red_mask && (!v || v1->depth >= v->depth && v1->depth <= 8)) {
	if (v) XFree((char*)v);
	v = v1;
	fl_transparent_pixel = overlayInfo[i].value;
      } else {
	XFree((char*)v1);
      }
    }
    if (v) {
      fl_overlay_visual = v;
      fl_overlay_colormap = 
	XCreateColormap(fl_display, RootWindow(fl_display, fl_screen),
			v->visual, AllocNone);
    }
  }
  XFree((char*)overlayInfo);
  //  printf("overlay visual %d selected\n", fl_overlay_visual->visualid);
  return fl_overlay_visual;
}

#endif

//
// End of "$Id: fl_overlay_visual.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Valuator.cxx ---
//
// "$Id: Fl_Valuator.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Valuator widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Base class for sliders and all other one-value "knobs"

#include <FL/Fl.H>
#include <FL/Fl_Valuator.H>
#include <FL/math.h>
#include <stdio.h>

Fl_Valuator::Fl_Valuator(int X, int Y, int W, int H, const char* L)
  : Fl_Widget(X,Y,W,H,L) {
  align(FL_ALIGN_BOTTOM);
  when(FL_WHEN_CHANGED);
  value_ = 0;
  min = 0;
  max = 1;
  A = 0.0;
  B = 1;
}

const double epsilon = 1e-12 ;

void Fl_Valuator::step(double s) {
  if (s < 0) s = -s;
  A = rint(s);
  B = 1;
  while (fabs(s-A/B) > epsilon) {B *= 10; A = rint(s*B);}
}

void Fl_Valuator::precision(int p) {
  A = 1.0;
  for (B = 1; p--;) B *= 10;
}

void Fl_Valuator::value_damage() {damage(FL_DAMAGE_EXPOSE);} // by default do partial-redraw

int Fl_Valuator::value(double v) {
  clear_changed();
  if (v == value_) return 0;
  value_ = v;
  value_damage();
  return 1;
}

double Fl_Valuator::softclamp(double v) {
  int which = (min<=max);
  double p = previous_value_;
  if ((v<min)==which && p!=min && (p<min)!=which) return min;
  else if ((v>max)==which && p!=max && (p>max)!=which) return max;
  else return v;
}

// inline void Fl_Valuator::handle_push() {previous_value_ = value_;}

void Fl_Valuator::handle_drag(double v) {
  if (v != value_) {
    value_ = v;
    value_damage();
    if (when() & FL_WHEN_CHANGED) do_callback();
    else set_changed();
  }
}

void Fl_Valuator::handle_release() {
  if (when()&FL_WHEN_RELEASE) {
    // insure changed() is off even if no callback is done.  It may have
    // been turned on by the drag, and then the slider returned to it's
    // initial position:
    clear_changed();
    // now do the callback only if slider in new position or always is on:
    if (value_ != previous_value_ || when() & FL_WHEN_NOT_CHANGED)
      do_callback();
  }
}

double Fl_Valuator::round(double v) {
  if (A) return rint(v*B/A)*A/B;
  else return v;
}

double Fl_Valuator::clamp(double v) {
  if ((v<min)==(min<=max)) return min;
  else if ((v>max)==(min<=max)) return max;
  else return v;
}

double Fl_Valuator::increment(double v, int n) {
  if (!A) return v+n*(max-min)/100;
  if (min > max) n = -n;
  return (rint(v*B/A)+n)*A/B;
}

int Fl_Valuator::format(char* buffer) {
  double v = value();
  if (!A || B==1) return sprintf(buffer, "%g", v);
  int i, x;
  for (x = 10, i = 2; x < B; x *= 10) i++;
  if (x == B) i--;
  return sprintf(buffer, "%.*f", i, v);
}

//
// End of "$Id: Fl_Valuator.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_abort.cxx ---
//
// "$Id: Fl_abort.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Warning/error message code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This method is in it's own source file so that stdlib and stdio
// do not need to be included in Fl.C:
// You can also override this by redefining all of these.

#include <FL/Fl.H>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <config.h>

#ifndef WIN32

static void warning(const char *format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fputc('\n', stderr);
  fflush(stderr);
}

static void error(const char *format, ...) {
  va_list args;
  va_start(args, format);
  vfprintf(stderr, format, args);
  va_end(args);
  fputc('\n', stderr);
  fflush(stderr);
  ::exit(1);
}

#else

#include <windows.h>
#  if !HAVE_VSNPRINTF || defined(__hpux)
extern "C" {
int vsnprintf(char* str, size_t size, const char* fmt, va_list ap);
}
#  endif /* !HAVE_VSNPRINTF */

static void warning(const char *format, ...) {
  va_list args;
  char buf[1024];
  va_start(args, format);
  vsnprintf(buf, 1024, format, args);
  va_end(args);
  MessageBox(0,buf,"Warning",MB_ICONEXCLAMATION|MB_OK);
}

static void error(const char *format, ...) {
  va_list args;
  char buf[1024];
  va_start(args, format);
  vsnprintf(buf, 1024, format, args);
  va_end(args);
  MessageBox(0,buf,"Error",MB_ICONSTOP|MB_SYSTEMMODAL);
  ::exit(1);
}

#endif

void (*Fl::warning)(const char* format, ...) = ::warning;
void (*Fl::error)(const char* format, ...) = ::error;
void (*Fl::fatal)(const char* format, ...) = ::error;

//
// End of "$Id: Fl_abort.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_match.cxx ---
//
// "$Id: filename_match.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Pattern matching routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

/* Adapted from Rich Salz. */
#include <FL/filename.H>
#include <ctype.h>

int filename_match(const char *s, const char *p) {
  int matched;

  for (;;) {
    switch(*p++) {

    case '?' :	// match any single character
      if (!*s++) return 0;
      break;

    case '*' :	// match 0-n of any characters
      if (!*p) return 1; // do trailing * quickly
      while (!filename_match(s, p)) if (!*s++) return 0;
      return 1;

    case '[': {	// match one character in set of form [abc-d] or [^a-b]
      if (!*s) return 0;
      int reverse = (*p=='^' || *p=='!'); if (reverse) p++;
      matched = 0;
      char last = 0;
      while (*p) {
	if (*p=='-' && last) {
	  if (*s <= *++p && *s >= last ) matched = 1;
	  last = 0;
	} else {
	  if (*s == *p) matched = 1;
	}
	last = *p++;
	if (*p==']') break;
      }
      if (matched == reverse) return 0;
      s++; p++;}
    break;

    case '{' : // {pattern1|pattern2|pattern3}
    NEXTCASE:
    if (filename_match(s,p)) return 1;
    for (matched = 0;;) {
      switch (*p++) {
      case '\\': if (*p) p++; break;
      case '{': matched++; break;
      case '}': if (!matched--) return 0; break;
      case '|': case ',': if (matched==0) goto NEXTCASE;
      case 0: return 0;
      }
    }
    case '|':	// skip rest of |pattern|pattern} when called recursively
    case ',':
      for (matched = 0; *p && matched >= 0;) {
	switch (*p++) {
	case '\\': if (*p) p++; break;
	case '{': matched++; break;
	case '}': matched--; break;
	}
      }
      break;
    case '}':
      break;

    case 0:	// end of pattern
      return !*s;

#ifdef WIN32
    case '\\':	// quote next character
      if (*p) p++;
      if (*s++ != *(p-1)) return 0;
      break;
    default:
      if (tolower(*s) != tolower(*(p-1))) return 0;
      s++;
#else
    case '\\':	// quote next character
      if (*p) p++;
    default  :
      if (*s++ != *(p-1)) return 0;
      break;
#endif
    }
  }
}

//
// End of "$Id: filename_match.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_ask.cxx ---
//
// "$Id: fl_ask.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Standard dialog functions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implementation of fl_message, fl_ask, fl_choice, fl_input
// The three-message fl_show_x functions are for forms compatibility
// mostly.  In most cases it is easier to get a multi-line message
// by putting newlines in the message.

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <config.h>

#include <FL/Fl.H>

#include <FL/fl_ask.H>

#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Return_Button.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Input.H>
#include <FL/Fl_Secret_Input.H>
#include <FL/x.H>

static Fl_Window *message_form;
static Fl_Box *message;
static Fl_Box *icon;
static Fl_Button *button[3];
static Fl_Input *input;
static char *iconlabel = "?";
uchar fl_message_font_ = 0;
uchar fl_message_size_ = FL_NORMAL_SIZE;

static Fl_Window *makeform() {
 if (message_form) return message_form;
 Fl_Window *w = message_form = new Fl_Window(410,105);
 // w->clear_border();
 // w->box(FL_UP_BOX);
 (message = new Fl_Box(60, 25, 340, 20))
   ->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
 (input = new Fl_Input(60,32,340,30))->hide();
 {Fl_Box* o = icon = new Fl_Box(10, 10, 50, 50);
  o->box(FL_THIN_UP_BOX);
  o->labelfont(FL_TIMES_BOLD);
  o->labelsize(34);
  o->color(FL_WHITE);
  o->labelcolor(FL_BLUE);
 }
 (button[0] = new Fl_Button(310, 70, 90, 25))->shortcut("^[");
 button[1] = new Fl_Return_Button(210, 70, 90, 25);
 button[2] = new Fl_Button(110, 70, 90, 25);
 w->end();
 w->set_modal();
 return w;
}

#if !HAVE_VSNPRINTF || defined(__hpux)
extern "C" {
int vsnprintf(char* str, size_t size, const char* fmt, va_list ap);
}
#endif

static int innards(const char* fmt, va_list ap,
  const char *b0,
  const char *b1,
  const char *b2,
  const char *l)
{
  makeform();
  char buffer[1024];
  if (!strcmp(fmt,"%s")) {
    message->label(va_arg(ap, const char*));
  } else {
    vsnprintf(buffer, 1024, fmt, ap);
    message->label(buffer);
  }
  Fl_Font f = (Fl_Font)fl_message_font_;
  message->labelfont(f);
  message->labelsize(fl_message_size_);
  if (b0) {button[0]->show();button[0]->label(b0);button[1]->position(210,70);}
  else {button[0]->hide(); button[1]->position(310,70);}
  if (b1) {button[1]->show(); button[1]->label(b1);}
  else button[1]->hide();
  if (b2) {button[2]->show(); button[2]->label(b2);}
  else button[2]->hide();
  const char* prev_icon_label = icon->label();
  if (!prev_icon_label) icon->label(iconlabel);
  message_form->hotspot(button[0]);
  message_form->label(l);
  message_form->show();
  int r;
  for (;;) {
    Fl_Widget *o = Fl::readqueue();
    if (!o) Fl::wait();
    else if (o == button[0]) {r = 0; break;}
    else if (o == button[1]) {r = 1; break;}
    else if (o == button[2]) {r = 2; break;}
    else if (o == message_form) {r = 0; break;}
  }
  message_form->hide();
  icon->label(prev_icon_label);
  return r;
}

// pointers you can use to change fltk to a foreign language:
const char* fl_no = "No";
const char* fl_yes= "Yes";
const char* fl_ok = "OK";
const char* fl_cancel= "Cancel";

// fltk functions:

void fl_message(const char *fmt, ...) {
  va_list ap;

#ifdef WIN32
  MessageBeep(MB_ICONASTERISK);
#endif // WIN32

  va_start(ap, fmt);
  iconlabel = "i";
  innards(fmt, ap, 0, fl_ok, 0, "Message");
  va_end(ap);
  iconlabel = "?";
}

void fl_alert(const char *fmt, ...) {
  va_list ap;

#ifdef WIN32
  MessageBeep(MB_ICONERROR);
#else
#ifndef NANO_X //tanghao
  XBell(fl_display, 100);
#endif //tanghao
#endif // WIN32

  va_start(ap, fmt);
  iconlabel = "!";
  innards(fmt, ap, 0, fl_ok, 0, "Alert");
  va_end(ap);
  iconlabel = "?";
}

int fl_ask(const char *fmt, ...) {
  va_list ap;

#ifdef WIN32
  MessageBeep(MB_ICONQUESTION);
#endif // WIN32

  va_start(ap, fmt);
  int r = innards(fmt, ap, fl_no, fl_yes, 0, "Question");
  va_end(ap);

  return r;
}

int fl_choice(const char*fmt,const char *b0,const char *b1,const char *b2,...){
  va_list ap;

#ifdef WIN32
  MessageBeep(MB_ICONQUESTION);
#endif // WIN32

  va_start(ap, b2);
  int r = innards(fmt, ap, b0, b1, b2, "Choose");
  va_end(ap);
  return r;
}

Fl_Widget *fl_message_icon() {makeform(); return icon;}

static const char* input_innards(const char* fmt, va_list ap,
				 const char* defstr, uchar type) {
  makeform();
  message->position(60,10);
  input->type(type);
  input->show();
  input->value(defstr);

#ifdef WIN32
  MessageBeep(MB_ICONQUESTION);
#endif // WIN32

  int r = innards(fmt, ap, fl_cancel, fl_ok, 0, "Input");
  input->hide();
  message->position(60,25);
  return r ? input->value() : 0;
}

const char* fl_input(const char *fmt, const char *defstr, ...) {
  va_list ap;
  va_start(ap, defstr);
  const char* r = input_innards(fmt, ap, defstr, FL_NORMAL_INPUT);
  va_end(ap);
  return r;
}

const char *fl_password(const char *fmt, const char *defstr, ...) {
  va_list ap;
  va_start(ap, defstr);
  const char* r = input_innards(fmt, ap, defstr, FL_SECRET_INPUT);
  va_end(ap);
  return r;
}

//
// End of "$Id: fl_ask.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_absolute.cxx ---
//
// "$Id: filename_absolute.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Filename expansion routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

/* expand a file name by prepending current directory, deleting . and
   .. (not really correct for symbolic links) between the prepended
   current directory.  Use $PWD if it exists.
   Returns true if any changes were made.
*/

#include <FL/filename.H>
#include <stdlib.h>
#include <string.h>
#if defined(WIN32) && !defined(CYGNUS)
# include <direct.h>
//# define getcwd(a,b) _getdcwd(0,a,b)
#else
# include <unistd.h>
# ifdef __EMX__
#  define getcwd _getcwd2
# endif
#endif

#if defined(WIN32) || defined(__EMX__)
inline int isdirsep(char c) {return c=='/' || c=='\\';}
#else
#define isdirsep(c) ((c)=='/')
#endif

int filename_absolute(char *to,const char *from) {

  if (isdirsep(*from) || *from == '|'
#if defined(WIN32) || defined(__EMX__)
      || from[1]==':'
#endif
      ) {
    strcpy(to,from);
    return 0;
  }

  char *a,temp[FL_PATH_MAX];
  const char *start = from;

  a = getenv("PWD");
  if (a) strncpy(temp,a,FL_PATH_MAX);
  else {a = getcwd(temp,FL_PATH_MAX); if (!a) return 0;}
#if defined(WIN32) || defined(__EMX__)
  for (a = temp; *a; a++) if (*a=='\\') *a = '/'; // ha ha
#else
  a = temp+strlen(temp);
#endif
  if (isdirsep(*(a-1))) a--;
  /* remove intermediate . and .. names: */
  while (*start == '.') {
    if (start[1]=='.' && isdirsep(start[2])) {
      char *b;
      for (b = a-1; b >= temp && !isdirsep(*b); b--);
      if (b < temp) break;
      a = b;
      start += 3;
    } else if (isdirsep(start[1])) {
      start += 2;
    } else
      break;
  }
  *a++ = '/';
  strcpy(a,start);
  strcpy(to,temp);
  return 1;

}

//
// End of "$Id: filename_absolute.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: vsnprintf.c ---
/*
 * "$Id: vsnprintf.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
 *
 * vsnprintf() function for the Fast Light Tool Kit (FLTK).
 *
 * Emulates this call on systems that lack it (pretty much everything
 * except glibc systems).
 *
 * KNOWN BUGS:
 *
 * Field width & Precision is ignored for %%, %c, and %s.
 *
 * A malicious user who manages to create a %-fmt string that prints
 * more than 99 characters can still overflow the temporary buffer.
 * For instance %110f will overflow.
 *
 * Only handles formats that are both documented in the glibc man page
 * for printf and also handled by your system's sprintf().
 *
 * Copyright 1998-1999 by Bill Spitzak and others.
 *
 * 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 at easysw.com".
 */

#include <stdio.h>
#include <stdarg.h>
#include <config.h>

#if !HAVE_VSNPRINTF

#ifdef __cplusplus
extern "C" {
#endif

int vsnprintf(char* str, size_t size, const char* fmt, va_list ap) {
  const char* e = str+size-1;
  char* p = str;
  char copy[20];
  char* copy_p;
  char sprintf_out[100];

  while (*fmt && p < e) {
    if (*fmt != '%') {
      *p++ = *fmt++;
    } else {
      fmt++;
      copy[0] = '%';
      for (copy_p = copy+1; copy_p < copy+19;) {
	switch ((*copy_p++ = *fmt++)) {
	case 0:
	  fmt--; goto CONTINUE;
	case '%':
	  *p++ = '%'; goto CONTINUE;
	case 'c':
	  *p++ = va_arg(ap, int);
	  goto CONTINUE;
	case 'd':
	case 'i':
	case 'o':
	case 'u':
	case 'x':
	case 'X':
	  *copy_p = 0;
	  sprintf(sprintf_out, copy, va_arg(ap, int));
	  copy_p = sprintf_out;
	  goto DUP;
	case 'e':
	case 'E':
	case 'f':
	case 'g':
	  *copy_p = 0;
	  sprintf(sprintf_out, copy, va_arg(ap, double));
	  copy_p = sprintf_out;
	  goto DUP;
	case 'p':
	  *copy_p = 0;
	  sprintf(sprintf_out, copy, va_arg(ap, void*));
	  copy_p = sprintf_out;
	  goto DUP;
	case 'n':
	  *(va_arg(ap, int*)) = p-str;
	  goto CONTINUE;
	case 's':
	  copy_p = va_arg(ap, char*);
	  if (!copy_p) copy_p = "NULL";
	DUP:
	  while (*copy_p && p < e) *p++ = *copy_p++;
	  goto CONTINUE;
	}
      }
    }
  CONTINUE:;
  }
  *p = 0;
  if (*fmt) return -1;
  return p-str;
}

#endif

#if !HAVE_SNPRINTF

int snprintf(char* str, size_t size, const char* fmt, ...) {
  int ret;
  va_list ap;
  va_start(ap, fmt);
  ret = vsnprintf(str, size, fmt, ap);
  va_end(ap);
  return ret;
}

#ifdef __cplusplus
}
#endif

#endif

/*
 * End of "$Id: vsnprintf.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
 */


--- NEW FILE: fl_engraved_label.cxx ---
//
// "$Id: fl_engraved_label.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Engraved label drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Drawing code for XForms style engraved & embossed labels

#include <FL/Fl.H>
#include <FL/Fl_Widget.H>
#include <FL/fl_draw.H>

// data[] is dx, dy, color triples

static void innards(
    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align,
    int data[][3], int n)
{
  Fl_Align a1 = align;
  if (a1 & FL_ALIGN_CLIP) {
    fl_clip(X, Y, W, H); a1 = (Fl_Align)(a1&~FL_ALIGN_CLIP);}
  fl_font((Fl_Font)o->font, o->size);
  for (int i = 0; i < n; i++) {
    fl_color((Fl_Color)(i < n-1 ? data[i][2] : o->color));
    fl_draw(o->value, X+data[i][0], Y+data[i][1], W, H, a1);
  }
  if (align & FL_ALIGN_CLIP) fl_pop_clip();
}

static void fl_shadow_label(
    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
  static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}};
  innards(o, X, Y, W, H, align, data, 2);
}

static void fl_engraved_label(
    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
  static int data[7][3] = {
    {1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3},
    {-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3},
    {0,0,0}};
  innards(o, X, Y, W, H, align, data, 7);
}

static void fl_embossed_label(
    const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
  static int data[7][3] = {
    {-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3},
    {1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3},
    {0,0,0}};
  innards(o, X, Y, W, H, align, data, 7);
}

Fl_Labeltype define_FL_SHADOW_LABEL() {
  Fl::set_labeltype(_FL_SHADOW_LABEL, fl_shadow_label, 0);
  return _FL_SHADOW_LABEL;
}
Fl_Labeltype define_FL_ENGRAVED_LABEL() {
  Fl::set_labeltype(_FL_ENGRAVED_LABEL, fl_engraved_label, 0);
  return _FL_ENGRAVED_LABEL;
}
Fl_Labeltype define_FL_EMBOSSED_LABEL() {
  Fl::set_labeltype(_FL_EMBOSSED_LABEL, fl_embossed_label, 0);
  return _FL_EMBOSSED_LABEL;
}

//
// End of "$Id: fl_engraved_label.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Choice.cxx ---
//
// "$Id: Fl_Choice.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Choice widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Choice.H>
#include <FL/fl_draw.H>

// Emulates the Forms choice widget.  This is almost exactly the same
// as an Fl_Menu_Button.  The only difference is the appearance of the
// button: it draws the text of the current pick and a down-arrow.

extern char fl_draw_shortcut;

void Fl_Choice::draw() {
  draw_box();
  if (box() == FL_FLAT_BOX) return; // for XForms compatability
  int H = labelsize()/2+1;
  draw_box(FL_THIN_UP_BOX,x()+w()-3*H,y()+(h()-H)/2,2*H,H,color());
  if (mvalue()) {
    Fl_Menu_Item m = *mvalue();
    if (active_r()) m.activate(); else m.deactivate();
    int BW = Fl::box_dx(box());
    fl_clip(x(), y(), w()-3*H, h());
    fl_draw_shortcut = 2; // hack value to make '&' disappear
    m.draw(x()+BW, y(), w()-2*BW-3*H, h(), this);
    fl_draw_shortcut = 0;
    fl_pop_clip();
  }
  draw_label();
}

Fl_Choice::Fl_Choice(int x,int y,int w,int h, const char *l)
: Fl_Menu_(x,y,w,h,l) {
  align(FL_ALIGN_LEFT);
  when(FL_WHEN_RELEASE);
  textfont(FL_HELVETICA);
  down_box(FL_NO_BOX);
}

int Fl_Choice::value(int v) {
  if (!Fl_Menu_::value(v)) return 0;
  redraw();
  return 1;
}

int Fl_Choice::handle(int e) {
  if (!menu() || !menu()->text) return 0;
  const Fl_Menu_Item* v;
  switch (e) {
  case FL_PUSH:
    Fl::event_is_click(0);
  J1:
    v = menu()->pulldown(x(), y(), w(), h(), mvalue(), this);
    if (!v || v->submenu()) return 1;
    if (v != mvalue()) redraw();
    picked(v);
    return 1;
  case FL_SHORTCUT:
    if (Fl_Widget::test_shortcut()) goto J1;
    v = menu()->test_shortcut();
    if (!v) return 0;
    if (v != mvalue()) redraw();
    picked(v);
    return 1;
  default:
    return 0;
  }
}

//
// End of "$Id: Fl_Choice.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Clock.cxx ---
//
// "$Id: Fl_Clock.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Clock widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Clock.H>
#include <FL/fl_draw.H>
#include <math.h>
#include <time.h>
#ifndef WIN32
#  include <sys/time.h>
#endif /* !WIN32 */

// Original clock display written by Paul Haeberli at SGI.
// Modifications by Mark Overmars for Forms
// Further changes by Bill Spitzak for fltk

const float hourhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -7.0f}};
const float  minhand[4][2] = {{-0.5f, 0}, {0, 1.5f}, {0.5f, 0}, {0, -11.5f}};
const float  sechand[4][2] = {{-0.1f, 0}, {0, 2.0f}, {0.1f, 0}, {0, -11.5f}};

static void drawhand(double ang,const float v[][2],Fl_Color fill,Fl_Color line)
{
  fl_push_matrix();
  fl_rotate(ang);
  fl_color(fill); fl_begin_polygon();
  int i; for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_polygon();
  fl_color(line); fl_begin_loop();
  for (i=0; i<4; i++) fl_vertex(v[i][0],v[i][1]); fl_end_loop();
  fl_pop_matrix();
}

void Fl_Clock_Output::drawhands(Fl_Color fill, Fl_Color line) {
  drawhand(-360*(hour()+minute()/60.0)/12, hourhand, fill, line);
  drawhand(-360*(minute()+second()/60.0)/60, minhand, fill, line);
  drawhand(-360*(second()/60.0), sechand, fill, line);
}

static void rect(double x, double y, double w, double h) {
  double r = x+w;
  double t = y+h;
  fl_begin_polygon();
  fl_vertex(x, y);
  fl_vertex(r, y);
  fl_vertex(r, t);
  fl_vertex(x, t);
  fl_end_polygon();
}

void Fl_Clock_Output::draw(int x, int y, int w, int h) {
  draw_box(box(), x, y, w, h, type()==FL_ROUND_CLOCK ? FL_GRAY : color());
  fl_push_matrix();
  fl_translate(x+w/2.0-.5, y+h/2.0-.5);
  fl_scale((w-1)/28.0, (h-1)/28.0);
  if (type() == FL_ROUND_CLOCK) {
    fl_color(color());
    fl_begin_polygon(); fl_circle(0,0,14); fl_end_polygon();
    fl_color(FL_BLACK);
    fl_begin_loop(); fl_circle(0,0,14); fl_end_loop();
  }
  // draw the shadows:
  fl_push_matrix();
  fl_translate(0.60, 0.60);
  drawhands(FL_DARK3, FL_DARK3);
  fl_pop_matrix();
  // draw the tick marks:
  fl_push_matrix();
  fl_color(FL_BLACK); // color was 52
  for (int i=0; i<12; i++) {
    if (i==6) rect(-0.5, 9, 1, 2);
    else if (i==3 || i==0 || i== 9) rect(-0.5, 9.5, 1, 1);
    else rect(-0.25, 9.5, .5, 1);
    fl_rotate(-30);
  }
  fl_pop_matrix();
  // draw the hands:
  drawhands(selection_color(), FL_GRAY0); // color was 54
  fl_pop_matrix();
}

void Fl_Clock_Output::draw() {
  draw(x(), y(), w(), h());
  draw_label();
}

void Fl_Clock_Output::value(int h, int m, int s) {
  if (h!=hour_ || m!=minute_ || s!=second_) {
    hour_ = h; minute_ = m; second_ = s;
    damage(FL_DAMAGE_CHILD);
  }
}

void Fl_Clock_Output::value(ulong v) {
  struct tm *timeofday;
  timeofday = localtime((const time_t *)&v);
  value(timeofday->tm_hour, timeofday->tm_min, timeofday->tm_sec);
}

Fl_Clock_Output::Fl_Clock_Output(int x, int y, int w, int h, const char *l)
: Fl_Widget(x, y, w, h, l) {
  box(FL_UP_BOX);
  selection_color(fl_gray_ramp(5));
  align(FL_ALIGN_BOTTOM);
  hour_ = 0;
  minute_ = 0;
  second_ = 0;
  value_ = 0;
}

////////////////////////////////////////////////////////////////

Fl_Clock::Fl_Clock(int x, int y, int w, int h, const char *l)
  : Fl_Clock_Output(x, y, w, h, l) {}

Fl_Clock::Fl_Clock(uchar t, int x, int y, int w, int h, const char *l)
  : Fl_Clock_Output(x, y, w, h, l) {
  type(t);
  box(t==FL_ROUND_CLOCK ? FL_NO_BOX : FL_UP_BOX);
}

static void tick(void *v) {
#ifdef WIN32
  ((Fl_Clock*)v)->value(time(0));
  Fl::add_timeout(1.0, tick, v);
#else
  struct timeval t;
  gettimeofday(&t, 0);
  ((Fl_Clock*)v)->value(t.tv_sec);
  double delay = 1.0-t.tv_usec*.000001;
  if (delay < .1 || delay > .9) delay = 1.0;
  Fl::add_timeout(delay, tick, v);
#endif
}

int Fl_Clock::handle(int event) {
  switch (event) {
  case FL_SHOW:
    tick(this);
    break;
  case FL_HIDE:
    Fl::remove_timeout(tick, this);
    break;
  }
  return Fl_Clock_Output::handle(event);
}
  
Fl_Clock::~Fl_Clock() {
  Fl::remove_timeout(tick, this);
}

//
// End of "$Id: Fl_Clock.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_call_main.c ---
/*
 * "$Id: fl_call_main.c,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
 *
 * Copyright 1998-1999 by Bill Spitzak and others.
 *
 * fl_call_main() calls main() for you Windows people.  Needs to be done in C
 * because Borland C++ won't let you call main() from C++.
 *
 * 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 at easysw.com".
 */

/*
 * This WinMain() function can be overridden by an application and
 * is provided for compatibility with programs written for other
 * operating systems that conform to the ANSI standard entry point
 * "main()".  This will allow you to build a WIN32 Application
 * without any special settings.
 *
 * Because of problems with the Microsoft Visual C++ header files
 * and/or compiler, you cannot have a WinMain function in a DLL.
 * I don't know why.  Thus, this nifty feature is only available
 * if you link to the static library.
 *
 * Currently the debug version of this library will create a
 * console window for your application so you can put printf()
 * statements for debugging or informational purposes.  Ultimately
 * we want to update this to always use the parent's console,
 * but at present we have not identified a function or API in
 * Microsoft(r) Windows(r) that allows for it.
 */

#if defined(WIN32) && !defined(FL_DLL) && !defined (__GNUC__)

#include <windows.h>
#include <stdio.h>

extern int main(int, char *[]);
#ifdef BORLAND5
#define __argc _argc
#define __argv _argv
#endif
extern int  __argc;
extern char **__argv;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                             LPSTR lpCmdLine, int nCmdShow) {
#ifdef _DEBUG
 /*
  * If we are using compiling in debug mode, open a console window so
  * we can see any printf's, etc...
  *
  * While we can detect if the program was run from the command-line -
  * look at the CMDLINE environment variable, it will be "WIN" for
  * programs started from the GUI - the shell seems to run all WIN32
  * applications in the background anyways...
  */

  AllocConsole();
  freopen("conin$", "r", stdin);
  freopen("conout$", "w", stdout);
  freopen("conout$", "w", stderr);
#endif /* _DEBUG */

  /* Run the standard main entry point function... */
  return main(__argc, __argv);
}

#endif

/*
 * End of "$Id: fl_call_main.c,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
 */


--- NEW FILE: fl_diamond_box.cxx ---
//
// "$Id: fl_diamond_box.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Diamond box code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Box drawing code for an obscure box type.
// These box types are in seperate files so they are not linked
// in if not used.

// The diamond box draws best if the area is square!

#include <FL/Fl.H>
#include <FL/fl_draw.H>

extern uchar* fl_gray_ramp();

static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
  w &= -2;
  h &= -2;
  int x1 = x+w/2;
  int y1 = y+h/2;
#ifdef PDA
  fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
  fl_color(FL_BLACK); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
#else
  fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
  uchar *g = fl_gray_ramp();
  fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
  fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
  fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
  fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
  fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
  fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
  fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
#endif
}

static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
  w &= -2;
  h &= -2;
  int x1 = x+w/2;
  int y1 = y+h/2;
#ifdef PDA
  fl_color(FL_BLACK); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
  fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
  fl_color(bgcolor); fl_polygon(x+5, y1, x1,y+5, x+w-5,y1, x1,y+h-5);
#else
  uchar *g = fl_gray_ramp();
  fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
  fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
  fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
  fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
  fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
  fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
  fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
  fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
#endif
}

extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
Fl_Boxtype define_FL_DIAMOND_BOX() {
  fl_internal_boxtype(_FL_DIAMOND_DOWN_BOX, fl_diamond_down_box);
  fl_internal_boxtype(_FL_DIAMOND_UP_BOX,fl_diamond_up_box);
  return _FL_DIAMOND_UP_BOX;
}

//
// End of "$Id: fl_diamond_box.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: filename_list.cxx ---
//
// "$Id: filename_list.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Filename list routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Wrapper for scandir with const-correct function prototypes.

#include <config.h>
#include <FL/filename.H>

extern "C" {
  int numericsort(dirent **, dirent **);
#if HAVE_SCANDIR
#else
  int alphasort(dirent **, dirent **);
  int scandir (const char *dir, dirent ***namelist,
	       int (*select)(dirent *),
	       int (*compar)(dirent **, dirent **));
#endif
}

int filename_list(const char *d, dirent ***list) {
#if defined(_AIX) || defined(CRAY) || defined(linux) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__)
  // on some systems you may need to do this, due to a rather common
  // error in the prototype for the sorting function, where a level
  // of pointer indirection is missing:
  return scandir(d, list, 0, (int(*)(const void*,const void*))numericsort);
#elif defined(__hpux)
  // HP-UX defines the comparison function to take const pointers instead of
  // ordinary ones...
  return scandir(d, list, 0, (int(*)(const dirent **, const dirent **))numericsort);
#else
  return scandir(d, list, 0, numericsort);
#endif
}

//
// End of "$Id: filename_list.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Single_Window.cxx ---
//
// "$Id: Fl_Single_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Single-buffered window for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

//	A window with a single-buffered context
//
//	This is provided for systems where the base class is double
//	buffered.  You can turn it off using this subclass in case
//	your display looks better without it.

#include <FL/Fl_Single_Window.H>

void Fl_Single_Window::show() {Fl_Window::show();}
void Fl_Single_Window::flush() {Fl_Window::flush();}

//
// End of "$Id: Fl_Single_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Browser_load.cxx ---
//
// "$Id: Fl_Browser_load.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// File loading routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Browser.H>
#include <stdio.h>

int Fl_Browser::load(const char *filename) {
#define MAXFL_BLINE 1024
    char newtext[MAXFL_BLINE];
    int c;
    int i;
    clear();
    if (!filename || !(filename[0])) return 1;
    FILE *fl = fopen(filename,"r");
    if (!fl) return 0;
    i = 0;
    do {
	c = getc(fl);
	if (c == '\n' || c <= 0 || i>=(MAXFL_BLINE-1)) {
	    newtext[i] = 0;
	    add(newtext);
	    i = 0;
	} else
	    newtext[i++] = c;
    } while (c >= 0);
    fclose(fl);
    return 1;
}

//
// End of "$Id: Fl_Browser_load.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_oval_box.cxx ---
//
// "$Id: fl_oval_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $"
//
// Oval box drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//


// Less-used box types are in seperate files so they are not linked
// in if not used.

#include <FL/Fl.H>
#include <FL/fl_draw.H>

static void fl_oval_flat_box(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c);
  fl_pie(x, y, w, h, 0, 360);
}

static void fl_oval_frame(int x, int y, int w, int h, Fl_Color c) {
  fl_color(c);
  fl_arc(x, y, w, h, 0, 360);
}

static void fl_oval_box(int x, int y, int w, int h, Fl_Color c) {
  fl_oval_flat_box(x,y,w-1,h-1,c);
  fl_oval_frame(x,y,w,h,FL_BLACK);
}

static void fl_oval_shadow_box(int x, int y, int w, int h, Fl_Color c) {
  fl_oval_flat_box(x+3,y+3,w,h,FL_DARK3);
  fl_oval_box(x,y,w,h,c);
}

extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
Fl_Boxtype define_FL_OVAL_BOX() {
  fl_internal_boxtype(_FL_OSHADOW_BOX,fl_oval_shadow_box);
  fl_internal_boxtype(_FL_OVAL_FRAME,fl_oval_frame);
  fl_internal_boxtype(_FL_OFLAT_BOX,fl_oval_flat_box);
  fl_internal_boxtype(_FL_OVAL_BOX,fl_oval_box);
  return _FL_OVAL_BOX;
}

//
// End of "$Id: fl_oval_box.cxx,v 1.1 2006-10-03 11:25:14 dslinux_amadeus Exp $".
//

--- NEW FILE: d1_mask.xbm ---
#define d1_mask_width 16
#define d1_mask_height 16
static unsigned char d1_mask_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
   0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
   0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00};

--- NEW FILE: Fl_Color_Chooser.cxx ---
//
// "$Id: Fl_Color_Chooser.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Color chooser for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Color_Chooser.H>
#include <FL/fl_draw.H>
#include <FL/math.h>
#include <stdio.h>

// Besides being a useful object on it's own, the Fl_Color_Chooser was
// an attempt to make a complex composite object that could be easily
// imbedded into a user interface.  If you wish to make complex objects
// of your own, be sure to read this code.

// The function fl_color_chooser() creates a window containing a color
// chooser and a few buttons and current-color indicators.  It is an
// easier interface for simple programs that just need a color.

// The "hue box" can be a circle or rectilinear.
// You get a circle by defining this:
// #define CIRCLE 1
// And the "hue box" can auto-update when the value changes
// you get this by defining this:
#define UPDATE_HUE_BOX 1

void Fl_Color_Chooser::hsv2rgb(
	double H, double S, double V, double& r, double& g, double& b) {
  if (S < 5.0e-6) {
    r = g = b = V;
  } else {
    int i = (int)H;  
    double f = H - (float)i;
    double p1 = V*(1.0-S);
    double p2 = V*(1.0-S*f);
    double p3 = V*(1.0-S*(1.0-f));
    switch (i) {
    case 0: r = V;   g = p3;  b = p1;  break;
    case 1: r = p2;  g = V;   b = p1;  break;
    case 2: r = p1;  g = V;   b = p3;  break;
    case 3: r = p1;  g = p2;  b = V;   break;
    case 4: r = p3;  g = p1;  b = V;   break;
    case 5: r = V;   g = p1;  b = p2;  break;
    }
  }
}

void Fl_Color_Chooser::rgb2hsv(
	double r, double g, double b, double& H, double& S, double& V) {
  double maxv = r > g ? r : g; if (b > maxv) maxv = b;
  V = maxv;
  if (maxv>0) {
    double minv = r < g ? r : g; if (b < minv) minv = b;
    S = 1.0 - double(minv)/maxv;
    if (maxv > minv) {
      if (maxv == r) {H = (g-b)/double(maxv-minv); if (H<0) H += 6.0;}
      else if (maxv == g) H = 2.0+(b-r)/double(maxv-minv);
      else H = 4.0+(r-g)/double(maxv-minv);
    }
  }
}

enum {M_RGB, M_BYTE, M_HEX, M_HSV}; // modes
static Fl_Menu_Item mode_menu[] = {
  {"rgb"},
  {"byte"},
  {"hex"},
  {"hsv"},
  {0}
};

int Flcc_Value_Input::format(char* buf) {
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
  if (c->mode() == M_HEX) return sprintf(buf,"0x%02X", int(value()));
  else return Fl_Valuator::format(buf);
}

void Fl_Color_Chooser::set_valuators() {
  switch (mode()) {
  case M_RGB:
    rvalue.range(0,1); rvalue.step(1,1000); rvalue.value(r_);
    gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(g_);
    bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(b_);
    break;
  case M_BYTE:
  case M_HEX:
    rvalue.range(0,255); rvalue.step(1); rvalue.value(int(255*r_+.5));
    gvalue.range(0,255); gvalue.step(1); gvalue.value(int(255*g_+.5));
    bvalue.range(0,255); bvalue.step(1); bvalue.value(int(255*b_+.5));
    break;
  case M_HSV:
    rvalue.range(0,6); rvalue.step(1,1000); rvalue.value(hue_);
    gvalue.range(0,1); gvalue.step(1,1000); gvalue.value(saturation_);
    bvalue.range(0,1); bvalue.step(1,1000); bvalue.value(value_);
    break;
  }
}

int Fl_Color_Chooser::rgb(double r, double g, double b) {
  if (r == r_ && g == g_ && b == b_) return 0;
  r_ = r; g_ = g; b_ = b;
  double ph = hue_;
  double ps = saturation_;
  double pv = value_;
  rgb2hsv(r,g,b,hue_,saturation_,value_);
  set_valuators();
  if (value_ != pv) {
#ifdef UPDATE_HUE_BOX
    huebox.damage(FL_DAMAGE_SCROLL);
#endif
    valuebox.damage(FL_DAMAGE_EXPOSE);}
  if (hue_ != ph || saturation_ != ps) {
    huebox.damage(FL_DAMAGE_EXPOSE); 
    valuebox.damage(FL_DAMAGE_SCROLL);
  }
  return 1;
}

int Fl_Color_Chooser::hsv(double h, double s, double v) {
  h = fmod(h,6.0); if (h < 0.0) h += 6.0;
  if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
  if (v < 0.0) v = 0.0; else if (v > 1.0) v = 1.0;
  if (h == hue_ && s == saturation_ && v == value_) return 0;
  double ph = hue_;
  double ps = saturation_;
  double pv = value_;
  hue_ = h; saturation_ = s; value_ = v;
  if (value_ != pv) {
#ifdef UPDATE_HUE_BOX
    huebox.damage(FL_DAMAGE_SCROLL);
#endif
    valuebox.damage(FL_DAMAGE_EXPOSE);}
  if (hue_ != ph || saturation_ != ps) {
    huebox.damage(FL_DAMAGE_EXPOSE); 
    valuebox.damage(FL_DAMAGE_SCROLL);
  }
  hsv2rgb(h,s,v,r_,g_,b_);
  set_valuators();
  return 1;
}

////////////////////////////////////////////////////////////////

static void tohs(double x, double y, double& h, double& s) {
#ifdef CIRCLE
  x = 2*x-1;
  y = 1-2*y;
  s = sqrt(x*x+y*y); if (s > 1.0) s = 1.0;
  h = (3.0/M_PI)*atan2(y,x);
  if (h<0) h += 6.0;
#else
  h = fmod(6.0*x,6.0); if (h < 0.0) h += 6.0;
  s = 1.0-y; if (s < 0.0) s = 0.0; else if (s > 1.0) s = 1.0;
#endif
}

int Flcc_HueBox::handle(int e) {
  static double ih, is;
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
  switch (e) {
  case FL_PUSH:
    ih = c->hue();
    is = c->saturation();
  case FL_DRAG: {
    double Xf, Yf, H, S;
    Xf = (Fl::event_x()-x()-Fl::box_dx(box()))/double(w()-Fl::box_dw(box()));
    Yf = (Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
    tohs(Xf, Yf, H, S);
    if (fabs(H-ih) < 3*6.0/w()) H = ih;
    if (fabs(S-is) < 3*1.0/h()) S = is;
    if (Fl::event_state(FL_CTRL)) H = ih;
    if (c->hsv(H, S, c->value())) c->do_callback();
    } return 1;
  default:
    return 0;
  }
}

static void generate_image(void* vv, int X, int Y, int W, uchar* buf) {
  Flcc_HueBox* v = (Flcc_HueBox*)vv;
  int iw = v->w()-Fl::box_dw(v->box());
  double Yf = double(Y)/(v->h()-Fl::box_dh(v->box()));
#ifdef UPDATE_HUE_BOX
  const double V = ((Fl_Color_Chooser*)(v->parent()))->value();
#else
  const double V = 1.0;
#endif
  for (int x = X; x < X+W; x++) {
    double Xf = double(x)/iw;
    double H,S; tohs(Xf,Yf,H,S);
    double r,g,b;
    Fl_Color_Chooser::hsv2rgb(H,S,V,r,g,b);
    *buf++ = uchar(255*r+.5);
    *buf++ = uchar(255*g+.5);
    *buf++ = uchar(255*b+.5);
  }
}

void Flcc_HueBox::draw() {
  if (damage()&FL_DAMAGE_ALL) draw_box();
  int x1 = x()+Fl::box_dx(box());
  int y1 = y()+Fl::box_dy(box());
  int w1 = w()-Fl::box_dw(box());
  int h1 = h()-Fl::box_dh(box());
  if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1+px,y1+py,6,6);
  fl_draw_image(generate_image, this, x1, y1, w1, h1);
  if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
#ifdef CIRCLE
  int X = int(.5*(cos(c->hue()*(M_PI/3.0))*c->saturation()+1) * (w1-6));
  int Y = int(.5*(1-sin(c->hue()*(M_PI/3.0))*c->saturation()) * (h1-6));
#else
  int X = int(c->hue()/6.0*(w1-6));
  int Y = int((1-c->saturation())*(h1-6));
#endif
  if (X < 0) X = 0; else if (X > w1-6) X = w1-6;
  if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
  //  fl_color(c->value()>.75 ? FL_BLACK : FL_WHITE);
  draw_box(FL_UP_BOX,x1+X,y1+Y,6,6,FL_GRAY);
  px = X; py = Y;
}

////////////////////////////////////////////////////////////////

int Flcc_ValueBox::handle(int e) {
  static double iv;
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
  switch (e) {
  case FL_PUSH:
    iv = c->value();
  case FL_DRAG: {
    double Yf;
    Yf = 1-(Fl::event_y()-y()-Fl::box_dy(box()))/double(h()-Fl::box_dh(box()));
    if (fabs(Yf-iv)<(3*1.0/h())) Yf = iv;
    if (c->hsv(c->hue(),c->saturation(),Yf)) c->do_callback();
    } return 1;
  default:
    return 0;
  }
}

static double tr, tg, tb;
static void generate_vimage(void* vv, int X, int Y, int W, uchar* buf) {
  Flcc_ValueBox* v = (Flcc_ValueBox*)vv;
  double Yf = 255*(1.0-double(Y)/(v->h()-Fl::box_dh(v->box())));
  uchar r = uchar(tr*Yf+.5);
  uchar g = uchar(tg*Yf+.5);
  uchar b = uchar(tb*Yf+.5);
  for (int x = X; x < X+W; x++) {
    *buf++ = r; *buf++ = g; *buf++ = b;
  }
}

void Flcc_ValueBox::draw() {
  if (damage()&FL_DAMAGE_ALL) draw_box();
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)parent();
  c->hsv2rgb(c->hue(),c->saturation(),1.0,tr,tg,tb);
  int x1 = x()+Fl::box_dx(box());
  int y1 = y()+Fl::box_dy(box());
  int w1 = w()-Fl::box_dw(box());
  int h1 = h()-Fl::box_dh(box());
  if (damage() == FL_DAMAGE_EXPOSE) fl_clip(x1,y1+py,w1,6);
  fl_draw_image(generate_vimage, this, x1, y1, w1, h1);
  if (damage() == FL_DAMAGE_EXPOSE) fl_pop_clip();
  int Y = int((1-c->value()) * (h1-6));
  if (Y < 0) Y = 0; else if (Y > h1-6) Y = h1-6;
  draw_box(FL_UP_BOX,x1,y1+Y,w1,6,FL_GRAY);
  py = Y;
}

////////////////////////////////////////////////////////////////

void Fl_Color_Chooser::rgb_cb(Fl_Widget* o, void*) {
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
  double r = c->rvalue.value();
  double g = c->gvalue.value();
  double b = c->bvalue.value();
  if (c->mode() == M_HSV) {
    if (c->hsv(r,g,b)) c->do_callback();
    return;
  }
  if (c->mode() != M_RGB) {
    r = r/255;
    g = g/255;
    b = b/255;
  }
  if (c->rgb(r,g,b)) c->do_callback();
}

void Fl_Color_Chooser::mode_cb(Fl_Widget* o, void*) {
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)(o->parent());
  // force them to redraw even if value is the same:
  c->rvalue.value(-1);
  c->gvalue.value(-1);
  c->bvalue.value(-1);
  c->set_valuators();
}

////////////////////////////////////////////////////////////////

Fl_Color_Chooser::Fl_Color_Chooser(int X, int Y, int W, int H, const char* L)
  : Fl_Group(0,0,180,100,L),
    huebox(0,0,100,100),
    valuebox(100,0,20,100),
    choice(120,0,60,20),
    rvalue(120,20,60,25),
    gvalue(120,45,60,25),
    bvalue(120,70,60,25),
    resize_box(0,95,100,5)
{
  end();
  resizable(resize_box);
  resize(X,Y,W,H);
  r_ = g_ = b_ = 0;
  hue_ = 0.0;
  saturation_ = 0.0;
  value_ = 0.0;
  huebox.box(FL_DOWN_FRAME);
  valuebox.box(FL_DOWN_FRAME);
  choice.menu(mode_menu);
  set_valuators();
  rvalue.callback(rgb_cb);
  gvalue.callback(rgb_cb);
  bvalue.callback(rgb_cb);
  choice.callback(mode_cb);
  choice.box(FL_THIN_UP_BOX);
  choice.textfont(FL_HELVETICA_BOLD_ITALIC);
}

////////////////////////////////////////////////////////////////
// fl_color_chooser():

#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Return_Button.H>

class ColorChip : public Fl_Widget {
  void draw();
public:
  uchar r,g,b;
  ColorChip(int X, int Y, int W, int H) : Fl_Widget(X,Y,W,H) {
    box(FL_ENGRAVED_FRAME);}
};

void ColorChip::draw() {
  if (damage()&FL_DAMAGE_ALL) draw_box();
  fl_rectf(x()+Fl::box_dx(box()),
	   y()+Fl::box_dy(box()),
	   w()-Fl::box_dw(box()),
	   h()-Fl::box_dh(box()),r,g,b);
}

static void chooser_cb(Fl_Object* o, void* vv) {
  Fl_Color_Chooser* c = (Fl_Color_Chooser*)o;
  ColorChip* v = (ColorChip*)vv;
  v->r = uchar(255*c->r()+.5);
  v->g = uchar(255*c->g()+.5);
  v->b = uchar(255*c->b()+.5);
  v->damage(FL_DAMAGE_EXPOSE);
}

extern const char* fl_ok;
extern const char* fl_cancel;

int fl_color_chooser(const char* name, double& r, double& g, double& b) {
  Fl_Window window(210,165,name);
  Fl_Color_Chooser chooser(5, 5, 200, 95);
  ColorChip ok_color(5, 105, 95, 30);
  Fl_Return_Button ok_button(5, 135, 95, 25, fl_ok);
  ColorChip cancel_color(110, 105, 95, 30);
  cancel_color.r = uchar(255*r+.5); ok_color.r = cancel_color.r;
  ok_color.g = cancel_color.g = uchar(255*g+.5);
  ok_color.b = cancel_color.b = uchar(255*b+.5);
  Fl_Button cancel_button(110, 135, 95, 25, fl_cancel);
  window.resizable(chooser);
  chooser.rgb(r,g,b);
  chooser.callback(chooser_cb, &ok_color);
  window.end();
  window.set_modal();
  window.hotspot(window);
  window.show();
  while (window.shown()) {
    Fl::wait();
    for (;;) {
      Fl_Widget* o = Fl::readqueue();
      if (!o) break;
      if (o == &ok_button) {
	r = chooser.r();
	g = chooser.g();
	b = chooser.b();
	return 1;
      }
      if (o == &window || o == &cancel_button) return 0;
    }
  }
  return 0;
}

int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b) {
  double dr = r/255.0;
  double dg = g/255.0;
  double db = b/255.0;
  if (fl_color_chooser(name,dr,dg,db)) {
    r = uchar(255*dr+.5);
    g = uchar(255*dg+.5);
    b = uchar(255*db+.5);
    return 1;
  }
  return 0;
}

//
// End of "$Id: Fl_Color_Chooser.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_draw_image.cxx ---
//
// "$Id: fl_draw_image.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Image drawing routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// I hope a simple and portable method of drawing color and monochrome
// images.  To keep this simple, only a single storage type is
// supported: 8 bit unsigned data, byte order RGB, and pixels are
// stored packed into rows with the origin at the top-left.  It is
// possible to alter the size of pixels with the "delta" argument, to
// add alpha or other information per pixel.  It is also possible to
// change the origin and direction of the image data by messing with
// the "delta" and "linedelta", making them negative, though this may
// defeat some of the shortcuts in translating the image for X.

#ifdef WIN32
#include "fl_draw_image_win32.cxx"
#else

// A list of assumptions made about the X display:

// bits_per_pixel must be one of 8, 16, 24, 32.

// scanline_pad must be a power of 2 and greater or equal to 8.

// PsuedoColor visuals must have 8 bits_per_pixel (although the depth
// may be less than 8).  This is the only limitation that affects any
// modern X displays, you can't use 12 or 16 bit colormaps.

// The mask bits in TrueColor visuals for each color are
// contiguous and have at least one bit of each color.  This
// is not checked for.

// For 24 and 32 bit visuals there must be at least 8 bits of each color.

////////////////////////////////////////////////////////////////

#include <FL/Fl.H>
#include <FL/fl_draw.H>
#include <FL/x.H>
#include "Fl_XColor.H"
#include <string.h>

#ifndef NANO_X //tanghao
static XImage i;	// template used to pass info to X

static int bytes_per_pixel;
static int scanline_add;
static int scanline_mask;

static void (*converter)(const uchar *from, uchar *to, int w, int delta);
static void (*mono_converter)(const uchar *from, uchar *to, int w, int delta);

static int dir;		// direction-alternator
static int ri,gi,bi;	// saved error-diffusion value

#if USE_COLORMAP
////////////////////////////////////////////////////////////////
// 8-bit converter with error diffusion

// I make a 16x16x16 cube of the closest colors in the fltk colormap
// we could allocate to each of the colors in a 4-bit image.  This is
// then used to find the pixel values and actual colors for error diffusion.
static uchar cube[16*16*16];

// calculate sum-of-squares error between 4-bit index and pixel colors:
static int calc_error(int r, int g, int b, int i) {
  int t; int s;
  t = ((r<<4)+8)-fl_xmap[0][i].r; s = t*t;
  t = ((g<<4)+8)-fl_xmap[0][i].g; s += t*t;
  t = ((b<<4)+8)-fl_xmap[0][i].b; s += t*t;
  return s;
}

// replace the color stored at a location with a better one:
static void improve(uchar *p, int& e, int r, int g, int b, int i) {
  if (i < FL_GRAY_RAMP || i > 255) return;
  int e1 = calc_error(r,g,b,i);
  if (e1 < e) {*p = i; e = e1;}
}

static int filled_color_cube;
static void fill_color_cube() {
  filled_color_cube = 1;
  int i;
  // allocate all the colors in the fltk color cube and gray ramp:
  // allocate widely seperated values first so that the bad ones are
  // distributed evenly through the colormap:
  for (i=0;;) {
    fl_xpixel((Fl_Color)(i+FL_COLOR_CUBE));
    i = (i+109)%(FL_NUM_RED*FL_NUM_GREEN*FL_NUM_BLUE); if (!i) break;
  }
  for (i=0;;) {
    fl_xpixel((Fl_Color)(i+FL_GRAY_RAMP));
    i = (i+7)%FL_NUM_GRAY; if (!i) break;
  }
  // fill in the 16x16x16 cube:
  uchar *p = cube;
  for (int r = 0; r<16; r++) {
    for (int g = 0; g<16; g++) {
      for (int b = 0; b<16; b++, p++) {
	// initial try is value from color cube:
	Fl_Color i = fl_color_cube(r*FL_NUM_RED/16, g*FL_NUM_GREEN/16,
				   b*FL_NUM_BLUE/16);
	int e = calc_error(r,g,b,i);
	*p = uchar(i);
	// try neighbor pixels in the cube to see if they are better:
	improve(p,e,r,g,b,i+FL_NUM_RED*FL_NUM_GREEN);
	improve(p,e,r,g,b,i-FL_NUM_RED*FL_NUM_GREEN);
	improve(p,e,r,g,b,i+FL_NUM_GREEN);
	improve(p,e,r,g,b,i-FL_NUM_GREEN);
	improve(p,e,r,g,b,i+1);
	improve(p,e,r,g,b,i-1);
	// try the gray ramp:
	i = fl_gray_ramp(g*FL_NUM_GRAY/15);
	improve(p,e,r,g,b,i);
	improve(p,e,r,g,b,i+1);
	improve(p,e,r,g,b,i-1);
      }
    }
  }
}

static void color8_converter(const uchar *from, uchar *to, int w, int delta) {
  if (!filled_color_cube) fill_color_cube();
  int r=ri, g=gi, b=bi;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    to = to+(w-1);
    d = -delta;
    td = -1;
  } else {
    dir = 1;
    d = delta;
    td = 1;
  }
  for (; w--; from += d, to += td) {
    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
    g += from[1]; if (g < 0) g = 0; else if (g>255) g = 255;
    b += from[2]; if (b < 0) b = 0; else if (b>255) b = 255;
    Fl_XColor* x = fl_xmap[0] + cube[((r<<4)&0xf00)+(g&0xf0)+(b>>4)];
    r -= x->r;
    g -= x->g;
    b -= x->b;
    *to = uchar(x->pixel);
  }
  ri = r; gi = g; bi = b;
}

static void mono8_converter(const uchar *from, uchar *to, int w, int delta) {
  if (!filled_color_cube) fill_color_cube();
  int r=ri;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    to = to+(w-1);
    d = -delta;
    td = -1;
  } else {
    dir = 1;
    d = delta;
    td = 1;
  }
  for (; w--; from += d, to += td) {
    r += from[0]; if (r < 0) r = 0; else if (r>255) r = 255;
    Fl_XColor* x = fl_xmap[0] + cube[(r>>4)*0x111];
    r -= x->g;
    *to = uchar(x->pixel);
  }
  ri = r;
}

#endif

////////////////////////////////////////////////////////////////
// 16 bit TrueColor converters with error diffusion
// Cray computers have no 16-bit type, so we use character pointers
// (which may be slow)

#ifdef U16
#define OUTTYPE U16
#define OUTSIZE 1
#define OUTASSIGN(v) *t = v
#else
#define OUTTYPE uchar
#define OUTSIZE 2
#define OUTASSIGN(v) int tt=v; t[0] = uchar(tt>>8); t[1] = uchar(tt)
#endif

static void color16_converter(const uchar *from, uchar *to, int w, int delta) {
  OUTTYPE *t = (OUTTYPE *)to;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    t = t+(w-1)*OUTSIZE;
    d = -delta;
    td = -OUTSIZE;
  } else {
    dir = 1;
    d = delta;
    td = OUTSIZE;
  }
  int r=ri, g=gi, b=bi;
  for (; w--; from += d, t += td) {
    r = (r&~fl_redmask)  +from[0]; if (r>255) r = 255;
    g = (g&~fl_greenmask)+from[1]; if (g>255) g = 255;
    b = (b&~fl_bluemask) +from[2]; if (b>255) b = 255;
    OUTASSIGN((
      ((r&fl_redmask)<<fl_redshift)+
      ((g&fl_greenmask)<<fl_greenshift)+
      ((b&fl_bluemask)<<fl_blueshift)
      ) >> fl_extrashift);
  }
  ri = r; gi = g; bi = b;
}

static void mono16_converter(const uchar *from,uchar *to,int w, int delta) {
  OUTTYPE *t = (OUTTYPE *)to;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    t = t+(w-1)*OUTSIZE;
    d = -delta;
    td = -OUTSIZE;
  } else {
    dir = 1;
    d = delta;
    td = OUTSIZE;
  }
  uchar mask = fl_redmask & fl_greenmask & fl_bluemask;
  int r=ri;
  for (; w--; from += d, t += td) {
    r = (r&~mask) + *from; if (r > 255) r = 255;
    uchar m = r&mask;
    OUTASSIGN((
      (m<<fl_redshift)+
      (m<<fl_greenshift)+
      (m<<fl_blueshift)
      ) >> fl_extrashift);
  }
  ri = r;
}

// special-case the 5r6g5b layout used by XFree86:

static void c565_converter(const uchar *from, uchar *to, int w, int delta) {
  OUTTYPE *t = (OUTTYPE *)to;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    t = t+(w-1)*OUTSIZE;
    d = -delta;
    td = -OUTSIZE;
  } else {
    dir = 1;
    d = delta;
    td = OUTSIZE;
  }
  int r=ri, g=gi, b=bi;
  for (; w--; from += d, t += td) {
    r = (r&7)+from[0]; if (r>255) r = 255;
    g = (g&3)+from[1]; if (g>255) g = 255;
    b = (b&7)+from[2]; if (b>255) b = 255;
    OUTASSIGN(((r&0xf8)<<8) + ((g&0xfc)<<3) + (b>>3));
  }
  ri = r; gi = g; bi = b;
}

static void m565_converter(const uchar *from,uchar *to,int w, int delta) {
  OUTTYPE *t = (OUTTYPE *)to;
  int d, td;
  if (dir) {
    dir = 0;
    from = from+(w-1)*delta;
    t = t+(w-1)*OUTSIZE;
    d = -delta;
    td = -OUTSIZE;
  } else {
    dir = 1;
    d = delta;
    td = OUTSIZE;
  }
  int r=ri;
  for (; w--; from += d, t += td) {
    r = (r&7) + *from; if (r > 255) r = 255;
    OUTASSIGN((r>>3) * 0x841);
  }
  ri = r;
}

////////////////////////////////////////////////////////////////
// 24bit TrueColor converters:

static void rgb_converter(const uchar *from, uchar *to, int w, int delta) {
  int d = delta-3;
  for (; w--; from += d) {
    *to++ = *from++;
    *to++ = *from++;
    *to++ = *from++;
  }
}

static void bgr_converter(const uchar *from, uchar *to, int w, int delta) {
  for (; w--; from += delta) {
    uchar r = from[0];
    uchar g = from[1];
    *to++ = from[2];
    *to++ = g;
    *to++ = r;
  }
}

static void rrr_converter(const uchar *from, uchar *to, int w, int delta) {
  for (; w--; from += delta) {
    *to++ = *from;
    *to++ = *from;
    *to++ = *from;
  }
}

////////////////////////////////////////////////////////////////
// 32bit TrueColor converters on a 32 or 64-bit machine:

#ifdef U64
#define STORETYPE U64
#if WORDS_BIGENDIAN
#define INNARDS32(f) \
  U64 *t = (U64*)to; \
  int w1 = (w+1)/2; \
  for (; w1--; from += delta) {U64 i = f; from += delta; *t++ = (i<<32)|(f);}
#else
#define INNARDS32(f) \
  U64 *t = (U64*)to; \
  int w1 = (w+1)/2; \
  for (; w1--; from += delta) {U64 i=f; from+= delta; *t++ = ((U64)(f)<<32)|i;}
#endif
#else
#define STORETYPE U32
#define INNARDS32(f)   U32 *t = (U32*)to; for(; w--; from += delta) *t++ = f;
#endif

static void rgbx_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32((unsigned(from[0])<<24)+(from[1]<<16)+(from[2]<<8));
}

static void xbgr_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32((from[0])+(from[1]<<8)+(from[2]<<16));
}

static void xrgb_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32((from[0]<<16)+(from[1]<<8)+(from[2]));
}

static void bgrx_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32((from[0]<<8)+(from[1]<<16)+(unsigned(from[2])<<24));
}

static void rrrx_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32(unsigned(*from) * 0x1010100U);
}

static void xrrr_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32(*from * 0x10101U);
}

static void
color32_converter(const uchar *from, uchar *to, int w, int delta) {
  INNARDS32(
    (from[0]<<fl_redshift)+(from[1]<<fl_greenshift)+(from[2]<<fl_blueshift));
}

static void
mono32_converter(const uchar *from,uchar *to,int w, int delta) {
  INNARDS32(
    (*from << fl_redshift)+(*from << fl_greenshift)+(*from << fl_blueshift));
}

////////////////////////////////////////////////////////////////

static void figure_out_visual() {
  static XPixmapFormatValues *pfvlist;
  static int FL_NUM_pfv;
  if (!pfvlist) pfvlist = XListPixmapFormats(fl_display,&FL_NUM_pfv);
  XPixmapFormatValues *pfv;
  for (pfv = pfvlist; pfv < pfvlist+FL_NUM_pfv; pfv++)
    if (pfv->depth == fl_visual->depth) break;
  i.format = ZPixmap;
  i.byte_order = ImageByteOrder(fl_display);
//i.bitmap_unit = 8;
//i.bitmap_bit_order = MSBFirst;
//i.bitmap_pad = 8;
  i.depth = fl_visual->depth;
  i.bits_per_pixel = pfv->bits_per_pixel;

  if (i.bits_per_pixel & 7) bytes_per_pixel = 0; // produce fatal error
  else bytes_per_pixel = i.bits_per_pixel/8;

  unsigned int n = pfv->scanline_pad/8;
  if (pfv->scanline_pad & 7 || (n&(n-1)))
    Fl::fatal("Can't do scanline_pad of %d",pfv->scanline_pad);
  if (n < sizeof(STORETYPE)) n = sizeof(STORETYPE);
  scanline_add = n-1;
  scanline_mask = -n;

#if USE_COLORMAP
  if (bytes_per_pixel == 1) {
    converter = color8_converter;
    mono_converter = mono8_converter;
    return;
  }
  if (!fl_visual->red_mask)
    Fl::fatal("Can't do %d bits_per_pixel colormap",i.bits_per_pixel);
#endif

  // otherwise it is a TrueColor visual:
  fl_xpixel(0,0,0); // setup fl_redmask, etc, in fl_color.C

  int rs = fl_redshift;
  int gs = fl_greenshift;
  int bs = fl_blueshift;

  switch (bytes_per_pixel) {

  case 2:
    // All 16-bit TrueColor visuals are supported on any machine with
    // 24 or more bits per integer.
#ifdef U16
    ::i.byte_order = WORDS_BIGENDIAN;
#else
    ::i.byte_order = 1;
#endif
    if (rs == 11 && gs == 6 && bs == 0 && fl_extrashift == 3) {
      converter = c565_converter;
      mono_converter = m565_converter;
    } else {
      converter = color16_converter;
      mono_converter = mono16_converter;
    }
    break;

  case 3:
    if (::i.byte_order) {rs = 16-rs; gs = 16-gs; bs = 16-bs;}
    if (rs == 0 && gs == 8 && bs == 16) {
      converter = rgb_converter;
      mono_converter = rrr_converter;
    } else if (rs == 16 && gs == 8 && bs == 0) {
      converter = bgr_converter;
      mono_converter = rrr_converter;
    } else {
      Fl::fatal("Can't do arbitrary 24bit color");
    }
    break;

  case 4:
    if ((::i.byte_order!=0) != WORDS_BIGENDIAN)
      {rs = 24-rs; gs = 24-gs; bs = 24-bs;}
    if (rs == 0 && gs == 8 && bs == 16) {
      converter = xbgr_converter;
      mono_converter = xrrr_converter;
    } else if (rs == 24 && gs == 16 && bs == 8) {
      converter = rgbx_converter;
      mono_converter = rrrx_converter;
    } else if (rs == 8 && gs == 16 && bs == 24) {
      converter = bgrx_converter;
      mono_converter = rrrx_converter;
    } else if (rs == 16 && gs == 8 && bs == 0) {
      converter = xrgb_converter;
      mono_converter = xrrr_converter;
    } else {
      ::i.byte_order = WORDS_BIGENDIAN;
      converter = color32_converter;
      mono_converter = mono32_converter;
    }
    break;

  default:
    Fl::fatal("Can't do %d bits_per_pixel",i.bits_per_pixel);
  }
}
#endif
#define MAXBUFFER 0x40000 // 256k

static void innards(const uchar *buf, int X, int Y, int W, int H,
		    int delta, int linedelta, int mono,
		    Fl_Draw_Image_Cb cb, void* userdata)
{
#ifndef NANO_X //tanghao
  if (!linedelta) linedelta = W*delta;

  int dx, dy, w, h;
  fl_clip_box(X,Y,W,H,dx,dy,w,h);
  if (w<=0 || h<=0) return;
  dx -= X;
  dy -= Y;

  if (!bytes_per_pixel) figure_out_visual();
  i.width = w;
  i.height = h;

  void (*conv)(const uchar *from, uchar *to, int w, int delta) = converter;
  if (mono) conv = mono_converter;

  // See if the data is already in the right format.  Unfortunately
  // some 32-bit x servers (XFree86) care about the unknown 8 bits
  // and they must be zero.  I can't confirm this for user-supplied
  // data, so the 32-bit shortcut is disabled...
  // This can set bytes_per_line negative if image is bottom-to-top
  // I tested it on Linux, but it may fail on other Xlib implementations:
  if (buf && (
#if 0	// set this to 1 to allow 32-bit shortcut
      delta == 4 &&
#if WORDS_BIGENDIAN
      conv == rgbx_converter
#else
      conv == xbgr_converter
#endif
      ||
#endif
      conv == rgb_converter && delta==3
      ) && !(linedelta&scanline_add)) {
    i.data = (char *)(buf+delta*dx+linedelta*dy);
    i.bytes_per_line = linedelta;

  } else {
    int linesize = ((w*bytes_per_pixel+scanline_add)&scanline_mask)/sizeof(STORETYPE);
    int blocking = h;
    static STORETYPE *buffer;	// our storage, always word aligned
    static long buffer_size;
    {int size = linesize*h;
    if (size > MAXBUFFER) {
      size = MAXBUFFER;
      blocking = MAXBUFFER/linesize;
    }
    if (size > buffer_size) {
      delete[] buffer;
      buffer_size = size;
      buffer = new STORETYPE[size];
    }}
    i.data = (char *)buffer;
    i.bytes_per_line = linesize*sizeof(STORETYPE);
    if (buf) {
      buf += delta*dx+linedelta*dy;
      for (int j=0; j<h; ) {
	STORETYPE *to = buffer;
	int k;
	for (k = 0; j<h && k<blocking; k++, j++) {
	  conv(buf, (uchar*)to, w, delta);
	  buf += linedelta;
	  to += linesize;
	}
#ifndef NANO_X //tanghao
	XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);
#endif //tanghao
      }
    } else {
#ifdef __GNUC__
      STORETYPE linebuf[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];
#else
      STORETYPE* linebuf = new STORETYPE[(W*delta+(sizeof(STORETYPE)-1))/sizeof(STORETYPE)];
#endif
      for (int j=0; j<h; ) {
	STORETYPE *to = buffer;
	int k;
	for (k = 0; j<h && k<blocking; k++, j++) {
	  cb(userdata, dx, dy+j, w, (uchar*)linebuf);
	  conv((uchar*)linebuf, (uchar*)to, w, delta);
	  to += linesize;
	}
#ifndef NANO_X
	XPutImage(fl_display,fl_window,fl_gc, &i, 0, 0, X+dx, Y+dy+j-k, w, k);
#endif //tanghao
      }
#ifndef __GNUC__
      delete[] linebuf;
#endif
    }
  }
#else
  if (linedelta == 0) linedelta = W*delta;

  if (buf)
  {
    bool flip_h = (    delta < 0); if (flip_h)     delta = -    delta;
    bool flip_v = (linedelta < 0); if (flip_v) linedelta = -linedelta;
    if (delta >= 1)
    {
      GR_WINDOW_ID id = fl_window;
      GR_GC_ID     gc = GrNewGC();
      U32          prev_fg = (U32) -1;
      GR_POINT     plist[1000];
      int          pcnt = 0;

      for ( int y = 0; y < H; ++y )
      {
        const uchar * pixel = buf;
        buf += linedelta;
        for ( int x = 0; x < W; ++x )
        {
          U32 fg;

	  // calculate the foreground color
	  if (delta >= 3) // presume it's RGB...
            fg = GR_RGB(pixel[0],pixel[1],pixel[2]);
          else // presume it's greyscale
            fg = GR_RGB(pixel[0],pixel[0],pixel[0]);

	  // if the foreground color changed, dump any queued pixels remaining
	  // for the old color, then change the color
          if (fg != prev_fg) {
            if (pcnt) {
              GrPoints(id,gc,pcnt,plist);
              pcnt = 0;
            }
            GrSetGCForeground(gc,fg);
            prev_fg = fg;
          }

          // queue the next pixel value
          plist[pcnt].x = X+(flip_h?(W-x-1):x);
          plist[pcnt].y = Y+(flip_v?(H-y-1):y);
          pcnt++;

          // if we've reached the max. number of queued pixels, dump them
          if (pcnt == sizeof(plist)/sizeof(*plist)) {
            GrPoints(id,gc,pcnt,plist);
            pcnt = 0;
          }

          pixel += delta;
        }
      }

      // dump any remaining queued points
      if (pcnt)
        GrPoints(id,gc,pcnt,plist);

      GrDestroyGC(gc);
    }
    else
    {
      Fl::fatal("Can't do a delta value of %d",delta);
    }
  } 
  else
  {
    int linesize = ((linedelta>0) ? linedelta : -linedelta);
    int blocking = H;
    static uchar * buffer = 0;
    static long buffer_size = 0;
    {
      int size = linesize*H;
      if (size > MAXBUFFER) 
      {
        size = MAXBUFFER;
        blocking = MAXBUFFER/linesize;
      }
      if (size > buffer_size) 
      {
        delete[] buffer;
        buffer_size = size;
        buffer = new uchar[size];
      }
    }
    uchar * linebuf = new uchar[linesize];
    for (int j=0; j<H; ) 
    {
      uchar *to = buffer;
      int k;
      for (k = 0; j<H && k<blocking; k++, j++) 
      {
        cb(userdata, X, Y+j, W, linebuf);
        memcpy(to,linebuf,linesize);
        to += linesize;
      }
      innards(buffer,X,Y+j-k,W,blocking,delta,linedelta,0,0,0);
    }
    delete [] linebuf;
  }
#endif //tanghao
}

void fl_draw_image(const uchar* buf, int x, int y, int w, int h, int d, int l){
  innards(buf,x,y,w,h,d,l,(d<3&&d>-3),0,0);
}
void fl_draw_image(Fl_Draw_Image_Cb cb, void* data,
		   int x, int y, int w, int h,int d) {
  innards(0,x,y,w,h,d,0,(d<3&&d>-3),cb,data);
}
void fl_draw_image_mono(const uchar* buf, int x, int y, int w, int h, int d, int l){
  innards(buf,x,y,w,h,d,l,1,0,0);
}
void fl_draw_image_mono(Fl_Draw_Image_Cb cb, void* data,
		   int x, int y, int w, int h,int d) {
  innards(0,x,y,w,h,d,0,1,cb,data);
}

void fl_rectf(int x, int y, int w, int h, uchar r, uchar g, uchar b) {
#ifndef NANO_X //tanghao
  if (fl_visual->depth > 16) {
    fl_color(r,g,b);
    fl_rectf(x,y,w,h);
  } else {
    uchar c[3];
    c[0] = r; c[1] = g; c[2] = b;
    innards(c,x,y,w,h,0,0,0,0,0);
  }
#else
  // this may need speeded up sometime, as in the above code .. jsk
    fl_color(r,g,b);
    fl_rectf(x,y,w,h);

#endif //tanghao
}

#endif

//
// End of "$Id: fl_draw_image.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Group.cxx ---
//
// "$Id: Fl_Group.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Group widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// The Fl_Group is the only defined container type in fltk.

// Fl_Window itself is a subclass of this, and most of the event
// handling is designed so windows themselves work correctly.

#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
#include <stdlib.h>

Fl_Group* Fl_Group::current_;

// Hack: A single child is stored in the pointer to the array, while
// multiple children are stored in an allocated array:
Fl_Widget*const* Fl_Group::array() const {
  return children_ <= 1 ? (Fl_Widget**)(&array_) : array_;
}

int Fl_Group::find(const Fl_Widget* o) const {
  Fl_Widget*const* a = array();
  int i; for (i=0; i < children_; i++) if (*a++ == o) break;
  return i;
}

extern Fl_Widget* fl_oldfocus; // set by Fl::focus

// For back-compatability, we must adjust all events sent to child
// windows so they are relative to that window.

static int send(Fl_Widget* o, int event) {
  if (o->type() < FL_WINDOW) return o->handle(event);
  int save_x = Fl::e_x; Fl::e_x -= o->x();
  int save_y = Fl::e_y; Fl::e_y -= o->y();
  int ret = o->handle(event);
  Fl::e_y = save_y;
  Fl::e_x = save_x;
  return ret;
}

// translate the current keystroke into up/down/left/right for navigation:
#define ctrl(x) (x^0x40)
static int navkey() {
  switch (Fl::event_key()) {
  case FL_Tab:
    if (!Fl::event_state(FL_SHIFT)) return FL_Right;
  case 0xfe20: // XK_ISO_Left_Tab
    return FL_Left;
  case FL_Right:
    return FL_Right;
  case FL_Left:
    return FL_Left;
  case FL_Up:
    return FL_Up;
  case FL_Down:
    return FL_Down;
  default:
		if(Fl::event_text()) {
			switch (Fl::event_text()[0]) {
				case ctrl('N') : return FL_Down;
				case ctrl('P') : return FL_Up;
				case ctrl('F') : return FL_Right;
				case ctrl('B') : return FL_Left;
			}
		}
  }
  return 0;
}

int Fl_Group::handle(int event) {

  Fl_Widget*const* a = array();
  int i;
  Fl_Widget* o;

  switch (event) {

  case FL_FOCUS:
    switch (navkey()) {
    default:
      if (savedfocus_ && savedfocus_->take_focus()) return 1;
    case FL_Right:
    case FL_Down:
      for (i = children(); i--;) if ((*a++)->take_focus()) return 1;
      break;
    case FL_Left:
    case FL_Up:
      for (i = children(); i--;) if (a[i]->take_focus()) return 1;
      break;
	 }
    return 0;

  case FL_UNFOCUS:
    savedfocus_ = fl_oldfocus;
    return 0;

  case FL_KEYBOARD:
    return navigation(navkey());

  case FL_SHORTCUT:
    for (i = children(); i--;) {
      o = a[i];
      if (o->takesevents() && Fl::event_inside(o) && send(o,FL_SHORTCUT))
	return 1;
    }
    for (i = children(); i--;) {
      o = a[i];
      if (o->takesevents() && !Fl::event_inside(o) && send(o,FL_SHORTCUT))
	return 1;
    }
    if (Fl::event_key() == FL_Enter) return navigation(FL_Down);
    return 0;

  case FL_ENTER:
  case FL_MOVE:
    for (i = children(); i--;) {
      o = a[i];
      if (o->takesevents() && Fl::event_inside(o)) {
	if (o->contains(Fl::belowmouse())) {
	  return send(o,FL_MOVE);
	} else if (send(o,FL_ENTER)) {
	  if (!o->contains(Fl::belowmouse())) Fl::belowmouse(o);
	  return 1;
	}
      }
    }
    Fl::belowmouse(this);
    return 1;

  case FL_PUSH:
    for (i = children(); i--;) {
      o = a[i];
      if (o->takesevents() && Fl::event_inside(o)) {
	if (send(o,FL_PUSH)) {
	  if (Fl::pushed() && !o->contains(Fl::pushed())) Fl::pushed(o);
	  return 1;
	}
      }
    }
    return 0;

  case FL_DEACTIVATE:
  case FL_ACTIVATE:
    for (i = children(); i--;) {
      o = *a++;
      if (o->active()) o->handle(event);
    }
    return 1;

  case FL_SHOW:
  case FL_HIDE:
    for (i = children(); i--;) {
      o = *a++;
      if (o->visible()) o->handle(event);
    }
    return 1;

  default:
    return 0;

  }
}

//void Fl_Group::focus(Fl_Widget *o) {Fl::focus(o); o->handle(FL_FOCUS);}

#if 0
const char *nameof(Fl_Widget *o) {
  if (!o) return "NULL";
  if (!o->label()) return "<no label>";
  return o->label();
}
#endif

// try to move the focus in response to a keystroke:
int Fl_Group::navigation(int key) {
  if (children() <= 1) return 0;
  int i;
  for (i = 0; ; i++) {
    if (i >= children_) return 0;
    if (array_[i]->contains(Fl::focus())) break;
  }
  Fl_Widget *previous = array_[i];

  for (;;) {
    switch (key) {
    case FL_Right:
    case FL_Down:
      i++;
      if (i >= children_) {
	if (parent()) return 0;
	i = 0;
      }
      break;
    case FL_Left:
    case FL_Up:
      if (i) i--;
      else {
	if (parent()) return 0;
	i = children_-1;
      }
      break;
    default:
      return 0;
    }
    Fl_Widget* o = array_[i];
    if (o == previous) return 0;
    switch (key) {
    case FL_Down:
    case FL_Up:
      // for up/down, the widgets have to overlap horizontally:
      if (o->x() >= previous->x()+previous->w() ||
	  o->x()+o->w() <= previous->x()) continue;
    }
    if (o->take_focus()) return 1;
  }
}

////////////////////////////////////////////////////////////////

Fl_Group::Fl_Group(int X,int Y,int W,int H,const char *l)
: Fl_Widget(X,Y,W,H,l) {
  align(FL_ALIGN_TOP);
  children_ = 0;
  array_ = 0;
  savedfocus_ = 0;
  resizable_ = this;
  sizes_ = 0; // this is allocated when first resize() is done
  // Subclasses may want to construct child objects as part of their
  // constructor, so make sure they are add()'d to this object.
  // But you must end() the object!
  begin();
}

void Fl_Group::clear() {
  Fl_Widget*const* old_array = array();
  int old_children = children();
  // clear everything now, in case fl_fix_focus recursively calls us:
  children_ = 0;
  // array_ = 0; dont do this, it will clobber old_array if only one child
  savedfocus_ = 0;
  resizable_ = this;
  init_sizes();
  // okay, now it is safe to destroy the children:
  Fl_Widget*const* a = old_array;
  for (int i=old_children; i--;) {
    Fl_Widget* o = *a++;
    // test the parent to see if child already destructed:
    if (o->parent() == this) delete o;
  }
  if (old_children > 1) free((void*)old_array);
}

Fl_Group::~Fl_Group() {clear();}

void Fl_Group::insert(Fl_Widget &o, int i) {
  if (o.parent()) ((Fl_Group*)(o.parent()))->remove(o);
  o.parent_ = this;
  if (children_ == 0) { // use array pointer to point at single child
    array_ = (Fl_Widget**)&o;
  } else if (children_ == 1) { // go from 1 to 2 children
    Fl_Widget* t = (Fl_Widget*)array_;
    array_ = (Fl_Widget**)malloc(2*sizeof(Fl_Widget*));
    if (i) {array_[0] = t; array_[1] = &o;}
    else {array_[0] = &o; array_[1] = t;}
  } else {
    if (!(children_ & (children_-1))) // double number of children
      array_ = (Fl_Widget**)realloc((void*)array_,
				    2*children_*sizeof(Fl_Widget*));
    int j; for (j = children_; j > i; j--) array_[j] = array_[j-1];
    array_[j] = &o;
  }
  children_++;
  init_sizes();
}

void Fl_Group::add(Fl_Widget &o) {insert(o, children_);}

void Fl_Group::remove(Fl_Widget &o) {
  int i = find(o);
  if (i >= children_) return;
  if (&o == savedfocus_) savedfocus_ = 0;
  o.parent_ = 0;
  children_--;
  if (children_ == 1) { // go from 2 to 1 child
    Fl_Widget *t = array_[!i];
    free((void*)array_);
    array_ = (Fl_Widget**)t;
  } else if (children_ > 1) { // delete from array
    for (; i < children_; i++) array_[i] = array_[i+1];
  }
  init_sizes();
}

////////////////////////////////////////////////////////////////

// Rather lame kludge here, I need to detect windows and ignore the
// changes to X,Y, since all children are relative to X,Y.  That
// is why I check type():

// sizes array stores the initial positions of widgets as
// left,right,top,bottom quads.  The first quad is the group, the
// second is the resizable (clipped to the group), and the
// rest are the children.  This is a convienent order for the
// algorithim.  If you change this be sure to fix Fl_Tile which
// also uses this array!

void Fl_Group::init_sizes() {
  delete[] sizes_; sizes_ = 0;
}

short* Fl_Group::sizes() {
  if (!sizes_) {
    short* p = sizes_ = new short[4*(children_+2)];
    // first thing in sizes array is the group's size:
    if (type() < FL_WINDOW) {p[0] = x(); p[2] = y();} else {p[0] = p[2] = 0;}
    p[1] = p[0]+w(); p[3] = p[2]+h();
    // next is the resizable's size:
    p[4] = p[0]; // init to the group's size
    p[5] = p[1];
    p[6] = p[2];
    p[7] = p[3];
    Fl_Widget* r = resizable();
    if (r && r != this) { // then clip the resizable to it
      int t;
      t = r->x(); if (t > p[0]) p[4] = t;
      t +=r->w(); if (t < p[1]) p[5] = t;
      t = r->y(); if (t > p[2]) p[6] = t;
      t +=r->h(); if (t < p[3]) p[7] = t;
    }
    // next is all the children's sizes:
    p += 8;
    Fl_Widget*const* a = array();
    for (int i=children_; i--;) {
      Fl_Widget* o = *a++;
      *p++ = o->x();
      *p++ = o->x()+o->w();
      *p++ = o->y();
      *p++ = o->y()+o->h();
    }
  }
  return sizes_;
}

void Fl_Group::resize(int X, int Y, int W, int H) {

  if (!resizable() || W==w() && H==h()) {

    if (type() < FL_WINDOW) {
      int dx = X-x();
      int dy = Y-y();
      Fl_Widget*const* a = array();
      for (int i=children_; i--;) {
	Fl_Widget* o = *a++;
	o->resize(o->x()+dx, o->y()+dy, o->w(), o->h());
      }
    }

  } else if (children_) {

    short* p = sizes();

    // get changes in size/position from the initial size:
    int dx = X - p[0];
    int dw = W - (p[1]-p[0]);
    int dy = Y - p[2];
    int dh = H - (p[3]-p[2]);
    if (type() >= FL_WINDOW) dx = dy = 0;
    p += 4;

    // get initial size of resizable():
    int IX = *p++;
    int IR = *p++;
    int IY = *p++;
    int IB = *p++;

    Fl_Widget*const* a = array();
    for (int i=children_; i--;) {
      Fl_Widget* o = *a++;
#if 1
      int X = *p++;
      if (X >= IR) X += dw;
      else if (X > IX) X = IX+((X-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);
      int R = *p++;
      if (R >= IR) R += dw;
      else if (R > IX) R = IX+((R-IX)*(IR+dw-IX)+(IR-IX)/2)/(IR-IX);

      int Y = *p++;
      if (Y >= IB) Y += dh;
      else if (Y > IY) Y = IY+((Y-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
      int B = *p++;
      if (B >= IB) B += dh;
      else if (B > IY) B = IY+((B-IY)*(IB+dh-IY)+(IB-IY)/2)/(IB-IY);
#else // much simpler code from Francois Ostiguy:
      int X = *p++;
      if (X >= IR) X += dw;
      else if (X > IX) X = X + dw * (X-IX)/(IR-IX);
      int R = *p++;
      if (R >= IR) R += dw;
      else if (R > IX) R = R + dw * (R-IX)/(IR-IX);

      int Y = *p++;
      if (Y >= IB) Y += dh;
      else if (Y > IY) Y = Y + dh*(Y-IY)/(IB-IY);
      int B = *p++;
      if (B >= IB) B += dh;
      else if (B > IY) B = B + dh*(B-IY)/(IB-IY);
#endif
      o->resize(X+dx, Y+dy, R-X, B-Y);
    }
  }

  Fl_Widget::resize(X,Y,W,H);
}

void Fl_Group::draw() {
  Fl_Widget*const* a = array();
  if (damage() & ~FL_DAMAGE_CHILD) { // redraw the entire thing:
//  if (1) { // redraw the entire thing:
    draw_box();
    draw_label();
    for (int i=children_; i--;) {
      Fl_Widget& o = **a++;
      draw_child(o);
      draw_outside_label(o);
    }
  } else {	// only redraw the children that need it:
    for (int i=children_; i--;) update_child(**a++);
  }
}

// Draw a child only if it needs it:
void Fl_Group::update_child(Fl_Widget& w) const {
  if (w.damage() && w.visible() && w.type() < FL_WINDOW &&
      fl_not_clipped(w.x(), w.y(), w.w(), w.h())) {
    w.draw();	
    w.clear_damage();
  }
}

// Force a child to redraw:
void Fl_Group::draw_child(Fl_Widget& w) const {
  if (w.visible() && w.type() < FL_WINDOW &&
      fl_not_clipped(w.x(), w.y(), w.w(), w.h())) {
    w.clear_damage(FL_DAMAGE_ALL);
    w.draw();
    w.clear_damage();
  }
}

extern char fl_draw_shortcut;

// Parents normally call this to draw outside labels:
void Fl_Group::draw_outside_label(const Fl_Widget& w) const {
  if (!w.visible()) return;
  // skip any labels that are inside the widget:
  if (!(w.align()&15) || (w.align() & FL_ALIGN_INSIDE)) return;
  // invent a box that is outside the widget:
  int align = w.align();
  int X = w.x();
  int Y = w.y();
  int W = w.w();
  int H = w.h();
  if (align & FL_ALIGN_TOP) {
    align ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
    Y = y();
    H = w.y()-Y;
  } else if (align & FL_ALIGN_BOTTOM) {
    align ^= (FL_ALIGN_BOTTOM|FL_ALIGN_TOP);
    Y = Y+H;
    H = y()+h()-Y;
  } else if (align & FL_ALIGN_LEFT) {
    align ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
    X = x();
    W = w.x()-X-3;
  } else if (align & FL_ALIGN_RIGHT) {
    align ^= (FL_ALIGN_LEFT|FL_ALIGN_RIGHT);
    X = X+W+3;
    W = x()+this->w()-X;
  }
  w.draw_label(X,Y,W,H,(Fl_Align)align);
}

//
// End of "$Id: Fl_Group.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Gl_Overlay.cxx ---
//
// "$Id: Fl_Gl_Overlay.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// OpenGL overlay code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#if HAVE_GL

#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/x.H>
#include "Fl_Gl_Choice.H"
#include <stdlib.h>

#if HAVE_GL_OVERLAY

#ifndef WIN32

// Methods on Fl_Gl_Window that create an overlay window.  Because
// many programs don't need the overlay, this is seperated into this
// source file so it is not linked in if not used.

// Under X this is done by creating another window, of class _Fl_Gl_Overlay
// which is a subclass of Fl_Gl_Window except it uses the overlay planes.
// A pointer to this is stored in the "overlay" pointer of the Fl_Gl_Window.

// Under win32 another GLX context is created to draw into the overlay
// and it is stored in into the "overlay" pointer.

// In both cases if overlay hardware is unavailable, the overlay is
// "faked" by drawing into the main layers.  This is indicated by
// setting overlay == this.

extern XVisualInfo *fl_find_overlay_visual();
extern XVisualInfo *fl_overlay_visual;
extern Colormap fl_overlay_colormap;
extern unsigned long fl_transparent_pixel;
static Fl_Gl_Choice overlay_choice;
extern uchar fl_overlay;

class _Fl_Gl_Overlay : public Fl_Gl_Window {
  void draw();
public:
  void show();
  _Fl_Gl_Overlay(int x, int y, int w, int h) :
    Fl_Gl_Window(x,y,w,h) {
    overlay_choice.vis = fl_overlay_visual;
    overlay_choice.colormap = fl_overlay_colormap;
    overlay_choice.r = 0;
    overlay_choice.d = 0;
    overlay_choice.o = 1;
    g = &overlay_choice;
    set_flag(INACTIVE);
  }
};

void _Fl_Gl_Overlay::draw() {
  if (damage() != FL_DAMAGE_EXPOSE) glClear(GL_COLOR_BUFFER_BIT);
  Fl_Gl_Window *w = (Fl_Gl_Window *)parent();
  uchar save_valid = w->valid_;
  w->valid_ = valid_;
  fl_overlay = 1;
  w->draw_overlay();
  fl_overlay = 0;
  valid_ = w->valid_;
  w->valid_ = save_valid;
}

void _Fl_Gl_Overlay::show() {
  if (shown()) {Fl_Gl_Window::show(); return;}
  fl_background_pixel = int(fl_transparent_pixel);
  Fl_Gl_Window::show();
  fl_background_pixel = -1;
  // find the outermost window to tell wm about the colormap:
  Fl_Window *w = window();
  for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
  XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
}

int Fl_Gl_Window::can_do_overlay() {
  return fl_find_overlay_visual() != 0;
}

#else // WIN32:

static int no_overlay_hardware;
int Fl_Gl_Window::can_do_overlay() {
  if (no_overlay_hardware) return 0;
  // need to write a test here...
  return 1;
}

#endif

#else

int Fl_Gl_Window::can_do_overlay() {return 0;}

#endif

void Fl_Gl_Window::make_overlay() {
  if (!overlay) {
#if HAVE_GL_OVERLAY
#ifdef WIN32
    if (!no_overlay_hardware) {
      HDC hdc = fl_private_dc(this, mode_,&g);
      GLXContext context = wglCreateLayerContext(hdc, 1);
      if (!context) { // no overlay hardware
	no_overlay_hardware = 1;
      } else {
	// copy all colors except #0 into the overlay palette:
	COLORREF pcr[256];
	for (int i = 0; i < 256; i++) {
	  uchar r,g,b; Fl::get_color((Fl_Color)i,r,g,b);
	  pcr[i] = RGB(r,g,b);
	}
	wglSetLayerPaletteEntries(hdc, 1, 1, 255, pcr+1);
	wglRealizeLayerPalette(hdc, 1, TRUE);
	if (fl_first_context) wglShareLists(fl_first_context, context);
	else fl_first_context = context;
	overlay = context;
	valid(0);
	return;
      }
    }
#else
    if (can_do_overlay()) {
      _Fl_Gl_Overlay* o = new _Fl_Gl_Overlay(0,0,w(),h());
      overlay = o;
      add_resizable(*o);
      o->show();
      return;
    }
#endif
#endif
    overlay = this; // fake the overlay
  }
}

void Fl_Gl_Window::redraw_overlay() {
  if (!shown()) return;
  make_overlay();
#ifndef WIN32
  if (overlay != this)
    ((Fl_Gl_Window*)overlay)->redraw();
  else
#endif
    damage(FL_DAMAGE_OVERLAY);
}

void Fl_Gl_Window::make_overlay_current() {
  make_overlay();
#if HAVE_GL_OVERLAY
  if (overlay != this) {
#ifdef WIN32
    fl_set_gl_context(this, (GLXContext)overlay);
#else
    ((Fl_Gl_Window*)overlay)->make_current();
#endif
  } else
#endif
    glDrawBuffer(GL_FRONT);
}

void Fl_Gl_Window::hide_overlay() {
#if HAVE_GL_OVERLAY
#ifdef WIN32
  // nothing needs to be done?  Or should it be erased?
#else
  if (overlay && overlay!=this) ((Fl_Gl_Window*)overlay)->hide();
#endif
#endif
}

#endif

//
// End of "$Id: Fl_Gl_Overlay.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Menu_Button.cxx ---
//
// "$Id: Fl_Menu_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Menu button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/fl_draw.H>
void Fl_Menu_Button::draw() {
  if (!box() || type()) return;
  draw_box(box(), color());
  draw_label();
  if (box() == FL_FLAT_BOX) return; // for XForms compatability
  int H = (labelsize()-3)&-2;
  int X = x()+w()-H*2;
  int Y = y()+(h()-H)/2;
  fl_color(FL_DARK3); fl_line(X+H/2, Y+H, X, Y, X+H, Y);
  fl_color(FL_LIGHT3); fl_line(X+H, Y, X+H/2, Y+H);
}

const Fl_Menu_Item* Fl_Menu_Button::popup() {
  const Fl_Menu_Item* m;

  if (!box() || type()) {
    m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this);
  } else {
    m = menu()->pulldown(x(), y(), w(), h(), 0, this);
  }
  picked(m);
  return m;
}

// Murphy
const Fl_Menu_Item* Fl_Menu_Button::popup( int xx, int yy ) {
  const Fl_Menu_Item *m;

  if (!box() || type()) {
    m = menu()->popup(xx, yy, label(), mvalue(), this);
  } else {
    m = menu()->pulldown(x(), y(), w(), h(), 0, this);
  }
  picked(m);
  return m;
}

int Fl_Menu_Button::handle(int e) {
  if (!menu() || !menu()->text) return 0;
  switch (e) {
  case FL_ENTER:
  case FL_LEAVE:
    return (box() && !type()) ? 1 : 0;
  case FL_PUSH:
    if (!box()) {
      if (Fl::event_button() != 3) return 0;
    } else if (type()) {
      if (!(type() & (1 << (Fl::event_button()-1)))) return 0;
    }
    popup();
    return 1;
  case FL_SHORTCUT:
    if (Fl_Widget::test_shortcut()) {popup(); return 1;}
    return test_shortcut() != 0;
  default:
    return 0;
  }
}

Fl_Menu_Button::Fl_Menu_Button(int X,int Y,int W,int H,const char *l)
: Fl_Menu_(X,Y,W,H,l) {
  down_box(FL_NO_BOX);
}

//
// End of "$Id: Fl_Menu_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_free.cxx ---
//
// "$Id: forms_free.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms free widget routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Emulation of the Forms "free" widget.
// This emulation allows the free demo to run, and has allowed
// me to port several other programs, but it is in no way
// complete.

#include <FL/Fl.H>
#include <FL/Fl_Free.H>

void Fl_Free::step(void *v) {
  Fl_Free *f = (Fl_Free *)v;
  f->handle(FL_STEP);
  Fl::add_timeout(.01,step,v);
}

Fl_Free::Fl_Free(uchar t,int x,int y,int w,int h,const char *l,
		 FL_HANDLEPTR hdl) :
Fl_Widget(x,y,w,h,l) {
  type(t);
  hfunc = hdl;
  if (t == FL_SLEEPING_FREE) set_flag(INACTIVE);
  if (t == FL_CONTINUOUS_FREE || t == FL_ALL_FREE)
    Fl::add_timeout(.01,step,this);
}

Fl_Free::~Fl_Free() {
  Fl::remove_timeout(step,this);
  hfunc(this,FL_FREEMEM,0,0,0);
}

void Fl_Free::draw() {hfunc(this,FL_DRAW,0,0,0);}

int Fl_Free::handle(int e) {
  char key = Fl::event_key();
  switch (e) {
  case FL_FOCUS:
    if (type()!=FL_INPUT_FREE && type()!=FL_ALL_FREE) return 0;
    break;
  case FL_PUSH:
  case FL_DRAG:
  case FL_RELEASE:
    key = 4-Fl::event_button();
    break;
  case FL_SHORTCUT:
    return 0;
  }
  if (hfunc(this, e, float(Fl::event_x()), float(Fl::event_y()), key)) do_callback();
  return 1;
}

//
// End of "$Id: forms_free.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: forms_fselect.cxx ---
//
// "$Id: forms_fselect.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// Forms file selection routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Emulate the Forms file chooser using the fltk file chooser.

#include <FL/forms.H>
#include <string.h>

static char fl_directory[1024];
static const char *fl_pattern;  // assummed passed value is static
static char fl_filename[256];

char* fl_show_file_selector(const char *message,const char *dir,
			    const char *pat,const char *fname) {
  if (dir && dir[0]) strncpy(fl_directory,dir,1023);
  if (pat && pat[0]) fl_pattern = pat;
  if (fname && fname[0]) strncpy(fl_filename,fname,255);
  char *p = fl_directory+strlen(fl_directory);
  if (p > fl_directory && *(p-1)!='/'
#ifdef WIN32
      && *(p-1)!='\\' && *(p-1)!=':'
#endif
      ) *p++ = '/';
  strcpy(p,fl_filename);
  const char *q = fl_file_chooser(message,fl_pattern,fl_directory);
  if (!q) return 0;
  strcpy(fl_directory, q);
  p = (char *)filename_name(fl_directory);
  strcpy(fl_filename, p);
  if (p > fl_directory+1) p--;
  *p = 0;
  return (char *)q;
}

char*	fl_get_directory() {return fl_directory;}

char*	fl_get_pattern() {return (char *)fl_pattern;}

char*	fl_get_filename() {return fl_filename;}

//
// End of "$Id: forms_fselect.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Tile.cxx ---
//
// "$Id: Fl_Tile.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Tile widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Group of 2 or 4 "tiles" that can be resized by dragging border
// The size of the first child determines where the resize border is.
// The resizebox is used to limit where the border can be dragged to.

#include <FL/Fl.H>
#include <FL/Fl_Tile.H>
#include <FL/Fl_Window.H>
#include <stdlib.h>

// Drag the edges that were initially at oldx,oldy to newx,newy:
// pass zero as oldx or oldy to disable drag in that direction:

void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
  Fl_Widget*const* a = array();
  short* p = sizes();
  p += 8; // skip group & resizable's saved size
  for (int i=children(); i--; p += 4) {
    Fl_Widget* o = *a++;
    if (o == resizable()) continue;
    int X = o->x();
    int R = X+o->w();
    if (oix) {
      int t = p[0];
      if (t == oix || t>oix && X<newx || t<oix && X>newx) X = newx;
      t = p[1];
      if (t == oix || t>oix && R<newx || t<oix && R>newx) R = newx;
    }
    int Y = o->y();
    int B = Y+o->h();
    if (oiy) {
      int t = p[2];
      if (t == oiy || t>oiy && Y<newy || t<oiy && Y>newy) Y = newy;
      t = p[3];
      if (t == oiy || t>oiy && B<newy || t<oiy && B>newy) B = newy;
    }
    o->damage_resize(X,Y,R-X,B-Y);
  }
}

// move the lower-right corner (sort of):
void Fl_Tile::resize(int X,int Y,int W,int H) {
  // remember how much to move the child widgets:
  int dx = X-x();
  int dy = Y-y();
  int dw = W-w();
  int dh = H-h();
  short* p = sizes();
  // resize this (skip the Fl_Group resize):
  Fl_Widget::resize(X,Y,W,H);
  // find bottom-right of resiable:
  int OR = p[5];
  int NR = X+W-(p[1]-OR);
  int OB = p[7];
  int NB = Y+H-(p[3]-OB);
  // move everything to be on correct side of new resizable:
  Fl_Widget*const* a = array();
  p += 8;
  for (int i=children(); i--;) {
    Fl_Widget* o = *a++;
    int X = o->x()+dx;
    int R = X+o->w();
    if (*p++ >= OR) X += dw; else if (X > NR) X = NR;
    if (*p++ >= OR) R += dw; else if (R > NR) R = NR;
    int Y = o->y()+dy;
    int B = Y+o->h();
    if (*p++ >= OB) Y += dh; else if (Y > NB) Y = NB;
    if (*p++ >= OB) B += dh; else if (B > NB) B = NB;
    o->resize(X,Y,R-X,B-Y); o->redraw();
  }
}

static void set_cursor(Fl_Tile*t, Fl_Cursor c) {
  static Fl_Cursor cursor;
  if (cursor == c) return;
  cursor = c;
#ifdef __sgi
  t->window()->cursor(c,FL_RED,FL_WHITE);
#else
  t->window()->cursor(c);
#endif
}

static Fl_Cursor cursors[4] = {
  FL_CURSOR_DEFAULT,
  FL_CURSOR_WE,
  FL_CURSOR_NS,
  FL_CURSOR_MOVE};

int Fl_Tile::handle(int event) {
  static int sdrag;
  static int sdx, sdy;
  static int sx, sy;
#define DRAGH 1
#define DRAGV 2
#define GRABAREA 4

  int mx = Fl::event_x();
  int my = Fl::event_y();

  switch (event) {

  case FL_MOVE:
  case FL_ENTER:
  case FL_PUSH: {
    int mindx = 100;
    int mindy = 100;
    int oldx = 0;
    int oldy = 0;
    Fl_Widget*const* a = array();
    short* q = sizes();
    short* p = q+8;
    for (int i=children(); i--; p += 4) {
      Fl_Widget* o = *a++;
      if (o == resizable()) continue;
      if (p[1]<q[1] && o->y()<=my+GRABAREA && o->y()+o->h()>=my-GRABAREA) {
	int t = mx - (o->x()+o->w());
	if (abs(t) < mindx) {
	  sdx = t;
	  mindx = abs(t);
	  oldx = p[1];
	}
      }
      if (p[3]<q[3] && o->x()<=mx+GRABAREA && o->x()+o->w()>=mx-GRABAREA) {
	int t = my - (o->y()+o->h());
	if (abs(t) < mindy) {
	  sdy = t;
	  mindy = abs(t);
	  oldy = p[3];
	}
      }
    }
    sdrag = 0; sx = sy = 0;
    if (mindx <= GRABAREA) {sdrag = DRAGH; sx = oldx;}
    if (mindy <= GRABAREA) {sdrag |= DRAGV; sy = oldy;}
    set_cursor(this, cursors[sdrag]);
    if (sdrag) return 1;
    return Fl_Group::handle(event);
  }

  case FL_LEAVE:
    set_cursor(this, FL_CURSOR_DEFAULT);
    break;

  case FL_DRAG:
    // This is necessary if CONSOLIDATE_MOTION in Fl_x.C is turned off:
    // if (damage()) return 1; // don't fall behind
  case FL_RELEASE: {
    if (!sdrag) return 0; // should not happen
    Fl_Widget* r = resizable(); if (!r) r = this;
    int newx;
    if (sdrag&DRAGH) {
      newx = Fl::event_x()-sdx;
      if (newx < r->x()) newx = r->x();
      else if (newx > r->x()+r->w()) newx = r->x()+r->w();
    } else
      newx = sx;
    int newy;
    if (sdrag&DRAGV) {
      newy = Fl::event_y()-sdy;
      if (newy < r->y()) newy = r->y();
      else if (newy > r->y()+r->h()) newy = r->y()+r->h();
    } else
      newy = sy;
    position(sx,sy,newx,newy);
    do_callback();
    return 1;}

  }

  return Fl_Group::handle(event);
}

//
// End of "$Id: Fl_Tile.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_visual.cxx ---
//
// "$Id: Fl_visual.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// Visual support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Set the default visual according to passed switches:

//#include <config.h>
#include <stdio.h>
#include <FL/Fl.H>
#include <FL/x.H>

#ifdef WIN32
int Fl::visual(int flags) {
  fl_GetDC(0);
  if (flags & FL_DOUBLE) return 0;
  if (!(flags & FL_INDEX) &&
    GetDeviceCaps(fl_gc,BITSPIXEL) <= 8) return 0;
  if ((flags & FL_RGB8) && GetDeviceCaps(fl_gc,BITSPIXEL)<24) return 0;
  return 1;
}

#else

#ifdef NANO_X

int Fl::visual(int flags) {
	printf("Now sopport FL::visula ,now!! in file(Fl_visul.cxx)\n");
	return 0;
}
#else
#if USE_XDBE
#include <X11/extensions/Xdbe.h>
#endif

static int test_visual(XVisualInfo& v, int flags) {
  if (v.screen != fl_screen) return 0;
  if (!(flags & FL_INDEX)) {
    if (v.c_class != StaticColor && v.c_class != TrueColor) return 0;
    if (v.depth <= 8) return 0; // fltk will work better in colormap mode
  }
  if (flags & FL_RGB8) {
    if (v.depth < 24) return 0;
  }
  // for now, fltk does not like colormaps of more than 8 bits:
  if ((v.c_class&1) && v.depth > 8) return 0;
#if USE_XDBE
  if (flags & FL_DOUBLE) {
    static XdbeScreenVisualInfo *xdbejunk;
    if (!xdbejunk) {
      int event_base, error_base;
      if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
      Drawable root = RootWindow(fl_display,fl_screen);
      int numscreens = 1;
      xdbejunk = XdbeGetVisualInfo(fl_display,&root,&numscreens);
      if (!xdbejunk) return 0;
    }
    for (int j = 0; ; j++) {
      if (j >= xdbejunk->count) return 0;
      if (xdbejunk->visinfo[j].visual == v.visualid) break;
    }
  }
#endif
  return 1;
}

int Fl::visual(int flags) {
#if USE_XDBE == 0
  if (flags & FL_DOUBLE) return 0;
#endif
  fl_open_display();
  // always use default if possible:
  if (test_visual(*fl_visual, flags)) return 1;
  // get all the visuals:
  XVisualInfo vTemplate;
  int num;
  XVisualInfo *visualList = XGetVisualInfo(fl_display, 0, &vTemplate, &num);
  // find all matches, use the one with greatest depth:
  XVisualInfo *found = 0;
  for (int i=0; i<num; i++) if (test_visual(visualList[i], flags)) {
    if (!found || found->depth < visualList[i].depth)
      found = &visualList[i];
  }
  if (!found) {XFree((void*)visualList); return 0;}
  fl_visual = found;
  fl_colormap = XCreateColormap(fl_display, RootWindow(fl_display,fl_screen),
				fl_visual->visual, AllocNone);
  return 1;
}
#endif //tanghao
#endif

//
// End of "$Id: Fl_visual.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Value_Input.cxx ---
//
// "$Id: Fl_Value_Input.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Value input widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Fltk widget for drag-adjusting a floating point value.
// Warning: this works by making a child Fl_Input object, even
// though this object is *not* an Fl_Group.  May be a kludge?

#include <FL/Fl.H>
#include <FL/Fl_Value_Input.H>
#include <FL/Fl_Group.H>
#include <stdlib.h>

static Fl_Value_Input* hack_o_rama;

void Fl_Value_Input::input_cb(Fl_Widget*, void* v) {
  Fl_Value_Input& t = *(Fl_Value_Input*)v;
  double nv;
  if (t.step()>=1.0) nv = strtol(t.input.value(), 0, 0);
  else nv = strtod(t.input.value(), 0);
  hack_o_rama = &t;
  t.handle_push();
  t.handle_drag(nv);
  t.handle_release();
  hack_o_rama = 0;
}

void Fl_Value_Input::draw() {
  if (damage()&~FL_DAMAGE_CHILD) input.clear_damage(FL_DAMAGE_ALL);
  input.box(box());
  input.color(color(), selection_color());
  input.draw();
  input.clear_damage();
}

void Fl_Value_Input::resize(int X, int Y, int W, int H) {
  Fl_Valuator::resize(X, Y, W, H);
  input.resize(X, Y, W, H);
}

void Fl_Value_Input::value_damage() {
  if (hack_o_rama==this) return;
  char buf[128];
  format(buf);
  input.value(buf);
  input.mark(input.position()); // turn off selection highlight
}

int Fl_Value_Input::handle(int event) {
  double v;
  int delta;
  int mx = Fl::event_x();
  static int ix, drag;
  switch (event) {
  case FL_PUSH:
    if (!step()) goto DEFAULT;
    ix = mx;
    drag = Fl::event_button();
    handle_push();
    return 1;
  case FL_DRAG:
    if (!step()) goto DEFAULT;
    delta = Fl::event_x()-ix;
    if (delta > 5) delta -= 5;
    else if (delta < -5) delta += 5;
    else delta = 0;
    switch (drag) {
    case 3: v = increment(previous_value(), delta*100); break;
    case 2: v = increment(previous_value(), delta*10); break;
    default:v = increment(previous_value(), delta); break;
    }
    v = round(v);
    handle_drag(soft()?softclamp(v):clamp(v));;
    return 1;
  case FL_RELEASE:
    if (!step()) goto DEFAULT;
    if (value() != previous_value() || !Fl::event_is_click())
      handle_release();
    else {
      input.handle(FL_PUSH);
      input.handle(FL_RELEASE);
    }
    return 1;
  case FL_FOCUS:
    return input.take_focus();
  default:
  DEFAULT:
    input.type(step()>=1.0 ? FL_INT_INPUT : FL_FLOAT_INPUT);
    return input.handle(event);
  }
}

Fl_Value_Input::Fl_Value_Input(int x, int y, int w, int h, const char* l)
: Fl_Valuator(x, y, w, h, l), input(x, y, w, h, 0) {
  soft_ = 0;
  if (input.parent())  // defeat automatic-add
    ((Fl_Group*)input.parent())->remove(input);
  input.parent(this); // kludge!
  input.callback(input_cb, this);
  input.when(FL_WHEN_CHANGED);
  box(input.box());
  color(input.color());
  selection_color(input.selection_color());
  align(FL_ALIGN_LEFT);
  value_damage();
}

//
// End of "$Id: Fl_Value_Input.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Repeat_Button.cxx ---
//
// "$Id: Fl_Repeat_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Repeat button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Repeat_Button.H>

#define INITIALREPEAT .5
#define REPEAT .1

void Fl_Repeat_Button::repeat_callback(void *v) {
  Fl_Button *b = (Fl_Button*)v;
  Fl::add_timeout(REPEAT,repeat_callback,b);
  b->do_callback();
}

int Fl_Repeat_Button::handle(int event) {
  int newval;
  switch (event) {
  case FL_HIDE:
  case FL_DEACTIVATE:
  case FL_RELEASE:
    newval = 0; goto J1;
  case FL_PUSH:
  case FL_DRAG:
    newval = Fl::event_inside(this);
  J1:
    if (value(newval)) {
      if (newval) {
	Fl::add_timeout(INITIALREPEAT,repeat_callback,this);
	do_callback();
      } else {
	Fl::remove_timeout(repeat_callback,this);
      }
    }
    return 1;
  default:
    return Fl_Button::handle(event);
  }
}

//
// End of "$Id: Fl_Repeat_Button.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: ew.xbm ---
#define ew_width 16
#define ew_height 16
#define ew_x_hot 8
#define ew_y_hot 8
static unsigned char ew_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
   0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

--- NEW FILE: Fl_Value_Slider.cxx ---
//
// "$Id: Fl_Value_Slider.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Value slider widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/fl_draw.H>
#include <math.h>

Fl_Value_Slider::Fl_Value_Slider(int x,int y,int w,int h, const char*l)
: Fl_Slider(x,y,w,h,l) {
  step(1,100);
  textfont_ = FL_HELVETICA;
  textsize_ = 10;
  textcolor_ = FL_BLACK;
}

void Fl_Value_Slider::draw() {
  int sxx = x(), syy = y(), sww = w(), shh = h();
  int bxx = x(), byy = y(), bww = w(), bhh = h();
  
  if (horizontal()) {
    bww = 35; sxx += 35; sww -= 35;
#ifdef PDA
	 bww += 1 ;
#endif
  } else {
    syy += 25; bhh = 25; shh -= 25;
#ifdef PDA
	 bhh += 1;
#endif
  }
  if (damage()&FL_DAMAGE_ALL) draw_box(box(),sxx,syy,sww,shh,color());
  Fl_Slider::draw(sxx+Fl::box_dx(box()),
		  syy+Fl::box_dy(box()),
		  sww-Fl::box_dw(box()),
		  shh-Fl::box_dh(box()));
  draw_box(box(),bxx,byy,bww,bhh,color());
  char buf[128];
  format(buf);
  fl_font(textfont(), textsize());
  fl_color(active_r() ? textcolor() : inactive(textcolor()));
  fl_draw(buf, bxx, byy, bww, bhh, FL_ALIGN_CLIP);
}

int Fl_Value_Slider::handle(int event) {
  int sxx = x(), syy = y(), sww = w(), shh = h();
  if (horizontal()) {
    sxx += 35; sww -= 35;
  } else {
    syy += 25; shh -= 25;
  }
  return Fl_Slider::handle(event,
			   sxx+Fl::box_dx(box()),
			   syy+Fl::box_dy(box()),
			   sww-Fl::box_dw(box()),
			   shh-Fl::box_dh(box()));
}

//
// End of "$Id: Fl_Value_Slider.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Light_Button.cxx ---
//
// "$Id: Fl_Light_Button.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Lighted button widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Subclass of Fl_Button where the "box" indicates whether it is
// pushed or not, and the "down box" is drawn small and square on
// the left to indicate the current state.

// The default down_box of zero draws a rectangle designed to look
// just like Flame's buttons.

#include <FL/Fl.H>
#include <FL/Fl_Light_Button.H>
#include <FL/fl_draw.H>

void Fl_Light_Button::draw() {
  if (box()) draw_box(this==Fl::pushed() ? down(box()) : box(), color());
  Fl_Color col = value() ? selection_color() : color();
  int d = h()/6;
  int W = w()<h() ? w() : h();
  if (down_box()) {
    // draw other down_box() styles:
    draw_box(down_box(), x()+d, y()+d+1, W-2*d-2, W-2*d-2, col);
  } else {
    // if down_box() is zero, draw light button style:
    int hh = h()-2*d;
    int ww = hh/2+1;
    int xx = d*2;
    if (w()<ww+2*xx) xx = (w()-ww)/2;
    draw_box(FL_THIN_DOWN_BOX, x()+xx, y()+d, ww, hh, col);
  }
#ifdef PDA
  labelcolor(labelcolor());
#endif
  draw_label(x()+W-d, y(), w()-W+d, h());
}

int Fl_Light_Button::handle(int event) {
  switch (event) {
  case FL_RELEASE:
    if (box()) redraw();
  default:
    return Fl_Button::handle(event);
  }
}

Fl_Light_Button::Fl_Light_Button(int x, int y, int w, int h, const char* l)
: Fl_Button(x, y, w, h, l) {
  type(FL_TOGGLE_BUTTON);
  selection_color(FL_YELLOW);
  align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
}

//
// End of "$Id: Fl_Light_Button.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Chart.cxx ---
//
// "$Id: Fl_Chart.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Forms-compatible chart widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/math.h>
#include <FL/Fl.H>
#include <FL/Fl_Chart.H>
#include <FL/fl_draw.H>
#include <string.h>
#include <stdlib.h>

#define ARCINC	(2.0*M_PI/360.0)

// this function is in fl_boxtype.C:
void fl_rectbound(int x,int y,int w,int h, Fl_Color color);

/* Widget specific information */

static void draw_barchart(int x,int y,int w,int h,
			  int numb, FL_CHART_ENTRY entries[],
			  double min, double max, int autosize, int maxnumb,
			  Fl_Color textcolor)
/* Draws a bar chart. x,y,w,h is the bounding box, entries the array of
   numb entries and min and max the boundaries. */
{
  double incr;
  int zeroh;
  double lh = fl_height();
  if (max == min) incr = h;
  else incr = h/(max-min);
  if ( (-min*incr) < lh) {
      incr = (h - lh + min*incr)/(max-min);
      zeroh = int(y+h-lh);
  } else {
      zeroh = int(y+h+min * incr + .5);
  }
  int bwidth = int(w/double(autosize?numb:maxnumb)+.5);
  /* Draw base line */
  fl_color(textcolor);
  fl_line(x, zeroh, x+w, zeroh);
  if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
  int i;
  /* Draw the bars */
  for (i=0; i<numb; i++) {
      int h = int(entries[i].val*incr+.5);
      if (h < 0)
	fl_rectbound(x+i*bwidth,zeroh,bwidth+1,-h+1, (Fl_Color)entries[i].col);
      else if (h > 0)
	fl_rectbound(x+i*bwidth,zeroh-h,bwidth+1,h+1,(Fl_Color)entries[i].col);
  }
  /* Draw the labels */
  fl_color(textcolor);
  for (i=0; i<numb; i++)
      fl_draw(entries[i].str,
	      x+i*bwidth+bwidth/2,zeroh,0,0,
	      FL_ALIGN_TOP);
}

static void draw_horbarchart(int x,int y,int w,int h,
			     int numb, FL_CHART_ENTRY entries[],
			     double min, double max, int autosize, int maxnumb,
			     Fl_Color textcolor)
/* Draws a horizontal bar chart. x,y,w,h is the bounding box, entries the
   array of numb entries and min and max the boundaries. */
{
  int i;
  double lw = 0.0;		/* Maximal label width */
  /* Compute maximal label width */
  for (i=0; i<numb; i++) {
      double w1 = fl_width(entries[i].str);
      if (w1 > lw) lw = w1;
  }
  if (lw > 0.0) lw += 4.0;
  double incr;
  int zeroh;
  if (max == min) incr = w;
  else incr = w/(max-min);
  if ( (-min*incr) < lw) {
      incr = (w - lw + min*incr)/(max-min);
      zeroh = x+int(lw+.5);
  } else {
      zeroh = int(x-min * incr + .5);
  }
  int bwidth = int(h/double(autosize?numb:maxnumb)+.5);
  /* Draw base line */
  fl_color(textcolor);
  fl_line(zeroh, y, zeroh, y+h);
  if (min == 0.0 && max == 0.0) return; /* Nothing else to draw */
  /* Draw the bars */
  for (i=0; i<numb; i++) {
      int w = int(entries[i].val*incr+.5);
      if (w > 0)
	fl_rectbound(zeroh,y+i*bwidth,w+1,bwidth+1, (Fl_Color)entries[i].col);
      else if (w < 0)
	fl_rectbound(zeroh+w,y+i*bwidth,-w+1,bwidth+1,(Fl_Color)entries[i].col);
  }
  /* Draw the labels */
  for (i=0; i<numb; i++)
      fl_draw(entries[i].str,
	      zeroh-2,y+i*bwidth+bwidth/2,0,0,
	      FL_ALIGN_RIGHT);
}

static void draw_linechart(int type, int x,int y,int w,int h,
			   int numb, FL_CHART_ENTRY entries[],
			   double min, double max, int autosize, int maxnumb,
			   Fl_Color textcolor)
/* Draws a line chart. x,y,w,h is the bounding box, entries the array of
   numb entries and min and max the boundaries. */
{
  int i;
  double lh = fl_height();
  double incr;
  if (max == min) incr = h-2.0*lh;
  else incr = (h-2.0*lh)/ (max-min);
  int zeroh = int(y+h-lh+min * incr + .5);
  double bwidth = w/double(autosize?numb:maxnumb);
  /* Draw the values */
  for (i=0; i<numb; i++) {
      int x0 = x + int((i-.5)*bwidth+.5);
      int x1 = x + int((i+.5)*bwidth+.5);
      int y0 = i ? zeroh - int(entries[i-1].val*incr+.5) : 0;
      int y1 = zeroh - int(entries[i].val*incr+.5);
      if (type == FL_SPIKE_CHART) {
	  fl_color((Fl_Color)entries[i].col);
	  fl_line(x1, zeroh, x1, y1);
      } else if (type == FL_LINE_CHART && i != 0) {
	  fl_color((Fl_Color)entries[i-1].col);
	  fl_line(x0,y0,x1,y1);
      } else if (type == FL_FILLED_CHART && i != 0) {
	  fl_color((Fl_Color)entries[i-1].col);
	  if ((entries[i-1].val>0.0)!=(entries[i].val>0.0)) {
	      double ttt = entries[i-1].val/(entries[i-1].val-entries[i].val);
	      int xt = x + int((i-.5+ttt)*bwidth+.5);
	      fl_polygon(x0,zeroh, x0,y0, xt,zeroh);
	      fl_polygon(xt,zeroh, x1,y1, x1,zeroh);
	  } else {
	      fl_polygon(x0,zeroh, x0,y0, x1,y1, x1,zeroh);
	  }
	  fl_color(textcolor);
	  fl_line(x0,y0,x1,y1);
      }
  }
  /* Draw base line */
  fl_color(textcolor);
  fl_line(x,zeroh,x+w,zeroh);
  /* Draw the labels */
  for (i=0; i<numb; i++)
      fl_draw(entries[i].str,
	      x+int((i+.5)*bwidth+.5), zeroh - int(entries[i].val*incr+.5),0,0,
	      entries[i].val>=0 ? FL_ALIGN_BOTTOM : FL_ALIGN_TOP);
}

static void draw_piechart(int x,int y,int w,int h,
			  int numb, FL_CHART_ENTRY entries[], int special,
			  Fl_Color textcolor)
/* Draws a pie chart. x,y,w,h is the bounding box, entries the array of
   numb entries */
{
  int i;
  double xc,yc,rad;	/* center and radius */
  double tot;		/* sum of values */
  double incr;		/* increment in angle */
  double curang;		/* current angle we are drawing */
  double txc,tyc;	/* temporary center */
  double lh = fl_height();
  /* compute center and radius */
  xc = x+w/2.0; yc = y+h/2.0;
  rad = h/2.0 - lh;
  if (special) { yc += 0.1*rad; rad = 0.9*rad;}
  /* compute sum of values */
  tot = 0.0;
  for (i=0; i<numb; i++)
    if (entries[i].val > 0.0) tot += entries[i].val;
  if (tot == 0.0) return;
  incr = 360.0/tot;
  /* Draw the pie */
  curang = 0.0;
  for (i=0; i<numb; i++)
    if (entries[i].val > 0.0)
    {
      txc = xc; tyc = yc;
      /* Correct for special pies */
      if (special && i==0)
      {
        txc += 0.3*rad*cos(ARCINC*(curang+0.5*incr*entries[i].val));
        tyc -= 0.3*rad*sin(ARCINC*(curang+0.5*incr*entries[i].val));
      }
      fl_color((Fl_Color)entries[i].col);
      fl_begin_polygon(); fl_vertex(txc,tyc);
      fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
      fl_end_polygon();
      fl_color(textcolor);
      fl_begin_loop(); fl_vertex(txc,tyc);
      fl_arc(txc,tyc,rad,curang, curang+incr*entries[i].val);
      fl_end_loop();
      curang += 0.5 * incr * entries[i].val;
      /* draw the label */
      double xl = txc + 1.1*rad*cos(ARCINC*curang);
      fl_draw(entries[i].str,
	      int(xl+.5),
	      int(tyc - 1.1*rad*sin(ARCINC*curang)+.5),
	      0, 0,
	      xl<txc ? FL_ALIGN_RIGHT : FL_ALIGN_LEFT);
      curang += 0.5 * incr * entries[i].val;
    }
}

void Fl_Chart::draw() {
    int xx,yy,ww,hh;
    int i;

    xx = x()+9;
    yy = y()+9;
    ww = w()-2*9;
    hh = h()-2*9;

    if (min >= max) {
	min = max = 0.0;
	for (i=0; i<numb; i++) {
	    if (entries[i].val < min) min = entries[i].val;
	    if (entries[i].val > max) max = entries[i].val;
	}
    }

    draw_box();
    fl_font(textfont(),textsize());

    switch (type()) {
    case FL_BAR_CHART:
	draw_barchart(xx,yy,ww,hh, numb, entries, min, max,
			autosize(), maxnumb, textcolor());
	break;
    case FL_HORBAR_CHART:
	draw_horbarchart(xx,yy,ww,hh, numb, entries, min, max,
			autosize(), maxnumb, textcolor());
	break;
    case FL_PIE_CHART:
	draw_piechart(xx,yy,ww,hh,numb,entries,0, textcolor());
	break;
    case FL_SPECIALPIE_CHART:
	draw_piechart(xx,yy,ww,hh,numb,entries,1,textcolor());
	break;
    default:
	draw_linechart(type(),xx,yy,ww,hh, numb, entries, min, max,
			autosize(), maxnumb, textcolor());
	break;
    }
    draw_label();
}

/*------------------------------*/

#define FL_CHART_BOXTYPE	FL_BORDER_BOX
#define FL_CHART_COL1		FL_COL1
#define FL_CHART_LCOL		FL_LCOL
#define FL_CHART_ALIGN		FL_ALIGN_BOTTOM

Fl_Chart::Fl_Chart(int x,int y,int w,int h,const char *l) :
Fl_Widget(x,y,w,h,l) {
  box(FL_BORDER_BOX);
  align(FL_ALIGN_BOTTOM);
  numb       = 0;
  maxnumb    = 0;
  sizenumb   = FL_CHART_MAX;
  autosize_  = 1;
  min = max  = 0;
  textfont_  = FL_HELVETICA;
  textsize_  = 10;
  textcolor_ = FL_BLACK;
  entries    = (FL_CHART_ENTRY *)calloc(sizeof(FL_CHART_ENTRY), FL_CHART_MAX + 1);
}

void Fl_Chart::clear() {
  numb = 0;
  redraw();
}

void Fl_Chart::add(double val, const char *str, uchar col) {
  /* Allocate more entries if required */
  if (numb >= sizenumb) {
    sizenumb += FL_CHART_MAX;
    entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1));
  }
  // Shift entries as needed
  if (numb >= maxnumb && maxnumb > 0) {
    memcpy(entries, entries + 1, sizeof(FL_CHART_ENTRY) * (numb - 1));
    numb --;
  }
  entries[numb].val = float(val);
  entries[numb].col = col;
    if (str) {
	strncpy(entries[numb].str,str,FL_CHART_LABEL_MAX+1);
	entries[numb].str[FL_CHART_LABEL_MAX] = 0;
    } else {
	entries[numb].str[0] = 0;
    }
  numb++;
  redraw();
}

void Fl_Chart::insert(int index, double val, const char *str, uchar col) {
  int i;
  if (index < 1 || index > numb+1) return;
  /* Allocate more entries if required */
  if (numb >= sizenumb) {
    sizenumb += FL_CHART_MAX;
    entries = (FL_CHART_ENTRY *)realloc(entries, sizeof(FL_CHART_ENTRY) * (sizenumb + 1));
  }
  // Shift entries as needed
  for (i=numb; i >= index; i--) entries[i] = entries[i-1];
  if (numb < maxnumb || maxnumb == 0) numb++;
  /* Fill in the new entry */
  entries[index-1].val = float(val);
  entries[index-1].col = col;
  if (str) {
      strncpy(entries[index-1].str,str,FL_CHART_LABEL_MAX+1);
      entries[index-1].str[FL_CHART_LABEL_MAX] = 0;
  } else {
      entries[index-1].str[0] = 0;
  }
  redraw();
}

void Fl_Chart::replace(int index,double val, const char *str, uchar col) {
  if (index < 1 || index > numb) return;
  entries[index-1].val = float(val);
  entries[index-1].col = col;
  if (str) {
      strncpy(entries[index-1].str,str,FL_CHART_LABEL_MAX+1);
      entries[index-1].str[FL_CHART_LABEL_MAX] = 0;
  } else {
      entries[index-1].str[0] = 0;
  }
  redraw();
}

void Fl_Chart::bounds(double min, double max) {
  this->min = min;
  this->max = max;
  redraw();
}

void Fl_Chart::maxsize(int m) {
  int i;
  /* Fill in the new number */
  if (m < 0) return;
  maxnumb = m;
  /* Shift entries if required */
  if (numb > maxnumb) {
      for (i = 0; i<maxnumb; i++)
	  entries[i] = entries[i+numb-maxnumb];
      numb = maxnumb;
      redraw();
  }
}

//
// End of "$Id: Fl_Chart.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Window_fullscreen.cxx ---
//
// "$Id: Fl_Window_fullscreen.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Fullscreen window support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Turning the border on/off by changing the motif_wm_hints property
// works on Irix 4DWM.  Does not appear to work for any other window
// manager.  Fullscreen still works on some window managers (fvwm is one)
// because they allow the border to be placed off-screen.

// Unfortunatly most X window managers ignore changes to the border
// and refuse to position the border off-screen, so attempting to make
// the window full screen will lose the size of the border off the
// bottom and right.

#include <FL/Fl.H>
#include <FL/x.H>

void Fl_Window::border(int b) {
  if (b) {
    if (border()) return;
    clear_flag(FL_NOBORDER);
  } else {
    if (!border()) return;
    set_flag(FL_NOBORDER);
  }
#ifdef WIN32
  // not yet implemented, but it's possible
  // for full fullscreen we have to make the window topmost as well
#else
  if (shown()) Fl_X::i(this)->sendxjunk();
#endif
}

void Fl_Window::fullscreen() {
#ifndef WIN32
  //this would clobber the fake wm, since it relies on the border flags to
  //determine its thickness
  border(0);
#endif
  if (!x()) x(1); // force it to call XResizeWindow()
  resize(0,0,Fl::w(),Fl::h());
}

void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
  // this order produces less blinking on IRIX:
  resize(X,Y,W,H);
#ifndef WIN32
  border(1);
#endif
}

//
// End of "$Id: Fl_Window_fullscreen.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl.cxx ---
#include <stdio.h>
//
// "$Id: Fl.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Main event handling code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/x.H>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
//
// Globals...
//

Fl_Widget	*Fl::belowmouse_,
		*Fl::pushed_,
		*Fl::focus_,
		*Fl::selection_owner_;
int		Fl::damage_,
		Fl::e_x,
		Fl::e_y,
		Fl::e_x_root,
		Fl::e_y_root,
		Fl::e_state,
		Fl::e_clicks,
		Fl::e_is_click,
		Fl::e_keysym;
char		*Fl::e_text = "";
int		Fl::e_length;

static double fl_elapsed();

//
// 'Fl:event_inside()' - Return whether or not the mouse event is inside
//                       the given rectangle.
//

int Fl::event_inside(int x,int y,int w,int h) /*const*/ {
  int mx = event_x() - x;
  int my = event_y() - y;

  return (mx >= 0 && mx < w && my >= 0 && my < h);
}

int Fl::event_inside(const Fl_Widget *o) /*const*/ {
  return event_inside(o->x(),o->y(),o->w(),o->h());
}

// Timeouts are insert-sorted into order.  This works good if there
// are only a small number:

static struct Timeout {
  double time;
  void (*cb)(void*);
  void* arg;
} * timeout;
static int numtimeouts;
static int timeout_array_size;

void Fl::add_timeout(double t, void (*cb)(void *), void *v) {

  fl_elapsed();

  if (numtimeouts >= timeout_array_size) {
    timeout_array_size = 2*timeout_array_size+1;
    timeout = (Timeout*)realloc(timeout, timeout_array_size*sizeof(Timeout));
  }

  // insert-sort the new timeout:
  int i;
  for (i=0; i<numtimeouts; i++) {
    if (timeout[i].time > t) {
      for (int j=numtimeouts; j>i; j--) timeout[j] = timeout[j-1];
      break;
    }
  }
  timeout[i].time = t;
  timeout[i].cb = cb;
  timeout[i].arg = v;

  numtimeouts++;
}

void Fl::remove_timeout(void (*cb)(void *), void *v) {
  int i,j;
  for (i=j=0; i<numtimeouts; i++) {
    if (timeout[i].cb == cb && timeout[i].arg==v) ;
    else {if (j<i) timeout[j]=timeout[i]; j++;}
  }
  numtimeouts = j;
}

static int call_timeouts() {
  int expired = 0;
  while (numtimeouts) {
    if (timeout[0].time > 0) break;
    // we must remove timeout from array before doing the callback:
    void (*cb)(void*) = timeout[0].cb;
    void *arg = timeout[0].arg;
    numtimeouts--; expired++;
    if (numtimeouts) memmove(timeout, timeout+1, numtimeouts*sizeof(Timeout));
    // now it is safe for the callback to do add_timeout:
    cb(arg);
  }
  return expired;
}

void Fl::flush() {
  if (damage()) {
    damage_ = 0;
    for (Fl_X* x = Fl_X::first; x; x = x->next) {
      if (x->w->damage() && x->w->visible_r()) {
//      if (1) {
	if (x->wait_for_expose) {
	  // leave Fl::damage() set so programs can tell damage still exists
	  	damage_ = 1;
		x->wait_for_expose=0;//tanghao
	} else {
	  x->flush();
	  x->w->clear_damage();
	}
      }
    }
  }
#ifndef WIN32
#ifdef NANO_X
  if (fl_display)GrFlush();
#else
  if (fl_display) XFlush(fl_display);
#endif
#endif
}

extern double fl_wait(int timeout_flag, double timeout);
extern int fl_ready();

static int initclock; // if false we didn't call fl_elapsed() last time

#ifndef WIN32
#include <sys/time.h>
#endif

// fl_elapsed must return the amount of time since the last time it was
// called.  To reduce the number of system calls to get the
// current time, the "initclock" symbol is turned on by an indefinite
// wait.  This should then reset the measured-from time and return zero
static double fl_elapsed() {

#ifdef WIN32

  unsigned long newclock = GetTickCount();
  const int TICKS_PER_SECOND = 1000; // divisor of the value to get seconds
  static unsigned long prevclock;
  if (!initclock) {prevclock = newclock; initclock = 1; return 0.0;}
  else if (newclock < prevclock) return 0.0;

  double t = double(newclock-prevclock)/TICKS_PER_SECOND;
  prevclock = newclock;

#else

  static struct timeval prevclock;
  struct timeval newclock;
  gettimeofday(&newclock, NULL);
  if (!initclock) {
    prevclock.tv_sec = newclock.tv_sec;
    prevclock.tv_usec = newclock.tv_usec;
    initclock = 1;
    return 0.0;
  }
  double t = newclock.tv_sec - prevclock.tv_sec +
    (newclock.tv_usec - prevclock.tv_usec)/1000000.0;
  prevclock.tv_sec = newclock.tv_sec;
  prevclock.tv_usec = newclock.tv_usec;

#endif

  // expire any timeouts:
  if (t > 0.0) for (int i=0; i<numtimeouts; i++) timeout[i].time -= t;
  return t;
}

void (*Fl::idle)();
static char in_idle;
static void callidle() {
  if (!Fl::idle || in_idle) return;
  in_idle = 1;
  Fl::idle();
  in_idle = 0;
}

int Fl::wait() {
  callidle();
  int expired = 0;
  if (numtimeouts) {fl_elapsed(); expired = call_timeouts();}
  flush();
  //if (!Fl_X::first) return 0; // no windows
  if (!Fl_X::first) {
      fl_wait(1,1);
      return 0;
  } else if ((idle && !in_idle) || expired) {
    fl_wait(1,0.0);
  } else if (numtimeouts) {
    fl_wait(1, timeout[0].time);
  } else {
    initclock = 0;
    //if (!Fl_X::first) {
    //  fl_wait(1,1);
    //  return 0;
    //} else {
      fl_wait(0,0);
    //}
  }
  return 1;
}

double Fl::wait(double time) {
  callidle();
  int expired = 0;
  if (numtimeouts) {time -= fl_elapsed(); expired = call_timeouts();}
  flush();
  double wait_time = (idle && !in_idle) || expired ? 0.0 : time;
  if (numtimeouts && timeout[0].time < wait_time) wait_time = timeout[0].time;
  fl_wait(1, wait_time);
  return time - fl_elapsed();
}

int Fl::check() {
  callidle();
  if (numtimeouts) {fl_elapsed(); call_timeouts();}
  fl_wait(1, 0.0);
  flush();
  return Fl_X::first != 0; // return true if there is a window
}

int Fl::ready() {
  // if (idle && !in_idle) return 1; // should it do this?
  if (numtimeouts) {fl_elapsed(); if (timeout[0].time <= 0) return 1;}
  return fl_ready();
}

int Fl::run() {
  while (wait());
  return 0;
}

////////////////////////////////////////////////////////////////
// Window list management:

Fl_X* Fl_X::first;

Fl_Window* fl_find(Window xid) {
  Fl_X *window;
  for (Fl_X **pp = &Fl_X::first; (window = *pp); pp = &window->next)
    if (window->xid == xid) {
      if (window != Fl_X::first && !Fl::modal()) {
	// make this window be first to speed up searches
	// this is not done if modal is true to avoid messing up modal stack
	*pp = window->next;
	window->next = Fl_X::first;
	Fl_X::first = window;
      }
      return window->w;
    }
  return 0;
}

void Fl::redraw() {
  for (Fl_X* x = Fl_X::first; x; x = x->next) x->w->redraw();
}

Fl_Window* Fl::first_window() {Fl_X* x = Fl_X::first; return x ? x->w : 0;}

Fl_Window* Fl::next_window(const Fl_Window* w) {
  Fl_X* x = Fl_X::i(w)->next; return x ? x->w : 0;}

////////////////////////////////////////////////////////////////
// Event handlers:

struct handler_link {
  int (*handle)(int);
  const handler_link *next;
};

static const handler_link *handlers = 0;

void Fl::add_handler(int (*h)(int)) {
  handler_link *l = new handler_link;
  l->handle = h;
  l->next = handlers;
  handlers = l;
}

static int send_handlers(int event) {
  for (const handler_link *h = handlers; h; h = h->next)
    if (h->handle(event)) return 1;
  return 0;
}

////////////////////////////////////////////////////////////////

Fl_Widget* fl_oldfocus; // kludge for Fl_Group...

void Fl::focus(Fl_Widget *o) {
  if (grab()) return; // don't do anything while grab is on
  Fl_Widget *p = focus_;
  if (o != p) {
    focus_ = o;
    fl_oldfocus = 0;
    for (; p && !p->contains(o); p = p->parent()) {
      p->handle(FL_UNFOCUS);
      fl_oldfocus = p;
    }
  }
}

void Fl::belowmouse(Fl_Widget *o) {
  if (grab()) return; // don't do anything while grab is on
  Fl_Widget *p = belowmouse_;
  if (o != p) {
    event_is_click(0);
    belowmouse_ = o;
    for (; p && !p->contains(o); p = p->parent()) p->handle(FL_LEAVE);
  }
}

void Fl::pushed(Fl_Widget *o) {
  pushed_ = o;
}

Fl_Window *fl_xfocus;	// which window X thinks has focus
Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER
Fl_Window *Fl::grab_;	// most recent Fl::grab()
Fl_Window *Fl::modal_;	// topmost modal() window

// Update modal(), focus() and other state according to system state,
// and send FL_ENTER, FL_LEAVE, FL_FOCUS, and/or FL_UNFOCUS events.
// This is the only function that produces these events in response
// to system activity.
// This is called whenever a window is added or hidden, and whenever
// X says the focus or mouse window have changed.

void fl_fix_focus() {

  if (Fl::grab()) return; // don't do anything while grab is on.

  // set focus based on Fl::modal() and fl_xfocus
  Fl_Widget* w = fl_xfocus;
  if (w) {
    while (w->parent()) w = w->parent();
    if (Fl::modal()) w = Fl::modal();
    if (!w->contains(Fl::focus()))
      if (!w->take_focus()) Fl::focus(w);
  } else
    Fl::focus(0);

  if (!Fl::pushed()) {

    // set belowmouse based on Fl::modal() and fl_xmousewin:
    w = fl_xmousewin;
    if (w) {
      if (Fl::modal()) w = Fl::modal();
      if (!w->contains(Fl::belowmouse())) {
	Fl::belowmouse(w);
	w->handle(FL_ENTER);
      } else {
	// send a FL_MOVE event so the enter/leave state is up to date
	Fl::e_x = Fl::e_x_root-fl_xmousewin->x();
	Fl::e_y = Fl::e_y_root-fl_xmousewin->y();
	w->handle(FL_MOVE);
      }
    } else {
      Fl::belowmouse(0);
    }
  }
}

#ifndef WIN32
Fl_Widget *fl_selection_requestor; // from Fl_cutpaste.C
#endif

// This function is called by ~Fl_Widget() and by Fl_Widget::deactivate
// and by Fl_Widget::hide().  It indicates that the widget does not want
// to receive any more events, and also removes all global variables that
// point at the widget.
// I changed this from the 1.0.1 behavior, the older version could send
// FL_LEAVE or FL_UNFOCUS events to the widget.  This appears to not be
// desirable behavior and caused flwm to crash.

void fl_throw_focus(Fl_Widget *o) {
  if (o->contains(Fl::pushed())) Fl::pushed_ = 0;
  if (o->contains(Fl::selection_owner())) Fl::selection_owner_ = 0;
#ifndef WIN32
  if (o->contains(fl_selection_requestor)) fl_selection_requestor = 0;
#endif
  if (o->contains(Fl::belowmouse())) Fl::belowmouse_ = 0;
  if (o->contains(Fl::focus())) Fl::focus_ = 0;
  if (o == fl_xfocus) fl_xfocus = 0;
  if (o == fl_xmousewin) fl_xmousewin = 0;
  fl_fix_focus();
}

////////////////////////////////////////////////////////////////

// Call to->handle but first replace the mouse x/y with the correct
// values to account for nested X windows. 'window' is the outermost

#if 0
static int send(int event, Fl_Widget* to, Fl_Window* window) {
  
  // Microwindows Hack

  int ret = to->handle(event);

  return ret;
}

#else

// window the event was posted to by X:
static int send(int event, Fl_Widget* to, Fl_Window* window) {

  int dx = window->x();
  int dy = window->y();
  
  for (const Fl_Widget* w = to; w; w = w->parent())
    if (w->type()>=FL_WINDOW) {
      dx -= w->x(); dy -= w->y();
    }

  int save_x = Fl::e_x; Fl::e_x += dx;
  int save_y = Fl::e_y; Fl::e_y += dy;

  int ret = to->handle(event);
  Fl::e_y = save_y;
  Fl::e_x = save_x;

  return ret;
}
#endif

int Fl::handle(int event, Fl_Window* window)
{
  Fl_Widget* w = window;

  switch (event) {

  case FL_CLOSE:
    if (grab() || modal() && window != modal()) return 0;
    w->do_callback();
    return 1;

  case FL_SHOW:
    ((Fl_Widget*)w)->show();
    return 1;

  case FL_HIDE:
    ((Fl_Widget*)w)->hide();
    return 1;

  case FL_PUSH:
    if (grab()) w = grab();
    else if (modal() && w != modal()) return 0;
    pushed_ = w;

    if (send(event, w, window)) return 1;
    // raise windows that are clicked on:
    window->show();
    return 1;

  case FL_MOVE:
  case FL_DRAG:
    fl_xmousewin = window; // this should already be set, but just in case.
    if (pushed()) {
      w = pushed();
      event = FL_DRAG;
    } else if (modal() && w != modal()) {
      w = 0;
    }
    if (grab()) w = grab();
    break;

  case FL_RELEASE: {
    if (pushed()) {
      w = pushed();
      pushed_ = 0; // must be zero before callback is done!
    }
    if (grab()) w = grab();
    int r = send(event, w, window);
    fl_fix_focus();
    return r;}

  case FL_UNFOCUS:
    window = 0;
  case FL_FOCUS:
    fl_xfocus = window;
    e_keysym = 0; // make sure it is not confused with navigation key
    fl_fix_focus();
    return 1;

  case FL_KEYBOARD:
    fl_xfocus = window; // this should already be set, but just in case.

    // Try it as keystroke, sending it to focus and all parents:
    for (w = grab() ? grab() : focus(); w; w = w->parent())
      if (send(FL_KEYBOARD, w, window)) return 1;

    // recursive call to try shortcut:
    if (handle(FL_SHORTCUT, window)) return 1;

    // and then try a shortcut with the case of the text swapped, by
    // changing the text and falling through to FL_SHORTCUT case:
    if (!isalpha(event_text()[0])) return 0;
    *(char*)(event_text()) ^= ('A'^'a');
    event = FL_SHORTCUT;

  case FL_SHORTCUT:

    if (grab()) {w = grab(); break;} // send it to grab window

    // Try it as shortcut, sending to mouse widget and all parents:
    w = belowmouse(); if (!w) {w = modal(); if (!w) w = window;}
    for (; w; w = w->parent()) if (send(FL_SHORTCUT, w, window)) return 1;

    // try using add_handle() functions:
    if (send_handlers(FL_SHORTCUT)) return 1;

    // make Escape key close windows:
    if (event_key()==FL_Escape) {
      w = modal(); if (!w) w = window;
      w->do_callback();
      return 1;
    }

    return 0;

  case FL_ENTER:
    fl_xmousewin = window;
    fl_fix_focus();
    return 1;

  case FL_LEAVE:
    if (window == fl_xmousewin) {fl_xmousewin = 0; fl_fix_focus();}
    return 1;

  default:
    break;
  }
  if (w && send(event, w, window)) return 1;
  return send_handlers(event);
}

////////////////////////////////////////////////////////////////
// hide() destroys the X window, it does not do unmap!

void Fl_Window::hide() {
  
  clear_visible();
  if (!shown()) return;

  // remove from the list of windows:
  Fl_X* x = i;
  Fl_X** pp = &Fl_X::first;
  for (; *pp != x; pp = &(*pp)->next) if (!*pp) return;
  *pp = x->next;
  i = 0;

  // recursively remove any subwindows:
  for (Fl_X *w = Fl_X::first; w;) {
    Fl_Window* W = w->w;
    if (W->window() == this) {
      W->hide();
      W->set_visible();
      w = Fl_X::first;
    } else w = w->next;
  }

  if (this == Fl::modal_) { // we are closing the modal window, find next one:
    Fl_Window* w;
    for (w = Fl::first_window(); w; w = Fl::next_window(w))
      if (w->modal()) break;
    Fl::modal_ = w;
  }

  // Make sure no events are sent to this window:
  fl_throw_focus(this);
  handle(FL_HIDE);

#ifdef WIN32
  if (x->private_dc) ReleaseDC(x->xid,x->private_dc);
  if (x->xid == fl_window) fl_GetDC(0); // releases dc belonging to window
#else
#ifdef NANO_X
  if (x->region) GrDestroyRegion(x->region);
#else
  if (x->region) XDestroyRegion(x->region);
#endif
#endif

#ifdef NANO_X
  GrDestroyWindow(x->xid);
#else
  XDestroyWindow(fl_display, x->xid);
#endif
  delete x;
}

Fl_Window::~Fl_Window() {
  hide();
}

// Child windows must respond to FL_SHOW and FL_HIDE by actually
// doing unmap operations.  Outer windows assumme FL_SHOW & FL_HIDE
// are messages from X:

int Fl_Window::handle(int event) {
  if (parent()) switch (event) {
  case FL_SHOW:
    if (!shown()) show();
	else
	{
#ifdef NANO_X
    GrMapWindow(fl_xid(this));
#else
    XMapWindow(fl_display, fl_xid(this));
#endif
	}
    break;
  case FL_HIDE:
#ifdef NANO_X
    if (shown()) GrUnmapWindow(fl_xid(this));
#else
    if (shown()) XUnmapWindow(fl_display, fl_xid(this));
#endif
    break;
  }

  return Fl_Group::handle(event);
}

////////////////////////////////////////////////////////////////
// ~Fl_Widget() calls this: this function must get rid of any
// global pointers to the widget.  This is also called by hide()
// and deactivate().

// call this to free a selection (or change the owner):
void Fl::selection_owner(Fl_Widget *owner) {
  if (selection_owner_ && owner != selection_owner_)
    selection_owner_->handle(FL_SELECTIONCLEAR);
  if (focus_ && owner != focus_ && focus_ != selection_owner_)
    focus_->handle(FL_SELECTIONCLEAR); // clear non-X-selection highlight
  selection_owner_ = owner;
}

#include <FL/fl_draw.H>

void Fl_Widget::redraw() {damage(FL_DAMAGE_ALL);}

void Fl_Widget::damage(uchar flags) {
  if (type() < FL_WINDOW) {
    // damage only the rectangle covered by a child widget:
    damage(flags, x(), y(), w(), h());
  } else {
    // damage entire window by deleting the region:
    Fl_X* i = Fl_X::i((Fl_Window*)this);
    if (!i) return; // window not mapped, so ignore it
    if (i->region) 
	{
#ifdef NANO_X
		GrDestroyRegion(i->region);
#else
		XDestroyRegion(i->region);
#endif
		i->region = 0;
	}
    damage_ |= flags;
    Fl::damage(FL_DAMAGE_CHILD);
  }
}

void Fl_Widget::damage(uchar flags, int X, int Y, int W, int H) {
  Fl_Widget* window = this;
  // mark all parent widgets between this and window with FL_DAMAGE_CHILD:
  while (window->type() < FL_WINDOW) {
    window->damage_ |= flags;
    window = window->parent();
    if (!window) return;
    flags = FL_DAMAGE_CHILD;
  }
  Fl_X* i = Fl_X::i((Fl_Window*)window);
  if (!i) return; // window not mapped, so ignore it

  if (X<=0 && Y<=0 && W>=window->w() && H>=window->h()) {
    // if damage covers entire window delete region:
    window->damage(flags);
    return;
  }

  // clip the damage to the window and quit if none:
  if (X < 0) {W += X; X = 0;}
  if (Y < 0) {H += Y; Y = 0;}
  if (W > window->w()-X) W = window->w()-X;
  if (H > window->h()-Y) H = window->h()-Y;
  if (W <= 0 || H <= 0) return;

  if (window->damage()) {
    // if we already have damage we must merge with existing region:
    if (i->region) {
#ifndef WIN32
#ifdef NANO_X
      GR_RECT R;
      R.x = X; R.y = Y; R.width = W; R.height = H;
      GrUnionRectWithRegion(i->region, &R);
#else
      XRectangle R;
      R.x = X; R.y = Y; R.width = W; R.height = H;
      XUnionRectWithRegion(&R, i->region, i->region);
#endif

#else
      Region R = XRectangleRegion(X, Y, W, H);
      CombineRgn(i->region, i->region, R, RGN_OR);
      XDestroyRegion(R);
#endif
    }
    window->damage_ |= flags;
  } else {
    // create a new region:
#ifdef NANO_X
    if (i->region) 
		GrDestroyRegion(i->region);
#else
    if (i->region) 
		XDestroyRegion(i->region);
#endif
    i->region = XRectangleRegion(X,Y,W,H);
    window->damage_ = flags;
  }
  Fl::damage(FL_DAMAGE_CHILD);
}

void Fl_Window::flush() {
  make_current();
//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
  fl_clip_region(i->region); i->region = 0;
  draw();
}

int fl_old_shortcut(const char* s) {
  if (!s || !*s) return 0;
  int n = 0;
  if (*s == '#') {n |= FL_ALT; s++;}
  if (*s == '+') {n |= FL_SHIFT; s++;}
  if (*s == '^') {n |= FL_CTRL; s++;}
  return n | *s;
}

//
// End of "$Id: Fl.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Browser.cxx ---
//
// "$Id: Fl_Browser.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $"
//
// Browser widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Browser.H>
#include <FL/fl_draw.H>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

// I modified this from the original Forms data to use a linked list
// so that the number of items in the browser and size of those items
// is unlimited.  The only problem is that the old browser used an
// index number to identify a line, and it is slow to convert from/to
// a pointer.  I use a cache of the last match to try to speed this
// up.

// Also added the ability to "hide" a line.  This set's it's height to
// zero, so the Fl_Browser_ cannot pick it.

#define SELECTED 1
#define NOTDISPLAYED 2

struct FL_BLINE {	// data is in a linked list of these
  FL_BLINE* prev;
  FL_BLINE* next;
  void* data;
  short length;		// sizeof(txt)-1, may be longer than string
  char flags;		// selected, displayed
  char txt[1];		// start of allocated array
};

void* Fl_Browser::item_first() const {return first;}

void* Fl_Browser::item_next(void* l) const {return ((FL_BLINE*)l)->next;}

void* Fl_Browser::item_prev(void* l) const {return ((FL_BLINE*)l)->prev;}

int Fl_Browser::item_selected(void* l) const {
  return ((FL_BLINE*)l)->flags&SELECTED;}

void Fl_Browser::item_select(void* l, int v) {
  if (v) ((FL_BLINE*)l)->flags |= SELECTED;
  else ((FL_BLINE*)l)->flags &= ~SELECTED;
}

FL_BLINE* Fl_Browser::find_line(int line) const {
  int n; FL_BLINE* l;
  if (line == cacheline) return cache;
  if (cacheline && line > (cacheline/2) && line < ((cacheline+lines)/2)) {
    n = cacheline; l = cache;
  } else if (line <= (lines/2)) {
    n = 1; l = first;
  } else {
    n = lines; l = last;
  }
  for (; n < line && l; n++) l = l->next;
  for (; n > line && l; n--) l = l->prev;
  ((Fl_Browser*)this)->cacheline = line;
  ((Fl_Browser*)this)->cache = l;
  return l;
}

int Fl_Browser::lineno(void* v) const {
  FL_BLINE* l = (FL_BLINE*)v;
  if (!l) return 0;
  if (l == cache) return cacheline;
  if (l == first) return 1;
  if (l == last) return lines;
  if (!cache) {
    ((Fl_Browser*)this)->cache = first;
    ((Fl_Browser*)this)->cacheline = 1;
  }
  // assumme it is near cache, search both directions:
  FL_BLINE* b = cache->prev;
  int bnum = cacheline-1;
  FL_BLINE* f = cache->next;
  int fnum = cacheline+1;
  int n = 0;
  for (;;) {
    if (b == l) {n = bnum; break;}
    if (f == l) {n = fnum; break;}
    if (b) {b = b->prev; bnum--;}
    if (f) {f = f->next; fnum++;}
  }
  ((Fl_Browser*)this)->cache = l;
  ((Fl_Browser*)this)->cacheline = n;
  return n;
}

FL_BLINE* Fl_Browser::_remove(int line) {
  FL_BLINE* ttt = find_line(line);
  deleting(ttt);

  cacheline = line-1;
  cache = ttt->prev;
  if (ttt->prev) ttt->prev->next = ttt->next;
  else first = ttt->next;
  if (ttt->next) ttt->next->prev = ttt->prev;
  else last = ttt->prev;

  lines--;
  full_height_ -= item_height(ttt);
  return(ttt);
}

void Fl_Browser::remove(int line) {
  if (line < 1 || line > lines) return;
  free(_remove(line));
}

void Fl_Browser::insert(int line, FL_BLINE* t) {
  if (!first) {
    t->prev = t->next = 0;
    first = last = t;
  } else if (line <= 1) {
    inserting(first, t);
    t->prev = 0;
    t->next = first;
    t->next->prev = t;
    first = t;
  } else if (line > lines) {
    t->prev = last;
    t->prev->next = t;
    t->next = 0;
    last = t;
  } else {
    FL_BLINE* n = find_line(line);
    inserting(n, t);
    t->next = n;
    t->prev = n->prev;
    t->prev->next = t;
    n->prev = t;
  }
  cacheline = line;
  cache = t;
  lines++;
  full_height_ += item_height(t);
  redraw_line(t);
}

void Fl_Browser::insert(int line, const char* newtext, void* data) {
  int l = strlen(newtext);
  FL_BLINE* t = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
  t->length = l;
  t->flags = 0;
  strcpy(t->txt, newtext);
  t->data = data;
  insert(line, t);
}

void Fl_Browser::move(int to, int from) {
  if (from < 1 || from > lines) return;
  insert(to, _remove(from));
}

void Fl_Browser::text(int line, const char* newtext) {
  if (line < 1 || line > lines) return;
  FL_BLINE* t = find_line(line);
  int l = strlen(newtext);
  if (l > t->length) {
    FL_BLINE* n = (FL_BLINE*)malloc(sizeof(FL_BLINE)+l);
    replacing(t, n);
    cache = n;
    n->data = t->data;
    n->length = l;
    n->flags = t->flags;
    n->prev = t->prev;
    if (n->prev) n->prev->next = n; else first = n;
    n->next = t->next;
    if (n->next) n->next->prev = n; else last = n;
    free(t);
    t = n;
  }
  strcpy(t->txt, newtext);
  redraw_line(t);
}

void Fl_Browser::data(int line, void* data) {
  if (line < 1 || line > lines) return;
  find_line(line)->data = data;
}

int Fl_Browser::item_height(void* lv) const {
  FL_BLINE* l = (FL_BLINE*)lv;
  if (l->flags & NOTDISPLAYED) return 0;

  int hmax = 2; // use 2 to insure we don't return a zero!

  if (!l->txt[0]) {
    // For blank lines set the height to exactly 1 line!
    fl_font(textfont(), textsize());
    int h = fl_height();
    if (h > hmax) hmax = h;
  }
  else {
    // do each column separately as they may all set different fonts:
    for (char* str = l->txt; *str; str++) {
      Fl_Font font = textfont(); // default font
      int size = textsize(); // default size
      while (*str==format_char()) {
	str++;
	switch (*str++) {
	case 'l': case 'L': size = 24; break;
	case 'm': case 'M': size = 18; break;
	case 's': size = 11; break;
	case 'b': font = (Fl_Font)(font|FL_BOLD); break;
	case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
	case 'f': case 't': font = FL_COURIER; break;
	case 'B':
	case 'C': strtol(str, &str, 10); break;// skip a color number
	case 'F': font = (Fl_Font)strtol(str,&str,10); break;
	case 'S': size = strtol(str,&str,10); break;
	case 0: case '@': str--;
	case '.': goto END_FORMAT;
	}
      }
      END_FORMAT:
      char* ptr = str;
      for(;*str && (*str!=column_char()); str++) ;
      if (ptr < str) {
	fl_font(font, size); int h = fl_height();
	if (h > hmax) hmax = h;
      }
      if (!*str) str --;
    }
  }

  return hmax; // previous version returned hmax+2!
}

int Fl_Browser::item_width(void* v) const {
  char* str = ((FL_BLINE*)v)->txt;
  const int* i = column_widths();
  int w = 0;

  while (*i) { // add up all tab-seperated fields
    w += *i++;
    char* e;
    for (e = str; *e && *e != column_char(); e++);
    if (!*e) return 0; // last one occupied by text
    str = e+1;
  }

  // OK, we gotta parse the string and find the string width...
  int size = textsize();
  Fl_Font font = textfont();
  int done = 0;

  // MRS - might this cause problems on some platforms - order of operations?

  while (*str == format_char_ && *++str && *str != format_char_) {
    switch (*str++) {
    case 'l': case 'L': size = 24; break;
    case 'm': case 'M': size = 18; break;
    case 's': size = 11; break;
    case 'b': font = (Fl_Font)(font|FL_BOLD); break;
    case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
    case 'f': case 't': font = FL_COURIER; break;
    case 'B':
    case 'C': strtol(str, &str, 10); break;// skip a color number
    case 'F': font = (Fl_Font)strtol(str, &str, 10); break;
    case 'S': size = strtol(str, &str, 10); break;
    case '.':
      done = 1;
    case '@':
      str--;
      done = 1;
    }

    if (done)
      break;
  }

  fl_font(font, size);
  return w + int(fl_width(str)) + 6;
}

int Fl_Browser::full_height() const {
  return full_height_;
}

int Fl_Browser::incr_height() const {
  return textsize()+2;
}

void Fl_Browser::item_draw(void* v, int x, int y, int w, int h) const {
  char* str = ((FL_BLINE*)v)->txt;
  const int* i = column_widths();

  while (w > 6) {	// do each tab-seperated field
    int w1 = w;	// width for this field
    char* e = 0; // pointer to end of field or null if none
    if (*i) { // find end of field and temporarily replace with 0
      for (e = str; *e && *e != column_char(); e++);
      if (*e) {*e = 0; w1 = *i++;} else e = 0;
    }
    int size = textsize();
    Fl_Font font = textfont();
    Fl_Color lcol = textcolor();
    Fl_Align align = FL_ALIGN_LEFT;
    // check for all the @-lines recognized by XForms:
    while (*str == format_char() && *++str && *str != format_char()) {
      switch (*str++) {
      case 'l': case 'L': size = 24; break;
      case 'm': case 'M': size = 18; break;
      case 's': size = 11; break;
      case 'b': font = (Fl_Font)(font|FL_BOLD); break;
      case 'i': font = (Fl_Font)(font|FL_ITALIC); break;
      case 'f': case 't': font = FL_COURIER; break;
      case 'c': align = FL_ALIGN_CENTER; break;
      case 'r': align = FL_ALIGN_RIGHT; break;
      case 'B': 
	fl_color((Fl_Color)strtol(str, &str, 10));
	fl_rectf(x, y, w1, h);
        break;
      case 'C':
	lcol = (Fl_Color)strtol(str, &str, 10);
	break;
      case 'F':
	font = (Fl_Font)strtol(str, &str, 10);
	break;
      case 'N':
	lcol = FL_INACTIVE_COLOR;
	break;
      case 'S':
	size = strtol(str, &str, 10);
	break;
      case '-':
	fl_color(FL_DARK3);
	fl_line(x+3, y+h/2, x+w1-3, y+h/2);
	fl_color(FL_LIGHT3);
	fl_line(x+3, y+h/2+1, x+w1-3, y+h/2+1);
	break;
      case 'u':
      case '_':
	fl_color(lcol);
	fl_line(x+3, y+h-1, x+w1-3, y+h-1);
	break;
      case '.':
	goto BREAK;
      case '@':
	str--; goto BREAK;
      }
    }
  BREAK:
    fl_font(font, size);
    if (!active_r()) lcol = inactive(lcol);
    if (((FL_BLINE*)v)->flags & SELECTED)
      lcol = contrast(lcol, selection_color());
    fl_color(lcol);
    fl_draw(str, x+3, y, w1-6, h, e ? Fl_Align(align|FL_ALIGN_CLIP) : align);
    if (!e) break; // no more fields...
    *e = column_char(); // put the seperator back
    x += w1;
    w -= w1;
    str = e+1;
  }
}

static const int no_columns[1] = {0};

Fl_Browser::Fl_Browser(int x, int y, int w, int h, const char*l)
  : Fl_Browser_(x, y, w, h, l) {
  column_widths_ = no_columns;
  lines = 0;
  full_height_ = 0;
  cacheline = 0;
  format_char_ = '@';
  column_char_ = '\t';
  first = last = cache = 0;
}

void Fl_Browser::lineposition(int line, Fl_Line_Position pos) {
  if (line<1) line = 1;
  if (line>lines) line = lines;
  int p = 0;

  FL_BLINE* l;
  for (l=first; l && line>1; l = l->next) {
    line--; p += item_height(l);
  }
  if (l && (pos == BOTTOM)) p += item_height (l);

  int final = p, X, Y, W, H;
  bbox(X, Y, W, H);

  switch(pos) {
    case TOP: break;
    case BOTTOM: final -= H; break;
    case MIDDLE: final -= H/2; break;
  }
  
  if (final > (full_height() - H)) final = full_height() -H;
  position(final);
}

int Fl_Browser::topline() const {
  return lineno(top());
}

void Fl_Browser::clear() {
  for (FL_BLINE* l = first; l;) {
    FL_BLINE* h = l->next;
    free(l);
    l = h;
  }
  full_height_ = 0;
  first = 0;
  lines = 0;
  new_list();
}

void Fl_Browser::add(const char* newtext, void* data) {
  insert(lines+1, newtext, data);
  //Fl_Browser_::display(last);
}

const char* Fl_Browser::text(int line) const {
  if (line < 1 || line > lines) return 0;
  return find_line(line)->txt;
}

void* Fl_Browser::data(int line) const {
  if (line < 1 || line > lines) return 0;
  return find_line(line)->data;
}

int Fl_Browser::select(int line, int value) {
  if (line < 1 || line > lines) return 0;
  return Fl_Browser_::select(find_line(line), value);
}

int Fl_Browser::selected(int line) const {
  if (line < 1 || line > lines) return 0;
  return find_line(line)->flags & SELECTED;
}

void Fl_Browser::show(int line) {
  FL_BLINE* t = find_line(line);
  if (t->flags & NOTDISPLAYED) {
    t->flags &= ~NOTDISPLAYED;
    full_height_ += item_height(t);
    if (Fl_Browser_::displayed(t)) redraw_lines();
  }
}

void Fl_Browser::hide(int line) {
  FL_BLINE* t = find_line(line);
  if (!(t->flags & NOTDISPLAYED)) {
    full_height_ -= item_height(t);
    t->flags |= NOTDISPLAYED;
    if (Fl_Browser_::displayed(t)) redraw_lines();
  }
}

void Fl_Browser::display(int line, int value) {
  if (line < 1 || line > lines) return;
  if (value) show(line); else hide(line);
}

int Fl_Browser::visible(int line) const {
  if (line < 1 || line > lines) return 0;
  return !(find_line(line)->flags&NOTDISPLAYED);
}

int Fl_Browser::value() const {
  return lineno(selection());
}

//
// End of "$Id: Fl_Browser.cxx,v 1.1 2006-10-03 11:25:07 dslinux_amadeus Exp $".
//

--- NEW FILE: ew_mask.xbm ---
#define ew_mask_width 16
#define ew_mask_height 16
#define ew_mask_x_hot 8
#define ew_mask_y_hot 8
static unsigned char ew_mask_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
   0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

--- NEW FILE: Fl_Overlay_Window.cxx ---
//
// "$Id: Fl_Overlay_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Overlay window code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// A window using double-buffering and able to draw an overlay
// on top of that.  Uses the hardware to draw the overlay if
// possible, otherwise it just draws in the front buffer.

#include <config.h>
#include <FL/Fl.H>
#include <FL/Fl_Overlay_Window.H>
#include <FL/fl_draw.H>
#include <FL/x.H>

void Fl_Overlay_Window::show() {
  Fl_Double_Window::show();
  if (overlay_ && overlay_ != this) overlay_->show();
}

void Fl_Overlay_Window::hide() {
  Fl_Double_Window::hide();
}

void Fl_Overlay_Window::flush() {
  int erase_overlay = (damage()&FL_DAMAGE_OVERLAY);
  clear_damage(damage()&~FL_DAMAGE_OVERLAY);
  Fl_Double_Window::flush(erase_overlay);
  if (overlay_ == this) draw_overlay();
}

void Fl_Overlay_Window::resize(int X, int Y, int W, int H) {
  Fl_Double_Window::resize(X,Y,W,H);
  if (overlay_ && overlay_!=this) overlay_->resize(0,0,w(),h());
}

Fl_Overlay_Window::~Fl_Overlay_Window() {
  hide();
//  delete overlay; this is done by ~Fl_Group
}

#if !HAVE_OVERLAY

int Fl_Overlay_Window::can_do_overlay() {return 0;}

void Fl_Overlay_Window::redraw_overlay() {
  overlay_ = this;
  clear_damage(damage()|FL_DAMAGE_OVERLAY);
  Fl::damage(FL_DAMAGE_CHILD);
}

#else

extern XVisualInfo *fl_find_overlay_visual();
extern XVisualInfo *fl_overlay_visual;
extern Colormap fl_overlay_colormap;
extern unsigned long fl_transparent_pixel;
static GC gc;	// the GC used by all X windows
extern uchar fl_overlay; // changes how fl_color(x) works

class _Fl_Overlay : public Fl_Window {
  friend class Fl_Overlay_Window;
  void flush();
  void show();
public:
  _Fl_Overlay(int x, int y, int w, int h) :
    Fl_Window(x,y,w,h) {set_flag(INACTIVE);}
};

int Fl_Overlay_Window::can_do_overlay() {
  return fl_find_overlay_visual() != 0;
}

void _Fl_Overlay::show() {
  if (shown()) {Fl_Window::show(); return;}
  fl_background_pixel = int(fl_transparent_pixel);
  Fl_X::make_xid(this, fl_overlay_visual, fl_overlay_colormap);
  fl_background_pixel = -1;
  // find the outermost window to tell wm about the colormap:
  Fl_Window *w = window();
  for (;;) {Fl_Window *w1 = w->window(); if (!w1) break; w = w1;}
  XSetWMColormapWindows(fl_display, fl_xid(w), &(Fl_X::i(this)->xid), 1);
}

void _Fl_Overlay::flush() {
  fl_window = fl_xid(this);
  if (!gc) gc = XCreateGC(fl_display, fl_xid(this), 0, 0);
  fl_gc = gc;
  fl_overlay = 1;
  Fl_Overlay_Window *w = (Fl_Overlay_Window *)parent();
  Fl_X *i = Fl_X::i(this);
  if (damage() != FL_DAMAGE_EXPOSE) XClearWindow(fl_display, fl_xid(this));
  fl_clip_region(i->region); i->region = 0;
  w->draw_overlay();
  fl_overlay = 0;
}

void Fl_Overlay_Window::redraw_overlay() {
  if (!fl_display) return; // this prevents fluid -c from opening display
  if (!overlay_) {
    if (can_do_overlay()) {
      Fl_Group::current(this);
      overlay_ = new _Fl_Overlay(0,0,w(),h());
      Fl_Group::current(0);
    } else {
      overlay_ = this;	// fake the overlay
    }
  }
  if (shown()) {
    if (overlay_ == this) {
      clear_damage(damage()|FL_DAMAGE_OVERLAY);
      Fl::damage(FL_DAMAGE_CHILD);
    } else if (!overlay_->shown())
      overlay_->show();
    else
      overlay_->redraw();
  }
}

#endif

//
// End of "$Id: Fl_Overlay_Window.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_win32.cxx ---
//
// "$Id: Fl_win32.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $"
//
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This file contains win32-specific code for fltk which is always linked
// in.  Search other files for "WIN32" or filenames ending in _win32.C
// for other system-specific code.

#include <config.h>
#include <FL/Fl.H>
#include <FL/win32.H>
#include <FL/Fl_Window.H>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <winsock.h>
#include <ctype.h>

//
// WM_SYNCPAINT is an "undocumented" message, which is finally defined in
// VC++ 6.0.
//
#ifndef WM_SYNCPAINT
#  define WM_SYNCPAINT 0x0088
#endif /* !WM_SYNCPAINT */

#ifndef WM_MOUSELEAVE
#  define WM_MOUSELEAVE 0x02a3
#endif

////////////////////////////////////////////////////////////////
// interface to poll/select call:

// fd's are only implemented for sockets.  Microsoft Windows does not
// have a unified IO system, so it doesn't support select() on files,
// devices, or pipes...  Also, unlike UNIX the Windows select() call
// doesn't use the nfds parameter, so we don't need to keep track of
// the maximum FD number...

static fd_set fdsets[3];
#define POLLIN 1
#define POLLOUT 4
#define POLLERR 8

static int nfds = 0;
static int fd_array_size = 0;
static struct FD {
  int fd;
  short events;
  void (*cb)(int, void*);
  void* arg;
} *fd = 0;

void Fl::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
  remove_fd(n,events);
  int i = nfds++;
  if (i >= fd_array_size) {
    fd_array_size = 2*fd_array_size+1;
    fd = (FD*)realloc(fd, fd_array_size*sizeof(FD));
  }
  fd[i].fd = n;
  fd[i].events = events;
  fd[i].cb = cb;
  fd[i].arg = v;
  if (events & POLLIN) FD_SET(n, &fdsets[0]);
  if (events & POLLOUT) FD_SET(n, &fdsets[1]);
  if (events & POLLERR) FD_SET(n, &fdsets[2]);
}

void Fl::add_fd(int fd, void (*cb)(int, void*), void* v) {
  Fl::add_fd(fd, POLLIN, cb, v);
}

void Fl::remove_fd(int n, int events) {
  int i,j;
  for (i=j=0; i<nfds; i++) {
    if (fd[i].fd == n) {
      int e = fd[i].events & ~events;
      if (!e) continue; // if no events left, delete this fd
      fd[i].events = e;
    }
    // move it down in the array if necessary:
    if (j<i) {
      fd[j]=fd[i];
    }
    j++;
  }
  nfds = j;
  if (events & POLLIN) FD_CLR(unsigned(n), &fdsets[0]);
  if (events & POLLOUT) FD_CLR(unsigned(n), &fdsets[1]);
  if (events & POLLERR) FD_CLR(unsigned(n), &fdsets[2]);
}

void Fl::remove_fd(int n) {
  remove_fd(n, -1);
}

MSG fl_msg;

int fl_ready() {
  if (PeekMessage(&fl_msg, NULL, 0, 0, PM_NOREMOVE)) return 1;

  timeval t;
  t.tv_sec = 0;
  t.tv_usec = 0;
  fd_set fdt[3];
  fdt[0] = fdsets[0];
  fdt[1] = fdsets[1];
  fdt[2] = fdsets[2];
  return ::select(0,&fdt[0],&fdt[1],&fdt[2],&t);
}

double fl_wait(int timeout_flag, double time) {
  int have_message = 0;
  int timerid;

  if (nfds) {
    // For WIN32 we need to poll for socket input FIRST, since
    // the event queue is not something we can select() on...
    timeval t;
    t.tv_sec = 0;
    t.tv_usec = 0;

    fd_set fdt[3];
    fdt[0] = fdsets[0];
    fdt[1] = fdsets[1];
    fdt[2] = fdsets[2];

    if (::select(0,&fdt[0],&fdt[1],&fdt[2],&t)) {
      // We got something - do the callback!
      for (int i = 0; i < nfds; i ++) {
	int f = fd[i].fd;
	short revents = 0;
	if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
	if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
	if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
	if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
      }
    }
  }

  // get the first message by waiting the correct amount of time:
  if (!timeout_flag) {
    // If we are monitoring sockets we need to check them periodically,
    // so set a timer in this case...
    if (nfds) {
      // First see if there is a message waiting...
      have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
      if (!have_message) {
	// If not then set a 1ms timer...
	timerid = SetTimer(NULL, 0, 1, NULL);
	GetMessage(&fl_msg, NULL, 0, 0);
	KillTimer(NULL, timerid);
      }
    } else {
      // Wait for a message...
      GetMessage(&fl_msg, NULL, 0, 0);
    }
    have_message = 1;
  } else {
    // Perform the requested timeout...
    have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
    if (!have_message && time > 0.0) {
      int t = (int)(time * 1000.0);
      if (t <= 0) t = 1;
      timerid = SetTimer(NULL, 0, t, NULL);
      GetMessage(&fl_msg, NULL, 0, 0);
      KillTimer(NULL, timerid);
      have_message = 1;
    }
  }

  // execute it, them execute any other messages that become ready during it:
  while (have_message) {
    TranslateMessage(&fl_msg);
    DispatchMessage(&fl_msg);
    have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
  }

  return time;
}

////////////////////////////////////////////////////////////////

int Fl::x()
{
  RECT r;

  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
  return r.left;
}

int Fl::y()
{
  RECT r;

  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
  return r.top;
}

int Fl::h()
{
  RECT r;

  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
  return r.bottom - r.top;
}

int Fl::w()
{
  RECT r;

  SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
  return r.right - r.left;
}

void Fl::get_mouse(int &x, int &y) {
  POINT p;
  GetCursorPos(&p);
  x = p.x;
  y = p.y;
}

////////////////////////////////////////////////////////////////

HWND fl_capture;

static int mouse_event(Fl_Window *window, int what, int button,
			WPARAM wParam, LPARAM lParam)
{
  static int px, py, pmx, pmy;
  POINT pt;
  Fl::e_x = pt.x = (signed short)LOWORD(lParam);
  Fl::e_y = pt.y = (signed short)HIWORD(lParam);
  ClientToScreen(fl_xid(window), &pt);
  Fl::e_x_root = pt.x;
  Fl::e_y_root = pt.y;
  while (window->parent()) {
    Fl::e_x += window->x();
    Fl::e_y += window->y();
    window = window->window();
  }

  ulong state = Fl::e_state & 0xff0000; // keep shift key states
#if 0
  // mouse event reports some shift flags, perhaps save them?
  if (wParam & MK_SHIFT) state |= FL_SHIFT;
  if (wParam & MK_CONTROL) state |= FL_CTRL;
#endif
  if (wParam & MK_LBUTTON) state |= FL_BUTTON1;
  if (wParam & MK_MBUTTON) state |= FL_BUTTON2;
  if (wParam & MK_RBUTTON) state |= FL_BUTTON3;
  Fl::e_state = state;

  switch (what) {
  case 1: // double-click
    if (Fl::e_is_click) {Fl::e_clicks++; goto J1;}
  case 0: // single-click
    Fl::e_clicks = 0;
  J1:
    if (!fl_capture) SetCapture(fl_xid(window));
    Fl::e_keysym = FL_Button + button;
    Fl::e_is_click = 1;
    px = pmx = Fl::e_x_root; py = pmy = Fl::e_y_root;
    return Fl::handle(FL_PUSH,window);

  case 2: // release:
    if (!fl_capture) ReleaseCapture();
    Fl::e_keysym = FL_Button + button;
    return Fl::handle(FL_RELEASE,window);

  case 3: // move:
  default: // avoid compiler warning
    // MSWindows produces extra events even if mouse does not move, ignore em:
    if (Fl::e_x_root == pmx && Fl::e_y_root == pmy) return 1;
    pmx = Fl::e_x_root; pmy = Fl::e_y_root;
    if (abs(Fl::e_x_root-px)>5 || abs(Fl::e_y_root-py)>5) Fl::e_is_click = 0;
    return Fl::handle(FL_MOVE,window);

  }
}

// convert a MSWindows VK_x to an Fltk (X) Keysym:
// See also the inverse converter in Fl_get_key_win32.C
// This table is in numeric order by VK:
static const struct {unsigned short vk, fltk, extended;} vktab[] = {
  {VK_BACK,	FL_BackSpace},
  {VK_TAB,	FL_Tab},
  {VK_CLEAR,	FL_KP+'5',	0xff0b/*XK_Clear*/},
  {VK_RETURN,	FL_Enter,	FL_KP_Enter},
  {VK_SHIFT,	FL_Shift_L,	FL_Shift_R},
  {VK_CONTROL,	FL_Control_L,	FL_Control_R},
  {VK_MENU,	FL_Alt_L,	FL_Alt_R},
  {VK_PAUSE,	FL_Pause},
  {VK_CAPITAL,	FL_Caps_Lock},
  {VK_ESCAPE,	FL_Escape},
  {VK_SPACE,	' '},
  {VK_PRIOR,	FL_KP+'9',	FL_Page_Up},
  {VK_NEXT,	FL_KP+'3',	FL_Page_Down},
  {VK_END,	FL_KP+'1',	FL_End},
  {VK_HOME,	FL_KP+'7',	FL_Home},
  {VK_LEFT,	FL_KP+'4',	FL_Left},
  {VK_UP,	FL_KP+'8',	FL_Up},
  {VK_RIGHT,	FL_KP+'6',	FL_Right},
  {VK_DOWN,	FL_KP+'2',	FL_Down},
  {VK_SNAPSHOT,	FL_Print},	// does not work on NT
  {VK_INSERT,	FL_KP+'0',	FL_Insert},
  {VK_DELETE,	FL_KP+'.',	FL_Delete},
  {VK_LWIN,	FL_Meta_L},
  {VK_RWIN,	FL_Meta_R},
  {VK_APPS,	FL_Menu},
  {VK_MULTIPLY,	FL_KP+'*'},
  {VK_ADD,	FL_KP+'+'},
  {VK_SUBTRACT,	FL_KP+'-'},
  {VK_DECIMAL,	FL_KP+'.'},
  {VK_DIVIDE,	FL_KP+'/'},
  {VK_NUMLOCK,	FL_Num_Lock},
  {VK_SCROLL,	FL_Scroll_Lock},
  {0xba,	';'},
  {0xbb,	'='},
  {0xbc,	','},
  {0xbd,	'-'},
  {0xbe,	'.'},
  {0xbf,	'/'},
  {0xc0,	'`'},
  {0xdb,	'['},
  {0xdc,	'\\'},
  {0xdd,	']'},
  {0xde,	'\''}
};
static int ms2fltk(int vk, int extended) {
  static unsigned short vklut[256];
  static unsigned short extendedlut[256];
  if (!vklut[1]) { // init the table
    unsigned int i;
    for (i = 0; i < 256; i++) vklut[i] = tolower(i);
    for (i=VK_F1; i<=VK_F16; i++) vklut[i] = i+(FL_F-(VK_F1-1));
    for (i=VK_NUMPAD0; i<=VK_NUMPAD9; i++) vklut[i] = i+(FL_KP+'0'-VK_NUMPAD0);
    for (i = 0; i < sizeof(vktab)/sizeof(*vktab); i++) {
      vklut[vktab[i].vk] = vktab[i].fltk;
      extendedlut[vktab[i].vk] = vktab[i].extended;
    }
    for (i = 0; i < 256; i++) if (!extendedlut[i]) extendedlut[i] = vklut[i];
  }
  return extended ? extendedlut[vk] : vklut[vk];
}

#if USE_COLORMAP
extern HPALETTE fl_select_palette(void); // in fl_color_win32.C
#endif

static Fl_Window* resize_bug_fix;

static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
  static char buffer[2];
  static int cnt=0;

  if(uMsg == WM_SYNCPAINT) {
    if(cnt) {
      InvalidateRect(fl_window,0,FALSE);
      cnt = 0;
    } else cnt = 1;
  } else if (uMsg == WM_PAINT) cnt = 0;

  fl_msg.message = uMsg;

  Fl_Window *window = fl_find(hWnd);

  if (window) switch (uMsg) {

  case WM_QUIT: // this should not happen?
    Fl::fatal("WM_QUIT message");

  case WM_CLOSE: // user clicked close box
    Fl::handle(FL_CLOSE, window);
    return 0;

  case WM_PAINT: {

    // This might be a better alternative, where we fully ignore NT's
    // "facilities" for painting. MS expects applications to paint according
    // to a very restrictive paradigm, and this is the way I found of
    // working around it. In a sense, we are using WM_PAINT simply as an
    // "exposure alert", like the X event.

    Fl_X *i = Fl_X::i(window);
    i->wait_for_expose = 0;
    // if region == entire window we should delete i->region, else
    if (window->damage()) {
      if (i->region) {
	InvalidateRgn(hWnd,i->region,FALSE);
	GetUpdateRgn(hWnd,i->region,0);
      }
    } else {
      if (!i->region) i->region = CreateRectRgn(0,0,0,0);
      GetUpdateRgn(hWnd,i->region,0);
    }
    window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
    i->flush();
    window->clear_damage();
    // This convinces MSWindows we have painted whatever they wanted
    // us to paint, and stops it from sending WM_PAINT messages.
    ValidateRgn(hWnd,NULL);
    } break;

  case WM_LBUTTONDOWN:  mouse_event(window, 0, 1, wParam, lParam); return 0;
  case WM_LBUTTONDBLCLK:mouse_event(window, 1, 1, wParam, lParam); return 0;
  case WM_LBUTTONUP:    mouse_event(window, 2, 1, wParam, lParam); return 0;
  case WM_MBUTTONDOWN:  mouse_event(window, 0, 2, wParam, lParam); return 0;
  case WM_MBUTTONDBLCLK:mouse_event(window, 1, 2, wParam, lParam); return 0;
  case WM_MBUTTONUP:    mouse_event(window, 2, 2, wParam, lParam); return 0;
  case WM_RBUTTONDOWN:  mouse_event(window, 0, 3, wParam, lParam); return 0;
  case WM_RBUTTONDBLCLK:mouse_event(window, 1, 3, wParam, lParam); return 0;
  case WM_RBUTTONUP:    mouse_event(window, 2, 3, wParam, lParam); return 0;
  case WM_MOUSEMOVE:    mouse_event(window, 3, 0, wParam, lParam); return 0;

#ifdef WM_MOUSELEAVE
  case WM_MOUSELEAVE:
    Fl::handle(FL_LEAVE, window);
    break;
#endif /* WM_MOUSELEAVE */

  case WM_SETFOCUS:
    Fl::handle(FL_FOCUS, window);
    break;

  case WM_KILLFOCUS:
    Fl::handle(FL_UNFOCUS, window);
    Fl::flush(); // it never returns to main loop when deactivated...
    break;

  case WM_SHOWWINDOW:
    if (!window->parent())
      Fl::handle(wParam ? FL_SHOW : FL_HIDE, window);
    break;

  case WM_KEYDOWN:
  case WM_SYSKEYDOWN:
  case WM_KEYUP:
  case WM_SYSKEYUP:
    // save the keysym until we figure out the characters:
    Fl::e_keysym = ms2fltk(wParam,lParam&(1<<24));
    // See if TranslateMessage turned it into a WM_*CHAR message:
    if (PeekMessage(&fl_msg, hWnd, WM_CHAR, WM_SYSDEADCHAR, 1)) {
      uMsg = fl_msg.message;
      wParam = fl_msg.wParam;
      lParam = fl_msg.lParam;
    }
  case WM_DEADCHAR:
  case WM_SYSDEADCHAR:
  case WM_CHAR:
  case WM_SYSCHAR:
    {ulong state = Fl::e_state & 0xff000000; // keep the mouse button state
     // if GetKeyState is expensive we might want to comment some of these out:
      if (GetKeyState(VK_SHIFT)&~1) state |= FL_SHIFT;
      if (GetKeyState(VK_CAPITAL)) state |= FL_CAPS_LOCK;
      if (GetKeyState(VK_CONTROL)&~1) state |= FL_CTRL;
      // Alt gets reported for the Alt-GR switch on foreign keyboards.
      // so we need to check the event as well to get it right:
      if ((lParam&(1<<29)) //same as GetKeyState(VK_MENU)
	&& uMsg != WM_CHAR) state |= FL_ALT;
      if (GetKeyState(VK_NUMLOCK)) state |= FL_NUM_LOCK;
      if (GetKeyState(VK_LWIN)&~1 || GetKeyState(VK_RWIN)&~1) {
	// WIN32 bug?  GetKeyState returns garbage if the user hit the
	// meta key to pop up start menu.  Sigh.
	if ((GetAsyncKeyState(VK_LWIN)|GetAsyncKeyState(VK_RWIN))&~1)
	  state |= FL_META;
      }
      if (GetKeyState(VK_SCROLL)) state |= FL_SCROLL_LOCK;
      Fl::e_state = state;}
    if (lParam & (1<<31)) goto DEFAULT; // ignore up events after fixing shift
    if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
      buffer[0] = char(wParam);
      Fl::e_length = 1;
    } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
      buffer[0] = Fl::e_keysym-FL_KP;
      Fl::e_length = 1;
    } else {
      buffer[0] = 0;
      Fl::e_length = 0;
    }
    Fl::e_text = buffer;
    // for (int i = lParam&0xff; i--;)
    while (window->parent()) window = window->window();
    if (Fl::handle(FL_KEYBOARD,window)) return 0;
    break;

  case WM_GETMINMAXINFO:
    Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
    break;

  case WM_SIZE:
    if (!window->parent()) {
      if (wParam == SIZE_MINIMIZED || wParam == SIZE_MAXHIDE) {
	Fl::handle(FL_HIDE, window);
      } else {
	Fl::handle(FL_SHOW, window);
	resize_bug_fix = window;
	window->size(LOWORD(lParam), HIWORD(lParam));
      }
    }
    break;

  case WM_MOVE:
    resize_bug_fix = window;
    window->position(LOWORD(lParam), HIWORD(lParam));
    break;

  case WM_SETCURSOR:
    if (LOWORD(lParam) == HTCLIENT) {
      while (window->parent()) window = window->window();
      SetCursor(Fl_X::i(window)->cursor);
      return 0;
    }
    break;

#if USE_COLORMAP
  case WM_QUERYNEWPALETTE :
    fl_GetDC(hWnd);
    if (fl_select_palette()) InvalidateRect(hWnd, NULL, FALSE);
    break;

  case WM_PALETTECHANGED:
    fl_GetDC(hWnd);
    if ((HWND)wParam != hWnd && fl_select_palette()) UpdateColors(fl_gc);
    break;

  case WM_CREATE :
    fl_GetDC(hWnd);
    fl_select_palette();
    break;

#endif

  default:
  DEFAULT:
    if (Fl::handle(0,0)) return 0;
    break;
  }

  return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

////////////////////////////////////////////////////////////////
// This function gets the dimensions of the top/left borders and
// the title bar, if there is one, based on the FL_BORDER, FL_MODAL
// and FL_NONMODAL flags, and on the window's size range.
// It returns the following values:
//
// value | border | title bar
//   0   |  none  |   no
//   1   |  fix   |   yes
//   2   |  size  |   yes

int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
  int W, H, xoff, yoff, dx, dy;
  int ret = bx = by = bt = 0;
  if (w->border() && !w->parent()) {
    if (w->maxw != w->minw || w->maxh != w->minh) {
      ret = 2;
      bx = GetSystemMetrics(SM_CXSIZEFRAME);
      by = GetSystemMetrics(SM_CYSIZEFRAME);
    } else {
      ret = 1;
      bx = GetSystemMetrics(SM_CXFIXEDFRAME);
      by = GetSystemMetrics(SM_CYFIXEDFRAME);
    }
    bt = GetSystemMetrics(SM_CYCAPTION);
  }
  //The coordinates of the whole window, including non-client area
  xoff = bx;
  yoff = by + bt;
  dx = 2*bx;
  dy = 2*by + bt;
  X = w->x()-xoff;
  Y = w->y()-yoff;
  W = w->w()+dx;
  H = w->h()+dy;

  //Proceed to positioning the window fully inside the screen, if possible
  //Make border's lower right corner visible
  if (Fl::w() < X+W) X = Fl::w() - W;
  if (Fl::h() < Y+H) Y = Fl::h() - H;
  //Make border's upper left corner visible
  if (X<0) X = 0;
  if (Y<0) Y = 0;
  //Make client area's lower right corner visible
  if (Fl::w() < X+dx+ w->w()) X = Fl::w() - w->w() - dx;
  if (Fl::h() < Y+dy+ w->h()) Y = Fl::h() - w->h() - dy;
  //Make client area's upper left corner visible
  if (X+xoff < 0) X = -xoff;
  if (Y+yoff < 0) Y = -yoff;
  //Return the client area's top left corner in (X,Y)
  X+=xoff;
  Y+=yoff;

  return ret;
}

////////////////////////////////////////////////////////////////

void Fl_Window::resize(int X,int Y,int W,int H) {
  UINT flags = SWP_NOSENDCHANGING | SWP_NOZORDER;
  int is_a_resize = (W != w() || H != h());
  int resize_from_program = (this != resize_bug_fix);
  if (!resize_from_program) resize_bug_fix = 0;
  if (X != x() || Y != y()) set_flag(FL_FORCE_POSITION);
    else {if (!is_a_resize) return; flags |= SWP_NOMOVE;}
  if (is_a_resize) {
    Fl_Group::resize(X,Y,W,H);
    if (shown()) {redraw(); i->wait_for_expose = 1;}
  } else {
    x(X); y(Y);
    flags |= SWP_NOSIZE;
  }
  if (resize_from_program && shown()) {
    int dummy, bt, bx, by;
    //Ignore window managing when resizing, so that windows (and more
    //specifically menus) can be moved offscreen.
    if (Fl_X::fake_X_wm(this, dummy, dummy, bt, bx, by)) {
      X -= bx;
      Y -= by+bt;
      W += 2*bx;
      H += 2*by+bt;
    }
    SetWindowPos(i->xid, 0, X, Y, W, H, flags);
  }
}

////////////////////////////////////////////////////////////////

void fl_fix_focus(); // in Fl.C

char fl_show_iconic;	// hack for Fl_Window::iconic()
// int fl_background_pixel = -1; // color to use for background
HCURSOR fl_default_cursor;
int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR

Fl_X* Fl_X::make(Fl_Window* w) {
  Fl_Group::current(0); // get rid of very common user bug: forgot end()

  const char* class_name = /*w->xclass();
  if (!class_name) class_name =*/ "FLTK"; // create a "FLTK" WNDCLASS

  WNDCLASSEX wc;
  // Documentation states a device context consumes about 800 bytes
  // of memory... so who cares? If 800 bytes per window is what it
  // takes to speed things up, I'm game.
  //wc.style = CS_HREDRAW | CS_VREDRAW | CS_CLASSDC | CS_DBLCLKS;
  wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC | CS_DBLCLKS;
  wc.lpfnWndProc = (WNDPROC)WndProc;
  wc.cbClsExtra = wc.cbWndExtra = 0;
  wc.hInstance = fl_display;
  if (!w->icon())
    w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
  wc.hIcon = wc.hIconSm = (HICON)w->icon();
  wc.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
  //uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
  //wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
  wc.hbrBackground = NULL;
  wc.lpszMenuName = NULL;
  wc.lpszClassName = class_name;
  wc.cbSize = sizeof(WNDCLASSEX);
  RegisterClassEx(&wc);

  HWND parent;
  DWORD style = WS_CLIPCHILDREN | WS_CLIPSIBLINGS;
  DWORD styleEx = WS_EX_LEFT;

  int xp = w->x();
  int yp = w->y();
  int wp = w->w();
  int hp = w->h();

  if (w->parent()) {
    style = WS_CHILD;
    styleEx = WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
    parent = fl_xid(w->window());
  } else {
    if (!w->size_range_set) {
      if (w->resizable()) {
	Fl_Widget *o = w->resizable();
	int minw = o->w(); if (minw > 100) minw = 100;
	int minh = o->h(); if (minh > 100) minh = 100;
	w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
      } else {
	w->size_range(w->w(), w->h(), w->w(), w->h());
      }
    }
    styleEx |= WS_EX_WINDOWEDGE | WS_EX_CONTROLPARENT;
    int xwm = xp , ywm = yp , bt, bx, by;
    switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
      // No border (user for menus)
      case 0: style |= WS_POPUP; break;

      // Thin border and title bar
      case 1: style |= WS_DLGFRAME | WS_CAPTION; break;

      // Thick, resizable border and title bar, with maximize button
      case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break;
    }
    if (by+bt) {
      if (!w->non_modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX;
      wp += 2*bx;
      hp += 2*by+bt;
    }
    if (!(w->flags() & Fl_Window::FL_FORCE_POSITION)) {
      xp = yp = CW_USEDEFAULT;
    } else {
      if (!Fl::grab()) {
	xp = xwm; yp = ywm;
        w->x(xp);w->y(yp);
      }
      xp -= bx;
      yp -= by+bt;
    }

    parent = 0;
    if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) {
      // find some other window to be "transient for":
      Fl_Window* w = Fl_X::first->w;
      while (w->parent()) w = w->window();
      parent = fl_xid(w);
    }
  }

  Fl_X* x = new Fl_X;
  x->other_xid = 0;
  x->setwindow(w);
  x->region = 0;
  x->private_dc = 0;
  x->cursor = fl_default_cursor;
  x->xid = CreateWindowEx(
    styleEx,
    class_name, w->label(), style,
    xp, yp, wp, hp,
    parent,
    NULL, // menu
    fl_display,
    NULL // creation parameters
    );
  x->next = Fl_X::first;
  Fl_X::first = x;

  x->wait_for_expose = 1;
  w->set_visible();
  w->handle(FL_SHOW); // get child windows to appear
  w->redraw(); // force draw to happen
  // If we've captured the mouse, we dont want do activate any
  // other windows from the code, or we loose the capture.
  ShowWindow(x->xid, fl_show_iconic ? SW_SHOWMINNOACTIVE :
             fl_capture? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
  fl_show_iconic = 0;
  if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
  return x;
}

////////////////////////////////////////////////////////////////

HINSTANCE fl_display = GetModuleHandle(NULL);

void Fl_Window::size_range_() {
  size_range_set = 1;
}

void Fl_X::set_minmax(LPMINMAXINFO minmax)
{
  int td, wd, hd, dummy;

  fake_X_wm(w, dummy, dummy, td, wd, hd);
  wd *= 2;
  hd *= 2;
  hd += td;

  minmax->ptMinTrackSize.x = w->minw + wd;
  minmax->ptMinTrackSize.y = w->minh + hd;
  if (w->maxw) {
    minmax->ptMaxTrackSize.x = w->maxw + wd;
    minmax->ptMaxSize.x = w->maxw + wd;
  }
  if (w->maxh) {
    minmax->ptMaxTrackSize.y = w->maxh + hd;
    minmax->ptMaxSize.y = w->maxh + hd;
  }
}

////////////////////////////////////////////////////////////////

#include <FL/filename.H> // need so FL_EXPORT filename_name works

// returns pointer to the filename, or null if name ends with '/'
const char *filename_name(const char *name) {
  const char *p,*q;
  q = name;
  if (q[0] && q[1]==':') q += 2; // skip leading drive letter
  for (p = q; *p; p++) if (*p == '/' || *p == '\\') q = p+1;
  return q;
}

void Fl_Window::label(const char *name,const char *iname) {
  Fl_Widget::label(name);
  iconlabel_ = iname;
  if (shown() && !parent()) {
    if (!name) name = "";
    SetWindowText(i->xid, name);
    // if (!iname) iname = filename_name(name);
    // should do something with iname here...
  }
}

////////////////////////////////////////////////////////////////
// Implement the virtual functions for the base Fl_Window class:

// If the box is a filled rectangle, we can make the redisplay *look*
// faster by using X's background pixel erasing.  We can make it
// actually *be* faster by drawing the frame only, this is done by
// setting fl_boxcheat, which is seen by code in fl_drawbox.C:
// For WIN32 it looks like all windows share a background color, so
// I use FL_GRAY for this and only do this cheat for windows that are
// that color.
// Actually it is totally disabled.
// Fl_Widget *fl_boxcheat;
//static inline int can_boxcheat(uchar b) {return (b==1 || (b&2) && b<=15);}

void Fl_Window::show() {
  if (!shown()) {
    // if (can_boxcheat(box())) fl_background_pixel = fl_xpixel(color());
    Fl_X::make(this);
  } else {
    // Once again, we would lose the capture if we activated the window.
    if (IsIconic(i->xid)) OpenIcon(i->xid);
    if (!fl_capture) BringWindowToTop(i->xid);
    //ShowWindow(i->xid,fl_capture?SW_SHOWNOACTIVATE:SW_RESTORE);
  }
}

Fl_Window *Fl_Window::current_;
// the current context
HDC fl_gc = 0;
// the current window handle, initially set to -1 so we can correctly
// allocate fl_GetDC(0)
HWND fl_window = (HWND)-1;

// Here we ensure only one GetDC is ever in place.
HDC fl_GetDC(HWND w) {
  if (fl_gc) {
    if (w == fl_window) return fl_gc;
    ReleaseDC(fl_window, fl_gc);
  }
  fl_gc = GetDC(w);
  fl_window = w;
  // calling GetDC seems to always reset these: (?)
  SetTextAlign(fl_gc, TA_BASELINE|TA_LEFT);
  SetBkMode(fl_gc, TRANSPARENT);
  return fl_gc;
}

// make X drawing go into this window (called by subclass flush() impl.)
void Fl_Window::make_current() {
  fl_GetDC(fl_xid(this));

#if USE_COLORMAP
  // Windows maintains a hardware and software color palette; the
  // SelectPalette() call updates the current soft->hard mapping
  // for all drawing calls, so we must select it here before any
  // code does any drawing...

  fl_select_palette();
#endif // USE_COLORMAP

  current_ = this;
  fl_clip_region(0);
}

//
// End of "$Id: Fl_win32.cxx,v 1.1 2006-10-03 11:25:11 dslinux_amadeus Exp $".
//

--- NEW FILE: glut_compatability.cxx ---
//
// "$Id: glut_compatability.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
//
// GLUT emulation routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Emulation of Glut using fltk.

// GLUT is Copyright (c) Mark J. Kilgard, 1994, 1995, 1996.
// "This program is freely distributable without licensing fees  and is
// provided without guarantee or warrantee expressed or  implied. This
// program is -not- in the public domain."

// Although I have copied the GLUT API, none of my code is based on
// any Glut implementation details and is therefore covered by the LGPL.

#include <config.h>
#if HAVE_GL

#include <FL/glut.H>

#define MAXWINDOWS 32
static Fl_Glut_Window *windows[MAXWINDOWS+1];

Fl_Glut_Window *glut_window;
int glut_menu;
void (*glut_menustate_function)(int);
void (*glut_menustatus_function)(int,int,int);

static void default_reshape(int w, int h) {glViewport(0,0,w,h);}

void Fl_Glut_Window::make_current() {
  glut_window = this;
  if (shown()) Fl_Gl_Window::make_current();
}

static int indraw;
void Fl_Glut_Window::draw() {
  glut_window = this;
  indraw = 1;
  if (!valid()) {reshape(w(),h()); valid(1);}
  display();
  indraw = 0;
}

void glutSwapBuffers() {
  if (!indraw) glut_window->swap_buffers();
}

void Fl_Glut_Window::draw_overlay() {
  glut_window = this;
  if (!valid()) {reshape(w(),h()); valid(1);}
  overlaydisplay();
}

static void domenu(int, int, int);

int Fl_Glut_Window::handle(int event) {
  make_current();
  int ex = Fl::event_x();
  int ey = Fl::event_y();
  int button;
  switch (event) {

  case FL_PUSH:
    button = Fl::event_button()-1;
    if (button<0) button = 0;
    if (button>2) button = 2;
    if (menu[button]) {domenu(menu[button],ex,ey); return 1;}
    mouse_down |= 1<<button;
    if (mouse) {mouse(button,GLUT_DOWN,ex,ey); return 1;}
    if (motion) return 1;
    break;

  case FL_RELEASE:
    for (button = 0; button < 3; button++) if (mouse_down & (1<<button)) {
      if (mouse) mouse(button,GLUT_UP,ex,ey);
    }
    mouse_down = 0;
    return 1;

  case FL_ENTER:
    if (entry) {entry(GLUT_ENTERED); return 1;}
    if (passivemotion) return 1;
    break;

  case FL_LEAVE:
    if (entry) {entry(GLUT_LEFT); return 1;}
    if (passivemotion) return 1;
    break;

  case FL_DRAG:
    if (motion) {motion(ex, ey); return 1;}
    break;

  case FL_MOVE:
    if (passivemotion) {passivemotion(ex, ey); return 1;}
    break;

  case FL_FOCUS:
    if (keyboard || special) return 1;
    break;

  case FL_KEYBOARD:
    if (Fl::event_text()[0]) {
      if (keyboard) {keyboard(Fl::event_text()[0],ex,ey); return 1;}
      break;
    } else {
      if (special) {
	int i = Fl::event_key();
	if (i > FL_F && i <= FL_F_Last) i = i-FL_F;
	special(i,ex,ey);
	return 1;
      }
      break;
    }

  case FL_HIDE:
    if (visibility) visibility(GLUT_NOT_VISIBLE);
    break;

  case FL_SHOW:
    if (visibility) visibility(GLUT_VISIBLE);
    break;
  }

  return Fl_Gl_Window::handle(event);
}

static int glut_mode = GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH;

void Fl_Glut_Window::_init() {
  for (number=1; number<MAXWINDOWS; number++) if (!windows[number]) break;
  windows[number] = this;
  menu[0] = menu[1] = menu[2] = 0;
  reshape = default_reshape;
  keyboard = 0;
  mouse = 0;
  motion = 0;
  passivemotion = 0;
  entry = 0;
  visibility = 0;
  special = 0;
  mouse_down = 0;
  mode(glut_mode);
}

Fl_Glut_Window::Fl_Glut_Window(int w, int h, const char *t) :
  Fl_Gl_Window(w,h,t) {_init();}

Fl_Glut_Window::Fl_Glut_Window(int x,int y,int w,int h, const char *t) :
  Fl_Gl_Window(x,y,w,h,t) {_init();}

static int initargc;
static char **initargv;

void glutInit(int *argc, char **argv) {
  initargc = *argc;
  initargv = new char*[*argc+1];
  int i,j;
  for (i=0; i<=*argc; i++) initargv[i] = argv[i];
  for (i=j=1; i<*argc; ) {
    if (Fl::arg(*argc,argv,i));
    else argv[j++] = argv[i++];
  }
  argv[j] = 0;
  *argc = j;
}

void glutInitDisplayMode(unsigned int mode) {
  glut_mode = mode;
}

void glutMainLoop() {Fl::run();}

////////////////////////////////////////////////////////////////

static int initx, inity, initw=300, inith=300, initpos;

void glutInitWindowPosition(int x, int y) {
  initx = x; inity = y; initpos = 1;
}

void glutInitWindowSize(int w, int h) {
  initw = w; inith = h;
}

int glutCreateWindow(char *title) {
  Fl_Glut_Window *W;
  if (initpos) {
    W = new Fl_Glut_Window(initx,inity,initw,inith,title);
    initpos = 0;
  } else {
    W = new Fl_Glut_Window(initw,inith,title);
  }
  W->resizable(W);
  if (initargc) {
    W->show(initargc,initargv);
    initargc = 0;
  } else {
    W->show();
  }
  W->make_current();
  return W->number;
}

int glutCreateSubWindow(int win, int x, int y, int w, int h) {
  Fl_Glut_Window *W = new Fl_Glut_Window(x,y,w,h,0);
  windows[win]->add(W);
  if (windows[win]->shown()) W->show();
  W->make_current();
  return W->number;
}

Fl_Glut_Window::~Fl_Glut_Window() {
  if (glut_window == this) glut_window = 0;
  windows[number] = 0;
}

void glutDestroyWindow(int win) {
  // should destroy children!!!
  delete windows[win];
}

void glutSetWindow(int win) {
  windows[win]->make_current();
}

////////////////////////////////////////////////////////////////
#include <FL/Fl_Menu_Item.H>

struct menu {
  void (*cb)(int);
  Fl_Menu_Item *m;
  int size;
  int alloc;
};

#define MAXMENUS 32
static menu menus[MAXMENUS+1];

static void domenu(int n, int ex, int ey) {
  glut_menu = n;
  menu *m = &menus[n];
  if (glut_menustate_function) glut_menustate_function(1);
  if (glut_menustatus_function) glut_menustatus_function(1,ex,ey);
  const Fl_Menu_Item* g = m->m->popup(Fl::event_x(), Fl::event_y(), 0);
  if (g && g->callback_) ((void (*)(int))(g->callback_))(int(g->argument()));
  if (glut_menustatus_function) glut_menustatus_function(0,ex,ey);
  if (glut_menustate_function) glut_menustate_function(0);
}

int glutCreateMenu(void (*cb)(int)) {
  int i;
  for (i=1; i<MAXMENUS; i++) if (!menus[i].cb) break;
  menu *m = &menus[i];
  m->cb = cb;
  return glut_menu = i;
}

void glutDestroyMenu(int n) {
  menu *m = &menus[n];
  delete[] m->m;
  m->m = 0;
  m->cb = 0;
  m->size = m->alloc = 0;
}

static Fl_Menu_Item* additem(menu *m) {
  if (m->size+1 >= m->alloc) {
    m->alloc = m->size*2+10;
    Fl_Menu_Item* nm = new Fl_Menu_Item[m->alloc];
    for (int i=0; i<m->size; i++) nm[i] = m->m[i];
    delete[] m->m;
    m->m = nm;
  }
  int n = m->size++;
  m->m[n+1].text = 0;
  Fl_Menu_Item* i = &(m->m[n]);
  i->shortcut_ = 0;
  i->flags = 0;
  i->labeltype_ = i->labelfont_ = i->labelsize_ = i->labelcolor_ = 0;
  return i;
}

void glutAddMenuEntry(char *label, int value) {
  menu *m = &menus[glut_menu];
  Fl_Menu_Item* i = additem(m);
  i->text = label;
  i->callback_ = (Fl_Callback*)(m->cb);
  i->user_data_ = (void *)value;
}

void glutAddSubMenu(char *label, int submenu) {
  menu *m = &menus[glut_menu];
  Fl_Menu_Item* i = additem(m);
  i->text = label;
  i->callback_ = 0;
  i->user_data_ = (void *)(menus[submenu].m);
  i->flags = FL_PUP_SUBMENU;
}

void glutChangeToMenuEntry(int item, char *label, int value) {
  menu *m = &menus[glut_menu];
  Fl_Menu_Item* i = &m->m[item-1];
  i->text = label;
  i->callback_ = (Fl_Callback*)(m->cb);
  i->user_data_ = (void *)value;
  i->flags = 0;
}

void glutChangeToSubMenu(int item, char *label, int submenu) {
  menu *m = &menus[glut_menu];
  Fl_Menu_Item* i = &m->m[item-1];
  i->text = label;
  i->callback_ = 0;
  i->user_data_ = (void *)(menus[submenu].m);
  i->flags = FL_PUP_SUBMENU;
}

void glutRemoveMenuItem(int item) {
  menu *m = &menus[glut_menu];
  if (item > m->size || item < 1) return;
  for (int i = item-1; i <= m->size; i++) m->m[i] = m->m[i+1];
  m->size--;
}

////////////////////////////////////////////////////////////////

int glutGet(GLenum type) {
  switch (type) {
  case GLUT_RETURN_ZERO: return 0;
  case GLUT_WINDOW_X: return glut_window->x();
  case GLUT_WINDOW_Y: return glut_window->y();
  case GLUT_WINDOW_WIDTH: return glut_window->w();
  case GLUT_WINDOW_HEIGHT: return glut_window->h();
  case GLUT_WINDOW_PARENT:
    if (glut_window->parent())
      return ((Fl_Glut_Window *)(glut_window->parent()))->number;
    else
      return 0;
//case GLUT_WINDOW_NUM_CHILDREN:
//case GLUT_WINDOW_CURSOR: return 
  case GLUT_SCREEN_WIDTH: return Fl::w();
  case GLUT_SCREEN_HEIGHT: return Fl::h();
//case GLUT_SCREEN_WIDTH_MM:
//case GLUT_SCREEN_HEIGHT_MM:
  case GLUT_MENU_NUM_ITEMS: return menus[glut_menu].size;
  case GLUT_DISPLAY_MODE_POSSIBLE: return Fl_Gl_Window::can_do(glut_mode);
  case GLUT_INIT_WINDOW_X: return initx;
  case GLUT_INIT_WINDOW_Y: return inity;
  case GLUT_INIT_WINDOW_WIDTH: return initw;
  case GLUT_INIT_WINDOW_HEIGHT: return inith;
  case GLUT_INIT_DISPLAY_MODE: return glut_mode;
//case GLUT_ELAPSED_TIME:
  case GLUT_WINDOW_BUFFER_SIZE:
    if (glutGet(GLUT_WINDOW_RGBA))
      return glutGet(GLUT_WINDOW_RED_SIZE)+
	glutGet(GLUT_WINDOW_GREEN_SIZE)+
	glutGet(GLUT_WINDOW_BLUE_SIZE)+
	glutGet(GLUT_WINDOW_ALPHA_SIZE);
    else
      return glutGet(GLUT_WINDOW_COLORMAP_SIZE);
  default: {GLint p; glGetIntegerv(type, &p); return p;}
  }
}

int glutLayerGet(GLenum type) {
  switch (type) {
  case GLUT_OVERLAY_POSSIBLE: return glut_window->can_do_overlay();
//case GLUT_LAYER_IN_USE:
//case GLUT_HAS_OVERLAY:
  case GLUT_TRANSPARENT_INDEX: return 0; // true for SGI
  case GLUT_NORMAL_DAMAGED: return glut_window->damage();
  case GLUT_OVERLAY_DAMAGED: return 1; // kind of works...
  default: return 0;
  }
}

#endif

//
// End of "$Id: glut_compatability.cxx,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Input_.cxx ---
//
// "$Id: Fl_Input_.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Common input widget routines for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This is the base class for Fl_Input.  You can use it directly
// if you are one of those people who like to define their own
// set of editing keys.  It may also be useful for adding scrollbars
// to the input field.

#include <FL/Fl.H>
#include <FL/Fl_Input_.H>
#include <FL/fl_draw.H>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

#define MAXBUF 1024

////////////////////////////////////////////////////////////////

// Wordwrap kludge.  It "sort of" works but there are lots of bugs.
// Really the whole multi-line-input should be moved to a seperate
// (and much more complex) subclass.  Single-line and multi-line
// input are really a *lot* different!
// To try the wordwrap define this:
//#define WORDWRAP
//#ifdef WORDWRAP
static int wordwrap; // width for wordwrapping, should be are to Fl_Input_.
//#endif

// Copy string p..e to the buffer, replacing characters with ^X and \nnn
// as necessary.  Truncate if necessary so the resulting string and
// null terminator fits in a buffer of size n.  Return new end pointer.
const char* Fl_Input_::expand(const char* p, char* buf) const {
  char* o = buf;
  char* e = buf+(MAXBUF-4);
//#ifdef WORDWRAP
  const char* lastspace = p;
  char* lastspace_out = o;
  int width_to_lastspace = 0;
//#endif
  if (type()==FL_SECRET_INPUT) {
    while (o<e && p < value_+size_) {*o++ = '*'; p++;}
  } else while (o<e) {
//#ifdef WORDWRAP
	  if (ww_)
	  {
    if (wordwrap && (p >= value_+size_ || *p==' ' || *p=='\n')) {
      width_to_lastspace += fl_width(lastspace, p-lastspace);
      if (p > lastspace+1) {
	if (width_to_lastspace > wordwrap) {
	  p = lastspace; o = lastspace_out; break;
	}
      }
      lastspace = p;
      lastspace_out = o;
    }
	  } // end of if
//#endif
    if (p >= value_+size_) break;
    int c = *p++ & 255;
    if (c < ' ' || c == 127) {
      if (c=='\n' && type()==FL_MULTILINE_INPUT) {p--; break;}
      if (c == '\t' && type()==FL_MULTILINE_INPUT) {
	for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';
      } else {
	*o++ = '^';
	*o++ = c ^ 0x40;
      }
    } else if (c >= 128 && c < 0xA0) {
      *o++ = '\\';
      *o++ = (c>>6)+'0';
      *o++ = ((c>>3)&7)+'0';
      *o++ = (c&7)+'0';
    } else if (c == 0xA0) { // nbsp
      *o++ = ' ';
    } else {
      *o++ = c;
    }
  }
  *o = 0;
  return p;
}

// After filling in such a buffer, find the width to e
double Fl_Input_::expandpos(
  const char* p,	// real string
  const char* e,	// pointer into real string
  const char* buf,	// conversion of real string by expand()
  int* returnn		// return offset into buf here
) const {
  int n = 0;
  if (type()==FL_SECRET_INPUT) n = e-p;
  else while (p<e) {
    int c = *p++ & 255;
    if (c < ' ' || c == 127) {
      if (c == '\t' && type()==FL_MULTILINE_INPUT) n += 8-(n%8);
      else n += 2;
    } else if (c >= 128 && c < 0xA0) {
      n += 4;
    } else {
      n++;
    }
  }
  if (returnn) *returnn = n;
  return fl_width(buf, n);
}

////////////////////////////////////////////////////////////////

// minimal update:
// Characters from mu_p to end of widget are redrawn.
// If erase_cursor_only, small part at mu_p is redrawn.
// Right now minimal update just keeps unchanged characters from
// being erased, so they don't blink.

void Fl_Input_::minimal_update(int p) {
  if (damage() & FL_DAMAGE_ALL) return; // don't waste time if it won't be done
  if (damage() & FL_DAMAGE_EXPOSE) {
    if (p < mu_p) mu_p = p;
  } else {
    mu_p = p;
  }
  damage(FL_DAMAGE_EXPOSE);
  erase_cursor_only = 0;
}

void Fl_Input_::minimal_update(int p, int q) {
  if (q < p) p = q;
  minimal_update(p);
}

////////////////////////////////////////////////////////////////

static double up_down_pos;
static int was_up_down;

void Fl_Input_::setfont() const {
 fl_font(textfont(), textsize());
}

void Fl_Input_::drawtext(int X, int Y, int W, int H) {

#ifdef PDA
	X += 1;
	Y += 1;
	W -= 2;
	H -= 2;
#endif

  int do_mu = !(damage()&FL_DAMAGE_ALL);
  if (Fl::focus()!=this && !size()) {
    if (do_mu) { // we have to erase it if cursor was there
      fl_color(color());
      fl_rectf(X, Y, W, H);
    }
    return;
  }

  int selstart, selend;
  if (Fl::focus()!=this && /*Fl::selection_owner()!=this &&*/ Fl::pushed()!=this)
    selstart = selend = 0;
  else if (position() <= mark()) {
    selstart = position(); selend = mark();
  } else {
    selend = position(); selstart = mark();
  }

  setfont();
//#ifdef WORDWRAP
  if (ww_)
  	if (type()==FL_MULTILINE_INPUT) wordwrap = W; else wordwrap = 0;
//#endif


  const char *p, *e;
  char buf[MAXBUF];

  // count how many lines and put the last one into the buffer:
  // And figure out where the cursor is:
  int height = fl_height();
  int lines;
  int curx, cury;
  for (p=value(), curx=cury=lines=0; ;) {
    e = expand(p, buf);
    if (position() >= p-value() && position() <= e-value()) {
      curx = int(expandpos(p, value()+position(), buf, 0)+.5);
      if (Fl::focus()==this && !was_up_down) up_down_pos = curx;
      cury = lines*height;
      if (Fl::focus()==this) {
	int fullw = int(expandpos(p, e, buf, 0));
	if (curx > xscroll_+W-20) {
	  xscroll_ = curx+20-W;
	  if (xscroll_ > fullw-W+2) xscroll_ = fullw-W+2;
	  mu_p = 0; erase_cursor_only = 0;
	}
	if (curx < xscroll_+20 && xscroll_) {
	  if (fullw > W-2) xscroll_ = curx-20;
	  else xscroll_ = 0;
	  mu_p = 0; erase_cursor_only = 0;
	}
	if (xscroll_ < 0) xscroll_ = 0;
      }
    }
    lines++;
    if (e >= value_+size_) break;
    if (*e == '\n' || *e == ' ') e++;
    p = e;
  }

  // adjust the scrolling:
  if (type()==FL_MULTILINE_INPUT) {
    int newy = yscroll_;
    if (cury < newy) newy = cury;
    if (cury > newy+H-height) newy = cury-H+height;
    if (newy < -1) newy = -1;
    if (newy != yscroll_) {yscroll_ = newy; mu_p = 0; erase_cursor_only = 0;}
  } else {
    yscroll_ = -(H-height)/2;
  }

  fl_clip(X, Y, W, H);
  Fl_Color color = active_r() ? textcolor() : inactive(textcolor());

  p = value();
  // visit each line and draw it:
  int desc = height-fl_descent();
  int ypos = -yscroll_;
  for (; ypos < H;) {

    // re-expand line unless it is the last one calculated above:
    if (lines>1) e = expand(p, buf);

    if (ypos <= -height) goto CONTINUE; // clipped off top

    if (do_mu) {	// for minimal update:
      const char* pp = value()+mu_p; // pointer to where minimal update starts
      if (e >= pp && (!erase_cursor_only || p <= pp)) { // we must erase this
	// calculate area to erase:
	int x1 = -xscroll_;
	if (p < pp) x1 += int(expandpos(p, pp, buf, 0));
	// erase it:
	fl_color(this->color());
	fl_rectf(X+x1, Y+ypos, erase_cursor_only?2:W-x1, height);
	// it now draws entire line over it
	// this should not draw letters to left of erased area, but
	// that is nyi.
      }
    }

    // Draw selection area if required:
    if (selstart < selend && selstart <= e-value() && selend > p-value()) {
      const char* pp = value()+selstart;
      int x1 = -xscroll_;
      int offset1 = 0;
      if (pp > p) {
	fl_color(color);
	x1 += int(expandpos(p, pp, buf, &offset1));
	fl_draw(buf, offset1, X-xscroll_, Y+ypos+desc);
      }
      pp = value()+selend;
      int x2 = W;
      int offset2;
      if (pp <= e) x2 = int(expandpos(p, pp, buf, &offset2))-xscroll_;
      else offset2 = strlen(buf);
      fl_color(selection_color());
      fl_rectf(X+int(x1+.5), Y+ypos, int(x2-x1), height);
      fl_color(contrast(textcolor(), selection_color()));
      fl_draw(buf+offset1, offset2-offset1, X+x1, Y+ypos+desc);
      if (pp < e) {
	fl_color(color);
	fl_draw(buf+offset2, X+x2, Y+ypos+desc);
      }
    } else {
      // draw the cursor:
      if (Fl::focus() == this && selstart == selend &&
	  position() >= p-value() && position() <= e-value()) {
	fl_color(cursor_color());
	fl_rectf(X+curx-xscroll_, Y+ypos, 2, height);
      }
      fl_color(color);
      fl_draw(buf, X-xscroll_, Y+ypos+desc);
    }
  CONTINUE:
    ypos += height;
    if (e >= value_+size_) break;
    if (*e == '\n' || *e == ' ') e++;
    p = e;
  }

  // for minimal update, erase all lines below last one if necessary:
  if (type()==FL_MULTILINE_INPUT && do_mu && ypos<H
      && (!erase_cursor_only || p <= value()+mu_p)) {
    if (ypos < 0) ypos = 0;
    fl_color(this->color());
    fl_rectf(X, Y+ypos, W, H-ypos);
  }

  fl_pop_clip();
}

static int isword(char c) {
  return (c&128 || isalnum(c) || strchr("#%&-/@\\_~", c));
}

int Fl_Input_::wordboundary(int i) const {
  if (i<=0 || i>=size()) return 1;
  return isword(index(i-1)) != isword(index(i));
}

int Fl_Input_::lineboundary(int i) const {
  if (i<=0 || i>=size()) return 1;
  if (type() != FL_MULTILINE_INPUT) return 0;
  return index(i-1) == '\n' || index(i) == '\n';
}
#include <stdio.h>
void Fl_Input_::handle_mouse(int X, int Y,
#ifdef WORDWRAP
			     int W,
#else
			     int /*W*/,
#endif
			     int /*H*/, int drag) {

  was_up_down = 0;
  if (!size()) return;
  setfont();

  const char *p, *e;
  char buf[MAXBUF];

  int theline = (type()==FL_MULTILINE_INPUT) ?
    (Fl::event_y()-Y+yscroll_)/fl_height() : 0;

  int newpos = 0;
#ifdef WORDWRAP
  	if (type()==FL_MULTILINE_INPUT) wordwrap = W; else wordwrap = 0;
#endif
  for (p=value();; ) {
    e = expand(p, buf);
    theline--; if (theline < 0) break;
    if (*e == '\n' || *e == ' ') e++;
    p = e;
    if (e >= value_+size_) break;
  }
  const char *l, *r, *t; double f0 = Fl::event_x()-X+xscroll_;
  for (l = p, r = e; l<r; ) {
    double f;
    t = l+(r-l+1)/2;
    f = X-xscroll_+expandpos(p, t, buf, 0);
    if (f <= Fl::event_x()) {l = t; f0 = Fl::event_x()-f;}
    else r = t-1;
  }
  if (l < e) { // see if closer to character on right:
    double f1 = X-xscroll_+expandpos(p, l+1, buf, 0)-Fl::event_x();
    if (f1 < f0) l = l+1;
  }
  newpos = l-value();

  int newmark = drag ? mark() : newpos;
  if (Fl::event_clicks()) {
    if (newpos >= newmark) {
      if (newpos == newmark) {
	if (newpos < size()) newpos++;
	else newmark--;
      }
      if (Fl::event_clicks()>1 || type()==FL_SECRET_INPUT) {
	while (!lineboundary(newpos)) newpos++;
	while (!lineboundary(newmark)) newmark--;
      } else {
	while (!wordboundary(newpos)) newpos++;
	while (!wordboundary(newmark)) newmark--;
      }
    } else {
      if (Fl::event_clicks()>1 || type()==FL_SECRET_INPUT) {
	while (!lineboundary(newpos)) newpos--;
      } else {
	while (!wordboundary(newpos)) newpos--;
      }
    }
    // if the multiple click does not increase the selection, revert
    // to single-click behavior:
    if (!drag && (mark() > position() ?
                  (newmark >= position() && newpos <= mark()) :
                  (newmark >= mark() && newpos <= position()))) {
      Fl::event_clicks(0);
      newmark = newpos = l-value();
    }
  }
  position(newpos, newmark);
}

int Fl_Input_::position(int p, int m) {
  was_up_down = 0;
  if (p<0) p = 0;
  if (p>size()) p = size();
  if (m<0) m = 0;
  if (m>size()) m = size();
  if (p == position_ && m == mark_) return 0;
  //if (Fl::selection_owner() == this) Fl::selection_owner(0);
  if (p != m) {
    if (p != position_) minimal_update(position_, p);
    if (m != mark_) minimal_update(mark_, m);
  } else {
    // new position is a cursor
    if (position_ == mark_) {
      // old position was just a cursor
      if (Fl::focus() == this && !(damage()&FL_DAMAGE_EXPOSE)) {
	minimal_update(position_); erase_cursor_only = 1;
      }
    } else { // old position was a selection
      minimal_update(position_, mark_);
    }
  }
  position_ = p;
  mark_ = m;
  return 1;
}

int Fl_Input_::up_down_position(int i, int keepmark) {
  while (i > 0 && index(i-1) != '\n') i--;	// go to start of line
  double oldwid = 0.0;
  setfont();
  while (index(i) && index(i)!='\n') {
    double tt = oldwid + fl_width(index(i));
    if ((oldwid+tt)/2 >= up_down_pos) break;
    oldwid = tt;
    i++;
  }
  int j = position(i, keepmark ? mark_ : i);
  was_up_down = 1;
  return j;
}

int Fl_Input_::copy() {
  if (mark() != position()) {
    int b, e; if (position() < mark()) {
      b = position(); e = mark();
    } else {
      e = position(); b = mark();
    }
    Fl::selection(*this, value()+b, (type()!=FL_SECRET_INPUT) ? e-b : 0);
    return 1;
  }
  return 0;
}

#define MAXFLOATSIZE 40

static char* undobuffer;
static int undobufferlength;
static Fl_Input_* undowidget;
static int undoat;	// points after insertion
static int undocut;	// number of characters deleted there
static int undoinsert;	// number of characters inserted
static int yankcut;	// length of valid contents of buffer, even if undocut=0

static void undobuffersize(int n) {
  if (n > undobufferlength) {
    if (undobuffer) {
      do {undobufferlength *= 2;} while (undobufferlength < n);
      undobuffer = (char*)realloc(undobuffer, undobufferlength);
    } else {
      undobufferlength = n+9;
      undobuffer = (char*)malloc(undobufferlength);
    }
  }
}

// all changes go through here, delete characters b-e and insert text:
int Fl_Input_::replace(int b, int e, const char* text, int ilen) {

  was_up_down = 0;

  if (b<0) b = 0;
  if (e<0) e = 0;
  if (b>size_) b = size_;
  if (e>size_) e = size_;
  if (e<b) {int t=b; b=e; e=t;}
  if (text && !ilen) ilen = strlen(text);
  if (e<=b && !ilen) return 0; // don't clobber undo for a null operation
  if (size_+ilen-(e-b) > maximum_size_) {
    ilen = maximum_size_-size_+(e-b);
    if (ilen < 0) ilen = 0;
  }

  put_in_buffer(size_+ilen);

  if (e>b) {
    if (undowidget == this && b == undoat) {
      undobuffersize(undocut+(e-b));
      memcpy(undobuffer+undocut, value_+b, e-b);
      undocut += e-b;
    } else if (undowidget == this && e == undoat && !undoinsert) {
      undobuffersize(undocut+(e-b));
      memmove(undobuffer+(e-b), undobuffer, undocut);
      memcpy(undobuffer, value_+b, e-b);
      undocut += e-b;
    } else if (undowidget == this && e == undoat && (e-b)<undoinsert) {
      undoinsert -= e-b;
    } else {
      undobuffersize(e-b);
      memcpy(undobuffer, value_+b, e-b);
      undocut = e-b;
      undoinsert = 0;
    }
    memmove(buffer+b, buffer+e, size_-e+1);
    size_ -= e-b;
    undowidget = this;
    undoat = b;
    if (type() == FL_SECRET_INPUT) yankcut = 0; else yankcut = undocut;
  }

  if (ilen) {
    if (undowidget == this && b == undoat)
      undoinsert += ilen;
    else {
      undocut = 0;
      undoinsert = ilen;
    }
    memmove(buffer+b+ilen, buffer+b, size_-b+1);
    memcpy(buffer+b, text, ilen);
    size_ += ilen;
  }
  undowidget = this;
  mark_ = position_ = undoat = b+ilen;

  minimal_update(b);
  if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
  return 1;
}

int Fl_Input_::undo() {
  was_up_down = 0;
  if (undowidget != this || !undocut && !undoinsert) return 0;

  int ilen = undocut;
  int xlen = undoinsert;
  int b = undoat-xlen;
  int b1 = b;

  put_in_buffer(size_+ilen);

  if (ilen) {
    memmove(buffer+b+ilen, buffer+b, size_-b+1);
    memcpy(buffer+b, undobuffer, ilen);
    size_ += ilen;
    b += ilen;
  }

  if (xlen) {
    undobuffersize(xlen);
    memcpy(undobuffer, buffer+b, xlen);
    memmove(buffer+b, buffer+b+xlen, size_-xlen-b+1);
    size_ -= xlen;
  }

  undocut = xlen;
  if (xlen) yankcut = xlen;
  undoinsert = ilen;
  undoat = b;
  mark_ = b /* -ilen */;
  position_ = b;

  minimal_update(b1);
  if (when()&FL_WHEN_CHANGED) do_callback(); else set_changed();
  return 1;
}

#if 0
int Fl_Input_::yank() {
  // fake yank by trying to get it out of undobuffer
  if (!yankcut) return 0;
  return change(position(), position(), undobuffer, yankcut);
}
#endif

int Fl_Input_::copy_cuts() {
  // put the yank buffer into the X clipboard
  if (!yankcut) return 0;
  Fl::selection(*this, undobuffer, yankcut);
  return 1;
}

void Fl_Input_::maybe_do_callback() {
  if (changed() || (when()&FL_WHEN_NOT_CHANGED)) {
    clear_changed(); do_callback();}
}

int Fl_Input_::handletext(int event, int X, int Y, int W, int H) {

  switch (event) {

  case FL_FOCUS:
    if ( (when() & FL_WHEN_NOT_CHANGED) || 
	 (when() & FL_WHEN_RELEASE_ALWAYS) )
      do_callback();
    if (mark_ == position_) {
      minimal_update(size()+1);
    } else //if (Fl::selection_owner() != this)
      minimal_update(mark_, position_);
    return 1;

  case FL_UNFOCUS:
    if (mark_ == position_) {
      if (!(damage()&FL_DAMAGE_EXPOSE)) {
			minimal_update(position_); erase_cursor_only = 1;
		}
    } else {//if (Fl::selection_owner() != this)
      	minimal_update(mark_, position_);
	 }
    if (when() & FL_WHEN_RELEASE) { 
				maybe_do_callback();
	 }
    return 1;

  case FL_PUSH:
    handle_mouse(X, Y, W, H, Fl::event_state(FL_SHIFT));
    return 1;

  case FL_DRAG:
    handle_mouse(X, Y, W, H, 1);
    return 1;

  case FL_RELEASE:
    // handle_mouse(X, Y, W, H, 1);
    copy();
    return 1;

//   case FL_SELECTIONCLEAR:
//     minimal_update(mark_, position_);
//     mark_ = position_;
//     return 1;

  case FL_PASTE: {
    // strip trailing control characters and spaces before pasting:
    const char* t = Fl::event_text();
    const char* e = t+Fl::event_length();
    if (type()!=FL_MULTILINE_INPUT) while (e > t && *(uchar*)(e-1) <= ' ') e--;
    return replace(position(), mark(), t, e-t);}

  default:
    return 0;
  }
}

/*------------------------------*/

Fl_Input_::Fl_Input_(int x, int y, int w, int h, const char* l)
: Fl_Widget(x, y, w, h, l) {
  box(FL_DOWN_BOX);
  color(FL_WHITE, FL_SELECTION_COLOR);
  align(FL_ALIGN_LEFT);
  textsize_ = FL_NORMAL_SIZE;
  textfont_ = FL_HELVETICA;
  textcolor_ = FL_BLACK;
  cursor_color_ = FL_BLACK; // was FL_BLUE
  mark_ = position_ = size_ = 0;
  bufsize = 0;
  buffer  = 0;
  value_ = "";
  xscroll_ = yscroll_ = 0;
  maximum_size_ = 32767;
  ww_ = 0;
}

void Fl_Input_::put_in_buffer(int len) {
  if (value_ == buffer && bufsize > len) {
    buffer[size_] = 0;
    return;
  }
  if (!bufsize) {
    if (len > size_) len += 9; // let a few characters insert before realloc
    bufsize = len+1; 
    buffer = (char*)malloc(bufsize);
  } else if (bufsize <= len) {
    // we may need to move old value in case it points into buffer:
    int moveit = (value_ >= buffer && value_ < buffer+bufsize);
    // enlarge current buffer
    if (len > size_) {
      do {bufsize *= 2;} while (bufsize <= len);
    } else {
      bufsize = len+1;
    }
    char* nbuffer = (char*)realloc(buffer, bufsize);
    if (moveit) value_ += (nbuffer-buffer);
    buffer = nbuffer;
  }
  memmove(buffer, value_, size_); buffer[size_] = 0;
  value_ = buffer;
}

int Fl_Input_::static_value(const char* str, int len) {
  clear_changed();
  if (undowidget == this) undowidget = 0;
  if (str == value_ && len == size_) return 0;
  if (len) { // non-empty new value:
    if (xscroll_ || yscroll_) {
      xscroll_ = yscroll_ = 0;
      minimal_update(0);
    } else {
      int i = 0;
      // find first different character:
      if (value_) {
	for (; i<size_ && i<len && str[i]==value_[i]; i++);
	if (i==size_ && i==len) return 0;
      }
      minimal_update(i);
    }
    value_ = str;
    size_ = len;
  } else { // empty new value:
    if (!size_) return 0; // both old and new are empty.
    size_ = 0;
    value_ = "";
    xscroll_ = yscroll_ = 0;
    minimal_update(0);
  }
  position(size(), 0);
  return 1;
}

int Fl_Input_::static_value(const char* str) {
  return static_value(str, str ? strlen(str) : 0);
}

int Fl_Input_::value(const char* str, int len) {
  int r = static_value(str, len);
  if (len) put_in_buffer(len);
  return r;
}

int Fl_Input_::value(const char* str) {
  return value(str, str ? strlen(str) : 0);
}

void Fl_Input_::resize(int X, int Y, int W, int H) {
  if (W != w()) xscroll_ = 0;
  if (H != h()) yscroll_ = 0;
  Fl_Widget::resize(X, Y, W, H);
}

Fl_Input_::~Fl_Input_() {
  if (undowidget == this) undowidget = 0;
  if (bufsize) free((void*)buffer);
}

//
// End of "$Id: Fl_Input_.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Positioner.cxx ---
//
// "$Id: Fl_Positioner.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $"
//
// Positioner widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// The positioner widget from Forms, gives 2D input
// Written by: Mark Overmars

#include <FL/Fl.H>
#include <FL/Fl_Positioner.H>
#include <FL/fl_draw.H>

static double flinear(double val, double smin, double smax, double gmin, double gmax)
{
  if (smin == smax) return gmax;
  else return gmin + (gmax - gmin) * (val - smin) / (smax - smin);
}

void Fl_Positioner::draw(int x, int y, int w, int h) {
  int x1 = x + 4;
  int y1 = y + 4;
  int w1 = w - 2 * 4;
  int h1 = h - 2 * 4;
  int xx = int(flinear(xvalue(), xmin, xmax, x1, x1+w1-1)+.5);
  int yy = int(flinear(yvalue(), ymin, ymax, y1, y1+h1-1)+.5);
  draw_box(box(), x, y, w, h, color());
  fl_color(selection_color());
  fl_xyline(x1, yy, x1+w1);
  fl_yxline(xx, y1, y1+h1);
}

void Fl_Positioner::draw() {
  draw(x(), y(), w(), h());
  draw_label();
}

int Fl_Positioner::value(double X, double Y) {
  clear_changed();
  if (X == xvalue_ && Y == yvalue_) return 0;
  xvalue_ = X; yvalue_ = Y;
  redraw();
  return 1;
}

int Fl_Positioner::xvalue(double X) {
  return(value(X, yvalue_));
}

int Fl_Positioner::yvalue(double Y) {
  return(value(xvalue_, Y));
}

int Fl_Positioner::handle(int event, int x, int y, int w, int h) {
  switch (event) {
  case FL_PUSH:
  case FL_DRAG:
  case FL_RELEASE: {
    double x1 = x + 4;
    double y1 = y + 4;
    double w1 = w - 2 * 4;
    double h1 = h - 2 * 4;
    double X = flinear(Fl::event_x(), x1, x1+w1-1.0, xmin, xmax);
    if (xstep_) X = int(X/xstep_+0.5) * xstep_;
    if (X < xmin) X = xmin;
    if (X > xmax) X = xmax;
    double Y = flinear(Fl::event_y(), y1, y1+h1-1.0, ymin, ymax);
    if (ystep_) Y = int(Y/ystep_+0.5) * ystep_;
    if (Y < ymin) Y = ymin;
    if (Y > ymax) Y = ymax;
    if (value(X, Y)) set_changed();}
    if (!(when() & FL_WHEN_CHANGED ||
	  when() & FL_WHEN_RELEASE && event == FL_RELEASE)) return 1;
    if (changed() || when()&FL_WHEN_NOT_CHANGED) {
      clear_changed(); do_callback();}
    return 1;
  default:
    return 0;
  }
}

int Fl_Positioner::handle(int e) {
  return handle(e, x(), y(), w(), h());
}

Fl_Positioner::Fl_Positioner(int x, int y, int w, int h, const char* l)
: Fl_Widget(x, y, w, h, l) {
  box(FL_DOWN_BOX);
  selection_color(FL_RED);
  align(FL_ALIGN_BOTTOM);
  when(FL_WHEN_CHANGED);
  xmin = ymin = 0;
  xmax = ymax = 1;
  xvalue_ = yvalue_ = .5;
  xstep_ = ystep_ = 0;
}

void Fl_Positioner::xbounds(double a, double b) {
  if (a != xmin || b != xmax) {
    xmin = a; xmax = b;
    redraw();
  }
}

void Fl_Positioner::ybounds(double a, double b) {
  if (a != ymin || b != ymax) {
    ymin = a; ymax = b;
    redraw();
  }
}

//
// End of "$Id: Fl_Positioner.cxx,v 1.1 2006-10-03 11:25:09 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Counter.cxx ---
//
// "$Id: Fl_Counter.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Counter widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <FL/Fl.H>
#include <FL/Fl_Counter.H>
#include <FL/fl_draw.H>

void Fl_Counter::draw() {
  int i; Fl_Boxtype boxtype[5];
  Fl_Color selcolor;

  boxtype[0] = box();
  if (boxtype[0] == FL_UP_BOX) boxtype[0] = FL_DOWN_BOX;
  for (i=1; i<5; i++)
    if (mouseobj == i)
      boxtype[i] = down(box());
    else
      boxtype[i] = box();

  int xx[5], ww[5];
  if (type() == FL_NORMAL_COUNTER) {
    int W = w()*15/100;
    xx[1] = x();	 ww[1] = W;
    xx[2] = x()+1*W;     ww[2] = W;
    xx[0] = x()+2*W;     ww[0] = w()-4*W;
    xx[3] = x()+w()-2*W; ww[3] = W;
    xx[4] = x()+w()-1*W; ww[4] = W;
  } else {
    int W = w()*20/100;
    xx[2] = x();	 ww[2] = W;
    xx[0] = x()+W;	 ww[0] = w()-2*W;
    xx[3] = x()+w()-1*W; ww[3] = W;
  }

  draw_box(boxtype[0], xx[0], y(), ww[0], h(), FL_WHITE);
  fl_font(textfont(), textsize());
  fl_color(active_r() ? textcolor() : inactive(textcolor()));
  char str[128]; format(str);
  fl_draw(str, xx[0], y(), ww[0], h(), FL_ALIGN_CENTER);
  if (!(damage()&FL_DAMAGE_ALL)) return; // only need to redraw text

  if (active_r())
    selcolor = labelcolor();
  else
    selcolor = inactive(labelcolor());

  if (type() == FL_NORMAL_COUNTER) {
    draw_box(boxtype[1], xx[1], y(), ww[1], h(), color());
    fl_draw_symbol("@-4<<", xx[1], y(), ww[1], h(), selcolor);
  }
  draw_box(boxtype[2], xx[2], y(), ww[2], h(), color());
  fl_draw_symbol("@-4<",  xx[2], y(), ww[2], h(), selcolor);
  draw_box(boxtype[3], xx[3], y(), ww[3], h(), color());
  fl_draw_symbol("@-4>",  xx[3], y(), ww[3], h(), selcolor);
  if (type() == FL_NORMAL_COUNTER) {
    draw_box(boxtype[4], xx[4], y(), ww[4], h(), color());
    fl_draw_symbol("@-4>>", xx[4], y(), ww[4], h(), selcolor);
  }
}

void Fl_Counter::increment_cb() {
  if (!mouseobj) return;
  double v = value();
  switch (mouseobj) {
  case 1: v -= lstep_; break;
  case 2: v = increment(v, -1); break;
  case 3: v = increment(v, 1); break;
  case 4: v += lstep_; break;
  }
  handle_drag(clamp(round(v)));
}

#define INITIALREPEAT .5
#define REPEAT .1

void Fl_Counter::repeat_callback(void* v) {
  Fl_Counter* b = (Fl_Counter*)v;
  if (b->mouseobj) {
    Fl::add_timeout(REPEAT, repeat_callback, b);
    b->increment_cb();
  }
}

int Fl_Counter::calc_mouseobj() {
  if (type() == FL_NORMAL_COUNTER) {
    int W = w()*15/100;
    if (Fl::event_inside(x(), y(), W, h())) return 1;
    if (Fl::event_inside(x()+W, y(), W, h())) return 2;
    if (Fl::event_inside(x()+w()-2*W, y(), W, h())) return 3;
    if (Fl::event_inside(x()+w()-W, y(), W, h())) return 4;
  } else {
    int W = w()*20/100;
    if (Fl::event_inside(x(), y(), W, h())) return 2;
    if (Fl::event_inside(x()+w()-W, y(), W, h())) return 3;
  }
  return -1;
}

int Fl_Counter::handle(int event) {
  int i;
  switch (event) {
  case FL_RELEASE:
    if (mouseobj) {
      Fl::remove_timeout(repeat_callback, this);
      mouseobj = 0;
      redraw();
    }
    handle_release();
    return 1;
  case FL_PUSH:
    handle_push();
  case FL_DRAG:
    i = calc_mouseobj();
    if (i != mouseobj) {
      Fl::remove_timeout(repeat_callback, this);
      mouseobj = i;
      if (i) Fl::add_timeout(INITIALREPEAT, repeat_callback, this);
      increment_cb();
      redraw();
    }
    return 1;
  default:
    return 0;
  }
}

Fl_Counter::~Fl_Counter() {
  Fl::remove_timeout(repeat_callback, this);
}

Fl_Counter::Fl_Counter(int x, int y, int w, int h, const char* l)
  : Fl_Valuator(x, y, w, h, l) {
  box(FL_UP_BOX);
  selection_color(FL_INACTIVE_COLOR); // was FL_BLUE
  align(FL_ALIGN_BOTTOM);
  bounds(-1000000.0, 1000000.0);
  Fl_Valuator::step(1, 10);
  lstep_ = 1.0;
  mouseobj = 0;
  textfont_ = FL_HELVETICA;
  textsize_ = FL_NORMAL_SIZE;
  textcolor_ = FL_BLACK;
}

//
// End of "$Id: Fl_Counter.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: fl_draw.cxx ---
//
// "$Id: fl_draw.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $"
//
// Label drawing code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Implementation of fl_draw(const char*,int,int,int,int,Fl_Align)
// Used to draw all the labels and text, this routine:
// Word wraps the labels to fit into their bounding box.
// Breaks them into lines at the newlines.
// Expands all unprintable characters to ^X or \nnn notation
// Aligns them against the inside of the box.

#include <FL/fl_draw.H>
#include <string.h>

#define MAXBUF 1024

char fl_draw_shortcut;	// set by fl_labeltypes.C
static char* underline_at;

// Copy p to buf, replacing unprintable characters with ^X and \nnn
// Stop at a newline of if MAXBUF characters written to buffer.
// Also word-wrap if width exceeds maxw.
// Returns a pointer to the start of the next line of caharcters.
// Sets n to the number of characters put into the buffer.
// Sets width to the width of the string in the current font.

static const char*
expand(const char* from, char* buf, double maxw, int& n, double &width, int wrap) {

  char* o = buf;
  char* e = buf+(MAXBUF-4);
  underline_at = 0;
  char* word_end = o;
  const char* word_start = from;
  double w = 0;

  const char* p = from;
  for (;; p++) {

    int c = *p & 255;

    if (!c || c == ' ' || c == '\n') {
      // test for word-wrap:
      if (word_start < p && wrap) {
	double newwidth = w + fl_width(word_end, o-word_end);
	if (word_end > buf && newwidth > maxw) { // break before this word
	  o = word_end;
	  p = word_start;
	  break;
	}
	word_end = o;
	w = newwidth;
      }
      if (!c) break;
      else if (c == '\n') {p++; break;}
      word_start = p+1;
    }

    if (o > e) break; // don't overflow buffer

    if (c == '\t') {
      for (c = (o-buf)%8; c<8 && o<e; c++) *o++ = ' ';

    } else if (c == '&' && fl_draw_shortcut && *(p+1)) {
      if (*(p+1) == '&') {p++; *o++ = '&';}
      else if (fl_draw_shortcut != 2) underline_at = o;

    } else if (c < ' ' || c == 127) { // ^X
      *o++ = '^';
      *o++ = c ^ 0x40;

   /*
    * mike at easysw.com - The following escaping code causes problems when
    * using the PostScript ISOLatin1 and WinANSI encodings, because these
    * map to I18N characters...
    */
#if 0
    } else if (c >= 128 && c < 0xA0) { // \nnn
      *o++ = '\\';
      *o++ = (c>>6)+'0';
      *o++ = ((c>>3)&7)+'0';
      *o++ = (c&7)+'0';
#endif /* 0 */

    } else if (c == 0xA0) { // non-breaking space
      *o++ = ' ';

    } else {
      *o++ = c;

    }
  }

  width = w + fl_width(word_end, o-word_end);
  *o = 0;
  n = o-buf;
  return p;
}

void fl_draw(
    const char* str,	// the (multi-line) string
    int x, int y, int w, int h,	// bounding box
    Fl_Align align,
    void (*callthis)(const char*,int,int,int)
) {
  const char* p;
  const char* e;
  char buf[MAXBUF];
  int buflen;

  // count how many lines and put the last one into the buffer:
  int lines;
  double width;
  for (p=str,lines=0; ;) {
    e = expand(p, buf, w, buflen, width, align&FL_ALIGN_WRAP);
    lines++;
    if (!*e) break;
    p = e;
  }

  // figure out vertical position of the first line:
  int ypos;
  int height = fl_height();
  if (align & FL_ALIGN_BOTTOM) ypos = y+h-(lines-1)*height;
  else if (align & FL_ALIGN_TOP) ypos = y+height;
  else ypos = y+(h-lines*height)/2+height;

  // now draw all the lines:
  int desc = fl_descent();
  for (p=str; ; ypos += height) {
    if (lines>1) e = expand(p, buf, w, buflen, width, align&FL_ALIGN_WRAP);

    int xpos;
    if (align & FL_ALIGN_LEFT) xpos = x;
    else if (align & FL_ALIGN_RIGHT) xpos = x+w-int(width+.5);
    else xpos = x+int((w-width)/2);

    callthis(buf,buflen,xpos,ypos-desc);

    if (underline_at)
      callthis("_",1,xpos+int(fl_width(buf,underline_at-buf)),ypos-desc);

    if (!*e) break;
    p = e;
  }

}

void fl_draw(
  const char* str,	// the (multi-line) string
  int x, int y, int w, int h,	// bounding box
  Fl_Align align) {
  if (!str || !*str) return;
  if (w && h && !fl_not_clipped(x, y, w, h)) return;
  if (align & FL_ALIGN_CLIP) fl_clip(x, y, w, h);
  fl_draw(str, x, y, w, h, align, fl_draw);
  if (align & FL_ALIGN_CLIP) fl_pop_clip();
}

void fl_measure(const char* str, int& w, int& h) {
  h = fl_height();
  if (!str || !*str) {w = 0; return;}
  const char* p;
  const char* e;
  char buf[MAXBUF];
  int buflen;
  int lines;
  double width;
  int W = 0;
  for (p=str,lines=0; ;) {
    e = expand(p, buf, w, buflen, width, w!=0);
    if (int(width) > W) W = int(width);
    lines++;
    if (!*e) break;
    p = e;
  }
  w = W;
  h = lines*h;
}

//
// End of "$Id: fl_draw.cxx,v 1.1 2006-10-03 11:25:12 dslinux_amadeus Exp $".
//

--- NEW FILE: scandir_win32.c ---
//
// "$Id: scandir_win32.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $"
//
// WIN32 scandir function for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Emulation of posix scandir() call

#include <config.h>
#include <string.h>
#include <windows.h>
#include <stdlib.h>

struct dirent { char d_name[1]; };

int scandir(const char *dirname, struct dirent ***namelist,
    int (*select)(struct dirent *),
    int (*compar)(struct dirent **, struct dirent **)) {
  int len;
  char *findIn, *d;
  WIN32_FIND_DATA find;
  HANDLE h;
  int nDir = 0, NDir = 0;
  struct dirent **dir = 0, *selectDir;
  unsigned long ret;

  len    = strlen(dirname);
  findIn = malloc(len+5);
  strcpy(findIn, dirname);
  for (d = findIn; *d; d++) if (*d=='/') *d='\\';
  if ((len==0)) { strcpy(findIn, ".\\*"); }
  if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); }
  if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; }
  if ((len>1) && (d[-1]=='.') && (d[-2]=='\\')) { d[-1] = '*'; }
  
  if ((h=FindFirstFile(findIn, &find))==INVALID_HANDLE_VALUE) {
    ret = GetLastError();
    if (ret != ERROR_NO_MORE_FILES) {
      // TODO: return some error code
    }
    *namelist = dir;
    return nDir;
  }
  do {
    selectDir=(struct dirent*)malloc(sizeof(struct dirent)+strlen(find.cFileName));
    strcpy(selectDir->d_name, find.cFileName);
    if (!select || (*select)(selectDir)) {
      if (nDir==NDir) {
	struct dirent **tempDir = calloc(sizeof(struct dirent*), NDir+33);
	if (NDir) memcpy(tempDir, dir, sizeof(struct dirent*)*NDir);
	if (dir) free(dir);
	dir = tempDir;
	NDir += 32;
      }
      dir[nDir] = selectDir;
      nDir++;
      dir[nDir] = 0;
    } else {
      free(selectDir);
    }
  } while (FindNextFile(h, &find));
  ret = GetLastError();
  if (ret != ERROR_NO_MORE_FILES) {
    // TODO: return some error code
  }
  FindClose(h);

  free (findIn);

  if (compar) qsort (dir, nDir, sizeof(*dir),
		     (int(*)(const void*, const void*))compar);

  *namelist = dir;
  return nDir;
}

int alphasort (struct dirent **a, struct dirent **b) {
  return strcmp ((*a)->d_name, (*b)->d_name);
}

//
// End of "$Id: scandir_win32.c,v 1.1 2006-10-03 11:25:16 dslinux_amadeus Exp $".
//

--- NEW FILE: mediumarrow.h ---
#define mediumarrow_width 16
#define mediumarrow_height 16
static unsigned char mediumarrow_bits[] = {
   0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00,
   0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f,
   0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02};

--- NEW FILE: Fl_add_idle.cxx ---
//
// "$Id: Fl_add_idle.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Idle routine support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Allows you to manage an arbitrary set of idle() callbacks.
// Replaces the older set_idle() call (which is used to implement this)

#include <FL/Fl.H>

struct idle_cb {
  void (*cb)(void*);
  void* data;
  idle_cb *next;
};

// the callbacks are stored linked in a ring.  last points at the one
// just called, first at the next to call.  last->next == first.

static idle_cb* first;
static idle_cb* last;
static idle_cb* freelist;

static void call_idle() {
  idle_cb* p = first;
  last = p; first = p->next;
  p->cb(p->data); // this may call add_idle() or remove_idle()!
}

void Fl::add_idle(void (*cb)(void*), void* data) {
  idle_cb* p = freelist;
  if (p) freelist = p->next;
  else p = new idle_cb;
  p->cb = cb;
  p->data = data;
  if (first) {
    last->next = p;
    p->next = first;
    first = p;
  } else {
    first = last = p;
    p->next = p;
    set_idle(call_idle);
  }
}

void Fl::remove_idle(void (*cb)(void*), void* data) {
  idle_cb* p = first;
  if (!p) return;
  idle_cb* l = last;
  for (;; p = p->next) {
    if (p->cb == cb && p->data == data) break;
    if (p==last) return; // not found
    l = p;
  }
  if (l == p) { // only one
    first = last = 0;
    set_idle(0);
  } else {
    last = l;
    first = l->next = p->next;
  }
  p->next = freelist;
  freelist = p;
}

//
// End of "$Id: Fl_add_idle.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Gl_Window.cxx ---
//
// "$Id: Fl_Gl_Window.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// OpenGL window code for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

#include <config.h>
#if HAVE_GL

#include <FL/Fl.H>
#include <FL/x.H>
#include <FL/Fl_Gl_Window.H>
#include "Fl_Gl_Choice.H"

////////////////////////////////////////////////////////////////

// The symbol SWAP_TYPE defines what is in the back buffer after doing
// a glXSwapBuffers().

// The OpenGl documentation says that the contents of the backbuffer
// are "undefined" after glXSwapBuffers().  However, if we know what
// is in the backbuffers then we can save a good deal of time.  For
// this reason you can define some symbols to describe what is left in
// the back buffer.

// The default of SWAP_SWAP works on an SGI, and will also work (but
// is sub-optimal) on machines that should be SWAP_COPY or SWAP_NODAMAGE.
// The win32 emulation of OpenGL can use COPY, but some (all?) OpenGL
// cards use SWAP.

// contents of back buffer after glXSwapBuffers():
#define UNDEFINED 0 	// unknown
#define SWAP 1		// former front buffer
#define COPY 2		// unchanged
#define NODAMAGE 3	// unchanged even by X expose() events

#ifdef MESA
#define SWAP_TYPE NODAMAGE
#else
#define SWAP_TYPE SWAP
#endif

//
// Windows may need a different color palette...
//

#if defined(WIN32) && HAVE_GL
extern HPALETTE fl_gl_palette;
#endif

////////////////////////////////////////////////////////////////

int Fl_Gl_Window::can_do(int a, const int *b) {
#ifdef WIN32
  Fl_Gl_Choice *g = Fl_Gl_Choice::find(a,b);
/*
  Is this necessary? Don't all windows have the same 
  support for pixel formats?
  HWND w = GetDesktopWindow();
  HDC dc = GetDC(w);
*/
  if (!fl_gc) fl_GetDC(0);
  int r = ChoosePixelFormat(fl_gc, &g->pfd);
  return r != 0;
#else
  return Fl_Gl_Choice::find(a,b) != 0;
#endif
}

void Fl_Gl_Window::show() {
#ifndef WIN32
  if (!shown()) {
    if (!g) {
      g = Fl_Gl_Choice::find(mode_,alist);
      if (!g) {Fl::error("Insufficient GL support"); return;}
    }
    Fl_X::make_xid(this, g->vis, g->colormap);
    if (overlay && overlay != this) ((Fl_Gl_Window*)overlay)->show();
  }
#endif
  Fl_Window::show();
}

void Fl_Gl_Window::invalidate() {
  valid(0);
#ifndef WIN32
  if (overlay) ((Fl_Gl_Window*)overlay)->valid(0);
#endif
}

int Fl_Gl_Window::mode(int m, const int *a) {
  if (m == mode_ && a == alist) return 0;
  mode_ = m; alist = a;
#ifdef WIN32
  // destroy context and g:
  if (shown()) {hide(); show();}
#else
  // under X, if the visual changes we must make a new X window (!):
  if (shown()) {
    Fl_Gl_Choice *g1 = g;
    g = Fl_Gl_Choice::find(mode_,alist);
    if (!g || g->vis->visualid != g1->vis->visualid || g->d != g1->d) {
      hide(); show();
    }
  }
#endif
  return 1;
}

void Fl_Gl_Window::make_current() {
  if (!context) {
#ifdef WIN32
    context = wglCreateContext(fl_private_dc(this, mode_,&g));
    if (fl_first_context) wglShareLists(fl_first_context, (GLXContext)context);
    else fl_first_context = (GLXContext)context;
#else
    context = glXCreateContext(fl_display, g->vis, fl_first_context, 1);
    if (!fl_first_context) fl_first_context = (GLXContext)context;
#endif
    valid(0);
  }
  fl_set_gl_context(this, (GLXContext)context);
#if defined(WIN32) && USE_COLORMAP
  if (fl_palette) {
    fl_GetDC(fl_xid(this));
    SelectPalette(fl_gc, fl_palette, FALSE);
    RealizePalette(fl_gc);
  }
#endif // USE_COLORMAP
  glDrawBuffer(GL_BACK);
}

void Fl_Gl_Window::ortho() {
  int p[2];
  glGetIntegerv(GL_MAX_VIEWPORT_DIMS, p);
  glLoadIdentity();
  glViewport(w()-p[0], h()-p[1], p[0], p[1]);
  glOrtho(w()-p[0], w(), h()-p[1], h(), -1, 1);
}

void Fl_Gl_Window::swap_buffers() {
#ifdef WIN32
  SwapBuffers(Fl_X::i(this)->private_dc);
#else
  glXSwapBuffers(fl_display, fl_xid(this));
#endif
}

#if HAVE_GL_OVERLAY
#ifdef WIN32
uchar fl_overlay; // changes how fl_color() works
#endif
#endif

void Fl_Gl_Window::flush() {
  make_current();

#if HAVE_GL_OVERLAY
#ifdef WIN32
  uchar save_valid = valid_;
  if (overlay && overlay!= this && damage() == FL_DAMAGE_OVERLAY) goto DRAW_OVERLAY_ONLY;
#endif
#endif

  if (g->d) {

#if SWAP_TYPE == NODAMAGE

    // don't draw if only overlay damage or expose events:
    if ((damage()&~(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE)) || !valid()) draw();
    swap_buffers();

#elif SWAP_TYPE == COPY

    // don't draw if only the overlay is damaged:
    if (damage() != FL_DAMAGE_OVERLAY || !valid()) draw();
    swap_buffers();

#else // SWAP_TYPE == SWAP || SWAP_TYPE == UNDEFINED

    if (overlay == this) { // Use CopyPixels to act like SWAP_TYPE == COPY

      // don't draw if only the overlay is damaged:
      if (damage1_ || damage() != FL_DAMAGE_OVERLAY || !valid()) draw();
      // we use a seperate context for the copy because rasterpos must be 0
      // and depth test needs to be off:
      static GLXContext ortho_context;
      int init = !ortho_context;
#ifdef WIN32
      if (init) ortho_context = wglCreateContext(Fl_X::i(this)->private_dc);
#else
      if (init)
	ortho_context = glXCreateContext(fl_display,g->vis,fl_first_context,1);
#endif
      fl_set_gl_context(this, ortho_context);
      if (init) {
	glDisable(GL_DEPTH_TEST);
	glReadBuffer(GL_BACK);
	glDrawBuffer(GL_FRONT);
      }
      glCopyPixels(0,0,w(),h(),GL_COLOR);
      make_current(); // set current context back to draw overlay
      damage1_ = 0;

    } else {

#if SWAP_TYPE == SWAP
      uchar old_damage = damage();
      clear_damage(damage1_|old_damage); draw();
      swap_buffers();
      damage1_ = old_damage;
#else // SWAP_TYPE == UNDEFINED
      clear_damage(~0); draw();
      swap_buffers();
      damage1_ = ~0;
#endif

    }
#endif

    if (overlay==this) { // fake overlay in front buffer
      glDrawBuffer(GL_FRONT);
      draw_overlay();
      glDrawBuffer(GL_BACK);
      glFlush();
    }

  } else {	// single-buffered context is simpler:

    draw();
    if (overlay == this) draw_overlay();
    glFlush();

  }

#if HAVE_GL_OVERLAY
#ifdef WIN32
  if (overlay && overlay != this) {
  DRAW_OVERLAY_ONLY:
    valid_ = save_valid;
    fl_set_gl_context(this, (GLXContext)overlay);
    glDisable(GL_SCISSOR_TEST);
    fl_overlay = 1;
    glClear(GL_COLOR_BUFFER_BIT);
    draw_overlay();
    wglSwapLayerBuffers(Fl_X::i(this)->private_dc,WGL_SWAP_OVERLAY1);
    fl_overlay = 0;
  }
#endif
#endif

  valid(1);
}

void Fl_Gl_Window::resize(int X,int Y,int W,int H) {
  if (W != w() || H != h()) valid(0);
  Fl_Window::resize(X,Y,W,H);
}

void Fl_Gl_Window::hide() {
  if (context) {
    fl_no_gl_context();
#ifdef WIN32
    if (context && context != fl_first_context)
      wglDeleteContext((GLXContext)context);
    g = 0;
#else
    if (context != fl_first_context)
      glXDestroyContext(fl_display, (GLXContext)context);
#ifdef GLX_MESA_release_buffers
    glXReleaseBuffersMESA(fl_display, fl_xid(this));
#endif
#endif
    context = 0;
  }
  Fl_Window::hide();
}

Fl_Gl_Window::~Fl_Gl_Window() {
  hide();
//  delete overlay; this is done by ~Fl_Group
}

void Fl_Gl_Window::init() {
  end(); // we probably don't want any children
  box(FL_NO_BOX);
  mode_ = FL_RGB | FL_DEPTH | FL_DOUBLE;
  alist = 0;
  context = 0;
  g = 0;
  overlay = 0;
  damage1_ = 0;
}

void Fl_Gl_Window::draw_overlay() {}

#endif

//
// End of "$Id: Fl_Gl_Window.cxx,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: Fl_Font.H ---
//
// "$Id: Fl_Font.H,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $"
//
// Font definitions for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Two internal fltk data structures:
//
// Fl_Fontdesc: an entry into the fl_font() table.  There is one of these
// for each fltk font number.
//
// Fl_FontSize: a structure for an actual system font, with junk to
// help choose it and info on character sizes.  Each Fl_Fontdesc has a
// linked list of these.  These are created the first time each system
// font/size combination is used.

#ifndef FL_FONT_
#define FL_FONT_

class Fl_FontSize {
public:
  Fl_FontSize *next;	// linked list for this Fl_Fontdesc
#ifndef WIN32

#ifdef NANO_X //tanghao
	GR_FONT_ID font;	
	bool isTTF;	// is a truetype font
	void Resize(int size);	// resize an existing font
public:
#else
  XFontStruct* font;	// X font information
#endif //tanghao
  FL_EXPORT Fl_FontSize(const char* fontname, int size = 16);
#else // not WIN32
  HFONT fid;
  int width[256];
  TEXTMETRIC metr;
  FL_EXPORT Fl_FontSize(const char* fontname, int size = 16);
#endif // WIN32
  int minsize;		// smallest point size that should use this
  int maxsize;		// largest point size that should use this

#if HAVE_GL
  unsigned int listbase;// base of display list, 0 = none
#endif
  FL_EXPORT ~Fl_FontSize();
};

extern FL_EXPORT Fl_FontSize *fl_fontsize; // the currently selected one

struct Fl_Fontdesc {
  const char *name;
  Fl_FontSize *first;	// linked list of sizes of this style
#ifndef WIN32
  char **xlist;		// matched X font names
  int n;		// size of xlist, negative = don't free xlist!
#endif
};

extern FL_EXPORT Fl_Fontdesc *fl_fonts; // the table

#ifndef WIN32
// functions for parsing X font names:
FL_EXPORT const char* fl_font_word(const char *p, int n);
FL_EXPORT char *fl_find_fontsize(char *name);
#endif

#endif

//
// End of "$Id: Fl_Font.H,v 1.1 2006-10-03 11:25:08 dslinux_amadeus Exp $".
//

--- NEW FILE: d1.xbm ---
#define d1_width 16
#define d1_height 16
static unsigned char d1_bits[] = {
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
   0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
   0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

--- NEW FILE: Fl_Value_Output.cxx ---
//
// "$Id: Fl_Value_Output.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $"
//
// Value output widget for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// Fltk widget for drag-adjusting a floating point value.
// This is much lighter than Fl_Value_Input because it has no text editor
// If step() is zero then it can be used to display a floating-point value

#include <FL/Fl.H>
#include <FL/Fl_Value_Output.H>
#include <FL/fl_draw.H>

void Fl_Value_Output::draw() {
  Fl_Boxtype b = box() ? box() : FL_DOWN_BOX;
  int X = x()+Fl::box_dx(b);
  int Y = y()+Fl::box_dy(b);
  int W = w()-Fl::box_dw(b);
  int H = h()-Fl::box_dh(b);
  if (damage()&~FL_DAMAGE_CHILD)
    draw_box(b, color());
  else {
    fl_color(color());
    fl_rectf(X, Y, W, H);
  }
  char buf[128];
  format(buf);
  fl_color(active_r() ? textcolor() : inactive(textcolor()));
  fl_font(textfont(), textsize());
  fl_draw(buf,X+3,Y,W-6,H,FL_ALIGN_LEFT);
}

int Fl_Value_Output::handle(int event) {
  if (!step()) return 0;
  double v;
  int delta;
  int mx = Fl::event_x();
  static int ix, drag;
  switch (event) {
  case FL_PUSH:
    ix = mx;
    drag = Fl::event_button();
    handle_push();
    return 1;
  case FL_DRAG:
    delta = Fl::event_x()-ix;
    if (delta > 5) delta -= 5;
    else if (delta < -5) delta += 5;
    else delta = 0;
    switch (drag) {
    case 3: v = increment(previous_value(),delta*100); break;
    case 2: v = increment(previous_value(),delta*10); break;
    default:v = increment(previous_value(),delta); break;
    }
    v = round(v);
    handle_drag(soft()?softclamp(v):clamp(v));;
    return 1;
  case FL_RELEASE:
    handle_release();
    return 1;
  default:
    return 0;
  }
}

Fl_Value_Output::Fl_Value_Output(int x,int y,int w,int h,const char *l)
: Fl_Valuator(x,y,w,h,l) {
  box(FL_NO_BOX);
  align(FL_ALIGN_LEFT);
  textfont_ = FL_HELVETICA;
  textsize_ = FL_NORMAL_SIZE;
  textcolor_ = FL_BLACK;
  soft_ = 0;
}

//
// End of "$Id: Fl_Value_Output.cxx,v 1.1 2006-10-03 11:25:10 dslinux_amadeus Exp $".
//

--- NEW FILE: ns.xbm ---
#define ns_width 16
#define ns_height 16
#define ns_x_hot 8
#define ns_y_hot 8
static unsigned char ns_bits[] = {
   0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
   0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
   0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00};

--- NEW FILE: fl_set_fonts_win32.cxx ---
//
// "$Id: fl_set_fonts_win32.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $"
//
// WIN32 font utilities for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-1999 by Bill Spitzak and others.
//
// 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 at easysw.com".
//

// This function fills in the fltk font table with all the fonts that
// are found on the X server.  It tries to place the fonts into families
// and to sort them so the first 4 in a family are normal, bold, italic,
// and bold italic.

#include <FL/Fl.H>
#include <FL/win32.H>
#include "Fl_Font.H"
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

// turn a stored font name into a pretty name:
const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
  const char* p = fl_fonts[fnum].name;
  if (!p || !*p) {if (ap) *ap = 0; return "";}
  int type;
  switch (*p) {
  case 'B': type = FL_BOLD; break;
  case 'I': type = FL_ITALIC; break;
  case 'P': type = FL_BOLD | FL_ITALIC; break;
  default:  type = 0; break;
  }
  if (!type) return p+1;
  static char *buffer; if (!buffer) buffer = new char[128];
  strcpy(buffer, p+1);
  if (type & FL_BOLD) strcat(buffer, " bold");
  if (type & FL_ITALIC) strcat(buffer, " italic");
  return buffer;
}

static int fl_free_font = FL_FREE_FONT;

static int CALLBACK enumcb(ENUMLOGFONT FAR *lpelf,
  NEWTEXTMETRIC FAR *lpntm, int FontType, LPARAM p) {
  if (!p && lpelf->elfLogFont.lfCharSet != ANSI_CHARSET) return 1;
  char *n = (char*)(lpelf->elfFullName);
  for (int i=0; i<FL_FREE_FONT; i++) // skip if one of our built-in fonts
    if (!strcmp(Fl::get_font_name((Fl_Font)i),n)) return 1;
  char buffer[128];
  strcpy(buffer+1, n);
  buffer[0] = ' '; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
  if (lpelf->elfLogFont.lfWeight <= 400)
    buffer[0] = 'B', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
  buffer[0] = 'I'; Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
  if (lpelf->elfLogFont.lfWeight <= 400)
    buffer[0] = 'P', Fl::set_font((Fl_Font)(fl_free_font++), strdup(buffer));
  return 1;
}

Fl_Font Fl::set_fonts(const char* xstarname) {
  EnumFontFamilies(fl_gc, NULL, (FONTENUMPROC)enumcb, xstarname != 0);
  return (Fl_Font)fl_free_font;
}

int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
  // pretend all fonts are scalable (most are and I don't know how
  // to tell anyways)
  static int array[1];
  sizep = array;
  return 1;
}

//
// End of "$Id: fl_set_fonts_win32.cxx,v 1.1 2006-10-03 11:25:15 dslinux_amadeus Exp $".
//




More information about the dslinux-commit mailing list